Skip to content

Commit 7675f01

Browse files
authored
GPU: Metal branches in the common array and math helpers (#15801)
MSL provides its own array type, so std::array aliases to it rather than using the device fallback. GPUCommonMath routes rsqrt and the atomics to their MSL spellings (atomic_*_explicit).
1 parent 9fbf915 commit 7675f01

2 files changed

Lines changed: 18 additions & 6 deletions

File tree

GPU/Common/GPUCommonArray.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
#include "GPUCommonDef.h"
2525
namespace std
2626
{
27-
#ifdef GPUCA_GPUCODE_DEVICE
27+
#ifdef __METAL__
28+
using ::array;
29+
#elif defined(GPUCA_GPUCODE_DEVICE)
2830
template <typename T, size_t N>
2931
struct array {
3032
GPUd() T& operator[](size_t i) { return m_internal_V__[i]; };

GPU/Common/GPUCommonMath.h

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@
3333
#include <cstdint>
3434
#endif
3535

36-
// GPUCA_CHOICE Syntax: GPUCA_CHOICE(Host, CUDA&HIP, OpenCL)
36+
// GPUCA_CHOICE Syntax: GPUCA_CHOICE(Host, CUDA&HIP, OpenCL&Metal)
3737
#if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__)) // clang-format off
3838
#define GPUCA_CHOICE(c1, c2, c3) (c2) // Select second option for CUDA and HIP
39-
#elif defined(GPUCA_GPUCODE_DEVICE) && defined (__OPENCL__)
40-
#define GPUCA_CHOICE(c1, c2, c3) (c3) // Select third option for OpenCL
39+
#elif defined(GPUCA_GPUCODE_DEVICE) && (defined(__OPENCL__) || defined(__METAL__))
40+
#define GPUCA_CHOICE(c1, c2, c3) (c3) // Select third option for OpenCL and Metal
4141
#else
4242
#define GPUCA_CHOICE(c1, c2, c3) (c1) // Select first option for Host
4343
#endif // clang-format on
@@ -236,7 +236,7 @@ GPUdi() constexpr T GPUCommonMath::nextMultipleOf(T val)
236236

237237
GPUdi() float2 GPUCommonMath::MakeFloat2(float x, float y)
238238
{
239-
#if !defined(GPUCA_GPUCODE) || defined(__OPENCL__) || defined(__OPENCL_HOST__)
239+
#if !defined(GPUCA_GPUCODE) || defined(__OPENCL__) || defined(__OPENCL_HOST__) || defined(__METAL__) || defined(__METAL_HOST__)
240240
float2 ret = {x, y};
241241
return ret;
242242
#else
@@ -421,7 +421,7 @@ GPUdi() float GPUCommonMath::InvSqrt(float _x)
421421
, // !GPUCA_DETERMINISTIC_CODE
422422
#if defined(__CUDACC__) || defined(__HIPCC__)
423423
return __frsqrt_rn(_x);
424-
#elif defined(__OPENCL__) && defined(__clang__)
424+
#elif (defined(__OPENCL__) || defined(__METAL__)) && defined(__clang__)
425425
return 1.f / sqrt(_x);
426426
#elif !defined(__OPENCL__) && (defined(__FAST_MATH__) || defined(__clang__))
427427
return 1.f / sqrtf(_x);
@@ -465,6 +465,8 @@ GPUdi() uint32_t GPUCommonMath::AtomicExchInternal(S* addr, T val)
465465
return ::atomic_xchg(addr, val);
466466
#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
467467
return ::atomicExch(addr, val);
468+
#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
469+
return atomic_exchange_explicit(addr, val, memory_order_relaxed);
468470
#elif defined(WITH_OPENMP)
469471
uint32_t old;
470472
__atomic_exchange(addr, &val, &old, __ATOMIC_SEQ_CST);
@@ -483,6 +485,8 @@ GPUdi() bool GPUCommonMath::AtomicCASInternal(S* addr, T cmp, T val)
483485
return ::atomic_cmpxchg(addr, cmp, val) == cmp;
484486
#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
485487
return ::atomicCAS(addr, cmp, val) == cmp;
488+
#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
489+
return atomic_compare_exchange_weak_explicit(addr, &cmp, val, memory_order_relaxed, memory_order_relaxed);
486490
#elif defined(WITH_OPENMP)
487491
return __atomic_compare_exchange(addr, &cmp, &val, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
488492
#else
@@ -499,6 +503,8 @@ GPUdi() uint32_t GPUCommonMath::AtomicAddInternal(S* addr, T val)
499503
return ::atomic_add(addr, val);
500504
#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
501505
return ::atomicAdd(addr, val);
506+
#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
507+
return atomic_fetch_add_explicit(addr, val, memory_order_relaxed);
502508
#elif defined(WITH_OPENMP)
503509
return __atomic_add_fetch(addr, val, __ATOMIC_SEQ_CST) - val;
504510
#else
@@ -515,6 +521,8 @@ GPUdi() void GPUCommonMath::AtomicMaxInternal(S* addr, T val)
515521
::atomic_max(addr, val);
516522
#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
517523
::atomicMax(addr, val);
524+
#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
525+
atomic_fetch_max_explicit(addr, val, memory_order_relaxed);
518526
#else
519527
S current;
520528
while ((current = *(volatile S*)addr) < val && !AtomicCASInternal(addr, current, val)) {
@@ -531,6 +539,8 @@ GPUdi() void GPUCommonMath::AtomicMinInternal(S* addr, T val)
531539
::atomic_min(addr, val);
532540
#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
533541
::atomicMin(addr, val);
542+
#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
543+
atomic_fetch_min_explicit(addr, val, memory_order_relaxed);
534544
#else
535545
S current;
536546
while ((current = *(volatile S*)addr) > val && !AtomicCASInternal(addr, current, val)) {

0 commit comments

Comments
 (0)