From d9ba1754584287487353ca765c4bfdfc711612f1 Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Wed, 14 Oct 2026 23:42:14 +0200 Subject: [PATCH] GPU: let the constant-address-space constants be built on Metal A constructor's implicit `this` is generic in MSL 4.1, and a generic pointer does not reach the constant address space, so a class-type constant at program scope could not be constructed at all: gpustd::bitset for the DetID and GlobalTrackID masks, CfChargePos for INVALID_CHARGE_POS. MSL lets a member function be qualified with the address space of its `this`, so each of the two constructors gains a constant-qualified overload next to the existing one; for bitset that sits next to the __constant copy constructor OpenCL already needs for the same reason. Reading those constants back needs nothing further, with one exception: sTrackSources is derived with operator| from the constant sMasks and then indexed by isTrackSource. Rather than give bitset constant-qualified accessors as well, that pair is left out of device code on Metal exactly as it already is on OpenCL; its only caller is on the host. --- .../include/ReconstructionDataFormats/GlobalTrackID.h | 4 ++-- GPU/GPUTracking/TPCClusterFinder/CfChargePos.h | 3 +++ GPU/Utils/GPUCommonBitSet.h | 3 +++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h index 63515261e544b..722dc75edb93a 100644 --- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h +++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h @@ -165,7 +165,7 @@ GPUconstexpr() GlobalTrackID::mask_t sMasks[GlobalTrackID::NSources] = ///< dete GlobalTrackID::mask_t(math_utils::bit2Mask(GlobalTrackID::MCHMID)) // Temporary ordering }; -#ifndef __OPENCL__ +#if !defined(__OPENCL__) && !defined(__METAL__) GPUconstexpr() GlobalTrackID::mask_t sTrackSources = sMasks[GlobalTrackID::ITS] | sMasks[GlobalTrackID::TPC] | sMasks[GlobalTrackID::MFT] | sMasks[GlobalTrackID::MCH] | sMasks[GlobalTrackID::ITSTPC] | sMasks[GlobalTrackID::TPCTOF] | sMasks[GlobalTrackID::TPCTRD] | sMasks[GlobalTrackID::MFTMCH] | sMasks[GlobalTrackID::ITSTPCTRD] | sMasks[GlobalTrackID::ITSTPCTOF] | sMasks[GlobalTrackID::TPCTRDTOF] | @@ -177,7 +177,7 @@ GPUconstexpr() GlobalTrackID::mask_t sTrackSources = GPUdi() constexpr GlobalTrackID::DetID::mask_t GlobalTrackID::getSourceDetectorsMask(int i) { return globaltrackid_internal::SourceDetectorsMasks[i]; } GPUdi() constexpr GlobalTrackID::mask_t GlobalTrackID::getSourceMask(int s) { return globaltrackid_internal::sMasks[s]; } -#ifndef __OPENCL__ +#if !defined(__OPENCL__) && !defined(__METAL__) GPUdi() bool GlobalTrackID::isTrackSource(int s) { return globaltrackid_internal::sTrackSources[s]; diff --git a/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h b/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h index 3f1265e6d0634..38d6c78d1bb6e 100644 --- a/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h +++ b/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h @@ -34,6 +34,9 @@ struct CfChargePos { : gpad(tpcGlobalPadIdx(row, pad)), timePadded(t + GPUCF_PADDING_TIME) { } +#ifdef __METAL__ + constexpr GPUhdi() CfChargePos(tpccf::Row row, tpccf::Pad pad, tpccf::TPCFragmentTime t) constant : gpad(tpcGlobalPadIdx(row, pad)), timePadded(t + GPUCF_PADDING_TIME) {} +#endif GPUdi() CfChargePos(const tpccf::GlobalPad& p, const tpccf::TPCFragmentTime& t) : gpad(p), timePadded(t) {} diff --git a/GPU/Utils/GPUCommonBitSet.h b/GPU/Utils/GPUCommonBitSet.h index e35587ab60c7b..8e2331a1155b9 100644 --- a/GPU/Utils/GPUCommonBitSet.h +++ b/GPU/Utils/GPUCommonBitSet.h @@ -47,6 +47,9 @@ class bitset GPUdDefault() constexpr bitset(const __constant bitset&) = default; #endif // __OPENCL__ GPUd() constexpr bitset(uint32_t vv) : v(vv) {}; +#ifdef __METAL__ + GPUd() constexpr bitset(uint32_t vv) constant : v(vv) {}; +#endif static GPUglobalconstexpr() uint32_t full_set = ((1ul << N) - 1ul); GPUd() constexpr bool all() const { return (v & full_set) == full_set; }