From f2d5321e4b22f49aa756c1ccb9c7dfe562aa315a Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 15 Sep 2026 13:19:24 +0200 Subject: [PATCH 1/2] GPU: fix typo --- GPU/Common/GPUCommonTypeTraits.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GPU/Common/GPUCommonTypeTraits.h b/GPU/Common/GPUCommonTypeTraits.h index a51a4ac50683f..92fe7fb316d9f 100644 --- a/GPU/Common/GPUCommonTypeTraits.h +++ b/GPU/Common/GPUCommonTypeTraits.h @@ -33,7 +33,7 @@ struct conditional { typedef F type; }; template -using contitional_t = typename conditional::type; +using conditional_t = typename conditional::type; template struct is_same { From 0663dd66cc3e48f76f416bc53c2f924f3e778cdd Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Tue, 15 Sep 2026 13:19:36 +0200 Subject: [PATCH 2/2] GPU: provide the std type_traits subset used on Metal MSL has no standard library, so the handful of traits the GPU code relies on are defined for __METAL__, as is already done for the other device compilers. --- GPU/Common/GPUCommonDef.h | 2 +- GPU/Common/GPUCommonTypeTraits.h | 32 ++++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/GPU/Common/GPUCommonDef.h b/GPU/Common/GPUCommonDef.h index 28768b57c43de..6e2269650f576 100644 --- a/GPU/Common/GPUCommonDef.h +++ b/GPU/Common/GPUCommonDef.h @@ -31,7 +31,7 @@ #include "GPUCommonDefSettings.h" #if !defined(__CLING__) && !defined(G__ROOT) // No GPU code for ROOT - #if defined(__CUDACC__) || defined(__OPENCL__) || defined(__HIPCC__) || defined(__OPENCL_HOST__) || defined(__METAL_HOST__) + #if defined(__CUDACC__) || defined(__OPENCL__) || defined(__HIPCC__) || defined(__OPENCL_HOST__) || defined(__METAL__) || defined(__METAL_HOST__) #define GPUCA_GPUCODE // Compiled by GPU compiler #endif diff --git a/GPU/Common/GPUCommonTypeTraits.h b/GPU/Common/GPUCommonTypeTraits.h index 92fe7fb316d9f..3f83e151b0f33 100644 --- a/GPU/Common/GPUCommonTypeTraits.h +++ b/GPU/Common/GPUCommonTypeTraits.h @@ -21,7 +21,16 @@ #ifndef GPUCA_GPUCODE_COMPILEKERNELS #include #endif +#else // OpenCL C++ and Metal, neither of which provides +// Spelled for MSL, which OpenCL C++ also accepts, so both backends share one implementation: +// enum values because program scope variables must be constant (MSL 4.1 spec, sec. 4.2), and +// is_pointer / is_member_pointer forward rather than inherit because MSL has no derived classes +// (sec. 1.5.4). Bare T* / T& need no address space: a partial specialization matches them all. +#ifdef __METAL__ +#define GPUCA_TT_PROGRAMSCOPE constant #else +#define GPUCA_TT_PROGRAMSCOPE // not empty-by-default: in OpenCL 'constant' would mean __constant +#endif namespace std { template @@ -37,14 +46,14 @@ using conditional_t = typename conditional::type; template struct is_same { - static constexpr bool value = false; + enum { value = false }; }; template struct is_same { - static constexpr bool value = true; + enum { value = true }; }; template -static constexpr bool is_same_v = is_same::value; +GPUCA_TT_PROGRAMSCOPE static constexpr bool is_same_v = is_same::value; template struct enable_if { @@ -97,14 +106,15 @@ using remove_volatile_t = typename remove_volatile::type; template struct is_pointer_t { - static constexpr bool value = false; + enum { value = false }; }; template struct is_pointer_t { - static constexpr bool value = true; + enum { value = true }; }; template -struct is_pointer : is_pointer_t::type> { +struct is_pointer { + enum { value = is_pointer_t::type>::value }; }; template @@ -124,19 +134,21 @@ using remove_reference_t = typename remove_reference::type; template struct is_member_pointer_helper { - static constexpr bool value = false; + enum { value = false }; }; template struct is_member_pointer_helper { - static constexpr bool value = true; + enum { value = true }; }; template -struct is_member_pointer : is_member_pointer_helper::type> { +struct is_member_pointer { + enum { value = is_member_pointer_helper::type>::value }; }; template -static constexpr bool is_member_pointer_v = is_member_pointer::value; +GPUCA_TT_PROGRAMSCOPE static constexpr bool is_member_pointer_v = is_member_pointer::value; } // namespace std +#undef GPUCA_TT_PROGRAMSCOPE #endif #endif