From d7606e74524faeb62eaf2834ae635eea465b0f69 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 01/17] TRD: place shared constants in the constant address
space
Same treatment the TPC constants already had. MSL requires every variable at
program scope to name an address space, and diagnoses it at the declaration,
so a header full of plain constexpr breaks any device translation unit that
merely includes it -- whether or not the constants are used. GPUglobalconstexpr()
expands to constexpr everywhere except Metal, where it adds constant.
Class-scope static members need it too: MSL counts them as program scope.
constexpr functions do not, and are left alone.
The six vDrift and ExB calibration defaults are double, which does not exist in
MSL at all. They are host-only -- nothing under GPU/ refers to them -- so they
are now compiled out of device code rather than converted, which would have
changed their precision on CUDA and HIP.
Preprocessed output is unchanged for host, CUDA, HIP and cling; device code
sees the same constants minus those six doubles. Together this takes the TRD
headers from 144 errors to 0 in a Metal translation unit.
---
.../TRD/include/DataFormatsTRD/Constants.h | 137 ++++++++-------
.../TRD/base/include/TRDBase/GeometryBase.h | 166 +++++++++---------
2 files changed, 154 insertions(+), 149 deletions(-)
diff --git a/DataFormats/Detectors/TRD/include/DataFormatsTRD/Constants.h b/DataFormats/Detectors/TRD/include/DataFormatsTRD/Constants.h
index 9a4da1024e251..a304bef503973 100644
--- a/DataFormats/Detectors/TRD/include/DataFormatsTRD/Constants.h
+++ b/DataFormats/Detectors/TRD/include/DataFormatsTRD/Constants.h
@@ -16,92 +16,97 @@
#ifndef AliceO2_TRD_Constants_H
#define AliceO2_TRD_Constants_H
+#include "GPUCommonDef.h"
+
namespace o2
{
namespace trd
{
namespace constants
{
-constexpr int NSECTOR = 18; ///< the number of sectors
-constexpr int NSTACK = 5; ///< the number of stacks per sector
-constexpr int NLAYER = 6; ///< the number of layers
-constexpr int NCHAMBERPERSEC = 30; ///< the number of chambers per sector
-constexpr int NHCPERSEC = 60; ///< the number of half-chambers per sector
-constexpr int MAXCHAMBER = 540; ///< the maximum number of installed chambers
-constexpr int MAXHALFCHAMBER = 1080; ///< the maximum number of installed half-chambers
-constexpr int NCHAMBER = 521; ///< the number of chambers actually installed
-constexpr int NHALFCRU = 72; ///< the number of half cru (link bundles)
-constexpr int NLINKSPERHALFCRU = 15; ///< the number of links per half cru or cru end point.
-constexpr int NLINKSPERCRU = 30; ///< the number of links per CRU (two CRUs serve one supermodule)
-constexpr int NCRU = 36; ///< the number of CRU we have
-constexpr int NFLP = 12; ///< the number of FLP we have.
-constexpr int NCRUPERFLP = 3; ///< the number of CRU per FLP
-constexpr int TRDLINKID = 15; ///< hard coded link id, specific to TRD
+GPUglobalconstexpr() int NSECTOR = 18; ///< the number of sectors
+GPUglobalconstexpr() int NSTACK = 5; ///< the number of stacks per sector
+GPUglobalconstexpr() int NLAYER = 6; ///< the number of layers
+GPUglobalconstexpr() int NCHAMBERPERSEC = 30; ///< the number of chambers per sector
+GPUglobalconstexpr() int NHCPERSEC = 60; ///< the number of half-chambers per sector
+GPUglobalconstexpr() int MAXCHAMBER = 540; ///< the maximum number of installed chambers
+GPUglobalconstexpr() int MAXHALFCHAMBER = 1080; ///< the maximum number of installed half-chambers
+GPUglobalconstexpr() int NCHAMBER = 521; ///< the number of chambers actually installed
+GPUglobalconstexpr() int NHALFCRU = 72; ///< the number of half cru (link bundles)
+GPUglobalconstexpr() int NLINKSPERHALFCRU = 15; ///< the number of links per half cru or cru end point.
+GPUglobalconstexpr() int NLINKSPERCRU = 30; ///< the number of links per CRU (two CRUs serve one supermodule)
+GPUglobalconstexpr() int NCRU = 36; ///< the number of CRU we have
+GPUglobalconstexpr() int NFLP = 12; ///< the number of FLP we have.
+GPUglobalconstexpr() int NCRUPERFLP = 3; ///< the number of CRU per FLP
+GPUglobalconstexpr() int TRDLINKID = 15; ///< hard coded link id, specific to TRD
-constexpr int NCOLUMN = 144; ///< the number of pad columns for each chamber
-constexpr int NROWC0 = 12; ///< the number of pad rows for chambers of type C0 (installed in stack 2)
-constexpr int NROWC1 = 16; ///< the number of pad rows for chambers of type C1 (installed in stacks 0, 1, 3 and 4)
-constexpr int FIRSTROW[NSTACK] = {0, 16, 32, 44, 60}; ///< first pad row for each stack
+GPUglobalconstexpr() int NCOLUMN = 144; ///< the number of pad columns for each chamber
+GPUglobalconstexpr() int NROWC0 = 12; ///< the number of pad rows for chambers of type C0 (installed in stack 2)
+GPUglobalconstexpr() int NROWC1 = 16; ///< the number of pad rows for chambers of type C1 (installed in stacks 0, 1, 3 and 4)
+GPUglobalconstexpr() int FIRSTROW[NSTACK] = {0, 16, 32, 44, 60}; ///< first pad row for each stack
-constexpr int NMCMROB = 16; ///< the number of MCMs per ROB
-constexpr int NMCMHCMAX = 64; ///< the maximum number of MCMs for one half chamber (C1 type)
-constexpr int NMCMROBINROW = 4; ///< the number of MCMs per ROB in row direction
-constexpr int NMCMROBINCOL = 4; ///< the number of MCMs per ROB in column direction
-constexpr int NROBC0 = 6; ///< the number of ROBs per C0 chamber
-constexpr int NROBC1 = 8; ///< the number of ROBs per C1 chamber
-constexpr int NADCMCM = 21; ///< the number of ADC channels per MCM
-constexpr int NCOLMCM = 18; ///< the number of pads per MCM
-constexpr int NCHANNELSPERROW = NMCMROBINCOL * 2 * NADCMCM; ///< the number of readout channels per pad row
-constexpr int NCHANNELSC0 = NROWC0 * NCHANNELSPERROW; ///< the number of readout channels per C0 chamber
-constexpr int NCHANNELSC1 = NROWC1 * NCHANNELSPERROW; ///< the number of readout channels per C1 chamber
-constexpr int NCHANNELSTOTAL = NSECTOR * NLAYER * (NSTACK - 1) * NCHANNELSC1 + NSECTOR * NLAYER * NCHANNELSC0; ///< the total number of readout channels for TRD
-constexpr int NCHANNELSPERSECTOR = NCHANNELSTOTAL / NSECTOR; ///< then number of readout channels per sector
-constexpr int NCHANNELSPERLAYER = NCHANNELSPERSECTOR / NLAYER; ///< then number of readout channels per layer
-constexpr int NCPU = 4; ///< the number of CPUs inside the TRAP chip
-constexpr int NCHARGES = 3; ///< the number of charges per tracklet (Q0/1/2)
+GPUglobalconstexpr() int NMCMROB = 16; ///< the number of MCMs per ROB
+GPUglobalconstexpr() int NMCMHCMAX = 64; ///< the maximum number of MCMs for one half chamber (C1 type)
+GPUglobalconstexpr() int NMCMROBINROW = 4; ///< the number of MCMs per ROB in row direction
+GPUglobalconstexpr() int NMCMROBINCOL = 4; ///< the number of MCMs per ROB in column direction
+GPUglobalconstexpr() int NROBC0 = 6; ///< the number of ROBs per C0 chamber
+GPUglobalconstexpr() int NROBC1 = 8; ///< the number of ROBs per C1 chamber
+GPUglobalconstexpr() int NADCMCM = 21; ///< the number of ADC channels per MCM
+GPUglobalconstexpr() int NCOLMCM = 18; ///< the number of pads per MCM
+GPUglobalconstexpr() int NCHANNELSPERROW = NMCMROBINCOL * 2 * NADCMCM; ///< the number of readout channels per pad row
+GPUglobalconstexpr() int NCHANNELSC0 = NROWC0 * NCHANNELSPERROW; ///< the number of readout channels per C0 chamber
+GPUglobalconstexpr() int NCHANNELSC1 = NROWC1 * NCHANNELSPERROW; ///< the number of readout channels per C1 chamber
+GPUglobalconstexpr() int NCHANNELSTOTAL = NSECTOR * NLAYER * (NSTACK - 1) * NCHANNELSC1 + NSECTOR * NLAYER * NCHANNELSC0; ///< the total number of readout channels for TRD
+GPUglobalconstexpr() int NCHANNELSPERSECTOR = NCHANNELSTOTAL / NSECTOR; ///< then number of readout channels per sector
+GPUglobalconstexpr() int NCHANNELSPERLAYER = NCHANNELSPERSECTOR / NLAYER; ///< then number of readout channels per layer
+GPUglobalconstexpr() int NCPU = 4; ///< the number of CPUs inside the TRAP chip
+GPUglobalconstexpr() int NCHARGES = 3; ///< the number of charges per tracklet (Q0/1/2)
// the values below should come out of the TRAP config in the future
-constexpr int NBITSTRKLPOS = 11; ///< number of bits for position in tracklet64 word
-constexpr int NBITSTRKLSLOPE = 8; ///< number of bits for slope in tracklet64 word
-constexpr int ADDBITSHIFTSLOPE = 1 << 3; ///< in the TRAP the slope is shifted by 3 additional bits compared to the position
-constexpr int PADGRANULARITYTRKLPOS = 40; ///< tracklet position is stored in units of 1/40 pad
-constexpr int PADGRANULARITYTRKLSLOPE = 128; ///< tracklet deflection is stored in units of 1/128 pad per time bin
-constexpr float GRANULARITYTRKLPOS = 1.f / PADGRANULARITYTRKLPOS; ///< granularity of position in tracklet64 word in pad-widths
-constexpr float GRANULARITYTRKLSLOPE = 1.f / PADGRANULARITYTRKLSLOPE; ///< granularity of slope in tracklet64 word in pads/timebin
-constexpr int ADCBASELINE = 10; ///< baseline in ADC units
+GPUglobalconstexpr() int NBITSTRKLPOS = 11; ///< number of bits for position in tracklet64 word
+GPUglobalconstexpr() int NBITSTRKLSLOPE = 8; ///< number of bits for slope in tracklet64 word
+GPUglobalconstexpr() int ADDBITSHIFTSLOPE = 1 << 3; ///< in the TRAP the slope is shifted by 3 additional bits compared to the position
+GPUglobalconstexpr() int PADGRANULARITYTRKLPOS = 40; ///< tracklet position is stored in units of 1/40 pad
+GPUglobalconstexpr() int PADGRANULARITYTRKLSLOPE = 128; ///< tracklet deflection is stored in units of 1/128 pad per time bin
+GPUglobalconstexpr() float GRANULARITYTRKLPOS = 1.f / PADGRANULARITYTRKLPOS; ///< granularity of position in tracklet64 word in pad-widths
+GPUglobalconstexpr() float GRANULARITYTRKLSLOPE = 1.f / PADGRANULARITYTRKLSLOPE; ///< granularity of slope in tracklet64 word in pads/timebin
+GPUglobalconstexpr() int ADCBASELINE = 10; ///< baseline in ADC units
// OS: Should this not be flexible for example in case of Kr calib?
-constexpr int TIMEBINS = 30; ///< the number of time bins
-constexpr float MAXIMPACTANGLE = 25.f; ///< the maximum impact angle for tracks relative to the TRD detector plane to be considered for vDrift and ExB calibration
-constexpr int NBINSANGLEDIFF = 25; ///< the number of bins for the track angle used for the vDrift and ExB calibration based on the tracking
+GPUglobalconstexpr() int TIMEBINS = 30; ///< the number of time bins
+GPUglobalconstexpr() float MAXIMPACTANGLE = 25.f; ///< the maximum impact angle for tracks relative to the TRD detector plane to be considered for vDrift and ExB calibration
+GPUglobalconstexpr() int NBINSANGLEDIFF = 25; ///< the number of bins for the track angle used for the vDrift and ExB calibration based on the tracking
+#ifndef GPUCA_GPUCODE_DEVICE
+// calibration defaults, host only: these are double and never used in device code
constexpr double VDRIFTDEFAULT = 1.546; ///< default value for vDrift
constexpr double VDRIFTMIN = 0.4; ///< min value for vDrift
constexpr double VDRIFTMAX = 2.0; ///< max value for vDrift
constexpr double EXBDEFAULT = 0.0; ///< default value for LorentzAngle
constexpr double EXBMIN = -0.4; ///< min value for LorentzAngle
constexpr double EXBMAX = 0.4; ///< max value for LorentzAngle
-constexpr int NBINSGAINCALIB = 320; ///< number of bins in the charge (Q0+Q1+Q2) histogram for gain calibration
-constexpr float MPVDEDXDEFAULT = 42.; ///< default Most Probable Value of TRD dEdx
-constexpr float T0DEFAULT = 1.2; ///< default value for t0
+#endif
+GPUglobalconstexpr() int NBINSGAINCALIB = 320; ///< number of bins in the charge (Q0+Q1+Q2) histogram for gain calibration
+GPUglobalconstexpr() float MPVDEDXDEFAULT = 42.; ///< default Most Probable Value of TRD dEdx
+GPUglobalconstexpr() float T0DEFAULT = 1.2; ///< default value for t0
// array size to store incoming half cru payload.
-constexpr int HBFBUFFERMAX = 1048576; ///< max buffer size for data read from a half cru, (all events)
-constexpr unsigned int CRUPADDING32 = 0xeeeeeeee; ///< padding word used in the cru.
-constexpr int CHANNELNRNOTRKLT = 23; ///< this marks channels in the ADC mask which don't contribute to a tracklet
-constexpr int NOTRACKLETFIT = 31; ///< this value is assigned to the fit pointer in case no tracklet is available
-constexpr int TRACKLETENDMARKER = 0x10001000; ///< marker for the end of tracklets in raw data, 2 of these.
-constexpr int PADDINGWORD = 0xeeeeeeee; ///< half-CRU links will be padded with this words to get an even number of 256bit words
-constexpr int DIGITENDMARKER = 0x0; ///< marker for the end of digits in raw data, 2 of these
-constexpr int MAXDATAPERLINK32 = 13824; ///< max number of 32 bit words per link ((21x12+2+4)*64) 64 mcm, 21 channels, 10 words per channel 2 header words(DigitMCMHeader DigitMCMADCmask) 4 words for tracklets.
-constexpr int MAXDATAPERLINK256 = 1728; ///< max number of linkwords per cru link. (256bit words)
-constexpr int MAXEVENTCOUNTERSEPERATION = 200; ///< how far apart can subsequent mcmheader event counters be before we flag for concern, used as a sanity check in rawreader.
-constexpr int MAXMCMCOUNT = 69120; ///< at most mcm count maxchamber x nrobc1 nmcmrob
-constexpr int MAXLINKERRORHISTOGRAMS = 10; ///< size of the array holding the link error plots from the raw reader
-constexpr int MAXPARSEERRORHISTOGRAMS = 60; ///< size of the array holding the parsing error plots from the raw reader
-constexpr unsigned int ETYPEPHYSICSTRIGGER = 0x2; ///< CRU Half Chamber header eventtype definition
-constexpr unsigned int ETYPECALIBRATIONTRIGGER = 0x3; ///< CRU Half Chamber header eventtype definition
-constexpr int MAXCRUERRORVALUE = 0x2; ///< Max possible value for a CRU Halfchamber link error. As of may 2022, can only be 0x0, 0x1, and 0x2, at least that is all so far(may2022).
-constexpr int INVALIDPRETRIGGERPHASE = 0xf; ///< Invalid value for phase, used to signify there is no hcheader.
+GPUglobalconstexpr() int HBFBUFFERMAX = 1048576; ///< max buffer size for data read from a half cru, (all events)
+GPUglobalconstexpr() unsigned int CRUPADDING32 = 0xeeeeeeee; ///< padding word used in the cru.
+GPUglobalconstexpr() int CHANNELNRNOTRKLT = 23; ///< this marks channels in the ADC mask which don't contribute to a tracklet
+GPUglobalconstexpr() int NOTRACKLETFIT = 31; ///< this value is assigned to the fit pointer in case no tracklet is available
+GPUglobalconstexpr() int TRACKLETENDMARKER = 0x10001000; ///< marker for the end of tracklets in raw data, 2 of these.
+GPUglobalconstexpr() int PADDINGWORD = 0xeeeeeeee; ///< half-CRU links will be padded with this words to get an even number of 256bit words
+GPUglobalconstexpr() int DIGITENDMARKER = 0x0; ///< marker for the end of digits in raw data, 2 of these
+GPUglobalconstexpr() int MAXDATAPERLINK32 = 13824; ///< max number of 32 bit words per link ((21x12+2+4)*64) 64 mcm, 21 channels, 10 words per channel 2 header words(DigitMCMHeader DigitMCMADCmask) 4 words for tracklets.
+GPUglobalconstexpr() int MAXDATAPERLINK256 = 1728; ///< max number of linkwords per cru link. (256bit words)
+GPUglobalconstexpr() int MAXEVENTCOUNTERSEPERATION = 200; ///< how far apart can subsequent mcmheader event counters be before we flag for concern, used as a sanity check in rawreader.
+GPUglobalconstexpr() int MAXMCMCOUNT = 69120; ///< at most mcm count maxchamber x nrobc1 nmcmrob
+GPUglobalconstexpr() int MAXLINKERRORHISTOGRAMS = 10; ///< size of the array holding the link error plots from the raw reader
+GPUglobalconstexpr() int MAXPARSEERRORHISTOGRAMS = 60; ///< size of the array holding the parsing error plots from the raw reader
+GPUglobalconstexpr() unsigned int ETYPEPHYSICSTRIGGER = 0x2; ///< CRU Half Chamber header eventtype definition
+GPUglobalconstexpr() unsigned int ETYPECALIBRATIONTRIGGER = 0x3; ///< CRU Half Chamber header eventtype definition
+GPUglobalconstexpr() int MAXCRUERRORVALUE = 0x2; ///< Max possible value for a CRU Halfchamber link error. As of may 2022, can only be 0x0, 0x1, and 0x2, at least that is all so far(may2022).
+GPUglobalconstexpr() int INVALIDPRETRIGGERPHASE = 0xf; ///< Invalid value for phase, used to signify there is no hcheader.
} // namespace constants
} // namespace trd
diff --git a/Detectors/TRD/base/include/TRDBase/GeometryBase.h b/Detectors/TRD/base/include/TRDBase/GeometryBase.h
index c817d21cb7c48..bb19472c2fbde 100644
--- a/Detectors/TRD/base/include/TRDBase/GeometryBase.h
+++ b/Detectors/TRD/base/include/TRDBase/GeometryBase.h
@@ -96,113 +96,113 @@ class GeometryBase
protected:
GeometryBase() = default;
- static constexpr float TLENGTH = 751.0; ///< Total length of the TRD mother volume
+ static GPUglobalconstexpr() float TLENGTH = 751.0; ///< Total length of the TRD mother volume
// Parameter of the super module mother volumes
- static constexpr float SHEIGHT = 77.9; ///< Height of the supermodule
- static constexpr float SWIDTH1 = 94.881; ///< Lower width of the supermodule
- static constexpr float SWIDTH2 = 122.353; ///< Upper width of the supermodule
- static constexpr float SLENGTH = 702.0; ///< Length of the supermodule
+ static GPUglobalconstexpr() float SHEIGHT = 77.9; ///< Height of the supermodule
+ static GPUglobalconstexpr() float SWIDTH1 = 94.881; ///< Lower width of the supermodule
+ static GPUglobalconstexpr() float SWIDTH2 = 122.353; ///< Upper width of the supermodule
+ static GPUglobalconstexpr() float SLENGTH = 702.0; ///< Length of the supermodule
// Length of the additional space in front of the supermodule used for services
- static constexpr float FLENGTH = (TLENGTH - SLENGTH) / 2.0;
+ static GPUglobalconstexpr() float FLENGTH = (TLENGTH - SLENGTH) / 2.0;
- static constexpr float SMPLTT = 0.2; ///< Thickness of the super module side plates
+ static GPUglobalconstexpr() float SMPLTT = 0.2; ///< Thickness of the super module side plates
- static constexpr float VSPACE = 1.784; ///< Vertical spacing of the chambers
- static constexpr float HSPACE = 2.0; ///< Horizontal spacing of the chambers
- static constexpr float VROCSM = 1.2; ///< Radial distance of the first ROC to the outer plates of the SM
+ static GPUglobalconstexpr() float VSPACE = 1.784; ///< Vertical spacing of the chambers
+ static GPUglobalconstexpr() float HSPACE = 2.0; ///< Horizontal spacing of the chambers
+ static GPUglobalconstexpr() float VROCSM = 1.2; ///< Radial distance of the first ROC to the outer plates of the SM
- static constexpr float CRAH = 4.8; ///< Height of the radiator part of the chambers
- static constexpr float CDRH = 3.0; ///< Height of the drift region of the chambers
- static constexpr float CAMH = 0.7; ///< Height of the amplification region of the chambers
- static constexpr float CROH = 2.316; ///< Height of the readout of the chambers
- static constexpr float CROW = 0.9; ///< Additional width of the readout chamber frames
- static constexpr float CSVH = VSPACE - 0.742; ///< Height of the services on top of the chambers
- static constexpr float CH = CRAH + CDRH + CAMH + CROH; ///< Total height of the chambers (w/o services)
- static constexpr float CHSV = CH + CSVH; ///< Total height of the chambers (with services)
+ static GPUglobalconstexpr() float CRAH = 4.8; ///< Height of the radiator part of the chambers
+ static GPUglobalconstexpr() float CDRH = 3.0; ///< Height of the drift region of the chambers
+ static GPUglobalconstexpr() float CAMH = 0.7; ///< Height of the amplification region of the chambers
+ static GPUglobalconstexpr() float CROH = 2.316; ///< Height of the readout of the chambers
+ static GPUglobalconstexpr() float CROW = 0.9; ///< Additional width of the readout chamber frames
+ static GPUglobalconstexpr() float CSVH = VSPACE - 0.742; ///< Height of the services on top of the chambers
+ static GPUglobalconstexpr() float CH = CRAH + CDRH + CAMH + CROH; ///< Total height of the chambers (w/o services)
+ static GPUglobalconstexpr() float CHSV = CH + CSVH; ///< Total height of the chambers (with services)
// Distance of anode wire plane relative to middle of alignable volume
- static constexpr float ANODEPOS = CRAH + CDRH + CAMH / 2.0 - CHSV / 2.0;
-
- static constexpr float CALT = 0.4; ///< Thicknesses of different parts of the chamber frame Lower aluminum frame
- static constexpr float CCLST = 0.21; ///< Thickness of the lower Wacosit frame sides
- static constexpr float CCLFT = 1.0; ///< Thickness of the lower Wacosit frame front
- static constexpr float CGLT = 0.25; ///< Thichness of the glue around the radiator
- static constexpr float CCUTA = 1.0; ///< Upper Wacosit frame around amplification region
- static constexpr float CCUTB = 0.8; ///< Thickness of the upper Wacosit frame around amp. region
- static constexpr float CAUT = 1.5; ///< Al frame of back panel
- static constexpr float CALW = 2.5; ///< Width of additional aluminum ledge on lower frame
- static constexpr float CALH = 0.4; ///< Height of additional aluminum ledge on lower frame
- static constexpr float CALWMOD = 0.4; ///< Width of additional aluminum ledge on lower frame
- static constexpr float CALHMOD = 2.5; ///< Height of additional aluminum ledge on lower frame
- static constexpr float CWSW = 1.2; ///< Width of additional wacosit ledge on lower frame
- static constexpr float CWSH = 0.3; ///< Height of additional wacosit ledge on lower frame
-
- static constexpr float CPADW = 0.0; ///>Difference of outer chamber width and pad plane width
- static constexpr float RPADW = 1.0; ///Difference of outer chamber width and pad plane width
+ static GPUglobalconstexpr() float RPADW = 1.0; ///< Difference of outer chamber width and pad plane width
//
// Thickness of the the material layers
//
- static constexpr float DRTHICK = CDRH; ///< Thickness of the drift region
- static constexpr float AMTHICK = CAMH; ///< Thickness of the amplification region
- static constexpr float XETHICK = DRTHICK + AMTHICK; ///< Thickness of the gas volume
- static constexpr float WRTHICK = 0.00011; ///< Thickness of the wire planes
-
- static constexpr float RMYTHICK = 0.0015; ///< Thickness of the mylar layers in the radiator
- static constexpr float RCBTHICK = 0.0055; ///< Thickness of the carbon layers in the radiator
- static constexpr float RGLTHICK = 0.0065; ///< Thickness of the glue layers in the radiator
- static constexpr float RRHTHICK = 0.8; ///< Thickness of the rohacell layers in the radiator
- static constexpr float RFBTHICK = CRAH - 2.0 * (RMYTHICK + RCBTHICK + RRHTHICK); ///< Thickness of the fiber layers in the radiator
-
- static constexpr float PPDTHICK = 0.0025; ///< Thickness of copper of the pad plane
- static constexpr float PPPTHICK = 0.0356; ///< Thickness of PCB board of the pad plane
- static constexpr float PGLTHICK = 0.1428; ///< Thickness of the glue layer
- static constexpr float PCBTHICK = 0.019; ///< Thickness of the carbon layers
- static constexpr float PPCTHICK = 0.0486; ///< Thickness of the PCB readout boards
- static constexpr float PRBTHICK = 0.0057; ///< Thickness of the PCB copper layers
- static constexpr float PELTHICK = 0.0029; ///< Thickness of all other electronics components (caps, etc.)
- static constexpr float PHCTHICK = CROH - PPDTHICK - PPPTHICK - PGLTHICK - PCBTHICK * 2.0 - PPCTHICK - PRBTHICK - PELTHICK; ///< Thickness of the honeycomb support structure
+ static GPUglobalconstexpr() float DRTHICK = CDRH; ///< Thickness of the drift region
+ static GPUglobalconstexpr() float AMTHICK = CAMH; ///< Thickness of the amplification region
+ static GPUglobalconstexpr() float XETHICK = DRTHICK + AMTHICK; ///< Thickness of the gas volume
+ static GPUglobalconstexpr() float WRTHICK = 0.00011; ///< Thickness of the wire planes
+
+ static GPUglobalconstexpr() float RMYTHICK = 0.0015; ///< Thickness of the mylar layers in the radiator
+ static GPUglobalconstexpr() float RCBTHICK = 0.0055; ///< Thickness of the carbon layers in the radiator
+ static GPUglobalconstexpr() float RGLTHICK = 0.0065; ///< Thickness of the glue layers in the radiator
+ static GPUglobalconstexpr() float RRHTHICK = 0.8; ///< Thickness of the rohacell layers in the radiator
+ static GPUglobalconstexpr() float RFBTHICK = CRAH - 2.0 * (RMYTHICK + RCBTHICK + RRHTHICK); ///< Thickness of the fiber layers in the radiator
+
+ static GPUglobalconstexpr() float PPDTHICK = 0.0025; ///< Thickness of copper of the pad plane
+ static GPUglobalconstexpr() float PPPTHICK = 0.0356; ///< Thickness of PCB board of the pad plane
+ static GPUglobalconstexpr() float PGLTHICK = 0.1428; ///< Thickness of the glue layer
+ static GPUglobalconstexpr() float PCBTHICK = 0.019; ///< Thickness of the carbon layers
+ static GPUglobalconstexpr() float PPCTHICK = 0.0486; ///< Thickness of the PCB readout boards
+ static GPUglobalconstexpr() float PRBTHICK = 0.0057; ///< Thickness of the PCB copper layers
+ static GPUglobalconstexpr() float PELTHICK = 0.0029; ///< Thickness of all other electronics components (caps, etc.)
+ static GPUglobalconstexpr() float PHCTHICK = CROH - PPDTHICK - PPPTHICK - PGLTHICK - PCBTHICK * 2.0 - PPCTHICK - PRBTHICK - PELTHICK; ///< Thickness of the honeycomb support structure
//
// Position of the material layers
//
- static constexpr float DRZPOS = 2.4; ///< Position of the drift region
- static constexpr float AMZPOS = 0.0; ///< Position of the amplification region
- static constexpr float WRZPOSA = 0.0; ///< Position of the wire planes
- static constexpr float WRZPOSB = -AMTHICK / 2.0 + 0.001; ///< Position of the wire planes
- static constexpr float CALZPOS = 0.3; ///< Position of the additional aluminum ledges
-
- static constexpr int MCMMAX = 16; ///< Maximum number of MCMs per ROB
- static constexpr int MCMROW = 4; ///< Maximum number of MCMs per ROB Row
- static constexpr int ROBMAXC0 = 6; ///< Maximum number of ROBs per C0 chamber
- static constexpr int ROBMAXC1 = 8; ///< Maximum number of ROBs per C1 chamber
- static constexpr int ADCMAX = 21; ///< Maximum number of ADC channels per MCM
- static constexpr int TBMAX = 60; ///< Maximum number of Time bins
- static constexpr int PADMAX = 18; ///< Maximum number of pads per MCM
- static constexpr int COLMAX = 144; ///< Maximum number of pads per padplane row
- static constexpr int ROWMAXC0 = 12; ///< Maximum number of Rows per C0 chamber
- static constexpr int ROWMAXC1 = 16; ///< Maximum number of Rows per C1 chamber
-
- static constexpr float TIME0BASE = 300.65; ///< Base value for calculation of Time-position of pad 0
+ static GPUglobalconstexpr() float DRZPOS = 2.4; ///< Position of the drift region
+ static GPUglobalconstexpr() float AMZPOS = 0.0; ///< Position of the amplification region
+ static GPUglobalconstexpr() float WRZPOSA = 0.0; ///< Position of the wire planes
+ static GPUglobalconstexpr() float WRZPOSB = -AMTHICK / 2.0 + 0.001; ///< Position of the wire planes
+ static GPUglobalconstexpr() float CALZPOS = 0.3; ///< Position of the additional aluminum ledges
+
+ static GPUglobalconstexpr() int MCMMAX = 16; ///< Maximum number of MCMs per ROB
+ static GPUglobalconstexpr() int MCMROW = 4; ///< Maximum number of MCMs per ROB Row
+ static GPUglobalconstexpr() int ROBMAXC0 = 6; ///< Maximum number of ROBs per C0 chamber
+ static GPUglobalconstexpr() int ROBMAXC1 = 8; ///< Maximum number of ROBs per C1 chamber
+ static GPUglobalconstexpr() int ADCMAX = 21; ///< Maximum number of ADC channels per MCM
+ static GPUglobalconstexpr() int TBMAX = 60; ///< Maximum number of Time bins
+ static GPUglobalconstexpr() int PADMAX = 18; ///< Maximum number of pads per MCM
+ static GPUglobalconstexpr() int COLMAX = 144; ///< Maximum number of pads per padplane row
+ static GPUglobalconstexpr() int ROWMAXC0 = 12; ///< Maximum number of Rows per C0 chamber
+ static GPUglobalconstexpr() int ROWMAXC1 = 16; ///< Maximum number of Rows per C1 chamber
+
+ static GPUglobalconstexpr() float TIME0BASE = 300.65; ///< Base value for calculation of Time-position of pad 0
// Time-position of pad 0
- static constexpr float TIME0[6] = {TIME0BASE + 0 * (CH + VSPACE),
- TIME0BASE + 1 * (CH + VSPACE),
- TIME0BASE + 2 * (CH + VSPACE),
- TIME0BASE + 3 * (CH + VSPACE),
- TIME0BASE + 4 * (CH + VSPACE),
- TIME0BASE + 5 * (CH + VSPACE)};
+ static GPUglobalconstexpr() float TIME0[6] = {TIME0BASE + 0 * (CH + VSPACE),
+ TIME0BASE + 1 * (CH + VSPACE),
+ TIME0BASE + 2 * (CH + VSPACE),
+ TIME0BASE + 3 * (CH + VSPACE),
+ TIME0BASE + 4 * (CH + VSPACE),
+ TIME0BASE + 5 * (CH + VSPACE)};
- static constexpr float XTRDBEG = 288.43; ///< X-coordinate in tracking system of begin of TRD mother volume
- static constexpr float XTRDEND = 366.33; ///< X-coordinate in tracking system of end of TRD mother volume
+ static GPUglobalconstexpr() float XTRDBEG = 288.43; ///< X-coordinate in tracking system of begin of TRD mother volume
+ static GPUglobalconstexpr() float XTRDEND = 366.33; ///< X-coordinate in tracking system of end of TRD mother volume
// The outer width of the chambers
- static constexpr float CWIDTH[constants::NLAYER] = {90.4, 94.8, 99.3, 103.7, 108.1, 112.6};
+ static GPUglobalconstexpr() float CWIDTH[constants::NLAYER] = {90.4, 94.8, 99.3, 103.7, 108.1, 112.6};
// The outer lengths of the chambers
// Includes the spacings between the chambers!
- static constexpr float CLENGTH[constants::NLAYER][constants::NSTACK] = {
+ static GPUglobalconstexpr() float CLENGTH[constants::NLAYER][constants::NSTACK] = {
{124.0, 124.0, 110.0, 124.0, 124.0},
{124.0, 124.0, 110.0, 124.0, 124.0},
{131.0, 131.0, 110.0, 131.0, 131.0},
From 7369a9a07a626c9bff3979cd9b223bce980f046f Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 02/17] CommonConstants: place shared constants in the constant
address space
MSL requires every variable at program scope to name an address space and
diagnoses it at the declaration, so these headers broke any device translation
unit that included them. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, where it adds constant.
Preprocessed declarations are unchanged for host, CUDA, HIP and cling.
---
Common/Constants/CMakeLists.txt | 3 +-
.../include/CommonConstants/LHCConstants.h | 8 +++--
.../include/CommonConstants/MathConstants.h | 32 ++++++++++---------
3 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/Common/Constants/CMakeLists.txt b/Common/Constants/CMakeLists.txt
index ced8bb7895f95..55f628ec34c88 100644
--- a/Common/Constants/CMakeLists.txt
+++ b/Common/Constants/CMakeLists.txt
@@ -9,4 +9,5 @@
# granted to it by virtue of its status as an Intergovernmental Organization
# or submit itself to any jurisdiction.
-o2_add_header_only_library(CommonConstants)
+o2_add_header_only_library(CommonConstants
+ INTERFACE_LINK_LIBRARIES O2::GPUCommon)
diff --git a/Common/Constants/include/CommonConstants/LHCConstants.h b/Common/Constants/include/CommonConstants/LHCConstants.h
index 84720f817ceb2..1582f2166ca0f 100644
--- a/Common/Constants/include/CommonConstants/LHCConstants.h
+++ b/Common/Constants/include/CommonConstants/LHCConstants.h
@@ -16,6 +16,8 @@
#ifndef ALICEO2_LHCCONSTANTS_H_
#define ALICEO2_LHCCONSTANTS_H_
+#include "GPUCommonDef.h"
+
namespace o2
{
namespace constants
@@ -28,17 +30,17 @@ enum BeamDirection : int { BeamA, // beamA = beam 0,
NBeamDirections,
InteractingBC = -1 // as used in the BunchFilling class
};
-constexpr int LHCMaxBunches = 3564; // max N bunches
+GPUglobalconstexpr() int LHCMaxBunches = 3564; // max N bunches
constexpr double LHCRFFreq = 400.789e6; // LHC RF frequency in Hz
constexpr double LHCBunchSpacingNS = 10 * 1.e9 / LHCRFFreq; // bunch spacing in ns (10 RFbuckets)
constexpr double LHCOrbitNS = LHCMaxBunches * LHCBunchSpacingNS; // orbit duration in ns
constexpr double LHCRevFreq = 1.e9 / LHCOrbitNS; // revolution frequency
constexpr double LHCBunchSpacingMUS = LHCBunchSpacingNS * 1e-3; // bunch spacing in \mus (10 RFbuckets)
constexpr double LHCOrbitMUS = LHCOrbitNS * 1e-3; // orbit duration in \mus
-constexpr unsigned int MaxNOrbits = 0xffffffff;
+GPUglobalconstexpr() unsigned int MaxNOrbits = 0xffffffff;
// Offsets of A, C beam bunches at P2
-constexpr int BunchOffsetsP2[2] = {344, 3017};
+GPUglobalconstexpr() int BunchOffsetsP2[2] = {344, 3017};
// convert LHC bunch ID to BC for 2 beam directions
constexpr int LHCBunch2P2BC(int bunch, BeamDirection dir)
diff --git a/Common/Constants/include/CommonConstants/MathConstants.h b/Common/Constants/include/CommonConstants/MathConstants.h
index 9ef3b4dba5ae0..89a06d21e6fe7 100644
--- a/Common/Constants/include/CommonConstants/MathConstants.h
+++ b/Common/Constants/include/CommonConstants/MathConstants.h
@@ -16,31 +16,33 @@
#ifndef ALICEO2_COMMON_MATH_CONSTANTS_
#define ALICEO2_COMMON_MATH_CONSTANTS_
+#include "GPUCommonDef.h"
+
namespace o2
{
namespace constants
{
namespace math
{
-constexpr float Almost0 = 0x1.0p-126f; // smallest non-denormal float
-constexpr float Epsilon = 0x0.000002p0f; // smallest float such that 1 != 1 + Epsilon
-constexpr float Almost1 = 1.f - 1.0e-6f;
-constexpr float VeryBig = 1.f / Almost0;
+GPUglobalconstexpr() float Almost0 = 0x1.0p-126f; // smallest non-denormal float
+GPUglobalconstexpr() float Epsilon = 0x0.000002p0f; // smallest float such that 1 != 1 + Epsilon
+GPUglobalconstexpr() float Almost1 = 1.f - 1.0e-6f;
+GPUglobalconstexpr() float VeryBig = 1.f / Almost0;
-constexpr float PI = 3.14159274101257324e+00f;
-constexpr float TwoPI = 2.f * PI;
-constexpr float PIHalf = 0.5f * PI;
-constexpr float PIThird = PI / 3.0f;
-constexpr float PIQuarter = 0.25f * PI;
-constexpr float Rad2Deg = 180.f / PI;
-constexpr float Deg2Rad = PI / 180.f;
+GPUglobalconstexpr() float PI = 3.14159274101257324e+00f;
+GPUglobalconstexpr() float TwoPI = 2.f * PI;
+GPUglobalconstexpr() float PIHalf = 0.5f * PI;
+GPUglobalconstexpr() float PIThird = PI / 3.0f;
+GPUglobalconstexpr() float PIQuarter = 0.25f * PI;
+GPUglobalconstexpr() float Rad2Deg = 180.f / PI;
+GPUglobalconstexpr() float Deg2Rad = PI / 180.f;
-constexpr int NSectors = 18;
-constexpr float SectorSpanDeg = 360. / NSectors;
-constexpr float SectorSpanRad = SectorSpanDeg * Deg2Rad;
+GPUglobalconstexpr() int NSectors = 18;
+GPUglobalconstexpr() float SectorSpanDeg = 360. / NSectors;
+GPUglobalconstexpr() float SectorSpanRad = SectorSpanDeg * Deg2Rad;
// conversion from B(kGaus) to curvature for 1GeV pt
-constexpr float B2C = -0.299792458e-3;
+GPUglobalconstexpr() float B2C = -0.299792458e-3;
} // namespace math
} // namespace constants
} // namespace o2
From f98a840f7bf6b49f96dafdaa9617c3773953c4d5 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 03/17] MathUtils: place TransformType constants in the
constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
Common/MathUtils/include/MathUtils/Cartesian.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/Common/MathUtils/include/MathUtils/Cartesian.h b/Common/MathUtils/include/MathUtils/Cartesian.h
index fd745dac99562..e61b10a7caee9 100644
--- a/Common/MathUtils/include/MathUtils/Cartesian.h
+++ b/Common/MathUtils/include/MathUtils/Cartesian.h
@@ -52,10 +52,10 @@ namespace math_utils
/// The IDs must be < 32
struct TransformType {
- static constexpr int L2G = 0;
- static constexpr int T2L = 1;
- static constexpr int T2G = 2;
- static constexpr int T2GRot = 3;
+ static GPUglobalconstexpr() int L2G = 0;
+ static GPUglobalconstexpr() int T2L = 1;
+ static GPUglobalconstexpr() int T2G = 2;
+ static GPUglobalconstexpr() int T2GRot = 3;
}; /// transformation types
template
From f35cb2dd1cb6d32e72d19fe29f8fc396c1bf613d Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 04/17] CommonDataFormat: place shared constants in the
constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
.../common/include/CommonDataFormat/AbstractRef.h | 9 ++++-----
.../common/include/CommonDataFormat/RangeReference.h | 6 +++---
2 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/DataFormats/common/include/CommonDataFormat/AbstractRef.h b/DataFormats/common/include/CommonDataFormat/AbstractRef.h
index 72c195cfb7bc8..7c337d3f3dd37 100644
--- a/DataFormats/common/include/CommonDataFormat/AbstractRef.h
+++ b/DataFormats/common/include/CommonDataFormat/AbstractRef.h
@@ -22,7 +22,6 @@
#include
#endif
-
namespace o2::dataformats
{
@@ -54,10 +53,10 @@ class AbstractRef
using Src_t = decltype(AbstractRef::MVAR());
using Flg_t = decltype(AbstractRef::MVAR());
- static constexpr Base_t BaseMask = Base_t((((0x1U << (NBIdx + NBSrc + NBFlg - 1)) - 1) << 1) + 1);
- static constexpr Idx_t IdxMask = Idx_t((((0x1U << (NBIdx - 1)) - 1) << 1) + 1);
- static constexpr Src_t SrcMask = Src_t((((0x1U << (NBSrc - 1)) - 1) << 1) + 1);
- static constexpr Flg_t FlgMask = Flg_t((((0x1U << (NBFlg - 1)) - 1) << 1) + 1);
+ static GPUglobalconstexpr() Base_t BaseMask = Base_t((((0x1U << (NBIdx + NBSrc + NBFlg - 1)) - 1) << 1) + 1);
+ static GPUglobalconstexpr() Idx_t IdxMask = Idx_t((((0x1U << (NBIdx - 1)) - 1) << 1) + 1);
+ static GPUglobalconstexpr() Src_t SrcMask = Src_t((((0x1U << (NBSrc - 1)) - 1) << 1) + 1);
+ static GPUglobalconstexpr() Flg_t FlgMask = Flg_t((((0x1U << (NBFlg - 1)) - 1) << 1) + 1);
static constexpr int NBitsIndex() { return NBIdx; }
static constexpr int NBitsSource() { return NBSrc; }
static constexpr int NBitsFlags() { return NBFlg; }
diff --git a/DataFormats/common/include/CommonDataFormat/RangeReference.h b/DataFormats/common/include/CommonDataFormat/RangeReference.h
index 3d0c58298de03..381e5e5adff69 100644
--- a/DataFormats/common/include/CommonDataFormat/RangeReference.h
+++ b/DataFormats/common/include/CommonDataFormat/RangeReference.h
@@ -64,9 +64,9 @@ class RangeRefComp
using Base = unsigned int;
private:
- static constexpr int NBitsTotal = sizeof(Base) * 8;
- static constexpr Base MaskN = ((0x1 << NBitsN) - 1);
- static constexpr Base MaskR = (~Base(0)) & (~MaskN);
+ static GPUglobalconstexpr() int NBitsTotal = sizeof(Base) * 8;
+ static GPUglobalconstexpr() Base MaskN = ((0x1 << NBitsN) - 1);
+ static GPUglobalconstexpr() Base MaskR = (~Base(0)) & (~MaskN);
Base mData = 0; ///< packed 1st entry reference + N entries
GPUhd() void sanityCheck()
{
From 8896beb44aa7b7d377beba7127332882c25fed7d Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 05/17] DetectorsCommonDataFormats: place DetID constants in
the constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
.../DetectorsCommonDataFormats/DetID.h | 64 ++++++++++---------
1 file changed, 33 insertions(+), 31 deletions(-)
diff --git a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h
index 2d2383783cfc3..80e3772d3ecc2 100644
--- a/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h
+++ b/DataFormats/Detectors/Common/include/DetectorsCommonDataFormats/DetID.h
@@ -28,6 +28,8 @@
#ifndef O2_BASE_DETID_
#define O2_BASE_DETID_
+#include "GPUCommonDef.h"
+
#include "GPUCommonRtypes.h"
#include "GPUCommonBitSet.h"
#include "MathUtils/Utils.h"
@@ -60,45 +62,45 @@ class DetID
/// Detector identifiers: continuous, starting from 0
typedef int ID;
- static constexpr ID ITS = 0;
- static constexpr ID TPC = 1;
- static constexpr ID TRD = 2;
- static constexpr ID TOF = 3;
- static constexpr ID PHS = 4;
- static constexpr ID CPV = 5;
- static constexpr ID EMC = 6;
- static constexpr ID HMP = 7;
- static constexpr ID MFT = 8;
- static constexpr ID MCH = 9;
- static constexpr ID MID = 10;
- static constexpr ID ZDC = 11;
- static constexpr ID FT0 = 12;
- static constexpr ID FV0 = 13;
- static constexpr ID FDD = 14;
- static constexpr ID TST = 15;
- static constexpr ID CTP = 16;
- static constexpr ID FOC = 17;
+ static GPUglobalconstexpr() ID ITS = 0;
+ static GPUglobalconstexpr() ID TPC = 1;
+ static GPUglobalconstexpr() ID TRD = 2;
+ static GPUglobalconstexpr() ID TOF = 3;
+ static GPUglobalconstexpr() ID PHS = 4;
+ static GPUglobalconstexpr() ID CPV = 5;
+ static GPUglobalconstexpr() ID EMC = 6;
+ static GPUglobalconstexpr() ID HMP = 7;
+ static GPUglobalconstexpr() ID MFT = 8;
+ static GPUglobalconstexpr() ID MCH = 9;
+ static GPUglobalconstexpr() ID MID = 10;
+ static GPUglobalconstexpr() ID ZDC = 11;
+ static GPUglobalconstexpr() ID FT0 = 12;
+ static GPUglobalconstexpr() ID FV0 = 13;
+ static GPUglobalconstexpr() ID FDD = 14;
+ static GPUglobalconstexpr() ID TST = 15;
+ static GPUglobalconstexpr() ID CTP = 16;
+ static GPUglobalconstexpr() ID FOC = 17;
#ifdef ENABLE_UPGRADES
- static constexpr ID IT3 = 18;
- static constexpr ID TRK = 19;
- static constexpr ID FT3 = 20;
- static constexpr ID FCT = 21;
- static constexpr ID TF3 = 22;
- static constexpr ID RCH = 23;
- static constexpr ID MI3 = 24;
- static constexpr ID ECL = 25;
- static constexpr ID FD3 = 26;
- static constexpr ID Last = FD3;
+ static GPUglobalconstexpr() ID IT3 = 18;
+ static GPUglobalconstexpr() ID TRK = 19;
+ static GPUglobalconstexpr() ID FT3 = 20;
+ static GPUglobalconstexpr() ID FCT = 21;
+ static GPUglobalconstexpr() ID TF3 = 22;
+ static GPUglobalconstexpr() ID RCH = 23;
+ static GPUglobalconstexpr() ID MI3 = 24;
+ static GPUglobalconstexpr() ID ECL = 25;
+ static GPUglobalconstexpr() ID FD3 = 26;
+ static GPUglobalconstexpr() ID Last = FD3;
#else
static constexpr ID Last = FOC; ///< if extra detectors added, update this !!!
#endif
- static constexpr ID First = ITS;
+ static GPUglobalconstexpr() ID First = ITS;
- static constexpr int nDetectors = Last + 1; ///< number of defined detectors
+ static GPUglobalconstexpr() int nDetectors = Last + 1; ///< number of defined detectors
typedef o2::gpu::gpustd::bitset<32> mask_t;
static_assert(nDetectors <= 32, "bitset<32> insufficient");
- static constexpr mask_t FullMask = (0x1u << nDetectors) - 1;
+ static GPUglobalconstexpr() mask_t FullMask = (0x1u << nDetectors) - 1;
#ifndef GPUCA_GPUCODE_DEVICE
static constexpr std::string_view NONE{"none"}; ///< keywork for no-detector
From a31dd775a3f0966e0728a4e15953f7b0b3a36112 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 06/17] DataFormatsTPC: place shared constants in the constant
address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
.../include/DataFormatsTPC/CalibdEdxCorrection.h | 4 ++--
.../TPC/include/DataFormatsTPC/ClusterNative.h | 14 +++++++-------
.../Detectors/TPC/include/DataFormatsTPC/Defs.h | 16 +++++++++-------
3 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h
index f5088959edcf8..f30ebfcc77930 100644
--- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h
+++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/CalibdEdxCorrection.h
@@ -39,8 +39,8 @@ GPUconstexpr() float TglScale[4] = {1.9, 1.5, 1.22, 1.02}; ///< Max Tgl values f
class CalibdEdxCorrection
{
public:
- static constexpr int FitSize = 288; ///< Number of fitted corrections
- static constexpr int ParamSize = 8; ///< Number of params per fit
+ static GPUglobalconstexpr() int FitSize = 288; ///< Number of fitted corrections
+ static GPUglobalconstexpr() int ParamSize = 8; ///< Number of params per fit
#if !defined(GPUCA_GPUCODE)
CalibdEdxCorrection()
diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNative.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNative.h
index fb81afdf67587..54dbb559709fa 100644
--- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNative.h
+++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNative.h
@@ -59,13 +59,13 @@ struct ClusterNative {
flagEdge = 0x4, // At edge of TPC sector
flagSingle = 0x8 }; // Single pad or single time-bin cluster
- static constexpr int scaleTimePacked = 64; //< ~50 is needed for 0.1mm precision, but leads to float rounding artifacts around 20ms
- static constexpr int scalePadPacked = 64; //< ~60 is needed for 0.1mm precision, but power of two avoids rounding
- static constexpr int scaleSigmaTimePacked = 32; // 1/32nd of pad/timebin precision for cluster size
- static constexpr int scaleSigmaPadPacked = 32;
- static constexpr int scaleSaturatedQtot = 8;
- static constexpr int maxRegularQtot = 25 * 1024;
- static constexpr int maxSaturatedQtot = (USHRT_MAX - maxRegularQtot) * scaleSaturatedQtot;
+ static GPUglobalconstexpr() int scaleTimePacked = 64; //< ~50 is needed for 0.1mm precision, but leads to float rounding artifacts around 20ms
+ static GPUglobalconstexpr() int scalePadPacked = 64; //< ~60 is needed for 0.1mm precision, but power of two avoids rounding
+ static GPUglobalconstexpr() int scaleSigmaTimePacked = 32; // 1/32nd of pad/timebin precision for cluster size
+ static GPUglobalconstexpr() int scaleSigmaPadPacked = 32;
+ static GPUglobalconstexpr() int scaleSaturatedQtot = 8;
+ static GPUglobalconstexpr() int maxRegularQtot = 25 * 1024;
+ static GPUglobalconstexpr() int maxSaturatedQtot = (USHRT_MAX - maxRegularQtot) * scaleSaturatedQtot;
uint32_t timeFlagsPacked; //< Contains the time in the lower 24 bits in a packed format, contains the flags in the
// upper 8 bits
diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/Defs.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/Defs.h
index fa04586479a22..a5be0da32f641 100644
--- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/Defs.h
+++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/Defs.h
@@ -19,6 +19,8 @@
#ifndef AliceO2_TPC_Defs_H
#define AliceO2_TPC_Defs_H
+#include "GPUCommonDef.h"
+
#ifndef GPUCA_GPUCODE_DEVICE
#include
#endif
@@ -37,8 +39,8 @@ enum Side { A = 0,
UNDEFINED = 2 };
// enum class Side {A=0, C=1};
// Problem with root cint. does not seem to support enum class ...
-constexpr unsigned char SECTORSPERSIDE = 18;
-constexpr unsigned char SIDES = 2;
+GPUglobalconstexpr() unsigned char SECTORSPERSIDE = 18;
+GPUglobalconstexpr() unsigned char SIDES = 2;
constexpr double PI = 3.14159265358979323846;
constexpr double TWOPI = 2. * PI;
@@ -54,10 +56,10 @@ enum GEMstack { IROCgem = 0,
OROC1gem = 1,
OROC2gem = 2,
OROC3gem = 3 };
-constexpr unsigned short GEMSTACKSPERSECTOR = 4;
-constexpr unsigned short GEMSPERSTACK = 4;
-constexpr unsigned short GEMSTACKSPERSIDE = GEMSTACKSPERSECTOR * SECTORSPERSIDE;
-constexpr unsigned short GEMSTACKS = GEMSTACKSPERSECTOR * SECTORSPERSIDE * SIDES;
+GPUglobalconstexpr() unsigned short GEMSTACKSPERSECTOR = 4;
+GPUglobalconstexpr() unsigned short GEMSPERSTACK = 4;
+GPUglobalconstexpr() unsigned short GEMSTACKSPERSIDE = GEMSTACKSPERSECTOR * SECTORSPERSIDE;
+GPUglobalconstexpr() unsigned short GEMSTACKS = GEMSTACKSPERSECTOR * SECTORSPERSIDE * SIDES;
/// Definition of the different pad subsets
enum class PadSubset : char {
@@ -71,7 +73,7 @@ enum ChargeType {
Max = 0,
Tot = 1
};
-constexpr unsigned short CHARGETYPES = 2;
+GPUglobalconstexpr() unsigned short CHARGETYPES = 2;
/// GEM stack identification
struct StackID {
From 679c4fd5ec95eb0bcc2a00273721236a3ae4f111 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 07/17] ReconstructionDataFormats: place shared constants in
the constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
.../ReconstructionDataFormats/GlobalTrackID.h | 6 +-
.../include/ReconstructionDataFormats/PID.h | 55 ++++++++++---------
.../TrackLTIntegral.h | 2 +-
.../TrackParametrization.h | 32 +++++------
4 files changed, 49 insertions(+), 46 deletions(-)
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h
index 06d3b50de03f0..63515261e544b 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/GlobalTrackID.h
@@ -16,6 +16,8 @@
#ifndef O2_GLOBAL_TRACK_ID
#define O2_GLOBAL_TRACK_ID
+#include "GPUCommonDef.h"
+
#include "GPUCommonBitSet.h"
#include "CommonDataFormat/AbstractRef.h"
#include "DetectorsCommonDataFormats/DetID.h"
@@ -78,8 +80,8 @@ class GlobalTrackID : public AbstractRef<25, 5, 2>
static constexpr std::string_view NONE{"none"}; ///< keywork for no sources
static constexpr std::string_view ALL{"all"}; ///< keywork for all sources
#endif
- static constexpr mask_t MASK_ALL = (1u << NSources) - 1;
- static constexpr mask_t MASK_NONE = 0;
+ static GPUglobalconstexpr() mask_t MASK_ALL = (1u << NSources) - 1;
+ static GPUglobalconstexpr() mask_t MASK_NONE = 0;
// methods for detector level manipulations
GPUdi() static constexpr DetID::mask_t getSourceDetectorsMask(int i);
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h
index ce70e69aa6ddd..c0daeb4334660 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/PID.h
@@ -33,7 +33,7 @@ namespace o2cp = o2::constants::physics;
namespace pid_constants // GPUs currently cannot have static constexpr array members
{
typedef uint8_t ID;
-static constexpr ID NIDsTot = 19;
+static GPUglobalconstexpr() ID NIDsTot = 19;
#if !defined(GPUCA_GPUCODE_DEVICE) || defined(GPUCA_GPU_DEBUG_PRINT)
GPUconstexpr() const char* sNames[NIDsTot + 1] = ///< defined particle names
@@ -91,34 +91,34 @@ class PID
// particle identifiers, continuos starting from 0
typedef pid_constants::ID ID;
- static constexpr ID Electron = 0;
- static constexpr ID Muon = 1;
- static constexpr ID Pion = 2;
- static constexpr ID Kaon = 3;
- static constexpr ID Proton = 4;
- static constexpr ID Deuteron = 5;
- static constexpr ID Triton = 6;
- static constexpr ID Helium3 = 7;
- static constexpr ID Alpha = 8;
+ static GPUglobalconstexpr() ID Electron = 0;
+ static GPUglobalconstexpr() ID Muon = 1;
+ static GPUglobalconstexpr() ID Pion = 2;
+ static GPUglobalconstexpr() ID Kaon = 3;
+ static GPUglobalconstexpr() ID Proton = 4;
+ static GPUglobalconstexpr() ID Deuteron = 5;
+ static GPUglobalconstexpr() ID Triton = 6;
+ static GPUglobalconstexpr() ID Helium3 = 7;
+ static GPUglobalconstexpr() ID Alpha = 8;
- static constexpr ID First = Electron;
- static constexpr ID Last = Alpha; ///< if extra IDs added, update this !!!
- static constexpr ID NIDs = Last + 1; ///< number of defined IDs
+ static GPUglobalconstexpr() ID First = Electron;
+ static GPUglobalconstexpr() ID Last = Alpha; ///< if extra IDs added, update this !!!
+ static GPUglobalconstexpr() ID NIDs = Last + 1; ///< number of defined IDs
// PID for derived particles
- static constexpr ID PI0 = 9;
- static constexpr ID Photon = 10;
- static constexpr ID K0 = 11;
- static constexpr ID Lambda = 12;
- static constexpr ID HyperTriton = 13;
- static constexpr ID Hyperhydrog4 = 14;
- static constexpr ID XiMinus = 15;
- static constexpr ID OmegaMinus = 16;
- static constexpr ID HyperHelium4 = 17;
- static constexpr ID HyperHelium5 = 18;
- static constexpr ID FirstExt = PI0;
- static constexpr ID LastExt = HyperHelium5;
- static constexpr ID NIDsTot = pid_constants::NIDsTot; ///< total number of defined IDs
+ static GPUglobalconstexpr() ID PI0 = 9;
+ static GPUglobalconstexpr() ID Photon = 10;
+ static GPUglobalconstexpr() ID K0 = 11;
+ static GPUglobalconstexpr() ID Lambda = 12;
+ static GPUglobalconstexpr() ID HyperTriton = 13;
+ static GPUglobalconstexpr() ID Hyperhydrog4 = 14;
+ static GPUglobalconstexpr() ID XiMinus = 15;
+ static GPUglobalconstexpr() ID OmegaMinus = 16;
+ static GPUglobalconstexpr() ID HyperHelium4 = 17;
+ static GPUglobalconstexpr() ID HyperHelium5 = 18;
+ static GPUglobalconstexpr() ID FirstExt = PI0;
+ static GPUglobalconstexpr() ID LastExt = HyperHelium5;
+ static GPUglobalconstexpr() ID NIDsTot = pid_constants::NIDsTot; ///< total number of defined IDs
static_assert(NIDsTot == LastExt + 1, "Incorrect NIDsTot, please update!");
GPUdDefault() PID() = default;
@@ -159,7 +159,8 @@ class PID
GPUdi() static constexpr ID nameToID(char const* name, ID id)
{
- return id > LastExt ? id : sameStr(name, pid_constants::sNames[id]) ? id : nameToID(name, id + 1);
+ return id > LastExt ? id : sameStr(name, pid_constants::sNames[id]) ? id
+ : nameToID(name, id + 1);
}
#endif
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackLTIntegral.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackLTIntegral.h
index e799804805972..5067399b9bede 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackLTIntegral.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackLTIntegral.h
@@ -28,7 +28,7 @@ namespace track
class TrackLTIntegral
{
public:
- static constexpr float NeglectTime = -1.; // if 1st mT slot contains this, don't fill time
+ static GPUglobalconstexpr() float NeglectTime = -1.; // if 1st mT slot contains this, don't fill time
GPUdDefault() TrackLTIntegral() = default;
GPUdDefault() TrackLTIntegral(const TrackLTIntegral& stc) = default;
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h
index 4b1fef22a3bb4..ee9b3c10e05b7 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/TrackParametrization.h
@@ -97,15 +97,15 @@ enum DirType : int { DirInward = -1,
DirAuto = 0,
DirOutward = 1 };
-constexpr int kNParams = 5, kCovMatSize = 15, kLabCovMatSize = 21;
+GPUglobalconstexpr() int kNParams = 5, kCovMatSize = 15, kLabCovMatSize = 21;
-constexpr float kCY2max = 100 * 100, // SigmaY<=100cm
- kCZ2max = 100 * 100, // SigmaZ<=100cm
- kCSnp2max = 1 * 1, // SigmaSin<=1
- kCTgl2max = 1 * 1, // SigmaTan<=1
- kC1Pt2max = 100 * 100, // Sigma1/Pt<=100 1/GeV
- kMostProbablePt = 0.6f, // Most Probable Pt (GeV), for running with Bz=0
- kCalcdEdxAuto = -999.f; // value indicating request for dedx calculation
+GPUglobalconstexpr() float kCY2max = 100 * 100, // SigmaY<=100cm
+ kCZ2max = 100 * 100, // SigmaZ<=100cm
+ kCSnp2max = 1 * 1, // SigmaSin<=1
+ kCTgl2max = 1 * 1, // SigmaTan<=1
+ kC1Pt2max = 100 * 100, // Sigma1/Pt<=100 1/GeV
+ kMostProbablePt = 0.6f, // Most Probable Pt (GeV), for running with Bz=0
+ kCalcdEdxAuto = -999.f; // value indicating request for dedx calculation
// access to covariance matrix by row and column
GPUconstexpr() int CovarMap[kNParams][kNParams] = {{0, 1, 3, 6, 10},
@@ -117,13 +117,13 @@ GPUconstexpr() int CovarMap[kNParams][kNParams] = {{0, 1, 3, 6, 10},
// access to covariance matrix diagonal elements
GPUconstexpr() int DiagMap[kNParams] = {0, 2, 5, 9, 14};
-constexpr float HugeF = o2::constants::math::VeryBig;
-constexpr float MaxPT = 100000.; // do not allow pTs exceeding this value (to avoid NANs)
-constexpr float MinPTInv = 1. / MaxPT; // do not allow q/pTs less this value (to avoid NANs)
-constexpr float ELoss2EKinThreshInv = 1. / 0.025; // do not allow E.Loss correction step with dE/Ekin above the inverse of this value
-constexpr int MaxELossIter = 50; // max number of iteration for the ELoss to account for BB dependence on beta*gamma
-constexpr float DefaultDCA = 999.f; // default DCA value
-constexpr float DefaultDCACov = 999.f; // default DCA cov value
+GPUglobalconstexpr() float HugeF = o2::constants::math::VeryBig;
+GPUglobalconstexpr() float MaxPT = 100000.; // do not allow pTs exceeding this value (to avoid NANs)
+GPUglobalconstexpr() float MinPTInv = 1. / MaxPT; // do not allow q/pTs less this value (to avoid NANs)
+GPUglobalconstexpr() float ELoss2EKinThreshInv = 1. / 0.025; // do not allow E.Loss correction step with dE/Ekin above the inverse of this value
+GPUglobalconstexpr() int MaxELossIter = 50; // max number of iteration for the ELoss to account for BB dependence on beta*gamma
+GPUglobalconstexpr() float DefaultDCA = 999.f; // default DCA value
+GPUglobalconstexpr() float DefaultDCACov = 999.f; // default DCA cov value
// uncomment this to enable correction for BB dependence on beta*gamma via BB derivative
// #define _BB_NONCONST_CORR_
@@ -277,7 +277,7 @@ class TrackParametrization
private:
//
- static constexpr value_t InvalidX = -99999.f;
+ static GPUglobalconstexpr() value_t InvalidX = -99999.f;
value_t mX = 0.f; /// X of track evaluation
value_t mAlpha = 0.f; /// track frame angle
value_t mP[kNParams] = {0.f}; /// 5 parameters: Y,Z,sin(phi),tg(lambda),q/pT
From b23e023795ca6536d218452c92a4f2346726755f Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 08/17] DetectorsBase: place shared constants in the constant
address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
Detectors/Base/include/DetectorsBase/MatCell.h | 10 +++++-----
.../Base/include/DetectorsBase/MatLayerCylSet.h | 12 ++++++------
Detectors/Base/include/DetectorsBase/Propagator.h | 8 +++++---
Detectors/Base/include/DetectorsBase/Ray.h | 6 +++---
4 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/Detectors/Base/include/DetectorsBase/MatCell.h b/Detectors/Base/include/DetectorsBase/MatCell.h
index 40c5fd3db1f69..063d5c28be265 100644
--- a/Detectors/Base/include/DetectorsBase/MatCell.h
+++ b/Detectors/Base/include/DetectorsBase/MatCell.h
@@ -26,9 +26,9 @@ namespace base
struct MatCell {
// small struct to hold and of the voxel
- static constexpr int NParams = 2; // number of material parameters described
- float meanRho; ///< mean density, g/cm^3
- float meanX2X0; ///< fraction of radiaton lenght
+ static GPUglobalconstexpr() int NParams = 2; // number of material parameters described
+ float meanRho; ///< mean density, g/cm^3
+ float meanX2X0; ///< fraction of radiaton lenght
GPUd() MatCell() : meanRho(0.f), meanX2X0(0.f) {}
GPUdDefault() MatCell(const MatCell& src) = default;
@@ -51,8 +51,8 @@ struct MatCell {
struct MatBudget : MatCell {
// small struct to hold , and length traversed by track in the voxel
- static constexpr int NParams = 3; // number of material parameters described
- float length; ///< length in material
+ static GPUglobalconstexpr() int NParams = 3; // number of material parameters described
+ float length; ///< length in material
GPUd() MatBudget() : length(0.f) {}
GPUdDefault() MatBudget(const MatBudget& src) = default;
diff --git a/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h b/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h
index 60c37eb11faeb..5518321764611 100644
--- a/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h
+++ b/Detectors/Base/include/DetectorsBase/MatLayerCylSet.h
@@ -145,12 +145,12 @@ class MatLayerCylSet : public o2::gpu::FlatObject
static constexpr size_t getBufferAlignmentBytes() { return 8; }
#endif // !GPUCA_GPUCODE
- static constexpr float LayerRMax = 500; // maximum value of R lookup (corresponds to last layer of MatLUT)
- static constexpr float VoxelRDelta = 0.05; // voxel spacing for layer lookup; seems a natural choice - corresponding ~ to smallest spacing
- static constexpr float InvVoxelRDelta = 1.f / VoxelRDelta;
- static constexpr int NumVoxels = int(LayerRMax / VoxelRDelta);
- static constexpr uint16_t VoxelAmbiguousBit = 0x8000u;
- static constexpr uint16_t VoxelSegmentMask = 0x7fffu;
+ static GPUglobalconstexpr() float LayerRMax = 500; // maximum value of R lookup (corresponds to last layer of MatLUT)
+ static GPUglobalconstexpr() float VoxelRDelta = 0.05; // voxel spacing for layer lookup; seems a natural choice - corresponding ~ to smallest spacing
+ static GPUglobalconstexpr() float InvVoxelRDelta = 1.f / VoxelRDelta;
+ static GPUglobalconstexpr() int NumVoxels = int(LayerRMax / VoxelRDelta);
+ static GPUglobalconstexpr() uint16_t VoxelAmbiguousBit = 0x8000u;
+ static GPUglobalconstexpr() uint16_t VoxelSegmentMask = 0x7fffu;
uint16_t mLayerVoxelLU[NumVoxels]; //! first interval based on known radius, plus the ambiguity flag (static dimension for easy copy to GPU)
bool mInitializedLayerVoxelLU = false; //! if the voxels have been initialized
diff --git a/Detectors/Base/include/DetectorsBase/Propagator.h b/Detectors/Base/include/DetectorsBase/Propagator.h
index 377094cc368b8..38f4e089a1a1a 100644
--- a/Detectors/Base/include/DetectorsBase/Propagator.h
+++ b/Detectors/Base/include/DetectorsBase/Propagator.h
@@ -16,6 +16,8 @@
#ifndef ALICEO2_BASE_PROPAGATOR_
#define ALICEO2_BASE_PROPAGATOR_
+#include "GPUCommonDef.h"
+
#include "GPUCommonRtypes.h"
#include "CommonConstants/PhysicsConstants.h"
#include "ReconstructionDataFormats/Track.h"
@@ -69,8 +71,8 @@ class PropagatorImpl
USEMatCorrLUT
}; // flag to use LUT for material queries (user must provide a pointer
- static constexpr float MAX_SIN_PHI = 0.85f;
- static constexpr float MAX_STEP = 2.0f;
+ static GPUglobalconstexpr() float MAX_SIN_PHI = 0.85f;
+ static GPUglobalconstexpr() float MAX_STEP = 2.0f;
GPUd() bool PropagateToXBxByBz(TrackParCov_t& track, value_type x,
value_type maxSnp = MAX_SIN_PHI, value_type maxStep = MAX_STEP, MatCorrType matCorr = MatCorrType::USEMatCorrLUT,
@@ -201,7 +203,7 @@ class PropagatorImpl
PropagatorImpl(bool uninitialized = false);
~PropagatorImpl() = default;
#endif
- static constexpr value_type Epsilon = 0.00001; // precision of propagation to X
+ static GPUglobalconstexpr() value_type Epsilon = 0.00001; // precision of propagation to X
template
GPUd() void getFieldXYZImpl(const math_utils::Point3D xyz, T* bxyz) const;
template
diff --git a/Detectors/Base/include/DetectorsBase/Ray.h b/Detectors/Base/include/DetectorsBase/Ray.h
index 0b0c2f2904d27..fab4337613243 100644
--- a/Detectors/Base/include/DetectorsBase/Ray.h
+++ b/Detectors/Base/include/DetectorsBase/Ray.h
@@ -42,9 +42,9 @@ class Ray
public:
using vecF3 = float[3];
- static constexpr float MinDistToConsider = 1e-4; // treat as 0 lenght distance below this
- static constexpr float InvalidT = -1e9;
- static constexpr float Tiny = 1e-9;
+ static GPUglobalconstexpr() float MinDistToConsider = 1e-4; // treat as 0 lenght distance below this
+ static GPUglobalconstexpr() float InvalidT = -1e9;
+ static GPUglobalconstexpr() float Tiny = 1e-9;
GPUd() Ray() : mP{0.f}, mD{0.f}, mDistXY2(0.f), mDistXY2i(0.f), mDistXYZ(0.f), mXDxPlusYDy(0.f), mXDxPlusYDyRed(0.f), mXDxPlusYDy2(0.f), mR02(0.f), mR12(0.f)
{
From 2a30386187ccc4b3a5b2e013635c7999df85f2cc Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 09/17] TPCFastTransformation: place shared constants in the
constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
.../TPCFastSpaceChargeCorrection.h | 2 +-
GPU/TPCFastTransformation/TPCFastTransform.h | 6 ++++--
GPU/TPCFastTransformation/TPCFastTransformGeo.h | 6 +++---
GPU/TPCFastTransformation/TPCFastTransformPOD.h | 10 ++++++----
4 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h
index 09704bb5706e1..10df167168f6b 100644
--- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h
+++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h
@@ -285,7 +285,7 @@ class TPCFastSpaceChargeCorrection : public FlatObject
/// release temporary memory used during construction
void releaseConstructionMemory();
- static constexpr float kMaxCorrection = 100.f; ///< maximum correction value, used to protect from FPEs
+ static GPUglobalconstexpr() float kMaxCorrection = 100.f; ///< maximum correction value, used to protect from FPEs
/// _______________ Data members _______________________________________________
diff --git a/GPU/TPCFastTransformation/TPCFastTransform.h b/GPU/TPCFastTransformation/TPCFastTransform.h
index c8afbb57ecab8..1a33170a600ec 100644
--- a/GPU/TPCFastTransformation/TPCFastTransform.h
+++ b/GPU/TPCFastTransformation/TPCFastTransform.h
@@ -17,6 +17,8 @@
#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_TPCFASTTRANSFORM_H
#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_TPCFASTTRANSFORM_H
+#include "GPUCommonDef.h"
+
#include "FlatObject.h"
#include "TPCFastTransformGeo.h"
#include "TPCFastSpaceChargeCorrection.h"
@@ -94,8 +96,8 @@ struct TPCSlowSpaceChargeCorrection {
class TPCFastTransform : public FlatObject
{
public:
- static constexpr float DEFLUMI = -1e6f; // default value to check if member was set
- static constexpr float DEFIDC = -1e6f; // default value to check if member was set
+ static GPUglobalconstexpr() float DEFLUMI = -1e6f; // default value to check if member was set
+ static GPUglobalconstexpr() float DEFIDC = -1e6f; // default value to check if member was set
/// _____________ Constructors / destructors __________________________
diff --git a/GPU/TPCFastTransformation/TPCFastTransformGeo.h b/GPU/TPCFastTransformation/TPCFastTransformGeo.h
index 2cd145c276ea3..681258a71d733 100644
--- a/GPU/TPCFastTransformation/TPCFastTransformGeo.h
+++ b/GPU/TPCFastTransformation/TPCFastTransformGeo.h
@@ -175,9 +175,9 @@ class TPCFastTransformGeo
private:
/// _______________ Data members _______________________________________________
- static constexpr int32_t NumberOfSectors = o2::tpc::constants::MAXSECTOR; ///< Number of TPC sectors ( sector = inner + outer sector )
- static constexpr int32_t NumberOfSectorsA = NumberOfSectors / 2; ///< Number of TPC sectors side A
- static constexpr int32_t MaxNumberOfRows = 160; ///< Max Number of TPC rows in a sector - MUST NOT CHANGE THIS due to on-disk format of stored maps
+ static GPUglobalconstexpr() int32_t NumberOfSectors = o2::tpc::constants::MAXSECTOR; ///< Number of TPC sectors ( sector = inner + outer sector )
+ static GPUglobalconstexpr() int32_t NumberOfSectorsA = NumberOfSectors / 2; ///< Number of TPC sectors side A
+ static GPUglobalconstexpr() int32_t MaxNumberOfRows = 160; ///< Max Number of TPC rows in a sector - MUST NOT CHANGE THIS due to on-disk format of stored maps
/// _______________ Construction control _______________________________________________
diff --git a/GPU/TPCFastTransformation/TPCFastTransformPOD.h b/GPU/TPCFastTransformation/TPCFastTransformPOD.h
index c7e06d4b47ca4..b843c4f399f7e 100644
--- a/GPU/TPCFastTransformation/TPCFastTransformPOD.h
+++ b/GPU/TPCFastTransformation/TPCFastTransformPOD.h
@@ -17,6 +17,8 @@
#ifndef ALICEO2_GPU_TPCFastTransformPOD_H
#define ALICEO2_GPU_TPCFastTransformPOD_H
+#include "GPUCommonDef.h"
+
#include "GPUCommonRtypes.h"
#include "TPCFastTransform.h"
#include "TPCFastTransformGeoPOD.h"
@@ -240,10 +242,10 @@ class TPCFastTransformPOD
GPUd() float convDriftLengthToTime(float driftLength, float vertexTime) const;
- static constexpr int NROWS = o2::tpc::constants::MAXGLOBALPADROW;
- static constexpr int NSECTORS = o2::tpc::constants::MAXSECTOR;
- static constexpr int NSECTORSA = o2::tpc::constants::MAXSECTOR / 2;
- static constexpr int NSplineIDs = 3; ///< number of spline data sets for each sector/row
+ static GPUglobalconstexpr() int NROWS = o2::tpc::constants::MAXGLOBALPADROW;
+ static GPUglobalconstexpr() int NSECTORS = o2::tpc::constants::MAXSECTOR;
+ static GPUglobalconstexpr() int NSECTORSA = o2::tpc::constants::MAXSECTOR / 2;
+ static GPUglobalconstexpr() int NSplineIDs = 3; ///< number of spline data sets for each sector/row
private:
#if !defined(GPUCA_GPUCODE)
From 175b5be3625b24fba5ccc70e8c5c5609e5c7820c Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 10/17] GPUUtils: place shared constants in the constant
address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
---
GPU/Utils/GPUCommonBitSet.h | 2 +-
GPU/Utils/MultivariatePolynomialHelper.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/GPU/Utils/GPUCommonBitSet.h b/GPU/Utils/GPUCommonBitSet.h
index 03b494dbd1231..302334e01e29d 100644
--- a/GPU/Utils/GPUCommonBitSet.h
+++ b/GPU/Utils/GPUCommonBitSet.h
@@ -42,7 +42,7 @@ class bitset
GPUdDefault() constexpr bitset(const __constant bitset&) = default;
#endif // __OPENCL__
GPUd() constexpr bitset(uint32_t vv) : v(vv) {};
- static constexpr uint32_t full_set = ((1ul << N) - 1ul);
+ static GPUglobalconstexpr() uint32_t full_set = ((1ul << N) - 1ul);
GPUd() constexpr bool all() const { return (v & full_set) == full_set; }
GPUd() constexpr bool any() const { return v & full_set; }
diff --git a/GPU/Utils/MultivariatePolynomialHelper.h b/GPU/Utils/MultivariatePolynomialHelper.h
index 2dd186a859ab0..a2092b5e743d6 100644
--- a/GPU/Utils/MultivariatePolynomialHelper.h
+++ b/GPU/Utils/MultivariatePolynomialHelper.h
@@ -163,8 +163,8 @@ class MultivariatePolynomialParametersHelper
template
class MultivariatePolynomialHelper : public MultivariatePolynomialParametersHelper
{
- static constexpr uint16_t FMaxdim = 10; ///< maximum dimensionality of the polynomials (number of different digits: 0,1,2,3....9 )
- static constexpr uint16_t FMaxdegree = 9; ///< maximum degree of the polynomials (maximum number of digits in unsigned integer - 1)
+ static GPUglobalconstexpr() uint16_t FMaxdim = 10; ///< maximum dimensionality of the polynomials (number of different digits: 0,1,2,3....9 )
+ static GPUglobalconstexpr() uint16_t FMaxdegree = 9; ///< maximum degree of the polynomials (maximum number of digits in unsigned integer - 1)
#if !defined(GPUCA_GPUCODE)
static_assert(Dim <= MultivariatePolynomialHelper::FMaxdim && Degree <= MultivariatePolynomialHelper::FMaxdegree, "Max. number of dimensions or degrees exceeded!");
From 5f1f118467b3efd5e10e8a35dce3164f82f307ed Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 11/17] GPUTracking: place shared constants in the constant
address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space and diagnoses it at the declaration, so these headers
broke any device translation unit that included them regardless of whether the
constants were used. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, where it adds constant.
Last of the series: with this the Metal translation unit has no program-scope
diagnostics left, down from 208.
---
GPU/GPUTracking/Base/GPUConstantMem.h | 6 ++--
GPU/GPUTracking/Base/GPUParam.h | 2 +-
.../DataCompression/GPUTPCCompression.h | 20 +++++++------
.../DataCompression/GPUTPCDecompression.h | 4 ++-
.../DataTypes/CalibdEdxTrackTopologyPol.h | 6 ++--
.../DataTypes/CalibdEdxTrackTopologySpline.h | 6 ++--
GPU/GPUTracking/DataTypes/GPUDataTypesIO.h | 8 +++---
GPU/GPUTracking/DataTypes/GPUSettings.h | 2 +-
.../DataTypes/GPUTPCGMPolynomialField.h | 6 ++--
GPU/GPUTracking/DataTypes/GPUTPCGeometry.h | 15 +++++-----
GPU/GPUTracking/DataTypes/TPCPadBitMap.h | 4 ++-
GPU/GPUTracking/DataTypes/TPCPadGainCalib.h | 8 ++++--
.../Definitions/GPUDefConstantsAndSettings.h | 16 +++++------
.../Definitions/GPUDefParametersConstants.h | 22 +++++++--------
GPU/GPUTracking/Merger/GPUTPCGMMerger.h | 2 +-
.../TPCClusterFinder/CfChargePos.h | 4 ++-
GPU/GPUTracking/TRDTracking/GPUTRDTracker.h | 28 +++++++++----------
GPU/GPUTracking/dEdx/GPUdEdx.h | 4 ++-
18 files changed, 90 insertions(+), 73 deletions(-)
diff --git a/GPU/GPUTracking/Base/GPUConstantMem.h b/GPU/GPUTracking/Base/GPUConstantMem.h
index 14c388e450d73..05547262ce100 100644
--- a/GPU/GPUTracking/Base/GPUConstantMem.h
+++ b/GPU/GPUTracking/Base/GPUConstantMem.h
@@ -15,6 +15,8 @@
#ifndef GPUCONSTANTMEM_H
#define GPUCONSTANTMEM_H
+#include "GPUCommonDef.h"
+
#include "GPUTPCTracker.h"
#include "GPUParam.h"
#include "GPUDataTypesIO.h"
@@ -87,12 +89,12 @@ union GPUConstantMemCopyable {
};
#if defined(GPUCA_GPUCODE)
-static constexpr size_t gGPUConstantMemBufferSize = (sizeof(GPUConstantMem) + sizeof(uint4) - 1);
+static GPUglobalconstexpr() size_t gGPUConstantMemBufferSize = (sizeof(GPUConstantMem) + sizeof(uint4) - 1);
#endif
} // namespace o2::gpu
#if defined(GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM)
GPUconstant() o2::gpu::GPUConstantMemCopyable gGPUConstantMemBuffer; // TODO: This should go into o2::gpu namespace, but then CUDA or HIP would not find the symbol
-#endif // GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM
+#endif // GPUCA_HAS_GLOBAL_SYMBOL_CONSTANT_MEM
namespace o2::gpu
{
diff --git a/GPU/GPUTracking/Base/GPUParam.h b/GPU/GPUTracking/Base/GPUParam.h
index 11c48f5aadc70..dad4785ce9617 100644
--- a/GPU/GPUTracking/Base/GPUParam.h
+++ b/GPU/GPUTracking/Base/GPUParam.h
@@ -41,7 +41,7 @@ namespace internal
{
template
struct GPUParam_t {
- static constexpr float dAlpha = 0.349066f;
+ static GPUglobalconstexpr() float dAlpha = 0.349066f;
T rec;
S par;
diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h
index 5efe3936067b7..852156d7ab7f0 100644
--- a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h
+++ b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h
@@ -15,6 +15,8 @@
#ifndef GPUTPCCOMPRESSION_H
#define GPUTPCCOMPRESSION_H
+#include "GPUCommonDef.h"
+
#include "GPUDef.h"
#include "GPUProcessor.h"
#include "GPUCommonMath.h"
@@ -46,14 +48,14 @@ class GPUTPCCompression : public GPUProcessor
void* SetPointersMemory(void* mem);
#endif
- static constexpr uint32_t P_MAX_QMAX = 1 << 10;
- static constexpr uint32_t P_MAX_REGULAR_QTOT = 5 * 5 * P_MAX_QMAX;
- static constexpr uint32_t P_MAX_SATURATED_QTOT = 1 << 16; // Need two different limits as saturated clusters use full u16 range for qTot
- static constexpr uint32_t P_MAX_TIME = 1 << 24;
- static constexpr uint32_t P_MAX_PAD = 1 << 16;
- static constexpr uint32_t P_MAX_SIGMA = 1 << 8;
- static constexpr uint32_t P_MAX_FLAGS = 1 << 8;
- static constexpr uint32_t P_MAX_QPT = 1 << 8;
+ static GPUglobalconstexpr() uint32_t P_MAX_QMAX = 1 << 10;
+ static GPUglobalconstexpr() uint32_t P_MAX_REGULAR_QTOT = 5 * 5 * P_MAX_QMAX;
+ static GPUglobalconstexpr() uint32_t P_MAX_SATURATED_QTOT = 1 << 16; // Need two different limits as saturated clusters use full u16 range for qTot
+ static GPUglobalconstexpr() uint32_t P_MAX_TIME = 1 << 24;
+ static GPUglobalconstexpr() uint32_t P_MAX_PAD = 1 << 16;
+ static GPUglobalconstexpr() uint32_t P_MAX_SIGMA = 1 << 8;
+ static GPUglobalconstexpr() uint32_t P_MAX_FLAGS = 1 << 8;
+ static GPUglobalconstexpr() uint32_t P_MAX_QPT = 1 << 8;
GPUd() static void truncateSignificantBitsCharge(uint16_t& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_REGULAR_QTOT); }
GPUd() static void truncateSignificantBitsChargeMax(uint16_t& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QMAX); }
@@ -71,7 +73,7 @@ class GPUTPCCompression : public GPUProcessor
uint32_t nStoredUnattachedClusters = 0;
};
- constexpr static uint32_t NSECTORS = GPUTPCGeometry::NSECTORS;
+ GPUglobalconstexpr() static uint32_t NSECTORS = GPUTPCGeometry::NSECTORS;
o2::tpc::CompressedClustersPtrs mPtrs;
o2::tpc::CompressedClusters* mOutput = nullptr;
diff --git a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h
index 59b1c564bff02..a3fd64199bce7 100644
--- a/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h
+++ b/GPU/GPUTracking/DataCompression/GPUTPCDecompression.h
@@ -15,6 +15,8 @@
#ifndef GPUTPCDECOMPRESSION_H
#define GPUTPCDECOMPRESSION_H
+#include "GPUCommonDef.h"
+
#include "GPUDef.h"
#include "GPUProcessor.h"
#include "GPUCommonMath.h"
@@ -50,7 +52,7 @@ class GPUTPCDecompression : public GPUProcessor
#endif
protected:
- constexpr static uint32_t NSECTORS = GPUTPCGeometry::NSECTORS;
+ GPUglobalconstexpr() static uint32_t NSECTORS = GPUTPCGeometry::NSECTORS;
o2::tpc::CompressedClusters mInputGPU;
uint32_t mMaxNativeClustersPerBuffer;
diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h
index 939d3daf73b24..8110e32c72391 100644
--- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h
+++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologyPol.h
@@ -197,9 +197,9 @@ class CalibdEdxTrackTopologyPol : public o2::gpu::FlatObject
/// ================================================================================================
private:
- constexpr static int32_t FFits{10}; ///< total number of fits: 10 regions * 2 charge types
- constexpr static int32_t FDim{5}; ///< dimensions of polynomials
- constexpr static int32_t FDegree{3}; ///< degree of polynomials
+ GPUglobalconstexpr() static int32_t FFits { 10 }; ///< total number of fits: 10 regions * 2 charge types
+ GPUglobalconstexpr() static int32_t FDim { 5 }; ///< dimensions of polynomials
+ GPUglobalconstexpr() static int32_t FDegree { 3 }; ///< degree of polynomials
o2::gpu::NDPiecewisePolynomials mCalibPolsqTot[FFits]; ///< polynomial objects storage for the polynomials for qTot
o2::gpu::NDPiecewisePolynomials mCalibPolsqMax[FFits]; ///< polynomial objects storage for the polynomials for qMax
float mScalingFactorsqTot[FFits]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; ///< value which is used to scale the result of the polynomial for qTot (can be used for normalization)
diff --git a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h
index 106bbe93c27f5..bf371d8670357 100644
--- a/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h
+++ b/GPU/GPUTracking/DataTypes/CalibdEdxTrackTopologySpline.h
@@ -17,6 +17,8 @@
#ifndef CalibdEdxTrackTopologySpline_H
#define CalibdEdxTrackTopologySpline_H
+#include "GPUCommonDef.h"
+
#include "FlatObject.h"
#include "Spline.h"
#include "GPUCommonRtypes.h"
@@ -225,8 +227,8 @@ class CalibdEdxTrackTopologySpline : public o2::gpu::FlatObject
#endif
private:
- constexpr static uint32_t FSplines = 10; ///< number of splines stored for each type
- constexpr static int32_t FDimX = 3; ///< dimensionality of the splines
+ GPUglobalconstexpr() static uint32_t FSplines = 10; ///< number of splines stored for each type
+ GPUglobalconstexpr() static int32_t FDimX = 3; ///< dimensionality of the splines
SplineType mCalibSplinesqMax[FSplines]; ///< spline objects storage for the splines for qMax
SplineType mCalibSplinesqTot[FSplines]; ///< spline objects storage for the splines for qTot
float mMaxTanTheta{2.f}; ///< max tanTheta for which the correction is stored
diff --git a/GPU/GPUTracking/DataTypes/GPUDataTypesIO.h b/GPU/GPUTracking/DataTypes/GPUDataTypesIO.h
index f3172aa18d387..b541df40a23e5 100644
--- a/GPU/GPUTracking/DataTypes/GPUDataTypesIO.h
+++ b/GPU/GPUTracking/DataTypes/GPUDataTypesIO.h
@@ -137,8 +137,8 @@ typedef GPUCalibObjectsTemplate GPUCalibObjects; // NOTE: These 2 mu
typedef GPUCalibObjectsTemplate GPUCalibObjectsConst;
struct GPUTrackingInOutZS {
- static constexpr uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
- static constexpr uint32_t NENDPOINTS = 20;
+ static GPUglobalconstexpr() uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
+ static GPUglobalconstexpr() uint32_t NENDPOINTS = 20;
struct GPUTrackingInOutZSSector {
const void* const* zsPtr[NENDPOINTS];
const uint32_t* nZSPtr[NENDPOINTS];
@@ -155,7 +155,7 @@ struct GPUTrackingInOutZS {
};
struct GPUTrackingInOutDigits {
- static constexpr uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
+ static GPUglobalconstexpr() uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
const o2::tpc::Digit* tpcDigits[NSECTORS] = {nullptr};
size_t nTPCDigits[NSECTORS] = {0};
const GPUTPCDigitsMCInput* tpcDigitsMC = nullptr;
@@ -165,7 +165,7 @@ struct GPUTrackingInOutPointers {
GPUTrackingInOutPointers() = default;
// TPC
- static constexpr uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
+ static GPUglobalconstexpr() uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
const GPUTrackingInOutZS* tpcZS = nullptr;
const GPUTrackingInOutDigits* tpcPackedDigits = nullptr;
const GPUTPCClusterData* clusterData[NSECTORS] = {nullptr};
diff --git a/GPU/GPUTracking/DataTypes/GPUSettings.h b/GPU/GPUTracking/DataTypes/GPUSettings.h
index 34b378b046aec..dff33328e437f 100644
--- a/GPU/GPUTracking/DataTypes/GPUSettings.h
+++ b/GPU/GPUTracking/DataTypes/GPUSettings.h
@@ -44,7 +44,7 @@ class GPUSettings
RejectionStrategyA = 1,
RejectionStrategyB = 2 };
- static constexpr const uint32_t TPC_MAX_TF_TIME_BIN = ((256 * 3564 + 2 * 8 - 2) / 8);
+ static GPUglobalconstexpr() const uint32_t TPC_MAX_TF_TIME_BIN = ((256 * 3564 + 2 * 8 - 2) / 8);
};
// Settings describing the global run parameters
diff --git a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h
index 6417e47352339..946605e2a4c35 100644
--- a/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h
+++ b/GPU/GPUTracking/DataTypes/GPUTPCGMPolynomialField.h
@@ -53,9 +53,9 @@ class GPUTPCGMPolynomialField
void Print() const;
- static constexpr const int32_t NTPCM = 10; // number of coefficients
- static constexpr const int32_t NTRDM = 20; // number of coefficients for the TRD field
- static constexpr const int32_t NITSM = 10; // number of coefficients for the ITS field
+ static GPUglobalconstexpr() const int32_t NTPCM = 10; // number of coefficients
+ static GPUglobalconstexpr() const int32_t NTRDM = 20; // number of coefficients for the TRD field
+ static GPUglobalconstexpr() const int32_t NITSM = 10; // number of coefficients for the ITS field
GPUd() static void GetPolynomsTpc(float x, float y, float z, float f[NTPCM]);
GPUd() static void GetPolynomsTrd(float x, float y, float z, float f[NTRDM]);
diff --git a/GPU/GPUTracking/DataTypes/GPUTPCGeometry.h b/GPU/GPUTracking/DataTypes/GPUTPCGeometry.h
index 164f768d646ff..14f2021269591 100644
--- a/GPU/GPUTracking/DataTypes/GPUTPCGeometry.h
+++ b/GPU/GPUTracking/DataTypes/GPUTPCGeometry.h
@@ -25,7 +25,7 @@ namespace o2::gpu
namespace gputpcgeometry_internal
{
#ifndef GPUCA_RUN2 // clang-format off
-constexpr uint32_t NREGIONS = 10;
+GPUglobalconstexpr() uint32_t NREGIONS = 10;
GPUconstexpr() float mX[o2::tpc::constants::MAXGLOBALPADROW] = {85.225f, 85.975f, 86.725f, 87.475f, 88.225f, 88.975f, 89.725f, 90.475f, 91.225f, 91.975f, 92.725f, 93.475f, 94.225f, 94.975f, 95.725f, 96.475f, 97.225f, 97.975f, 98.725f, 99.475f, 100.225f, 100.975f,
101.725f, 102.475f, 103.225f, 103.975f, 104.725f, 105.475f, 106.225f, 106.975f, 107.725f, 108.475f, 109.225f, 109.975f, 110.725f, 111.475f, 112.225f, 112.975f, 113.725f, 114.475f, 115.225f, 115.975f, 116.725f, 117.475f,
118.225f, 118.975f, 119.725f, 120.475f, 121.225f, 121.975f, 122.725f, 123.475f, 124.225f, 124.975f, 125.725f, 126.475f, 127.225f, 127.975f, 128.725f, 129.475f, 130.225f, 130.975f, 131.725f, 135.2f, 136.2f, 137.2f,
@@ -61,8 +61,8 @@ GPUconstexpr() float mPadWidthRow[o2::tpc::constants::MAXGLOBALPADROW] = {.416,
.604, .604, .604, .604, .604, .604, .604, .604, .604, .604, .604, .604, .604,
.607, .607, .607, .607, .607, .607, .607, .607, .607, .607, .607, .607};
-constexpr float TPC_LENGTH = 250.f;
-constexpr float FACTOR_T2Z = 250.f / 512.f; // Used in compression, must remain constant at 250cm, 512 time bins!
+GPUglobalconstexpr() float TPC_LENGTH = 250.f;
+GPUglobalconstexpr() float FACTOR_T2Z = 250.f / 512.f; // Used in compression, must remain constant at 250cm, 512 time bins!
#else
constexpr uint32_t NREGIONS = 3;
GPUconstexpr() float mX[o2::tpc::constants::MAXGLOBALPADROW] = {85.195f, 85.945f, 86.695f, 87.445f, 88.195f, 88.945f, 89.695f, 90.445f, 91.195f, 91.945f, 92.695f, 93.445f, 94.195f, 94.945f, 95.695f, 96.445f, 97.195f, 97.945f, 98.695f, 99.445f, 100.195f, 100.945f, 101.695f,
@@ -101,11 +101,11 @@ GPUconstexpr() float mSectorAlpha[o2::tpc::constants::MAXSECTOR] = {0x1.65718ep-
class GPUTPCGeometry
{
- static constexpr float FACTOR_Z2T = 1.f / gputpcgeometry_internal::FACTOR_T2Z;
+ static GPUglobalconstexpr() float FACTOR_Z2T = 1.f / gputpcgeometry_internal::FACTOR_T2Z;
public:
- static constexpr uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
- static constexpr uint32_t NROWS = o2::tpc::constants::MAXGLOBALPADROW;
+ static GPUglobalconstexpr() uint32_t NSECTORS = o2::tpc::constants::MAXSECTOR;
+ static GPUglobalconstexpr() uint32_t NROWS = o2::tpc::constants::MAXGLOBALPADROW;
#ifndef GPUCA_RUN2
GPUd() static constexpr int32_t GetRegion(int32_t row) { return gputpcgeometry_internal::mRegion[row]; }
@@ -121,7 +121,8 @@ class GPUTPCGeometry
GPUd() static constexpr int32_t MaxNPadsPerRow() { return 138; }
GPUd() static constexpr float PadWidth(int32_t row) { return (gputpcgeometry_internal::mPadWidthRow[row]); }
#else
- GPUd() static constexpr int32_t GetRegion(int32_t row) { return (row < 63 ? 0 : row < 63 + 64 ? 1 : 2); }
+ GPUd() static constexpr int32_t GetRegion(int32_t row) { return (row < 63 ? 0 : row < 63 + 64 ? 1
+ : 2); }
GPUd() static constexpr int32_t GetRegionRows(int32_t region) { return 0; } // dummy
GPUd() static constexpr int32_t GetRegionStart(int32_t region) { return 0; } // dummy
GPUd() static constexpr int32_t GetROC(int32_t row) { return GetRegion(row); }
diff --git a/GPU/GPUTracking/DataTypes/TPCPadBitMap.h b/GPU/GPUTracking/DataTypes/TPCPadBitMap.h
index 6cbdffdc55a52..70ff0886ec8da 100644
--- a/GPU/GPUTracking/DataTypes/TPCPadBitMap.h
+++ b/GPU/GPUTracking/DataTypes/TPCPadBitMap.h
@@ -15,6 +15,8 @@
#ifndef O2_GPU_TPC_PAD_BITMAP_H
#define O2_GPU_TPC_PAD_BITMAP_H
+#include "GPUCommonDef.h"
+
#include "clusterFinderDefs.h"
#include "GPUCommonMath.h"
#include "DataFormatsTPC/Constants.h"
@@ -69,7 +71,7 @@ struct TPCPadBitMap {
{
public:
using T = uint32_t;
- static constexpr int32_t NWORDS = (TPC_REAL_PADS_IN_SECTOR + sizeof(T) * 8 - 1) / sizeof(T);
+ static GPUglobalconstexpr() int32_t NWORDS = (TPC_REAL_PADS_IN_SECTOR + sizeof(T) * 8 - 1) / sizeof(T);
GPUdi() SectorBitMap()
{
reset();
diff --git a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h
index 4295b75b6d2b2..c6fd0b58f36dc 100644
--- a/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h
+++ b/GPU/GPUTracking/DataTypes/TPCPadGainCalib.h
@@ -15,6 +15,8 @@
#ifndef O2_GPU_TPC_PAD_GAIN_CALIB_H
#define O2_GPU_TPC_PAD_GAIN_CALIB_H
+#include "GPUCommonDef.h"
+
#include "clusterFinderDefs.h"
#include "GPUCommonMath.h"
#include "DataFormatsTPC/Constants.h"
@@ -34,12 +36,12 @@ struct TPCPadGainCorrectionStepNum {
template <>
struct TPCPadGainCorrectionStepNum {
- static constexpr int32_t value = 254;
+ static GPUglobalconstexpr() int32_t value = 254;
};
template <>
struct TPCPadGainCorrectionStepNum {
- static constexpr int32_t value = 65534;
+ static GPUglobalconstexpr() int32_t value = 65534;
};
struct TPCPadGainCalib {
@@ -102,7 +104,7 @@ struct TPCPadGainCalib {
public:
float mMinCorrectionFactor = 0.f;
float mMaxCorrectionFactor = 2.f;
- constexpr static int32_t NumOfSteps = TPCPadGainCorrectionStepNum::value;
+ GPUglobalconstexpr() static int32_t NumOfSteps = TPCPadGainCorrectionStepNum::value;
GPUdi() SectorPadGainCorrection()
{
diff --git a/GPU/GPUTracking/Definitions/GPUDefConstantsAndSettings.h b/GPU/GPUTracking/Definitions/GPUDefConstantsAndSettings.h
index d8812bae72aad..a9fe70a286e04 100644
--- a/GPU/GPUTracking/Definitions/GPUDefConstantsAndSettings.h
+++ b/GPU/GPUTracking/Definitions/GPUDefConstantsAndSettings.h
@@ -32,17 +32,17 @@
namespace o2::gpu::constants
{
-static constexpr uint32_t MERGER_MAX_TRACK_CLUSTERS = 1024; // Maximum number of clusters a track may have after merging
-static constexpr uint32_t NEIGHBOURS_MAX_N = 40; // Maximum number of neighbor hits to consider in one row in neightbors finder
-static constexpr float MAX_SIN_PHI_LOW = 0.99f; // Limits for maximum sin phi during fit
-static constexpr float MAX_SIN_PHI = 0.999f; // Must be preprocessor define because c++ pre 11 cannot use static constexpr for initializes
-static constexpr float GRID_MIN_BIN_SIZE = 2.f; // Minimum bin size in TPC fast access grid
-static constexpr float GRID_MAX_BIN_SIZE = 1000.f; // Maximum bin size in TPC fast access grid
-static constexpr uint32_t TPC_COMP_CHUNK_SIZE = 1024; // Chunk size of sorted unattached TPC cluster in compression
+static GPUglobalconstexpr() uint32_t MERGER_MAX_TRACK_CLUSTERS = 1024; // Maximum number of clusters a track may have after merging
+static GPUglobalconstexpr() uint32_t NEIGHBOURS_MAX_N = 40; // Maximum number of neighbor hits to consider in one row in neightbors finder
+static GPUglobalconstexpr() float MAX_SIN_PHI_LOW = 0.99f; // Limits for maximum sin phi during fit
+static GPUglobalconstexpr() float MAX_SIN_PHI = 0.999f; // Must be preprocessor define because c++ pre 11 cannot use static constexpr for initializes
+static GPUglobalconstexpr() float GRID_MIN_BIN_SIZE = 2.f; // Minimum bin size in TPC fast access grid
+static GPUglobalconstexpr() float GRID_MAX_BIN_SIZE = 1000.f; // Maximum bin size in TPC fast access grid
+static GPUglobalconstexpr() uint32_t TPC_COMP_CHUNK_SIZE = 1024; // Chunk size of sorted unattached TPC cluster in compression
#ifdef GPUCA_RUN2
static constexpr uint32_t TPC_MAX_TIME_BIN_TRIGGERED = 1024;
#else
-static constexpr uint32_t TPC_MAX_TIME_BIN_TRIGGERED = 600;
+static GPUglobalconstexpr() uint32_t TPC_MAX_TIME_BIN_TRIGGERED = 600;
#endif
} // namespace o2::gpu::constants
diff --git a/GPU/GPUTracking/Definitions/GPUDefParametersConstants.h b/GPU/GPUTracking/Definitions/GPUDefParametersConstants.h
index 751d4a035ac85..d62d69a87a920 100644
--- a/GPU/GPUTracking/Definitions/GPUDefParametersConstants.h
+++ b/GPU/GPUTracking/Definitions/GPUDefParametersConstants.h
@@ -31,20 +31,20 @@
namespace o2::gpu::constants
{
-static constexpr size_t GPU_MAX_THREADS = 1024;
-static constexpr size_t GPU_MAX_STREAMS = o2::tpc::constants::MAXSECTOR;
+static GPUglobalconstexpr() size_t GPU_MAX_THREADS = 1024;
+static GPUglobalconstexpr() size_t GPU_MAX_STREAMS = o2::tpc::constants::MAXSECTOR;
-static constexpr size_t GPU_ROWALIGNMENT = 16; // Align of Row Hits and Grid
-static constexpr size_t GPU_BUFFER_ALIGNMENT = 64; // Alignment of buffers obtained from SetPointers
-static constexpr size_t GPU_MEMALIGN = (64 * 1024); // Alignment of allocated memory blocks
+static GPUglobalconstexpr() size_t GPU_ROWALIGNMENT = 16; // Align of Row Hits and Grid
+static GPUglobalconstexpr() size_t GPU_BUFFER_ALIGNMENT = 64; // Alignment of buffers obtained from SetPointers
+static GPUglobalconstexpr() size_t GPU_MEMALIGN = (64 * 1024); // Alignment of allocated memory blocks
//; Default maximum numbers
-static constexpr size_t GPU_MEM_MAX_TPC_CLUSTERS = 1024 * 1024 * 1024ull; // Maximum number of TPC clusters
-static constexpr size_t GPU_MEM_MAX_TRD_TRACKLETS = 128 * 1024ull; // Maximum number of TRD tracklets
-static constexpr size_t GPU_DEFAULT_MEMORY_SIZE = 6 * 1024 * 1024 * 1024ull; // Size of memory allocated on Device
-static constexpr size_t GPU_DEFAULT_HOST_MEMORY_SIZE = 1 * 1024 * 1024 * 1024ull; // Size of memory allocated on Host
-static constexpr size_t GPU_STACK_SIZE = 8 * 1024ull; // Stack size per GPU thread
-static constexpr size_t GPU_HEAP_SIZE = 16 * 1025 * 1024ull; // Stack size per GPU thread
+static GPUglobalconstexpr() size_t GPU_MEM_MAX_TPC_CLUSTERS = 1024 * 1024 * 1024ull; // Maximum number of TPC clusters
+static GPUglobalconstexpr() size_t GPU_MEM_MAX_TRD_TRACKLETS = 128 * 1024ull; // Maximum number of TRD tracklets
+static GPUglobalconstexpr() size_t GPU_DEFAULT_MEMORY_SIZE = 6 * 1024 * 1024 * 1024ull; // Size of memory allocated on Device
+static GPUglobalconstexpr() size_t GPU_DEFAULT_HOST_MEMORY_SIZE = 1 * 1024 * 1024 * 1024ull; // Size of memory allocated on Host
+static GPUglobalconstexpr() size_t GPU_STACK_SIZE = 8 * 1024ull; // Stack size per GPU thread
+static GPUglobalconstexpr() size_t GPU_HEAP_SIZE = 16 * 1025 * 1024ull; // Stack size per GPU thread
} // namespace o2::gpu::constants
// clang-format on
diff --git a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h
index bf587454ab20e..eefaf6fb74497 100644
--- a/GPU/GPUTracking/Merger/GPUTPCGMMerger.h
+++ b/GPU/GPUTracking/Merger/GPUTPCGMMerger.h
@@ -64,7 +64,7 @@ class GPUTPCGMMerger : public GPUProcessor
~GPUTPCGMMerger() = default;
GPUTPCGMMerger(const GPUTPCGMMerger&) = delete;
const GPUTPCGMMerger& operator=(const GPUTPCGMMerger&) const = delete;
- static constexpr const int32_t NSECTORS = GPUTPCGeometry::NSECTORS; //* N sectors
+ static GPUglobalconstexpr() const int32_t NSECTORS = GPUTPCGeometry::NSECTORS; //* N sectors
struct memory {
GPUAtomic(uint32_t) nRetryRefit;
diff --git a/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h b/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h
index 3d853345b8f95..3f1265e6d0634 100644
--- a/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h
+++ b/GPU/GPUTracking/TPCClusterFinder/CfChargePos.h
@@ -15,6 +15,8 @@
#ifndef O2_GPU_CHARGE_POS_H
#define O2_GPU_CHARGE_POS_H
+#include "GPUCommonDef.h"
+
#include "clusterFinderDefs.h"
namespace o2::gpu
@@ -56,7 +58,7 @@ struct CfChargePos {
}
};
-inline constexpr CfChargePos INVALID_CHARGE_POS{255, 255, INVALID_TIME_BIN};
+inline GPUglobalconstexpr() CfChargePos INVALID_CHARGE_POS{255, 255, INVALID_TIME_BIN};
} // namespace o2::gpu
diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h
index 0f94732f7d536..b11ec28aa4d89 100644
--- a/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h
+++ b/GPU/GPUTracking/TRDTracking/GPUTRDTracker.h
@@ -176,20 +176,20 @@ class GPUTRDTracker_t : public GPUProcessor
// the array has (kNChambers + 1) * numberOfCollisions entries
// note, that for collision iColl one has to add an offset corresponding to the index of the first tracklet of iColl to the index stored in mTrackletIndexArray
int32_t* mTrackletIndexArray;
- int32_t* mFT0TriggeredBC; // arrays with the FT0 triggered BCs, in number of BCs since the beginning of the TF
- int32_t mNFT0BC; // number of FT0 BCs
- Hypothesis* mHypothesis; // array with multiple track hypothesis
- TRDTRK* mCandidates; // array of tracks for multiple hypothesis tracking
- GPUTRDSpacePoint* mSpacePoints; // array with tracklet coordinates in global tracking frame
- const GPUTRDGeometry* mGeo; // TRD geometry
- const GPUTRDRecoParam* mRecoParam; // TRD RecoParam
- bool mDebugOutput; // store debug output
- static constexpr const float sRadialOffset = -0.1f; // due to (possible) mis-calibration of t0 -> will become obsolete when tracklet conversion is done outside of the tracker
- float mMaxEta; // TPC tracks with higher eta are ignored
- float mRoadZ; // in z, a constant search road is used
- float mTPCVdrift; // TPC drift velocity used for shifting TPC tracks along Z
- float mTPCTDriftOffset; // TPC drift time additive offset
- GPUTRDTrackerDebug* mDebug; // debug output
+ int32_t* mFT0TriggeredBC; // arrays with the FT0 triggered BCs, in number of BCs since the beginning of the TF
+ int32_t mNFT0BC; // number of FT0 BCs
+ Hypothesis* mHypothesis; // array with multiple track hypothesis
+ TRDTRK* mCandidates; // array of tracks for multiple hypothesis tracking
+ GPUTRDSpacePoint* mSpacePoints; // array with tracklet coordinates in global tracking frame
+ const GPUTRDGeometry* mGeo; // TRD geometry
+ const GPUTRDRecoParam* mRecoParam; // TRD RecoParam
+ bool mDebugOutput; // store debug output
+ static GPUglobalconstexpr() const float sRadialOffset = -0.1f; // due to (possible) mis-calibration of t0 -> will become obsolete when tracklet conversion is done outside of the tracker
+ float mMaxEta; // TPC tracks with higher eta are ignored
+ float mRoadZ; // in z, a constant search road is used
+ float mTPCVdrift; // TPC drift velocity used for shifting TPC tracks along Z
+ float mTPCTDriftOffset; // TPC drift time additive offset
+ GPUTRDTrackerDebug* mDebug; // debug output
};
} // namespace o2::gpu
diff --git a/GPU/GPUTracking/dEdx/GPUdEdx.h b/GPU/GPUTracking/dEdx/GPUdEdx.h
index dad62c1decb53..0c85a81483d20 100644
--- a/GPU/GPUTracking/dEdx/GPUdEdx.h
+++ b/GPU/GPUTracking/dEdx/GPUdEdx.h
@@ -15,6 +15,8 @@
#ifndef GPUDEDX_H
#define GPUDEDX_H
+#include "GPUCommonDef.h"
+
#include "GPUDef.h"
#include "GPUCommonMath.h"
#include "GPUParam.h"
@@ -37,7 +39,7 @@ class GPUdEdx
GPUd() void fillSubThreshold(int32_t padRow);
GPUd() void computedEdx(GPUdEdxInfo& output, const GPUParam& param);
- static constexpr size_t MAX_NCL = GPUTPCGeometry::NROWS;
+ static GPUglobalconstexpr() size_t MAX_NCL = GPUTPCGeometry::NROWS;
private:
GPUd() float GetSortTruncMean(GPUCA_PAR_DEDX_STORAGE_TYPE_A* array, int32_t count, int32_t trunclow, int32_t trunchigh);
From 2eee04effb0cac31cb6e4af337e0d987f489cff1 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 12/17] DataFormatsTPC: place the zero-suppression constants in
the constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
.../include/DataFormatsTPC/ZeroSuppression.h | 22 +++++++++----------
.../DataFormatsTPC/ZeroSuppressionLinkBased.h | 14 ++++++------
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppression.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppression.h
index b1df9445bcf42..32305acfdb5f6 100644
--- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppression.h
+++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppression.h
@@ -35,12 +35,12 @@ enum ZSVersion : unsigned char {
};
struct TPCZSHDR {
- static constexpr size_t TPC_ZS_PAGE_SIZE = 8192;
- static constexpr size_t TPC_MAX_SEQ_LEN = 138;
- static constexpr size_t TPC_MAX_ZS_ROW_IN_ENDPOINT = 9;
- static constexpr unsigned int MAX_DIGITS_IN_PAGE = (TPC_ZS_PAGE_SIZE - 64 - 6 - 4 - 3) * 8 / 10;
- static constexpr unsigned int TPC_ZS_NBITS_V1 = 10;
- static constexpr unsigned int TPC_ZS_NBITS_V2 = 12;
+ static GPUglobalconstexpr() size_t TPC_ZS_PAGE_SIZE = 8192;
+ static GPUglobalconstexpr() size_t TPC_MAX_SEQ_LEN = 138;
+ static GPUglobalconstexpr() size_t TPC_MAX_ZS_ROW_IN_ENDPOINT = 9;
+ static GPUglobalconstexpr() unsigned int MAX_DIGITS_IN_PAGE = (TPC_ZS_PAGE_SIZE - 64 - 6 - 4 - 3) * 8 / 10;
+ static GPUglobalconstexpr() unsigned int TPC_ZS_NBITS_V1 = 10;
+ static GPUglobalconstexpr() unsigned int TPC_ZS_NBITS_V2 = 12;
unsigned char version; // ZS format version:
// 1: original row-based format with 10-bit ADC values
@@ -53,10 +53,10 @@ struct TPCZSHDR {
unsigned short nADCsamples; // Total number of ADC samples in this raw page
};
struct TPCZSHDRV2 : public TPCZSHDR {
- static constexpr unsigned int TPC_ZS_NBITS_V34 = 12;
- static constexpr bool TIGHTLY_PACKED_V3 = false;
- static constexpr unsigned int SAMPLESPER64BIT = 64 / TPC_ZS_NBITS_V34; // 5 12-bit samples with 4 bit padding per 64 bit word for non-TIGHTLY_PACKED data
- static constexpr unsigned int TRIGGER_WORD_SIZE = 16; // trigger word size in bytes
+ static GPUglobalconstexpr() unsigned int TPC_ZS_NBITS_V34 = 12;
+ static GPUglobalconstexpr() bool TIGHTLY_PACKED_V3 = false;
+ static GPUglobalconstexpr() unsigned int SAMPLESPER64BIT = 64 / TPC_ZS_NBITS_V34; // 5 12-bit samples with 4 bit padding per 64 bit word for non-TIGHTLY_PACKED data
+ static GPUglobalconstexpr() unsigned int TRIGGER_WORD_SIZE = 16; // trigger word size in bytes
enum ZSFlags : unsigned char {
TriggerWordPresent = 1,
nTimeBinSpanBit8 = 2,
@@ -89,7 +89,7 @@ struct ZeroSuppressedContainer { // Struct for the TPC zero suppressed data form
///
/// Trigger word is always 128bit and occurs always in the last page of a HBF before the meta header
struct TriggerWordDLBZS {
- static constexpr uint16_t MaxTriggerEntries = 8; ///< Maximum number of trigger information
+ static GPUglobalconstexpr() uint16_t MaxTriggerEntries = 8; ///< Maximum number of trigger information
/// trigger types as in the ttype bits
enum TriggerType : uint8_t {
diff --git a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppressionLinkBased.h b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppressionLinkBased.h
index a753f24aec11f..455cefd8ce00f 100644
--- a/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppressionLinkBased.h
+++ b/DataFormats/Detectors/TPC/include/DataFormatsTPC/ZeroSuppressionLinkBased.h
@@ -30,16 +30,16 @@ namespace tpc
namespace zerosupp_link_based
{
-static constexpr uint32_t DataWordSizeBits = 128; ///< size of header word and data words in bits
-static constexpr uint32_t DataWordSizeBytes = DataWordSizeBits / 8; ///< size of header word and data words in bytes
-static constexpr uint32_t ChannelPerTBHeader = 80;
+static GPUglobalconstexpr() uint32_t DataWordSizeBits = 128; ///< size of header word and data words in bits
+static GPUglobalconstexpr() uint32_t DataWordSizeBytes = DataWordSizeBits / 8; ///< size of header word and data words in bytes
+static GPUglobalconstexpr() uint32_t ChannelPerTBHeader = 80;
/// common header definition of the zero suppressed link based data
struct CommonHeader {
- static constexpr uint32_t MagicWordLinkZS = 0xFC;
- static constexpr uint32_t MagicWordLinkZSMetaHeader = 0xFD;
- static constexpr uint32_t MagicWordTrigger = 0xAA;
- static constexpr uint32_t MagicWordTriggerV2 = 0xAB;
+ static GPUglobalconstexpr() uint32_t MagicWordLinkZS = 0xFC;
+ static GPUglobalconstexpr() uint32_t MagicWordLinkZSMetaHeader = 0xFD;
+ static GPUglobalconstexpr() uint32_t MagicWordTrigger = 0xAA;
+ static GPUglobalconstexpr() uint32_t MagicWordTriggerV2 = 0xAB;
union {
uint64_t word0 = 0; ///< lower 64 bits
From ec8409b61535ffe8b41e78bb2d1c8bae6258c708 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 13/17] DataFormatsTRD: place the Tracklet64 bit masks in the
constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
.../TRD/include/DataFormatsTRD/Tracklet64.h | 40 +++++++++----------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/DataFormats/Detectors/TRD/include/DataFormatsTRD/Tracklet64.h b/DataFormats/Detectors/TRD/include/DataFormatsTRD/Tracklet64.h
index e63d8fbb5f277..d1c479544243e 100644
--- a/DataFormats/Detectors/TRD/include/DataFormatsTRD/Tracklet64.h
+++ b/DataFormats/Detectors/TRD/include/DataFormatsTRD/Tracklet64.h
@@ -206,27 +206,27 @@ class Tracklet64
#endif // GPUCA_GPUCODE_DEVICE
// bit masks for the above raw data;
- static constexpr uint64_t formatmask = 0xf000000000000000;
- static constexpr uint64_t hcidmask = 0x0ffe000000000000;
- static constexpr uint64_t padrowmask = 0x0001e00000000000;
- static constexpr uint64_t colmask = 0x0000180000000000;
- static constexpr uint64_t posmask = 0x000007ff00000000;
- static constexpr uint64_t slopemask = 0x00000000ff000000;
- static constexpr uint64_t Q2mask = 0x0000000000ff0000;
- static constexpr uint64_t Q1mask = 0x000000000000ff00;
- static constexpr uint64_t Q0mask = 0x00000000000000ff;
- static constexpr uint64_t PIDmask = 0x0000000000ffffff;
+ static GPUglobalconstexpr() uint64_t formatmask = 0xf000000000000000;
+ static GPUglobalconstexpr() uint64_t hcidmask = 0x0ffe000000000000;
+ static GPUglobalconstexpr() uint64_t padrowmask = 0x0001e00000000000;
+ static GPUglobalconstexpr() uint64_t colmask = 0x0000180000000000;
+ static GPUglobalconstexpr() uint64_t posmask = 0x000007ff00000000;
+ static GPUglobalconstexpr() uint64_t slopemask = 0x00000000ff000000;
+ static GPUglobalconstexpr() uint64_t Q2mask = 0x0000000000ff0000;
+ static GPUglobalconstexpr() uint64_t Q1mask = 0x000000000000ff00;
+ static GPUglobalconstexpr() uint64_t Q0mask = 0x00000000000000ff;
+ static GPUglobalconstexpr() uint64_t PIDmask = 0x0000000000ffffff;
// bit shifts for the above raw data
- static constexpr uint64_t formatbs = 60;
- static constexpr uint64_t hcidbs = 49;
- static constexpr uint64_t padrowbs = 45;
- static constexpr uint64_t colbs = 43;
- static constexpr uint64_t posbs = 32;
- static constexpr uint64_t slopebs = 24;
- static constexpr uint64_t PIDbs = 0;
- static constexpr uint64_t Q2bs = 16;
- static constexpr uint64_t Q1bs = 8;
- static constexpr uint64_t Q0bs = 0;
+ static GPUglobalconstexpr() uint64_t formatbs = 60;
+ static GPUglobalconstexpr() uint64_t hcidbs = 49;
+ static GPUglobalconstexpr() uint64_t padrowbs = 45;
+ static GPUglobalconstexpr() uint64_t colbs = 43;
+ static GPUglobalconstexpr() uint64_t posbs = 32;
+ static GPUglobalconstexpr() uint64_t slopebs = 24;
+ static GPUglobalconstexpr() uint64_t PIDbs = 0;
+ static GPUglobalconstexpr() uint64_t Q2bs = 16;
+ static GPUglobalconstexpr() uint64_t Q1bs = 8;
+ static GPUglobalconstexpr() uint64_t Q0bs = 0;
protected:
uint64_t mtrackletWord; // the 64 bit word holding all the tracklet information for run3.
From d5ef704de989e2b934b5763ed1cecbf1bedad661 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 14/17] ReconstructionDataFormats: place the Vertex and
HelixHelper constants in the constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
.../include/ReconstructionDataFormats/HelixHelper.h | 2 +-
.../Reconstruction/include/ReconstructionDataFormats/Vertex.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/HelixHelper.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/HelixHelper.h
index d197cba256c0e..47de5457cea16 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/HelixHelper.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/HelixHelper.h
@@ -54,7 +54,7 @@ struct TrackAuxPar : public o2::math_utils::CircleXYf_t {
//__________________________________________________________
//< crossing coordinates of 2 circles
struct CrossInfo {
- static constexpr float MaxDistXYDef = 10.;
+ static GPUglobalconstexpr() float MaxDistXYDef = 10.;
float xDCA[2] = {};
float yDCA[2] = {};
int nDCA = 0;
diff --git a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h
index 588a23d25a000..106517bc4cf36 100644
--- a/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h
+++ b/DataFormats/Reconstruction/include/ReconstructionDataFormats/Vertex.h
@@ -42,7 +42,7 @@ class VertexBase
kCovXZ,
kCovYZ,
kCovZZ };
- static constexpr int kNCov = 6;
+ static GPUglobalconstexpr() int kNCov = 6;
GPUhdDefault() VertexBase() = default;
GPUhdDefault() ~VertexBase() = default;
GPUhd() VertexBase(const float* pos, const float* cov)
From c41e462c1c51a39369c0b8b917a659418ee195db Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 15/17] DetectorsRaw: place the RDH constants in the constant
address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
Detectors/Raw/include/DetectorsRaw/RDHUtils.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Detectors/Raw/include/DetectorsRaw/RDHUtils.h b/Detectors/Raw/include/DetectorsRaw/RDHUtils.h
index a5d8cc8615c79..5dd2c25a7980f 100644
--- a/Detectors/Raw/include/DetectorsRaw/RDHUtils.h
+++ b/Detectors/Raw/include/DetectorsRaw/RDHUtils.h
@@ -51,8 +51,8 @@ struct RDHUtils {
using RDHv6 = o2::header::RAWDataHeaderV6;
using RDHv7 = o2::header::RAWDataHeaderV7; // update this for every new version
- static constexpr int GBTWord128 = 16; // length of GBT word
- static constexpr int MAXCRUPage = 512 * GBTWord128;
+ static GPUglobalconstexpr() int GBTWord128 = 16; // length of GBT word
+ static GPUglobalconstexpr() int MAXCRUPage = 512 * GBTWord128;
/// get numeric version of the RDH
///_______________________________
From 8a9dddc768c48f4b37693c4b05c9b8409866a9fa Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 16/17] GPUCommon: place the GPU common constants in the
constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
GPU/Common/GPUCommonConstants.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/GPU/Common/GPUCommonConstants.h b/GPU/Common/GPUCommonConstants.h
index 1a7e34885c34a..f0b62a6db9650 100644
--- a/GPU/Common/GPUCommonConstants.h
+++ b/GPU/Common/GPUCommonConstants.h
@@ -19,8 +19,8 @@
namespace o2::gpu::gpu_common_constants
{
-static constexpr const float kCLight = 0.000299792458f; // TODO: Duplicate of MathConstants, fix this now that we use only OpenCL CPP
-static constexpr const float kZeroFieldCut = 0.013f;
+static GPUglobalconstexpr() const float kCLight = 0.000299792458f; // TODO: Duplicate of MathConstants, fix this now that we use only OpenCL CPP
+static GPUglobalconstexpr() const float kZeroFieldCut = 0.013f;
}
#endif
From f6ea55c2b161527f706a494f15620a96228af4c1 Mon Sep 17 00:00:00 2001
From: Giulio Eulisse <10544+ktf@users.noreply.github.com>
Date: Sun, 20 Sep 2026 09:58:01 +0200
Subject: [PATCH 17/17] GPUTracking: place the remaining cluster-finder
constants in the constant address space
MSL requires every variable at program scope, class-scope statics included, to
name an address space. GPUglobalconstexpr() expands to constexpr everywhere
except Metal, so this is a no-op for host, CUDA, HIP, OpenCL and cling.
These were missed by the earlier pass: the header they sit in only started
being compiled once the errors ahead of it were gone.
---
.../DataCompression/GPUTPCCompressionTrackModel.h | 2 +-
GPU/GPUTracking/Refit/GPUTrackingRefit.cxx | 2 +-
.../TPCClusterFinder/GPUTPCCFClusterizer.h | 2 +-
.../TPCClusterFinder/GPUTPCCFDecodeZS.h | 14 +++++++-------
.../TPCClusterFinder/GPUTPCCFDeconvolution.h | 2 +-
.../TPCClusterFinder/GPUTPCCFNoiseSuppression.h | 2 +-
.../TPCClusterFinder/GPUTPCCFPeakFinder.h | 2 +-
.../TPCClusterFinder/GPUTPCNNClusterizerKernels.h | 2 +-
GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h | 2 +-
9 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h
index 0021f3331cb2e..effa1a2dc917e 100644
--- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h
+++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionTrackModel.h
@@ -40,7 +40,7 @@ namespace o2::gpu
struct GPUParam;
-constexpr float MaxSinPhi = 0.999f;
+GPUglobalconstexpr() float MaxSinPhi = 0.999f;
class GPUTPCCompressionTrackModel
{
diff --git a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx
index de0525edcce2a..4ef0f29eabdff 100644
--- a/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx
+++ b/GPU/GPUTracking/Refit/GPUTrackingRefit.cxx
@@ -38,7 +38,7 @@ using namespace o2::track;
using namespace o2::base;
using namespace o2::tpc;
-static constexpr int32_t kIGNORE_ENDS = 3;
+static GPUglobalconstexpr() int32_t kIGNORE_ENDS = 3;
#define IgnoreErrors(SNP) \
if (mIgnoreErrorsOnTrackEnds) { \
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h
index 09814b464651c..ce673c778e42d 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFClusterizer.h
@@ -36,7 +36,7 @@ class MCLabelAccumulator;
class GPUTPCCFClusterizer : public GPUKernelTemplate
{
public:
- static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFClusterizer);
+ static GPUglobalconstexpr() size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFClusterizer);
struct GPUSharedMemory {
CfChargePos posBcast[SCRATCH_PAD_WORK_GROUP_SIZE];
PackedCharge buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_BUILD_N];
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h
index 74b76f6bf7598..21d4ec0a28958 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDecodeZS.h
@@ -132,9 +132,9 @@ class GPUTPCCFDecodeZSLink : public GPUTPCCFDecodeZSLinkBase
{
public:
// constants for decoding
- static inline constexpr int32_t DECODE_BITS = tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34;
- static inline constexpr float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10));
- static inline constexpr uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1;
+ static inline GPUglobalconstexpr() int32_t DECODE_BITS = tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34;
+ static inline GPUglobalconstexpr() float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10));
+ static inline GPUglobalconstexpr() uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1;
struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 {
// GPUCA_SHARED_STORAGE(uint32_t ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint32_t)]);
@@ -155,11 +155,11 @@ class GPUTPCCFDecodeZSDenseLink : public GPUTPCCFDecodeZSLinkBase
{
public:
// constants for decoding
- static inline constexpr int32_t DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34;
- static inline constexpr float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10));
- static inline constexpr uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1;
+ static inline GPUglobalconstexpr() int32_t DECODE_BITS = o2::tpc::TPCZSHDRV2::TPC_ZS_NBITS_V34;
+ static inline GPUglobalconstexpr() float DECODE_BITS_FACTOR = 1.f / (1 << (DECODE_BITS - 10));
+ static inline GPUglobalconstexpr() uint32_t DECODE_MASK = (1 << DECODE_BITS) - 1;
- static inline constexpr int32_t MaxNLinksPerTimebin = 16;
+ static inline GPUglobalconstexpr() int32_t MaxNLinksPerTimebin = 16;
struct GPUSharedMemory : GPUKernelTemplate::GPUSharedMemoryWarpScan64 {
// GPUCA_SHARED_STORAGE(uint32_t ZSPage[o2::tpc::TPCZSHDR::TPC_ZS_PAGE_SIZE / sizeof(uint32_t)]);
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h
index 2debce3dc0d6c..d6a4acb7ddb3c 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFDeconvolution.h
@@ -29,7 +29,7 @@ namespace o2::gpu
class GPUTPCCFDeconvolution : public GPUKernelTemplate
{
public:
- static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDeconvolution);
+ static GPUglobalconstexpr() size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFDeconvolution);
struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 {
CfChargePos posBcast1[SCRATCH_PAD_WORK_GROUP_SIZE];
uint8_t aboveThresholdBcast[SCRATCH_PAD_WORK_GROUP_SIZE];
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h
index 27095bb17c1e9..bdee75dc87732 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFNoiseSuppression.h
@@ -34,7 +34,7 @@ class GPUTPCCFNoiseSuppression : public GPUKernelTemplate
noiseSuppression = 0,
updatePeaks = 1,
};
- static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFNoiseSuppression_noiseSuppression);
+ static GPUglobalconstexpr() size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFNoiseSuppression_noiseSuppression);
static_assert(GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFNoiseSuppression_noiseSuppression) == GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFNoiseSuppression_updatePeaks));
struct GPUSharedMemory {
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h
index eeda0cecb3bc3..0d61378d3e6f2 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCCFPeakFinder.h
@@ -30,7 +30,7 @@ struct CfChargePos;
class GPUTPCCFPeakFinder : public GPUKernelTemplate
{
public:
- static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFPeakFinder);
+ static GPUglobalconstexpr() size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFPeakFinder);
struct GPUSharedMemory : public GPUKernelTemplate::GPUSharedMemoryScan64 {
CfChargePos posBcast[SCRATCH_PAD_WORK_GROUP_SIZE];
PackedCharge buf[SCRATCH_PAD_WORK_GROUP_SIZE * SCRATCH_PAD_SEARCH_N];
diff --git a/GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerKernels.h b/GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerKernels.h
index d7194d163f341..10ce5f3ee0288 100644
--- a/GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerKernels.h
+++ b/GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerKernels.h
@@ -37,7 +37,7 @@ class GPUTPCNNClusterizerKernels : public GPUKernelTemplate
{
public:
// Must all have same number of threads, since they use a common SCRATCH_PAD_WORK_GROUP_SIZE below
- static constexpr size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFClusterizer);
+ static GPUglobalconstexpr() size_t SCRATCH_PAD_WORK_GROUP_SIZE = GPUCA_GET_THREAD_COUNT(GPUCA_LB_GPUTPCCFClusterizer);
using GPUSharedMemory = GPUTPCCFClusterizer::GPUSharedMemory;
GPUhdi() constexpr static gpudatatypes::RecoStep GetRecoStep()
diff --git a/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h b/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h
index a99cc5f4a7a2d..0867582fffa14 100644
--- a/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h
+++ b/GPU/GPUTracking/TRDTracking/GPUTRDGeometry.h
@@ -74,7 +74,7 @@ class GPUTRDGeometry : private o2::trd::GeometryFlat
GPUd() int32_t GetRowMax(int32_t layer, int32_t stack, int32_t sector) const { return getRowMax(layer, stack, sector); }
GPUd() bool ChamberInGeometry(int32_t det) const { return chamberInGeometry(det); }
- static constexpr int32_t kNstack = o2::trd::constants::NSTACK;
+ static GPUglobalconstexpr() int32_t kNstack = o2::trd::constants::NSTACK;
};
} // namespace o2::gpu