Skip to content

Commit 46ef93f

Browse files
committed
GPU: Template workaround to get static constexpr values as constexpr from references
1 parent 4654958 commit 46ef93f

File tree

3 files changed

+76
-7
lines changed

3 files changed

+76
-7
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file GPUGetConstexpr.h
13+
/// \author David Rohr
14+
15+
#ifndef GPUGETCONSTEXPR_H
16+
#define GPUGETCONSTEXPR_H
17+
18+
#include "GPUCommonDef.h"
19+
#include "GPUCommonTypeTraits.h"
20+
21+
// This is a temporary workaround required for clang (with c++20), until we can go to C++23 with P2280R4, which allows getting constexpr static values from references
22+
23+
#if defined(__clang__) && __cplusplus >= 202002L && __cplusplus < 202302L
24+
25+
namespace o2::gpu::internal
26+
{
27+
28+
#define GPUCA_GET_CONSTEXPR(obj, val) ( \
29+
std::is_member_pointer_v<decltype(&std::remove_reference_t<decltype(obj)>::val)> ? o2::gpu::internal::getConstexpr(&std::remove_reference_t<decltype(obj)>::val, o2::gpu::internal::getConstexprHelper<decltype(&std::remove_reference_t<decltype(obj)>::val), decltype(&obj)>(&obj).value) : o2::gpu::internal::getConstexpr(&std::remove_reference_t<decltype(obj)>::val, o2::gpu::internal::getConstexprHelper<decltype(&std::remove_reference_t<decltype(obj)>::val), decltype(&obj)>().value))
30+
31+
template <class T, class S>
32+
struct getConstexprHelper;
33+
34+
template <class T, class S>
35+
requires(!std::is_member_pointer_v<T>)
36+
struct getConstexprHelper<T, S> {
37+
GPUdi() constexpr getConstexprHelper(const void* = nullptr) {}
38+
static constexpr const void* value = nullptr;
39+
};
40+
41+
template <class T, class S>
42+
requires(std::is_member_pointer_v<T>)
43+
struct getConstexprHelper<T, S> {
44+
GPUdi() constexpr getConstexprHelper(const S& v) : value(v) {}
45+
GPUdDefault() constexpr getConstexprHelper() = default;
46+
const S value = nullptr;
47+
};
48+
49+
GPUdi() constexpr auto getConstexpr(const auto* v, const void* = nullptr)
50+
{
51+
return *v;
52+
}
53+
54+
GPUdi() constexpr auto getConstexpr(const auto v, const auto w)
55+
{
56+
return w->*v;
57+
}
58+
59+
} // namespace o2::gpu::internal
60+
61+
#else // __clang__
62+
63+
#define GPUCA_GET_CONSTEXPR(obj, val) (obj).val
64+
65+
#endif
66+
67+
#endif // GPUGETCONSTEXPR_H

GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "DataFormatsTPC/PIDResponse.h"
2121
#include "TPCFastTransform.h"
2222
#include "CorrectionMapsHelper.h"
23+
#include "GPUGetConstexpr.h"
2324

2425
#ifndef GPUCA_GPUCODE
2526
#include "SimulationDataFormat/ConstMCTruthContainer.h"
@@ -141,10 +142,10 @@ GPUdii() void GPUTPCGMO2Output::Thread<GPUTPCGMO2Output::output>(int32_t nBlocks
141142

142143
oTrack.setChi2(tracks[i].GetParam().GetChi2());
143144
auto& outerPar = tracks[i].OuterParam();
144-
if GPUCA_RTC_CONSTEXPR (param.par.dodEdx) {
145+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.par, dodEdx)) {
145146
if (param.dodEdxEnabled) {
146147
oTrack.setdEdx(tracksdEdx[i]);
147-
if GPUCA_RTC_CONSTEXPR (param.rec.tpc.dEdxClusterRejectionFlagMask != param.rec.tpc.dEdxClusterRejectionFlagMaskAlt) {
148+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMask) != GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMaskAlt)) {
148149
oTrack.setdEdxAlt(tracksdEdxAlt[i]);
149150
} else {
150151
oTrack.setdEdxAlt(tracksdEdx[i]);

GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include "GPUTPCConvertImpl.h"
4040
#include "GPUTPCGMMergerTypes.h"
4141
#include "GPUParam.inc"
42+
#include "GPUGetConstexpr.h"
4243

4344
#ifdef GPUCA_CADEBUG_ENABLED
4445
#include "../utils/qconfig.h"
@@ -216,12 +217,12 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
216217
continue;
217218
}
218219
} else if (allowModification && lastRow != 255 && CAMath::Abs(cluster.row - lastRow) > 1) {
219-
if GPUCA_RTC_CONSTEXPR (param.par.dodEdx) {
220+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.par, dodEdx)) {
220221
bool dodEdx = param.dodEdxEnabled && param.rec.tpc.adddEdxSubThresholdClusters && iWay == nWays - 1 && CAMath::Abs(cluster.row - lastRow) == 2 && cluster.leg == clusters[maxN - 1].leg;
221222
dodEdx = AttachClustersPropagate(merger, cluster.sector, lastRow, cluster.row, iTrk, cluster.leg == clusters[maxN - 1].leg, prop, inFlyDirection, GPUCA_MAX_SIN_PHI, dodEdx);
222223
if (dodEdx) {
223224
dEdx.fillSubThreshold(lastRow - wayDirection);
224-
if GPUCA_RTC_CONSTEXPR (param.rec.tpc.dEdxClusterRejectionFlagMask != param.rec.tpc.dEdxClusterRejectionFlagMaskAlt) {
225+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMask) != GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMaskAlt)) {
225226
dEdxAlt.fillSubThreshold(lastRow - wayDirection);
226227
}
227228
}
@@ -371,7 +372,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
371372
CADEBUG(printf("Reinit linearization\n"));
372373
prop.SetTrack(this, prop.GetAlpha());
373374
}
374-
if GPUCA_RTC_CONSTEXPR (param.par.dodEdx) {
375+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.par, dodEdx)) {
375376
if (param.dodEdxEnabled && iWay == nWays - 1 && cluster.leg == clusters[maxN - 1].leg) { // TODO: Costimize flag to remove, and option to remove double-clusters
376377
bool acc = (clusterState & param.rec.tpc.dEdxClusterRejectionFlagMask) == 0, accAlt = (clusterState & param.rec.tpc.dEdxClusterRejectionFlagMaskAlt) == 0;
377378
if (acc || accAlt) {
@@ -395,7 +396,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
395396
if (acc) {
396397
dEdx.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime);
397398
}
398-
if GPUCA_RTC_CONSTEXPR (param.rec.tpc.dEdxClusterRejectionFlagMask != param.rec.tpc.dEdxClusterRejectionFlagMaskAlt) {
399+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMask) != GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMaskAlt)) {
399400
if (accAlt) {
400401
dEdxAlt.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime);
401402
}
@@ -436,7 +437,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
436437

437438
if (param.par.dodEdx && param.dodEdxEnabled) {
438439
dEdx.computedEdx(merger->MergedTracksdEdx()[iTrk], param);
439-
if GPUCA_RTC_CONSTEXPR (param.rec.tpc.dEdxClusterRejectionFlagMask != param.rec.tpc.dEdxClusterRejectionFlagMaskAlt) {
440+
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMask) != GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMaskAlt)) {
440441
dEdxAlt.computedEdx(merger->MergedTracksdEdxAlt()[iTrk], param);
441442
}
442443
}

0 commit comments

Comments
 (0)