Skip to content

Commit 18c429a

Browse files
committed
MathUtils: materialise the product in SMatrixGPU's operator*=
Unlike ROOT's SMatrix, where the product of two matrices is a matrix, SMatrixGPU returns a lazy expression, and every element of that expression reads the whole of the left operand. Assigning it back element by element therefore reads values that have already been overwritten. It also did not compile: the expression matched the generic operator= that copies the representation, which an expression does not have. This was unreachable until now, since nothing instantiated a matrix multiply assignment in device code.
1 parent 5e1b1f9 commit 18c429a

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

‎Common/MathUtils/include/MathUtils/SMatrixGPU.h‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,14 +1433,18 @@ template <class T, unsigned int D1, unsigned int D2, class R>
14331433
template <class R2>
14341434
GPUdi() SMatrixGPU<T, D1, D2, R>& SMatrixGPU<T, D1, D2, R>::operator*=(const SMatrixGPU<T, D1, D2, R2>& rhs)
14351435
{
1436-
return operator=(*this* rhs);
1436+
// the product is an expression evaluated element by element, and every element
1437+
// of it reads the whole of *this, so it has to be materialised first
1438+
const SMatrixGPU<T, D1, D2, R> tmp(*this * rhs);
1439+
return operator=(tmp);
14371440
}
14381441

14391442
template <class T, unsigned int D1, unsigned int D2, class R>
14401443
template <class A, class R2>
14411444
GPUdi() SMatrixGPU<T, D1, D2, R>& SMatrixGPU<T, D1, D2, R>::operator*=(const Expr<A, T, D1, D2, R2>& rhs)
14421445
{
1443-
return operator=(*this* rhs);
1446+
const SMatrixGPU<T, D1, D2, R> tmp(*this * rhs);
1447+
return operator=(tmp);
14441448
}
14451449

14461450
template <class T, unsigned int D1, unsigned int D2, class R>

0 commit comments

Comments
 (0)