|
27 | 27 | //Define macros for GPU keywords. i-version defines inline functions. |
28 | 28 | //All host-functions in GPU code are automatically inlined, to avoid duplicate symbols. |
29 | 29 | //For non-inline host only functions, use no keyword at all! |
30 | | -#if !defined(GPUCA_GPUCODE) || defined(__OPENCL_HOST__) // For host / ROOT dictionary |
| 30 | +#if !defined(GPUCA_GPUCODE) || defined(__OPENCL_HOST__) || defined(__METAL_HOST__) // For host / ROOT dictionary |
31 | 31 | #define GPUd() // device function |
32 | 32 | #define GPUdDefault() // default (constructor / operator) device function |
33 | 33 | #define GPUhdDefault() // default (constructor / operator) host device function |
|
124 | 124 | #if (!defined(__OPENCL__) || !defined(GPUCA_NO_CONSTANT_MEMORY)) |
125 | 125 | #define GPUconstantref() GPUconstant() |
126 | 126 | #endif |
| 127 | +#elif defined(__METAL__) //Defines for Metal Shading Language |
| 128 | + // ADDRESS SPACES. This backend targets MSL 4.1 (macOS 27) and later only -- |
| 129 | + // see -std=metal4.1 in the CMakeLists, which fails the build on anything |
| 130 | + // older rather than miscompiling quietly. |
| 131 | + // |
| 132 | + // That version is what makes the port tractable: up to MSL 4.0 a member |
| 133 | + // function's implicit `this` is `thread`, which is wrong for us, since most |
| 134 | + // objects the kernels touch live in `device` memory. Pinning defaulted |
| 135 | + // constructors and operators to `device` was the 4.0 workaround, and it made |
| 136 | + // the same type unusable in `thread` or `threadgroup`. In 4.1 an unannotated |
| 137 | + // `this` is GENERIC and resolves to whichever address space the object is in |
| 138 | + // -- the C++ semantics this codebase already assumes -- so GPUdDefault() |
| 139 | + // needs nothing at all. The compiler resolves it statically in almost every |
| 140 | + // case; it only falls back to a runtime branch where it cannot see through, |
| 141 | + // such as argument buffers or dynamic libraries. |
| 142 | + // |
| 143 | + // The *ref() macros below stay explicit even so. They are already correct |
| 144 | + // from the OpenCL port, an explicit annotation is never slower than a generic |
| 145 | + // one, and `constant` is not covered by generic pointers at all. |
| 146 | + #define GPUdDefault() // generic `this` (MSL 4.1+) |
| 147 | + #define GPUd() |
| 148 | + #define GPUhdDefault() |
| 149 | + #define GPUdi() inline |
| 150 | + #define GPUdii() inline |
| 151 | + #define GPUdni() |
| 152 | + #define GPUdnii() |
| 153 | + #define GPUh() inline |
| 154 | + #define GPUhi() inline |
| 155 | + #define GPUhd() inline |
| 156 | + #define GPUhdi() inline |
| 157 | + #define GPUhdni() |
| 158 | + #define GPUg() kernel |
| 159 | + #define GPUshared() threadgroup |
| 160 | + #define GPUglobal() device |
| 161 | + #define GPUconstant() constant // TODO: possibly add const __restrict where possible later! |
| 162 | + #define GPUconstexpr() constant |
| 163 | + #define GPUprivate() thread |
| 164 | + #define GPUgeneric() |
| 165 | + #define GPUglobalref() device |
| 166 | + #define GPUsharedref() threadgroup |
| 167 | + #define GPUprivateref() thread |
| 168 | + #define GPUconstantref() constant |
| 169 | + #define GPUconstexprref() GPUconstexpr() |
| 170 | + #define GPUdouble() float |
| 171 | + #define GPUbarrier() threadgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup) |
| 172 | + #define GPUbarrierWarp() simdgroup_barrier(mem_flags::mem_device | mem_flags::mem_threadgroup) |
| 173 | + #define GPUAtomic(type) atomic<type> // atomic variable type |
127 | 174 | #elif defined(__HIPCC__) //Defines for HIP |
128 | 175 | #define GPUd() __device__ |
129 | 176 | #define GPUdDefault() __device__ |
|
230 | 277 | #define get_group_id(dim) iBlock |
231 | 278 | #endif |
232 | 279 |
|
233 | | - // clang-format on |
| 280 | +// clang-format on |
234 | 281 | #endif |
0 commit comments