38 virtual ~INode() =
default;
41 INode(
double v) :
f(
v) {}
44class InternalNode :
public INode
51 ~InternalNode()
override
58class LeafNode :
public INode
63 LeafNode(
double v, uint32_t
w) : INode(
v), c(
w) {}
67 bool operator()(
const INode* lhs,
const INode* rhs)
const {
return lhs->f >
rhs->f; }
70INode*
BuildTree(
const double* frequencies, uint32_t UniqueSymbols)
72 std::priority_queue<INode*, std::vector<INode*>, NodeCmp> trees;
74 for (uint32_t
i = 0;
i < UniqueSymbols;
i++) {
75 if (frequencies[
i] != 0) {
76 trees.push(
new LeafNode(frequencies[
i],
i));
79 while (trees.size() > 1) {
80 INode* childR = trees.top();
83 INode* childL = trees.top();
86 INode* parent =
new InternalNode(childR, childL);
94 if (
const LeafNode* lf =
dynamic_cast<const LeafNode*
>(node)) {
95 outCodes[lf->c] = prefix;
96 }
else if (
const InternalNode* in =
dynamic_cast<const InternalNode*
>(node)) {
98 leftPrefix.push_back(
false);
102 rightPrefix.push_back(
true);
111 uint32_t decodingErrors = 0;
113 std::vector<o2::tpc::ClusterNative> clusterBuffer;
115 auto allocator = [&clusterBuffer](
size_t size) {clusterBuffer.resize(
size);
return clusterBuffer.data(); };
117 std::vector<o2::tpc::ClusterNative> tmpClusters;
122 GPUError(
"Number of clusters mismatch sector %u row %u: expected %d v.s. decoded %d",
i,
j, clustersNative->
nClusters[
i][
j], clustersNativeDecoded.
nClusters[
i][
j]);
126 tmpClusters.resize(clustersNative->
nClusters[
i][
j]);
127 for (uint32_t k = 0; k < clustersNative->
nClusters[
i][
j]; k++) {
128 tmpClusters[k] = clustersNative->
clusters[
i][
j][k];
130 GPUTPCCompression::truncateSignificantBitsChargeMax(tmpClusters[k].qMax,
param);
131 GPUTPCCompression::truncateSignificantBitsCharge(tmpClusters[k].qTot,
param);
132 GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaPadPacked,
param);
133 GPUTPCCompression::truncateSignificantBitsWidth(tmpClusters[k].sigmaTimePacked,
param);
136 std::sort(tmpClusters.begin(), tmpClusters.end());
137 for (uint32_t k = 0; k < clustersNative->
nClusters[
i][
j]; k++) {
140 if (
c1.timeFlagsPacked !=
c2.timeFlagsPacked ||
c1.padPacked !=
c2.padPacked ||
c1.sigmaTimePacked !=
c2.sigmaTimePacked ||
c1.sigmaPadPacked !=
c2.sigmaPadPacked ||
c1.qMax !=
c2.qMax ||
c1.qTot !=
c2.qTot) {
141 if (decodingErrors++ < 100) {
142 GPUWarning(
"Cluster mismatch: sector %2u row %3u hit %5u: %6d %3d %4d %3d %3d %4d %4d",
i,
j, k, (int32_t)
c1.getTimePacked(), (int32_t)
c1.getFlags(), (int32_t)
c1.padPacked, (int32_t)
c1.sigmaTimePacked, (int32_t)
c1.sigmaPadPacked, (int32_t)
c1.qMax, (int32_t)
c1.qTot);
143 GPUWarning(
"%45s %6d %3d %4d %3d %3d %4d %4d",
"", (int32_t)
c2.getTimePacked(), (int32_t)
c2.getFlags(), (int32_t)
c2.padPacked, (int32_t)
c2.sigmaTimePacked, (int32_t)
c2.sigmaPadPacked, (int32_t)
c2.qMax, (int32_t)
c2.qTot);
149 if (decodingErrors) {
151 GPUWarning(
"Errors during cluster decoding %u\n", decodingErrors);
153 GPUInfo(
"Cluster decoding verification: PASSED");
191 GPUError(
"-----------------------------------------\nERROR - INCORRECT CLUSTER DECODING!\n-----------------------------------------");
197 GPUInfo(
"\nRunning cluster compression entropy statistics");
223 double eQCombined =
Analyze(
mPQA,
"combined Q Attached");
224 eQCombined +=
Analyze(
mPQU,
"combined Q Unattached");
227 GPUInfo(
"Combined Row/Sector: %6.4f --> %6.4f (%6.4f%%)", eRowSector, eRowSectorCombined, eRowSector > 1e-1 ? (100. * (eRowSector - eRowSectorCombined) / eRowSector) : 0.f);
228 GPUInfo(
"Combined Sigma: %6.4f --> %6.4f (%6.4f%%)", eSigma, eSigmaCombined, eSigma > 1e-3 ? (100. * (eSigma - eSigmaCombined) / eSigma) : 0.f);
229 GPUInfo(
"Combined Q: %6.4f --> %6.4f (%6.4f%%)", eQ, eQCombined, eQ > 1e-3 ? (100. * (eQ - eQCombined) / eQ) : 0.f);
237 double huffmanSize = 0;
239 std::vector<double> prob(p.size());
240 double log2 = log(2.);
242 for (uint32_t
i = 0;
i < p.size();
i++) {
246 for (uint32_t
i = 0;
i < prob.size();
i++) {
248 prob[
i] = (double)p[
i] / total;
249 double I = -log(prob[
i]) / log2;
250 double H = I * prob[
i];
256 INode* root =
BuildTree(prob.data(), prob.size());
262 for (HuffCodeMap::const_iterator it = codes.begin(); it != codes.end(); it++) {
263 huffmanSize += it->second.size() * prob[it->first];
271 GPUInfo(
"Size: %30s: Entropy %7.4f Huffman %7.4f (Count) %9ld",
name, entropy, huffmanSize, (int64_t)total);
275template <
class T,
int32_t I>
278 for (
size_t i = 0;
i <
n;
i++) {
280 if (
val >= p.size()) {
284 GPUError(
"Invalid Value: %d >= %d",
val, (int32_t)p.size());
292template <
class T,
class S,
int32_t I>
295 for (
size_t i = 0;
i <
n;
i++) {
296 uint32_t
val = ptr1[
i] + ptr2[
i] * max1;
297 if (
val >= p.size()) {
301 GPUError(
"Invalid Value: %d >= %d",
val, (int32_t)p.size());
bool const GPUTPCGMMerger::trackCluster * c1
bool const GPUTPCGMMerger::trackCluster const clcomparestruct * c2
std::vector< int32_t > mPQA
std::vector< int32_t > mPsigmaTimeA
std::vector< int32_t > mPpadResA
static constexpr uint32_t NSECTORS
static constexpr uint32_t P_MAX_QMAX
std::vector< int32_t > mPsigmaTimeU
float Analyze(std::vector< int32_t > &p, const char *name, bool count=true)
std::vector< int32_t > mPsigmaU
std::vector< int32_t > mPflagsU
std::vector< int32_t > mPqMaxU
void FillStatisticCombined(std::vector< int32_t > &p, const T *ptr1, const S *ptr2, size_t n, int32_t max1)
std::vector< int32_t > mPtimeResA
TPCClusterDecompressor mDecoder
std::vector< int32_t > mPtimeDiffU
std::vector< int32_t > mPqPtA
std::vector< int32_t > mPnSectorRowClusters
std::vector< int32_t > mPqTotA
std::vector< int32_t > mPnTrackClusters
std::vector< int32_t > mPtimeA
std::vector< int32_t > mProwA
std::vector< int32_t > mProwDiffA
std::vector< int32_t > mPsigmaPadU
std::vector< int32_t > mPqMaxA
void FillStatistic(std::vector< int32_t > &p, const T *ptr, size_t n)
static constexpr uint32_t P_MAX_SIGMA
std::vector< int32_t > mPflagsA
std::vector< int32_t > mPsigmaA
std::vector< int32_t > mPsectorLegDiffA
void RunStatistics(const o2::tpc::ClusterNativeAccess *clustersNative, const o2::tpc::CompressedClusters *clustersCompressed, const GPUParam ¶m)
std::vector< int32_t > mProwSectorA
std::vector< int32_t > mPqTotU
std::vector< int32_t > mPQU
std::vector< int32_t > mPpadDiffU
std::vector< int32_t > mPsigmaPadA
std::vector< int32_t > mPpadA
std::vector< int32_t > mPsectorA
static int32_t decompress(const o2::tpc::CompressedClustersFlat *clustersCompressed, o2::tpc::ClusterNativeAccess &clustersNative, std::function< o2::tpc::ClusterNative *(size_t)> allocator, const GPUParam ¶m, bool deterministicRec)
GLuint const GLchar * name
GLubyte GLubyte GLubyte GLubyte w
D const SVectorGPU< T, D > & rhs
void GenerateCodes(const INode *node, const HuffCode &prefix, HuffCodeMap &outCodes)
std::vector< bool > HuffCode
INode * BuildTree(const double *frequencies, uint32_t UniqueSymbols)
std::map< uint32_t, HuffCode > HuffCodeMap
unsigned int nClusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
const ClusterNative * clusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
unsigned int nUnattachedClusters
unsigned int nAttachedClusters
unsigned int nAttachedClustersReduced