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
237237GPUdi () 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