Skip to content

Commit 963bbcb

Browse files
committed
GPU TPC: Add trigger word handling during GPU decoding
1 parent 45ca699 commit 963bbcb

File tree

15 files changed

+109
-6
lines changed

15 files changed

+109
-6
lines changed

Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum struct OutputType { Digits,
6565
ZSRaw,
6666
QA,
6767
NoSharedClusterMap,
68+
TPCTriggers
6869
};
6970

7071
using CompletionPolicyData = std::vector<framework::InputSpec>;

Detectors/TPC/workflow/src/RecoWorkflow.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ const std::unordered_map<std::string, OutputType> OutputMap{
9191
{"send-clusters-per-sector", OutputType::SendClustersPerSector},
9292
{"zsraw", OutputType::ZSRaw},
9393
{"qa", OutputType::QA},
94-
{"no-shared-cluster-map", OutputType::NoSharedClusterMap}};
94+
{"no-shared-cluster-map", OutputType::NoSharedClusterMap},
95+
{"tpc-triggers", OutputType::TPCTriggers}};
9596

9697
framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData, std::vector<int> const& tpcSectors, unsigned long tpcSectorMask, std::vector<int> const& laneConfiguration,
9798
bool propagateMC, unsigned nLanes, std::string const& cfgInput, std::string const& cfgOutput, bool disableRootInput,
@@ -445,6 +446,7 @@ framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData, std::vecto
445446
cfg.processMC = propagateMC;
446447
cfg.sendClustersPerSector = isEnabled(OutputType::SendClustersPerSector);
447448
cfg.askDISTSTF = askDISTSTF;
449+
cfg.tpcTriggerHandling = isEnabled(OutputType::TPCTriggers);
448450

449451
Inputs ggInputs;
450452
auto ggRequest = std::make_shared<o2::base::GRPGeomRequest>(false, true, false, true, true, o2::base::GRPGeomRequest::Aligned, ggInputs, true);

Detectors/TPC/workflow/src/tpc-reco-workflow.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void customize(std::vector<o2::framework::ConfigParamSpec>& workflowOptions)
5656

5757
std::vector<ConfigParamSpec> options{
5858
{"input-type", VariantType::String, "digits", {"digitizer, digits, zsraw, clustershw, clusters, compressed-clusters, compressed-clusters-ctf, pass-through"}},
59-
{"output-type", VariantType::String, "tracks", {"digits, zsraw, clustershw, clusters, tracks, compressed-clusters, encoded-clusters, disable-writer, send-clusters-per-sector, qa, no-shared-cluster-map"}},
59+
{"output-type", VariantType::String, "tracks", {"digits, zsraw, clustershw, clusters, tracks, compressed-clusters, encoded-clusters, disable-writer, send-clusters-per-sector, qa, no-shared-cluster-map, tpc-triggers"}},
6060
{"disable-root-input", o2::framework::VariantType::Bool, false, {"disable root-files input reader"}},
6161
{"no-ca-clusterer", VariantType::Bool, false, {"Use HardwareClusterer instead of clusterer of GPUCATracking"}},
6262
{"disable-mc", VariantType::Bool, false, {"disable sending of MC information"}},

GPU/GPUTracking/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ set(HDRS_INSTALL
153153
DataTypes/GPUO2FakeClasses.h
154154
Definitions/GPUSettingsList.h
155155
DataTypes/GPUOutputControl.h
156+
DataTypes/GPUTriggerOutputs.h
156157
DataTypes/GPUO2DataTypes.h
157158
DataTypes/GPUHostDataTypes.h
158159
DataTypes/GPUdEdxInfo.h

GPU/GPUTracking/DataTypes/GPUOutputControl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct GPUTrackingOutputs {
7474
GPUOutputControl tpcTracksO2;
7575
GPUOutputControl tpcTracksO2ClusRefs;
7676
GPUOutputControl tpcTracksO2Labels;
77+
GPUOutputControl tpcTriggerWords;
7778

7879
static constexpr size_t count() { return sizeof(GPUTrackingOutputs) / sizeof(GPUOutputControl); }
7980
GPUOutputControl* asArray() { return (GPUOutputControl*)this; }
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 GPUTriggerOutputs.h
13+
/// \author David Rohr
14+
15+
#ifndef GPUTRIGGEROUTPUTS_H
16+
#define GPUTRIGGEROUTPUTS_H
17+
18+
#include "GPUCommonDef.h"
19+
#include <unordered_set>
20+
#include <array>
21+
#ifdef GPUCA_HAVE_O2HEADERS
22+
#include "DataFormatsTPC/ZeroSuppression.h"
23+
#endif
24+
25+
namespace GPUCA_NAMESPACE
26+
{
27+
namespace gpu
28+
{
29+
30+
struct GPUTriggerOutputs {
31+
#ifdef GPUCA_HAVE_O2HEADERS
32+
struct hasher {
33+
size_t operator()(const std::array<unsigned long, o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE / sizeof(unsigned long)>& key) const
34+
{
35+
std::hash<unsigned long> std_hasher;
36+
size_t result = 0;
37+
for (size_t i = 0; i < key.size(); ++i) {
38+
result ^= std_hasher(key[i]);
39+
}
40+
return result;
41+
}
42+
};
43+
44+
std::unordered_set<std::array<unsigned long, o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE / sizeof(unsigned long)>, hasher> triggers;
45+
static_assert(o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE % sizeof(unsigned long) == 0);
46+
#endif
47+
};
48+
49+
} // namespace gpu
50+
} // namespace GPUCA_NAMESPACE
51+
52+
#endif

GPU/GPUTracking/Definitions/GPUSettingsList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ EndConfig()
178178
BeginSubConfig(GPUSettingsProcessingParam, param, configStandalone.proc, "PARAM", 0, "Processing settings", proc_param)
179179
AddOptionArray(tpcErrorParamY, float, 4, (0.06, 0.24, 0.12, 0.1), "", 0, "TPC Cluster Y Error Parameterization")
180180
AddOptionArray(tpcErrorParamZ, float, 4, (0.06, 0.24, 0.15, 0.1), "", 0, "TPC Cluster Z Error Parameterization")
181+
AddOption(tpcTriggerHandling, bool, false, "", 0, "Enable TPC trigger handling")
181182
AddHelp("help", 'h')
182183
EndConfig()
183184

GPU/GPUTracking/Global/GPUChainTracking.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "GPUMemorySizeScalers.h"
4343
#include "GPUTrackingInputProvider.h"
4444
#include "GPUNewCalibValues.h"
45+
#include "GPUTriggerOutputs.h"
4546

4647
#ifdef GPUCA_HAVE_O2HEADERS
4748
#include "GPUTPCClusterStatistics.h"
@@ -65,7 +66,7 @@ using namespace GPUCA_NAMESPACE::gpu;
6566
using namespace o2::tpc;
6667
using namespace o2::trd;
6768

68-
GPUChainTracking::GPUChainTracking(GPUReconstruction* rec, unsigned int maxTPCHits, unsigned int maxTRDTracklets) : GPUChain(rec), mIOPtrs(processors()->ioPtrs), mInputsHost(new GPUTrackingInputProvider), mInputsShadow(new GPUTrackingInputProvider), mClusterNativeAccess(new ClusterNativeAccess), mMaxTPCHits(maxTPCHits), mMaxTRDTracklets(maxTRDTracklets), mDebugFile(new std::ofstream)
69+
GPUChainTracking::GPUChainTracking(GPUReconstruction* rec, unsigned int maxTPCHits, unsigned int maxTRDTracklets) : GPUChain(rec), mIOPtrs(processors()->ioPtrs), mInputsHost(new GPUTrackingInputProvider), mInputsShadow(new GPUTrackingInputProvider), mClusterNativeAccess(new ClusterNativeAccess), mTriggerBuffer(new GPUTriggerOutputs), mMaxTPCHits(maxTPCHits), mMaxTRDTracklets(maxTRDTracklets), mDebugFile(new std::ofstream)
6970
{
7071
ClearIOPointers();
7172
mFlatObjectsShadow.mChainTracking = this;

GPU/GPUTracking/Global/GPUChainTracking.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class GPUTrackingInputProvider;
6464
struct GPUChainTrackingFinalContext;
6565
struct GPUTPCCFChainContext;
6666
struct GPUNewCalibValues;
67+
struct GPUTriggerOutputs;
6768

6869
class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelegateBase
6970
{
@@ -266,6 +267,7 @@ class GPUChainTracking : public GPUChain, GPUReconstructionHelpers::helperDelega
266267
// Ptrs to internal buffers
267268
std::unique_ptr<o2::tpc::ClusterNativeAccess> mClusterNativeAccess;
268269
std::array<GPUOutputControl*, GPUTrackingOutputs::count()> mSubOutputControls = {nullptr};
270+
std::unique_ptr<GPUTriggerOutputs> mTriggerBuffer;
269271

270272
// (Ptrs to) configuration objects
271273
std::unique_ptr<GPUTPCCFChainContext> mCFContext;

GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "CommonDataFormat/InteractionRecord.h"
2525
#endif
2626
#ifdef GPUCA_HAVE_O2HEADERS
27+
#include "GPUTriggerOutputs.h"
2728
#include "GPUHostDataTypes.h"
2829
#include "GPUTPCCFChainContext.h"
2930
#include "DataFormatsTPC/ZeroSuppression.h"
@@ -198,6 +199,15 @@ std::pair<unsigned int, unsigned int> GPUChainTracking::TPCClusterizerDecodeZSCo
198199
const TPCZSHDR* const hdr = (const TPCZSHDR*)(rdh_utils::getLink(o2::raw::RDHUtils::getFEEID(*rdh)) == rdh_utils::DLBZSLinkID ? (page + o2::raw::RDHUtils::getMemorySize(*rdh) - sizeof(TPCZSHDRV2)) : (page + sizeof(o2::header::RAWDataHeader)));
199200
if (mCFContext->zsVersion == -1) {
200201
mCFContext->zsVersion = hdr->version;
202+
if (GetProcessingSettings().param.tpcTriggerHandling && mCFContext->zsVersion < ZSVersion::ZSVersionDenseLinkBased) {
203+
GPUError("Trigger handling only possible with TPC Dense Link Based data, received version %d", mCFContext->zsVersion);
204+
if (GetProcessingSettings().ignoreNonFatalGPUErrors) {
205+
mCFContext->abandonTimeframe = true;
206+
return {0, 0};
207+
} else {
208+
GPUFatal("Cannot process with invalid TPC ZS data, exiting");
209+
}
210+
}
201211
} else if (mCFContext->zsVersion != (int)hdr->version) {
202212
GPUError("Received TPC ZS 8kb page of mixed versions, expected %d, received %d (linkid %d, feeCRU %d, feeEndpoint %d, feelinkid %d)", mCFContext->zsVersion, (int)hdr->version, (int)o2::raw::RDHUtils::getLinkID(*rdh), (int)rdh_utils::getCRU(*rdh), (int)rdh_utils::getEndPoint(*rdh), (int)rdh_utils::getLink(*rdh));
203213
constexpr size_t bufferSize = 3 * std::max(sizeof(*rdh), sizeof(*hdr)) + 1;
@@ -219,6 +229,15 @@ std::pair<unsigned int, unsigned int> GPUChainTracking::TPCClusterizerDecodeZSCo
219229
GPUFatal("Cannot process with invalid TPC ZS data, exiting");
220230
}
221231
}
232+
if (GetProcessingSettings().param.tpcTriggerHandling) {
233+
const TPCZSHDRV2* const hdr2 = (const TPCZSHDRV2*)hdr;
234+
if (hdr2->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) {
235+
const char* triggerWord = (const char*)hdr - TPCZSHDRV2::TRIGGER_WORD_SIZE;
236+
std::array<unsigned long, TPCZSHDRV2::TRIGGER_WORD_SIZE / sizeof(unsigned long)> tmp;
237+
memcpy((void*)tmp.data(), triggerWord, TPCZSHDRV2::TRIGGER_WORD_SIZE);
238+
mTriggerBuffer->triggers.emplace(tmp);
239+
}
240+
}
222241
nDigits += hdr->nADCsamples;
223242
endpointAdcSamples[j] += hdr->nADCsamples;
224243
unsigned int timeBin = (hdr->timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN;
@@ -459,6 +478,9 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers)
459478
if (mIOPtrs.tpcZS) {
460479
unsigned int nDigitsFragmentMax[NSLICES];
461480
mCFContext->zsVersion = -1;
481+
if (GetProcessingSettings().param.tpcTriggerHandling) {
482+
mTriggerBuffer->triggers.clear();
483+
}
462484
for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) {
463485
if (mIOPtrs.tpcZS->slice[iSlice].count[0]) {
464486
const void* rdh = mIOPtrs.tpcZS->slice[iSlice].zsPtr[0][0];
@@ -484,6 +506,15 @@ int GPUChainTracking::RunTPCClusterizer_prepare(bool restorePointers)
484506
processors()->tpcClusterer[iSlice].mPmemory->counters.nDigits = x.first;
485507
mRec->MemoryScalers()->nTPCdigits += x.first;
486508
}
509+
if (GetProcessingSettings().param.tpcTriggerHandling) {
510+
GPUOutputControl* triggerOutput = mSubOutputControls[GPUTrackingOutputs::getIndex(&GPUTrackingOutputs::tpcTriggerWords)];
511+
if (triggerOutput && triggerOutput->allocator) {
512+
GPUInfo("Storing %lu trigger words", mTriggerBuffer->triggers.size());
513+
auto* outputBuffer = (decltype(mTriggerBuffer->triggers)::value_type*)triggerOutput->allocator(mTriggerBuffer->triggers.size() * sizeof(decltype(mTriggerBuffer->triggers)::value_type));
514+
std::copy(mTriggerBuffer->triggers.begin(), mTriggerBuffer->triggers.end(), outputBuffer);
515+
}
516+
mTriggerBuffer->triggers.clear();
517+
}
487518
for (unsigned int iSlice = 0; iSlice < NSLICES; iSlice++) {
488519
unsigned int nDigitsBase = nDigitsFragmentMax[iSlice];
489520
unsigned int threshold = 40000000;

0 commit comments

Comments
 (0)