Skip to content

Commit e40fb9b

Browse files
committed
GPU: Provide flat output of compressed clusters
1 parent d92dbfb commit e40fb9b

19 files changed

Lines changed: 137 additions & 82 deletions

DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClusters.h

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifndef ALICEO2_DATAFORMATSTPC_COMPRESSED_CLUSTERS_H
1616
#define ALICEO2_DATAFORMATSTPC_COMPRESSED_CLUSTERS_H
1717

18+
#include "GPUCommonDef.h"
1819
#include "GPUCommonRtypes.h"
1920

2021
namespace o2
@@ -29,52 +30,75 @@ struct CompressedClustersCounters {
2930
unsigned int nSliceRows = 36 * 152;
3031
unsigned char nComppressionModes = 0;
3132

32-
ClassDefNV(CompressedClustersCounters, 1);
33+
ClassDefNV(CompressedClustersCounters, 2);
3334
};
3435

35-
template <class T>
36-
struct CompressedClustersPtrs_helper : public T {
37-
unsigned short* qTotA = nullptr; //! [nAttachedClusters]
38-
unsigned short* qMaxA = nullptr; //! [nAttachedClusters]
39-
unsigned char* flagsA = nullptr; //! [nAttachedClusters]
40-
unsigned char* rowDiffA = nullptr; //! [nAttachedClustersReduced]
41-
unsigned char* sliceLegDiffA = nullptr; //! [nAttachedClustersReduced]
42-
unsigned short* padResA = nullptr; //! [nAttachedClustersReduced]
43-
unsigned int* timeResA = nullptr; //! [nAttachedClustersReduced]
44-
unsigned char* sigmaPadA = nullptr; //! [nAttachedClusters]
45-
unsigned char* sigmaTimeA = nullptr; //! [nAttachedClusters]
46-
47-
unsigned char* qPtA = nullptr; //! [nTracks]
48-
unsigned char* rowA = nullptr; //! [nTracks]
49-
unsigned char* sliceA = nullptr; //! [nTracks]
50-
unsigned int* timeA = nullptr; //! [nTracks]
51-
unsigned short* padA = nullptr; //! [nTracks]
52-
53-
unsigned short* qTotU = nullptr; //! [nUnattachedClusters]
54-
unsigned short* qMaxU = nullptr; //! [nUnattachedClusters]
55-
unsigned char* flagsU = nullptr; //! [nUnattachedClusters]
56-
unsigned short* padDiffU = nullptr; //! [nUnattachedClusters]
57-
unsigned int* timeDiffU = nullptr; //! [nUnattachedClusters]
58-
unsigned char* sigmaPadU = nullptr; //! [nUnattachedClusters]
59-
unsigned char* sigmaTimeU = nullptr; //! [nUnattachedClusters]
60-
61-
unsigned short* nTrackClusters = nullptr; //! [nTracks]
62-
unsigned int* nSliceRowClusters = nullptr; //! [nSliceRows]
36+
template <class TCHAR, class TSHORT, class TINT>
37+
struct CompressedClustersPtrs_x {
38+
TSHORT qTotA = 0; //!
39+
TSHORT qMaxA = 0; //!
40+
TCHAR flagsA = 0; //!
41+
TCHAR rowDiffA = 0; //!
42+
TCHAR sliceLegDiffA = 0; //!
43+
TSHORT padResA = 0; //!
44+
TINT timeResA = 0; //!
45+
TCHAR sigmaPadA = 0; //!
46+
TCHAR sigmaTimeA = 0; //!
6347

48+
TCHAR qPtA = 0; //!
49+
TCHAR rowA = 0; //!
50+
TCHAR sliceA = 0; //!
51+
TINT timeA = 0; //!
52+
TSHORT padA = 0; //!
53+
54+
TSHORT qTotU = 0; //!
55+
TSHORT qMaxU = 0; //!
56+
TCHAR flagsU = 0; //!
57+
TSHORT padDiffU = 0; //!
58+
TINT timeDiffU = 0; //!
59+
TCHAR sigmaPadU = 0; //!
60+
TCHAR sigmaTimeU = 0; //!
61+
62+
TSHORT nTrackClusters = 0; //!
63+
TINT nSliceRowClusters = 0; //!
64+
65+
ClassDefNV(CompressedClustersPtrs_x, 2);
66+
};
67+
68+
struct CompressedClustersPtrs : public CompressedClustersPtrs_x<unsigned char*, unsigned short*, unsigned int*> {
69+
};
70+
71+
struct CompressedClustersOffsets : public CompressedClustersPtrs_x<size_t, size_t, size_t> {
72+
};
73+
74+
struct CompressedClustersFlat;
75+
76+
struct CompressedClusters : public CompressedClustersCounters, public CompressedClustersPtrs {
77+
CompressedClusters() CON_DEFAULT;
78+
~CompressedClusters() CON_DEFAULT;
79+
CompressedClusters(const CompressedClustersFlat& c);
80+
81+
ClassDefNV(CompressedClusters, 2);
82+
};
83+
84+
struct CompressedClustersROOT : public CompressedClusters {
85+
CompressedClustersROOT() CON_DEFAULT;
86+
CompressedClustersROOT(const CompressedClustersFlat& v) : CompressedClusters(v) {}
6487
// flatbuffer used for streaming
6588
int flatdataSize = 0;
6689
char* flatdata = nullptr; //[flatdataSize]
6790

68-
ClassDefNV(CompressedClustersPtrs_helper, 2);
91+
ClassDefNV(CompressedClustersROOT, 2);
6992
};
7093

71-
struct CompressedClustersDummy_helper {
94+
struct CompressedClustersFlat : private CompressedClustersCounters, private CompressedClustersOffsets {
95+
friend struct CompressedClusters; // We don't want anyone to access the members directly, should only be used to construct a CompressedClusters struct
96+
CompressedClustersFlat() CON_DELETE; // Must not be constructed, but just reinterpret_casted from void* array (void* to enforce alignment)
97+
size_t totalDataSize = 0;
98+
99+
void set(size_t bufferSize, const CompressedClusters& v);
72100
};
73101

74-
//Version with valid ROOT streamers for storage
75-
using CompressedClusters = CompressedClustersPtrs_helper<CompressedClustersCounters>;
76-
//Slightly smaller version with pointers only for GPU constant cache
77-
using CompressedClustersPtrsOnly = CompressedClustersPtrs_helper<CompressedClustersDummy_helper>;
78102
} // namespace tpc
79103
} // namespace o2
80104

DataFormats/Detectors/TPC/include/DataFormatsTPC/CompressedClustersHelpers.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct CompressedClustersHelpers {
3535
/// @param ptr buffer pointer, passed onto to operation
3636
/// @param counters the counters object CompressedClustersCounters
3737
template <typename Op, typename BufferType>
38-
static size_t apply(Op op, BufferType& ptr, CompressedClusters& c)
38+
static size_t apply(Op op, BufferType& ptr, CompressedClustersROOT& c)
3939
{
4040
size_t size = 0;
4141
size += op(ptr, c.nAttachedClusters, c.qTotA, c.qMaxA, c.flagsA, c.sigmaPadA, c.sigmaTimeA);
@@ -49,7 +49,7 @@ struct CompressedClustersHelpers {
4949
/// Create a flat copy of the class
5050
/// The target container is resized accordingly
5151
template <typename ContainerType>
52-
static size_t flattenTo(ContainerType& container, CompressedClusters& clusters)
52+
static size_t flattenTo(ContainerType& container, CompressedClustersROOT& clusters)
5353
{
5454
static_assert(sizeof(typename ContainerType::value_type) == 1);
5555
char* dummyptr = nullptr;
@@ -65,7 +65,7 @@ struct CompressedClustersHelpers {
6565

6666
/// Restore the array pointers from the data in the container
6767
template <typename ContainerType>
68-
static size_t restoreFrom(ContainerType& container, CompressedClusters& clusters)
68+
static size_t restoreFrom(ContainerType& container, CompressedClustersROOT& clusters)
6969
{
7070
static_assert(sizeof(typename ContainerType::value_type) == 1);
7171
char* dummyptr = nullptr;

DataFormats/Detectors/TPC/src/CompressedClusters.cxx

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,46 @@
1212
/// \brief Container to store compressed TPC cluster data
1313

1414
#include "DataFormatsTPC/CompressedClusters.h"
15+
16+
#ifndef GPUCA_STANDALONE
1517
#include "DataFormatsTPC/CompressedClustersHelpers.h"
1618
#include "TBuffer.h"
1719
#include <vector>
1820
#include <gsl/span>
21+
#endif
1922

2023
namespace o2::tpc
2124
{
2225

23-
template <>
24-
void CompressedClusters::Streamer(TBuffer& R__b)
26+
CompressedClusters::CompressedClusters(const CompressedClustersFlat& c)
27+
{
28+
CompressedClustersCounters& cc = *this;
29+
CompressedClustersPtrs& cp = *this;
30+
const CompressedClustersOffsets& offsets = c;
31+
cc = c;
32+
for (unsigned int i = 0; i < sizeof(cp) / sizeof(size_t); i++) {
33+
reinterpret_cast<void**>(&cp)[i] = reinterpret_cast<void*>(reinterpret_cast<const size_t*>(&offsets)[i] + reinterpret_cast<size_t>(&c)); // Restore pointers from offsets
34+
}
35+
};
36+
37+
void CompressedClustersFlat::set(size_t bufferSize, const CompressedClusters& v)
38+
{
39+
CompressedClustersCounters& cc = *this;
40+
CompressedClustersOffsets& offsets = *this;
41+
const CompressedClustersPtrs& ptrs = v;
42+
cc = v;
43+
for (unsigned int i = 0; i < sizeof(offsets) / sizeof(size_t); i++) {
44+
reinterpret_cast<size_t*>(&offsets)[i] = (reinterpret_cast<const size_t*>(&ptrs)[i] - reinterpret_cast<size_t>(this)); // Compute offsets from beginning of structure
45+
}
46+
totalDataSize = bufferSize;
47+
}
48+
49+
#ifndef GPUCA_STANDALONE
50+
void CompressedClustersROOT::Streamer(TBuffer& R__b)
2551
{
26-
// the custom streamer for CompressedClusters
52+
// the custom streamer for CompressedClustersROOT
2753
if (R__b.IsReading()) {
28-
R__b.ReadClassBuffer(CompressedClusters::Class(), this);
54+
R__b.ReadClassBuffer(CompressedClustersROOT::Class(), this);
2955
gsl::span flatdata{this->flatdata, this->flatdataSize};
3056
CompressedClustersHelpers::restoreFrom(flatdata, *this);
3157
} else {
@@ -44,12 +70,13 @@ void CompressedClusters::Streamer(TBuffer& R__b)
4470
this->flatdataSize = flatdata.size();
4571
this->flatdata = flatdata.data();
4672
}
47-
R__b.WriteClassBuffer(CompressedClusters::Class(), this);
73+
R__b.WriteClassBuffer(CompressedClustersROOT::Class(), this);
4874
if (!isflat) {
4975
this->flatdataSize = 0;
5076
this->flatdata = nullptr;
5177
}
5278
}
5379
}
80+
#endif
5481

5582
} // namespace o2::tpc

DataFormats/Detectors/TPC/src/DataFormatsTPCLinkDef.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,10 @@
3737
#pragma link C++ class std::vector < o2::tpc::ClusterNativeHelper::TreeWriter::BranchData> + ;
3838
#pragma link C++ class o2::tpc::dEdxInfo + ;
3939
#pragma link C++ class o2::tpc::CompressedClustersCounters + ;
40-
#pragma link C++ class o2::tpc::CompressedClustersPtrs_helper < o2::tpc::CompressedClustersCounters> - ;
41-
#pragma link C++ class o2::tpc::CompressedClusters - ;
40+
#pragma link C++ class o2::tpc::CompressedClustersPtrs_x < unsigned char*, unsigned short*, unsigned int*> + ;
41+
#pragma link C++ class o2::tpc::CompressedClustersPtrs + ;
42+
#pragma link C++ class o2::tpc::CompressedClusters + ;
43+
#pragma link C++ class o2::tpc::CompressedClustersROOT - ;
4244
#pragma link C++ enum o2::tpc::StatisticsType;
4345

4446
#endif

DataFormats/Detectors/TPC/test/testCompressedClusters.cxx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct ClustersData {
6464
std::vector<unsigned int> nSliceRowClusters; //! [nSliceRows]
6565
};
6666

67-
void fillClusters(CompressedClusters& clusters, ClustersData& data)
67+
void fillClusters(CompressedClustersROOT& clusters, ClustersData& data)
6868
{
6969
clusters.nAttachedClusters = rand() % 32;
7070
fillRandom(data.qTotA, clusters.nAttachedClusters);
@@ -125,12 +125,14 @@ void fillClusters(CompressedClusters& clusters, ClustersData& data)
125125

126126
BOOST_AUTO_TEST_CASE(test_tpc_compressedclusters)
127127
{
128-
CompressedClusters clusters;
128+
CompressedClustersROOT clusters;
129129
ClustersData data;
130130
fillClusters(clusters, data);
131131
std::vector<char> buffer;
132132
CompressedClustersHelpers::flattenTo(buffer, clusters);
133-
CompressedClusters restored{static_cast<CompressedClustersCounters&>(clusters)};
133+
CompressedClustersROOT restored;
134+
CompressedClustersCounters& x = restored;
135+
x = static_cast<CompressedClustersCounters&>(clusters);
134136
BOOST_REQUIRE(restored.qTotA == nullptr);
135137
CompressedClustersHelpers::restoreFrom(buffer, restored);
136138

@@ -147,7 +149,7 @@ BOOST_AUTO_TEST_CASE(test_tpc_compressedclusters)
147149

148150
BOOST_AUTO_TEST_CASE(test_tpc_compressedclusters_root_streaming)
149151
{
150-
CompressedClusters clusters;
152+
CompressedClustersROOT clusters;
151153
ClustersData data;
152154
fillClusters(clusters, data);
153155

@@ -172,12 +174,12 @@ BOOST_AUTO_TEST_CASE(test_tpc_compressedclusters_root_streaming)
172174
BOOST_REQUIRE(tree != nullptr);
173175
TBranch* branch = tree->GetBranch("compclusters");
174176
BOOST_REQUIRE(branch != nullptr);
175-
CompressedClusters* readback = nullptr;
177+
CompressedClustersROOT* readback = nullptr;
176178
branch->SetAddress(&readback);
177179
branch->GetEntry(0);
178180
BOOST_REQUIRE(readback != nullptr);
179181

180-
CompressedClusters& restored = *readback;
182+
CompressedClustersROOT& restored = *readback;
181183
// check one entry from each category
182184
BOOST_CHECK(restored.nAttachedClusters == data.qMaxA.size());
183185
BOOST_CHECK(memcmp(restored.qMaxA, data.qMaxA.data(), restored.nAttachedClusters * sizeof(decltype(data.qMaxA)::value_type)) == 0);

Detectors/TPC/workflow/src/CATrackerSpec.cxx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -561,9 +561,9 @@ DataProcessorSpec getCATrackerSpec(ca::Config const& specconfig, std::vector<int
561561
//std::vector<o2::tpc::ClusterNative> clusterBuffer; // std::vector that will hold the actual clusters, clustersNativeDecoded will point inside here
562562
//mDecoder.decompress(clustersCompressed, clustersNativeDecoded, clusterBuffer, param); // Run decompressor
563563
if (pc.outputs().isAllowed({gDataOriginTPC, "COMPCLUSTERS", 0})) {
564-
const o2::tpc::CompressedClusters* compressedClusters = ptrs.compressedClusters;
565-
if (compressedClusters != nullptr) {
566-
pc.outputs().snapshot(Output{gDataOriginTPC, "COMPCLUSTERS", 0}, ROOTSerialized<o2::tpc::CompressedClusters const>(*compressedClusters));
564+
if (ptrs.compressedClusters != nullptr) {
565+
o2::tpc::CompressedClustersROOT compressedClusters = *ptrs.compressedClusters;
566+
pc.outputs().snapshot(Output{gDataOriginTPC, "COMPCLUSTERS", 0}, ROOTSerialized<o2::tpc::CompressedClustersROOT const>(compressedClusters));
567567
} else {
568568
LOG(ERROR) << "unable to get compressed cluster info from track";
569569
}

Detectors/TPC/workflow/src/EntropyEncoderSpec.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ DataProcessorSpec getEntropyEncoderSpec()
5252
auto processAttributes = std::make_shared<ProcessAttributes>();
5353

5454
auto processingFct = [processAttributes](ProcessingContext& pc) {
55-
auto clusters = pc.inputs().get<CompressedClusters*>("input");
55+
auto clusters = pc.inputs().get<CompressedClustersROOT*>("input");
5656
if (clusters == nullptr) {
5757
LOG(ERROR) << "invalid input";
5858
return;

Detectors/TPC/workflow/src/RecoWorkflow.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ framework::WorkflowSpec getWorkflow(std::vector<int> const& tpcSectors, std::vec
464464
const char* defaultTreeName = "tpcrec";
465465

466466
//branch definitions for RootTreeWriter spec
467-
using CCluSerializedType = ROOTSerialized<CompressedClusters>;
467+
using CCluSerializedType = ROOTSerialized<CompressedClustersROOT>;
468468
auto ccldef = BranchDefinition<CCluSerializedType>{InputSpec{"inputCompCl", "TPC", "COMPCLUSTERS"}, //
469469
"TPCCompClusters_0", "compcluster-branch-name"}; //
470470

GPU/GPUTracking/Base/GPUDataTypes.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ namespace o2
3434
namespace tpc
3535
{
3636
struct ClusterNativeAccess;
37-
template <class T>
38-
struct CompressedClustersPtrs_helper;
39-
struct CompressedClustersCounters;
40-
using CompressedClusters = CompressedClustersPtrs_helper<CompressedClustersCounters>;
37+
struct CompressedClustersFlat;
4138
class Digit;
4239
} // namespace tpc
4340
} // namespace o2
@@ -216,7 +213,7 @@ struct GPUTrackingInOutPointers {
216213
unsigned int nMergedTracks = 0;
217214
const GPUTPCGMMergedTrackHit* mergedTrackHits = nullptr;
218215
unsigned int nMergedTrackHits = 0;
219-
const o2::tpc::CompressedClusters* tpcCompressedClusters = nullptr;
216+
const o2::tpc::CompressedClustersFlat* tpcCompressedClusters = nullptr;
220217
const GPUTRDTrackletWord* trdTracklets = nullptr;
221218
unsigned int nTRDTracklets = 0;
222219
const GPUTRDTrackletLabels* trdTrackletsMC = nullptr;

GPU/GPUTracking/Base/GPUO2FakeClasses.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class GPUTPCConvert
9191
class GPUTPCCompression
9292
{
9393
public:
94-
GPUFakeEmpty mOutput;
94+
GPUFakeEmpty* mOutput;
9595
};
9696
class GPUTPCClusterFinder
9797
{

0 commit comments

Comments
 (0)