CbmRoot
Loading...
Searching...
No Matches
CommonUnpacker.h
Go to the documentation of this file.
1/* Copyright (C) 2024 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Felix Weiglhofer [committer], Dominik Smith */
4#pragma once
5
7#include "PODVector.h"
8#include "Timeslice.hpp"
15
16#include <cstdint>
17#include <gsl/span>
18#include <map>
19#include <vector>
20
21#include <xpu/host.h>
22
23namespace cbm::algo
24{
25
26 namespace detail
27 {
28
30 fles::Subsystem system; // subsystem
31 size_t numComponents = 0; // number of components used
32 size_t numMs = 0; // number of microslices
33 size_t sizeBytesIn = 0; // total size of microslice contents
34 size_t sizeBytesOut = 0; // total size of unpacked digis
35 size_t errInvalidSysVer = 0;
36 size_t errInvalidEqId = 0;
37
38 double ExpansionFactor() const { return sizeBytesIn > 0 ? static_cast<double>(sizeBytesOut) / sizeBytesIn : 0.0; }
39 };
40
46 struct MSData {
47 std::vector<fles::MicrosliceDescriptor> msDesc; // microslice descriptors
48 std::vector<const u8*> msContent; // pointer to microslice contents
49
50 UnpackMonitorBase monitor; // monitoring data
51
52 MSData(const fles::Timeslice& ts, fles::Subsystem system, gsl::span<u16> legalEqIds);
53 ~MSData() = default;
54 };
55
56 } // namespace detail
57
58 template<class MSMonitor>
60 std::vector<MSMonitor> msMonitor; // monitoring data per microslice
61
62 std::string print() const
63 {
64 MSMonitor tsStats;
65 for (auto& msStats : msMonitor) {
66 tsStats.add(msStats);
67 }
68 return tsStats.print();
69 }
70 };
71
72 template<class MSAux>
73 struct UnpackAux {
74 std::vector<MSAux> msAux; // auxiliary data per microslice
75 };
76
77 struct UnpackKey {
80
81 UnpackKey(u16 eqId_, u8 sysVer_) : eqId(eqId_), sysVer(sysVer_) {}
82 UnpackKey(const fles::MicrosliceDescriptor& msDesc) : eqId(msDesc.eq_id), sysVer(msDesc.sys_ver) {}
83
84 bool operator<(const UnpackKey& other) const
85 {
86 return eqId < other.eqId || (eqId == other.eqId && sysVer < other.sysVer);
87 }
88 };
89
90 template<class Digi, class MSMonitor, class MSAux>
92 protected:
95 using Result_t = std::tuple<PODVector<Digi>, Monitor_t, Aux_t>;
97
98 CommonUnpacker() : fAlgos{} { fAlgos[{0xF000, 0xF0}] = std::make_unique<vt::UnpackMS<Digi, MSMonitor, MSAux>>(); }
99
100 std::map<UnpackKey, std::unique_ptr<Unpack_t>> fAlgos; //< Equipment id to unpacker map. Filled by child class!
101
102 Result_t DoUnpack(const fles::Subsystem subsystem, const fles::Timeslice& ts) const
103 {
104 xpu::scoped_timer t_(fles::to_string(subsystem));
105 auto legalEqIds = GetEqIds();
106
107 detail::MSData msData{ts, subsystem, gsl::make_span(legalEqIds)};
108 const size_t numMs = msData.monitor.numMs;
109
110 Result_t out;
111 auto& digisOut = std::get<0>(out);
112 auto& monitorOut = std::get<1>(out);
113 auto& auxOut = std::get<2>(out);
114
115 static_cast<detail::UnpackMonitorBase&>(monitorOut) = msData.monitor;
116
117 std::vector<std::vector<Digi>> msDigis(numMs); // unpacked digis per microslice
118 monitorOut.msMonitor.resize(numMs); // monitoring data per microslice
119 auxOut.msAux.resize(numMs); // auxiliary data per microslice
120
121 xpu::t_add_bytes(msData.monitor.sizeBytesIn);
122
123 xpu::push_timer("Unpack");
124 xpu::t_add_bytes(msData.monitor.sizeBytesIn);
125 CBM_PARALLEL_FOR(schedule(dynamic))
126 for (size_t i = 0; i < numMs; i++) {
127 auto& msDesc = msData.msDesc[i];
128 auto algo = fAlgos.find(UnpackKey{msDesc});
129
130 if (algo == fAlgos.end()) {
131 if (!Contains(legalEqIds, msDesc.eq_id)) {
132 L_(error) << "Invalid equip id " << std::hex << int{msDesc.eq_id} << std::dec << " for subsystem "
133 << util::ToString(subsystem);
134 monitorOut.errInvalidEqId++;
135 }
136 else {
137 L_(error) << "Invalid system version " << std::hex << int{msDesc.sys_ver} << std::dec << " for subsystem "
138 << util::ToString(subsystem);
139 monitorOut.errInvalidSysVer++;
140 }
141 continue;
142 }
143
144 auto result = (*algo->second)(msData.msContent[i], msData.msDesc[i], ts.start_time());
145 msDigis[i] = std::move(std::get<0>(result));
146 monitorOut.msMonitor[i] = std::move(std::get<1>(result));
147 auxOut.msAux[i] = std::move(std::get<2>(result));
148 }
149 xpu::pop_timer();
150
151 xpu::push_timer("Resize");
152 size_t nDigisTotal = 0;
153 for (const auto& digis : msDigis) {
154 nDigisTotal += digis.size();
155 }
156 digisOut.resize(nDigisTotal);
157 monitorOut.sizeBytesOut = nDigisTotal * sizeof(Digi);
158 xpu::pop_timer();
159
160 xpu::push_timer("Merge");
161 xpu::t_add_bytes(monitorOut.sizeBytesOut);
162 CBM_PARALLEL_FOR(schedule(dynamic))
163 for (size_t i = 0; i < numMs; i++) {
164 size_t offset = 0;
165 for (size_t x = 0; x < i; x++)
166 offset += msDigis[x].size();
167 std::copy(msDigis[i].begin(), msDigis[i].end(), digisOut.begin() + offset);
168 }
169 xpu::pop_timer();
170
171 xpu::push_timer("Sort");
172 xpu::t_add_bytes(monitorOut.sizeBytesOut);
173 DoSort(digisOut);
174 xpu::pop_timer();
175
176 return out;
177 }
178
179 private:
180 void DoSort(gsl::span<Digi> digis) const
181 {
182 Sort(digis.begin(), digis.end(), [](const Digi& a, const Digi& b) { return a.GetTime() < b.GetTime(); });
183 }
184
185 std::vector<u16> GetEqIds() const
186 {
187 std::vector<u16> eqIds;
188 eqIds.reserve(fAlgos.size());
189 for (const auto& [key, algo] : fAlgos) {
190 eqIds.push_back(key.eqId);
191 }
192 return eqIds;
193 }
194
195 std::vector<u8> GetSysVers(u16 eqId) const
196 {
197 std::vector<u8> sysVers;
198 for (const auto& [key, algo] : fAlgos) {
199 if (key.eqId == eqId) {
200 sysVers.push_back(key.sysVer);
201 }
202 }
203 return sysVers;
204 }
205 };
206} // namespace cbm::algo
#define L_(level)
static constexpr size_t size()
Definition KfSimdPseudo.h:2
#define CBM_PARALLEL_FOR(...)
Definition OpenMP.h:25
This file contains utility functions for STL containers.
void DoSort(gsl::span< Digi > digis) const
UnpackMSBase< CbmBmonDigi, UnpackMonitorData, UnpackAuxData > Unpack_t
Result_t DoUnpack(const fles::Subsystem subsystem, const fles::Timeslice &ts) const
std::map< UnpackKey, std::unique_ptr< Unpack_t > > fAlgos
std::vector< u8 > GetSysVers(u16 eqId) const
std::vector< u16 > GetEqIds() const
std::tuple< PODVector< CbmBmonDigi >, Monitor_t, Aux_t > Result_t
uint16_t u16
Definition Definitions.h:19
uint8_t u8
Definition Definitions.h:17
void Sort(It first, It last, Compare comp)
Wrapper for std::sort.
Definition Algorithm.h:46
std::string_view ToString(T t)
Definition CbmEnumDict.h:64
bool Contains(const C &container, const T &value)
Definition StlUtils.h:21
std::vector< MSAux > msAux
UnpackKey(u16 eqId_, u8 sysVer_)
bool operator<(const UnpackKey &other) const
UnpackKey(const fles::MicrosliceDescriptor &msDesc)
std::vector< MSMonitor > msMonitor
std::string print() const
Collection of MS data to unpack.
MSData(const fles::Timeslice &ts, fles::Subsystem system, gsl::span< u16 > legalEqIds)
UnpackMonitorBase monitor
std::vector< const u8 * > msContent
std::vector< fles::MicrosliceDescriptor > msDesc