Skip to content

Commit c0e4d40

Browse files
committed
MathUtils: make SMatrixGPU compile as MSL
Three separate issues: * Metal has no static storage duration inside a function, so MatRepSymGPU::off() drops the static on its offset table. Nothing is lost by dropping it everywhere rather than forking: arrays, unlike scalars, are emitted into read-only data either way. On the host it is marginally better, since the static form reached the table through the GOT. * operator=(Expr) now takes the expression by value. MSL folds the address space into a deduced parameter, so the generic operator=(const M&) deduced M = thread Expr<...>, matched exactly, beat the Expr overload and then tried mRep = rhs.mRep on an expression. A by-value parameter has no address space to deduce, so the Expr overload wins on Metal as it already did elsewhere. Expr is two references, so there is no copy cost. * Metal supports up to C++17, so it needs the same treatment as OpenCL for a requires-clause.
1 parent 0f3fb8b commit c0e4d40

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ class MatRepSymGPU
340340

341341
static GPUdi() int off(int i)
342342
{
343-
static constexpr auto v = row_offsets_utils::make<D * D>(off1);
343+
constexpr auto v = row_offsets_utils::make<D * D>(off1);
344344
return v[i];
345345
}
346346

@@ -456,7 +456,7 @@ class SMatrixGPU
456456
template <class M>
457457
GPUd() SMatrixGPU<T, D1, D2, R>& operator=(const M& rhs);
458458
template <class A, class R2>
459-
GPUd() SMatrixGPU<T, D1, D2, R>& operator=(const Expr<A, T, D1, D2, R2>& rhs);
459+
GPUd() SMatrixGPU<T, D1, D2, R>& operator=(Expr<A, T, D1, D2, R2> rhs);
460460
enum {
461461
kRows = D1, // rows
462462
kCols = D2, // columns
@@ -518,7 +518,7 @@ class SMatrixGPU
518518
R mRep;
519519
};
520520

521-
#ifndef __OPENCL__ // TODO: current C++ for OpenCL 2021 is at C++17, so no concepts. But we don't need this trick for OpenCL anyway, so we can just hide it.
521+
#if !defined(__OPENCL__) && !defined(__METAL__) // TODO: current C++ for OpenCL 2021 and MSL 4.1 are both at C++17, so no concepts. But we don't need this trick there anyway, so we can just hide it.
522522
template <class T, unsigned int D1, unsigned int D2, class R, typename Y, typename X = Y>
523523
requires(sizeof(typename X::traits_type::pos_type) != 0) // do not provide a template to fair::Logger, etc... (pos_type is a member type of all std::ostream classes)
524524
GPUd() X& operator<<(Y& y, const SMatrixGPU<T, D1, D2, R>&)
@@ -677,7 +677,7 @@ struct AssignSym {
677677

678678
template <class T, unsigned int D1, unsigned int D2, class R>
679679
template <class A, class R2>
680-
GPUdi() SMatrixGPU<T, D1, D2, R>& SMatrixGPU<T, D1, D2, R>::operator=(const Expr<A, T, D1, D2, R2>& rhs)
680+
GPUdi() SMatrixGPU<T, D1, D2, R>& SMatrixGPU<T, D1, D2, R>::operator=(Expr<A, T, D1, D2, R2> rhs)
681681
{
682682
Assign<T, D1, D2, A, R, R2>::Evaluate(*this, rhs);
683683
return *this;

0 commit comments

Comments
 (0)