Skip to content

Commit 9647d48

Browse files
committed
GPU: Add debug dumps for compressed / uncompressed TPC clusters
1 parent 440e500 commit 9647d48

14 files changed

+201
-47
lines changed

GPU/GPUTracking/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ set(HDRS_INSTALL
138138
Definitions/GPULogging.h
139139
Definitions/GPUSettingsList.h
140140
Global/GPUChainTrackingDefs.h
141+
Global/GPUChainTrackingDebug.h
141142
Global/GPUChainTrackingGetters.inc
142143
Global/GPUErrorCodes.h
143144
Merger/GPUTPCGMBorderTrack.h

GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,59 @@ void GPUTPCCompression::SetMaxData(const GPUTrackingInOutPointers& io)
130130
mMaxClusters += 16 - (mMaxClusters % 16);
131131
}
132132
}
133+
134+
void GPUTPCCompression::DumpCompressedClusters(std::ostream& out)
135+
{
136+
const o2::tpc::CompressedClusters O = *mOutputFlat;
137+
out << "\n\nCompressed Clusters:\n";
138+
out << O.nTracks << " Tracks\n";
139+
out << "Slice Row Clusters:\n";
140+
for (uint32_t i = 0; i < NSECTORS; i++) {
141+
out << "Sector " << i << ": ";
142+
for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) {
143+
out << O.nSliceRowClusters[i * GPUCA_ROW_COUNT + j] << ", ";
144+
}
145+
out << "\n";
146+
}
147+
out << "\nTrack Clusters:\n";
148+
for (uint32_t i = 0; i < O.nTracks; i++) {
149+
if (i && i % 100 == 0) {
150+
out << "\n";
151+
}
152+
out << O.nTrackClusters[i] << ", ";
153+
}
154+
out << "\n\nUnattached Clusters\n";
155+
uint32_t offset = 0;
156+
for (uint32_t i = 0; i < NSECTORS; i++) {
157+
for (uint32_t j = 0; j < GPUCA_ROW_COUNT; j++) {
158+
out << "Sector " << i << " Row " << j << ": ";
159+
for (uint32_t k = 0; k < O.nSliceRowClusters[i * GPUCA_ROW_COUNT + j]; k++) {
160+
if (k && k % 10 == 0) {
161+
out << "\n ";
162+
}
163+
const uint32_t l = k + offset;
164+
out << "[" << (uint32_t)O.qTotU[l] << ", " << (uint32_t)O.qMaxU[l] << ", " << (uint32_t)O.flagsU[l] << ", " << (int32_t)O.padDiffU[l] << ", " << (int32_t)O.timeDiffU[l] << ", " << (uint32_t)O.sigmaPadU[l] << ", " << (uint32_t)O.sigmaTimeU[l] << "] ";
165+
}
166+
offset += O.nSliceRowClusters[i * GPUCA_ROW_COUNT + j];
167+
out << "\n";
168+
}
169+
}
170+
out << "\n\nAttached Clusters\n";
171+
offset = 0;
172+
for (uint32_t i = 0; i < O.nTracks; i++) {
173+
out << "Track " << i << ": {" << (uint32_t)O.qPtA[i] << ", " << (uint32_t)O.rowA[i] << ", " << (uint32_t)O.sliceA[i] << ", " << (uint32_t)O.timeA[i] << ", " << (uint32_t)O.padA[i] << "} - ";
174+
for (uint32_t k = 0; k < O.nTrackClusters[i]; k++) {
175+
if (k && k % 10 == 0) {
176+
out << "\n ";
177+
}
178+
const uint32_t l1 = k + offset, l2 = k + offset - i;
179+
out << "[";
180+
if (k) {
181+
out << (int32_t)O.rowDiffA[l2] << ", " << (int32_t)O.sliceLegDiffA[l2] << ", " << (uint32_t)O.padResA[l2] << ", " << (uint32_t)O.timeResA[l2] << ", ";
182+
}
183+
out << (uint32_t)O.qTotA[l1] << ", " << (uint32_t)O.qMaxA[l1] << ", " << (uint32_t)O.flagsA[l1] << ", " << (uint32_t)O.sigmaPadA[l1] << ", " << (uint32_t)O.sigmaTimeA[l1] << "] ";
184+
}
185+
offset += O.nTrackClusters[i];
186+
out << "\n";
187+
}
188+
}

GPU/GPUTracking/DataCompression/GPUTPCCompression.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class GPUTPCCompression : public GPUProcessor
5757
GPUd() static void truncateSignificantBitsChargeMax(uint16_t& charge, const GPUParam& param) { truncateSignificantBits(charge, param.rec.tpc.sigBitsCharge, P_MAX_QMAX); }
5858
GPUd() static void truncateSignificantBitsWidth(uint8_t& width, const GPUParam& param) { truncateSignificantBits(width, param.rec.tpc.sigBitsWidth, P_MAX_SIGMA); }
5959

60+
#ifndef GPUCA_GPUCODE
61+
void DumpCompressedClusters(std::ostream& out);
62+
#endif
63+
6064
protected:
6165
struct memory {
6266
uint32_t nStoredTracks = 0;

GPU/GPUTracking/Definitions/GPUSettingsList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ AddOption(trdNCandidates, int32_t, 3, "", 0, "Number of branching track candidat
295295
AddOption(trdTrackModelO2, bool, false, "", 0, "Use O2 track model instead of GPU track model for TRD tracking")
296296
AddOption(debugLevel, int32_t, -1, "debug", 'd', "Set debug level (-2 = silent, -1 = autoselect (-2 for O2, 0 for standalone))")
297297
AddOption(allocDebugLevel, int32_t, 0, "allocDebug", 0, "Some debug output for memory allocations (without messing with normal debug level)")
298-
AddOption(debugMask, int32_t, 262143, "", 0, "Mask for debug output dumps to file")
298+
AddOption(debugMask, uint32_t, 262143, "", 0, "Mask for debug output dumps to file")
299299
AddOption(serializeGPU, int8_t, 0, "", 0, "Synchronize after each kernel call (bit 1) and DMA transfer (bit 2) and identify failures")
300300
AddOption(recoTaskTiming, bool, 0, "", 0, "Perform summary timing after whole reconstruction tasks")
301301
AddOption(deterministicGPUReconstruction, int32_t, -1, "", 0, "Make CPU and GPU debug output comparable (sort / skip concurrent parts), -1 = automatic if debugLevel >= 6", def(1))

GPU/GPUTracking/Global/GPUChain.h

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "GPUKernelClassesFwd.h"
2121

2222
#include <ctime>
23+
#include <functional>
2324

2425
namespace o2::gpu
2526
{
@@ -226,12 +227,19 @@ class GPUChain
226227
virtual int32_t DoStuckProtection(int32_t stream, deviceEvent event) { return 0; }
227228

228229
template <class T, class S, typename... Args>
229-
bool DoDebugAndDump(RecoStep step, int32_t mask, T& processor, S T::*func, Args&&... args)
230+
bool DoDebugAndDump(RecoStep step, uint32_t mask, T& processor, S T::*func, Args&&... args)
230231
{
231232
return DoDebugAndDump(step, mask, true, processor, func, args...);
232233
}
233234
template <class T, class S, typename... Args>
234-
bool DoDebugAndDump(RecoStep step, int32_t mask, bool transfer, T& processor, S T::*func, Args&&... args);
235+
bool DoDebugAndDump(RecoStep step, uint32_t mask, bool transfer, T& processor, S T::*func, Args&&... args);
236+
template <typename... Args>
237+
bool DoDebugDump(uint32_t mask, std::function<void(Args&...)> func, Args&... args);
238+
template <class S, typename... Args>
239+
bool DoDebugDump(uint32_t mask, S* func, Args&&... args)
240+
{
241+
return DoDebugDump(mask, std::function<void(Args && ...)>([&func](Args&&... args_tmp) { (*func)(args_tmp...); }), args...);
242+
}
235243

236244
template <class T, class S, typename... Args>
237245
int32_t runRecoStep(RecoStep step, S T::*func, Args... args);
@@ -278,24 +286,7 @@ inline void GPUChain::timeCpy(RecoStep step, int32_t toGPU, S T::*func, Args...
278286
}
279287

280288
template <class T, class S, typename... Args>
281-
bool GPUChain::DoDebugAndDump(GPUChain::RecoStep step, int32_t mask, bool transfer, T& processor, S T::*func, Args&&... args)
282-
{
283-
if (GetProcessingSettings().keepAllMemory) {
284-
if (transfer) {
285-
TransferMemoryResourcesToHost(step, &processor, -1, true);
286-
}
287-
if (GetProcessingSettings().debugLevel >= 6 && (mask == 0 || (GetProcessingSettings().debugMask & mask))) {
288-
if (func) {
289-
(processor.*func)(args...);
290-
}
291-
return true;
292-
}
293-
}
294-
return false;
295-
}
296-
297-
template <class T, class S, typename... Args>
298-
int32_t GPUChain::runRecoStep(RecoStep step, S T::*func, Args... args)
289+
inline int32_t GPUChain::runRecoStep(RecoStep step, S T::*func, Args... args)
299290
{
300291
if (GetRecoSteps().isSet(step)) {
301292
auto* timer = GetProcessingSettings().recoTaskTiming ? &mRec->getRecoStepTimer(step) : nullptr;

GPU/GPUTracking/Global/GPUChainTracking.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ class GPUChainTracking : public GPUChain
234234
void PrepareDebugOutput();
235235
void PrintDebugOutput();
236236
void PrintOutputStat();
237+
static void DumpClusters(std::ostream& out, const o2::tpc::ClusterNativeAccess* clusters);
237238

238239
bool ValidateSteps();
239240
bool ValidateSettings();

GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "GPUChainTracking.h"
1616
#include "GPUChainTrackingDefs.h"
17+
#include "GPUChainTrackingDebug.h"
1718
#include "GPULogging.h"
1819
#include "GPUO2DataTypes.h"
1920
#include "GPUMemorySizeScalers.h"
@@ -813,7 +814,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
813814
if (fragment.index == 0) {
814815
runKernel<GPUMemClean16>({GetGridAutoStep(lane, RecoStep::TPCClusterFinding)}, clustererShadow.mPpadIsNoisy, TPC_PADS_IN_SECTOR * sizeof(*clustererShadow.mPpadIsNoisy));
815816
}
816-
DoDebugAndDump(RecoStep::TPCClusterFinding, 262144, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Zeroed Charges");
817+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererZeroedCharges, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Zeroed Charges");
817818

818819
if (doGPU) {
819820
if (mIOPtrs.tpcZS && mCFContext->nPagesSector[iSector] && mCFContext->zsVersion != -1) {
@@ -900,7 +901,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
900901
if (!mIOPtrs.tpcZS) {
901902
runKernel<GPUTPCCFChargeMapFiller, GPUTPCCFChargeMapFiller::fillFromDigits>({GetGrid(clusterer.mPmemory->counters.nPositions, lane), {iSector}});
902903
}
903-
if (DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 1, clusterer, &GPUTPCClusterFinder::DumpDigits, *mDebugFile)) {
904+
if (DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererDigits, clusterer, &GPUTPCClusterFinder::DumpDigits, *mDebugFile)) {
904905
clusterer.DumpChargeMap(*mDebugFile, "Charges");
905906
}
906907

@@ -919,13 +920,13 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
919920
}
920921

921922
runKernel<GPUTPCCFPeakFinder>({GetGrid(clusterer.mPmemory->counters.nPositions, lane), {iSector}});
922-
if (DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 2, clusterer, &GPUTPCClusterFinder::DumpPeaks, *mDebugFile)) {
923+
if (DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererPeaks, clusterer, &GPUTPCClusterFinder::DumpPeaks, *mDebugFile)) {
923924
clusterer.DumpPeakMap(*mDebugFile, "Peaks");
924925
}
925926

926927
RunTPCClusterizer_compactPeaks(clusterer, clustererShadow, 0, doGPU, lane);
927928
TransferMemoryResourceLinkToHost(RecoStep::TPCClusterFinding, clusterer.mMemoryId, lane);
928-
DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 2, clusterer, &GPUTPCClusterFinder::DumpPeaksCompacted, *mDebugFile); // clang-format off
929+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererPeaks, clusterer, &GPUTPCClusterFinder::DumpPeaksCompacted, *mDebugFile); // clang-format off
929930
});
930931
mRec->runParallelOuterLoop(doGPU, maxLane, [&](uint32_t lane) {
931932
uint32_t iSector = iSectorBase + lane;
@@ -939,13 +940,13 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
939940
}
940941
runKernel<GPUTPCCFNoiseSuppression, GPUTPCCFNoiseSuppression::noiseSuppression>({GetGrid(clusterer.mPmemory->counters.nPeaks, lane), {iSector}});
941942
runKernel<GPUTPCCFNoiseSuppression, GPUTPCCFNoiseSuppression::updatePeaks>({GetGrid(clusterer.mPmemory->counters.nPeaks, lane), {iSector}});
942-
if (DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 3, clusterer, &GPUTPCClusterFinder::DumpSuppressedPeaks, *mDebugFile)) {
943+
if (DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererSuppressedPeaks, clusterer, &GPUTPCClusterFinder::DumpSuppressedPeaks, *mDebugFile)) {
943944
clusterer.DumpPeakMap(*mDebugFile, "Suppressed Peaks");
944945
}
945946

946947
RunTPCClusterizer_compactPeaks(clusterer, clustererShadow, 1, doGPU, lane);
947948
TransferMemoryResourceLinkToHost(RecoStep::TPCClusterFinding, clusterer.mMemoryId, lane);
948-
DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 3, clusterer, &GPUTPCClusterFinder::DumpSuppressedPeaksCompacted, *mDebugFile); // clang-format off
949+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererSuppressedPeaks, clusterer, &GPUTPCClusterFinder::DumpSuppressedPeaksCompacted, *mDebugFile); // clang-format off
949950
});
950951
mRec->runParallelOuterLoop(doGPU, maxLane, [&](uint32_t lane) {
951952
uint32_t iSector = iSectorBase + lane;
@@ -979,7 +980,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
979980

980981
if (clustererNNShadow.mNnClusterizerUseCfRegression || (int)(nn_settings.nnClusterizerApplyCfDeconvolution)) {
981982
runKernel<GPUTPCCFDeconvolution>({GetGrid(clusterer.mPmemory->counters.nPositions, lane), {iSector}});
982-
DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 4, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Split Charges");
983+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererChargeMap, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Split Charges");
983984
}
984985

985986
// float time_clusterizer = 0, time_fill = 0, time_networks = 0;
@@ -1092,7 +1093,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
10921093
#endif
10931094
} else {
10941095
runKernel<GPUTPCCFDeconvolution>({GetGrid(clusterer.mPmemory->counters.nPositions, lane), {iSector}});
1095-
DoDebugAndDump(RecoStep::TPCClusterFinding, 262144 << 4, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Split Charges");
1096+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererChargeMap, clusterer, &GPUTPCClusterFinder::DumpChargeMap, *mDebugFile, "Split Charges");
10961097
runKernel<GPUTPCCFClusterizer>({GetGrid(clusterer.mPmemory->counters.nClusters, lane), {iSector}}, 0);
10971098
}
10981099

@@ -1111,7 +1112,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput)
11111112
TransferMemoryResourcesToHost(RecoStep::TPCClusterFinding, &clusterer, lane);
11121113
laneHasData[lane] = true;
11131114
// Include clusters in default debug mask, exclude other debug output by default
1114-
DoDebugAndDump(RecoStep::TPCClusterFinding, 131072, clusterer, &GPUTPCClusterFinder::DumpClusters, *mDebugFile); // clang-format off
1115+
DoDebugAndDump(RecoStep::TPCClusterFinding, GPUChainTrackingDebugFlags::TPCClustererClusters, clusterer, &GPUTPCClusterFinder::DumpClusters, *mDebugFile); // clang-format off
11151116
});
11161117
mRec->SetNActiveThreadsOuterLoop(1);
11171118
}

GPU/GPUTracking/Global/GPUChainTrackingCompression.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
/// \author David Rohr
1414

1515
#include "GPUChainTracking.h"
16+
#include "GPUChainTrackingDebug.h"
1617
#include "GPULogging.h"
1718
#include "GPUO2DataTypes.h"
1819
#include "GPUTrackingInputProvider.h"
@@ -202,6 +203,7 @@ int32_t GPUChainTracking::RunTPCCompression()
202203
((GPUChainTracking*)GetNextChainInQueue())->mRec->BlockStackedMemory(mRec);
203204
}
204205
mRec->PopNonPersistentMemory(RecoStep::TPCCompression, qStr2Tag("TPCCOMPR"));
206+
DoDebugAndDump(RecoStep::TPCCompression, GPUChainTrackingDebugFlags::TPCCompressedClusters, Compressor, &GPUTPCCompression::DumpCompressedClusters, *mDebugFile);
205207
return 0;
206208
}
207209

@@ -425,5 +427,6 @@ int32_t GPUChainTracking::RunTPCDecompression()
425427
}
426428
mRec->PopNonPersistentMemory(RecoStep::TPCDecompression, qStr2Tag("TPCDCMPR"));
427429
}
430+
DoDebugDump(GPUChainTrackingDebugFlags::TPCDecompressedClusters, &GPUChainTracking::DumpClusters, *mDebugFile, mIOPtrs.clustersNative);
428431
return 0;
429432
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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 GPUChainTrackingDEBUG.h
13+
/// \author David Rohr
14+
15+
#ifndef GPUCHAINTRACKINGDEBUG_H
16+
#define GPUCHAINTRACKINGDEBUG_H
17+
18+
#include <cstdint>
19+
#include <functional>
20+
#include <fstream>
21+
22+
namespace o2::gpu
23+
{
24+
// NOTE: Values below 262144 are activated by default with --debug 6 in GPUSettingsList.h::debugMask
25+
enum GPUChainTrackingDebugFlags : uint32_t {
26+
TPCSectorTrackingData = 1,
27+
TPCPreLinks = 2,
28+
TPCLinks = 4,
29+
TPCStartHits = 8,
30+
TPCTracklets = 16,
31+
TPCSectorTracks = 32,
32+
TPCHitWeights = 256,
33+
TPCCompressedClusters = 512,
34+
TPCDecompressedClusters = 1024,
35+
TPCMergingRanges = 2048,
36+
TPCMergingSectorTracks = 4096,
37+
TPCMergingMergedTracks = 8192,
38+
TPCMergingCollectedTracks = 16384,
39+
TPCMergingCE = 32768,
40+
TPCMergingRefit = 65536,
41+
TPCClustererClusters = 131072,
42+
TPCClusterer = 262144,
43+
TPCClustererDigits = 262144 << 1,
44+
TPCClustererPeaks = 262144 << 2,
45+
TPCClustererSuppressedPeaks = 262144 << 3,
46+
TPCClustererChargeMap = 262144 << 4,
47+
TPCClustererZeroedCharges = 262144 << 5
48+
};
49+
50+
template <class T, class S, typename... Args>
51+
inline bool GPUChain::DoDebugAndDump(GPUChain::RecoStep step, uint32_t mask, bool transfer, T& processor, S T::*func, Args&&... args)
52+
{
53+
if (GetProcessingSettings().keepAllMemory) {
54+
if (transfer) {
55+
TransferMemoryResourcesToHost(step, &processor, -1, true);
56+
}
57+
std::function<void(Args && ...)> lambda = [&processor, &func](Args&... args_tmp) {
58+
if (func) {
59+
(processor.*func)(args_tmp...);
60+
}
61+
};
62+
return DoDebugDump(mask, lambda, args...);
63+
}
64+
return false;
65+
}
66+
67+
template <typename... Args>
68+
inline bool GPUChain::DoDebugDump(uint32_t mask, std::function<void(Args&...)> func, Args&... args)
69+
{
70+
if (GetProcessingSettings().debugLevel >= 6 && (mask == 0 || (GetProcessingSettings().debugMask & mask))) {
71+
func(args...);
72+
return true;
73+
}
74+
return false;
75+
}
76+
77+
} // namespace o2::gpu
78+
79+
#endif

GPU/GPUTracking/Global/GPUChainTrackingDebugAndProfiling.cxx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,3 +333,18 @@ void GPUChainTracking::RunTPCClusterFilter(o2::tpc::ClusterNativeAccess* cluster
333333
}
334334
}
335335
}
336+
337+
void GPUChainTracking::DumpClusters(std::ostream& out, const o2::tpc::ClusterNativeAccess* clusters)
338+
{
339+
out << "\nTPC Clusters:\n";
340+
for (uint32_t iSec = 0; iSec < GPUCA_NSECTORS; iSec++) {
341+
out << "TPCClusters - Sector " << iSec << "\n";
342+
for (uint32_t i = 0; i < GPUCA_ROW_COUNT; i++) {
343+
out << " Row: " << i << ": " << clusters->nClusters[iSec][i] << " clusters:\n";
344+
for (uint32_t j = 0; j < clusters->nClusters[iSec][i]; j++) {
345+
const auto& cl = clusters->clusters[iSec][i][j];
346+
out << " " << std::hex << cl.timeFlagsPacked << std::dec << " " << cl.padPacked << " " << int32_t{cl.sigmaTimePacked} << " " << int32_t{cl.sigmaPadPacked} << " " << cl.qMax << " " << cl.qTot << "\n";
347+
}
348+
}
349+
}
350+
}

0 commit comments

Comments
 (0)