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 "Definitions.h"
8#include "PODVector.h"
9#include "Timeslice.hpp"
10#include "UnpackMSBase.h"
11#include "compat/Algorithm.h"
12#include "compat/OpenMP.h"
13#include "util/StlUtils.h"
14
15#include <cstdint>
16#include <gsl/span>
17#include <map>
18#include <vector>
19
20#include <xpu/host.h>
21
22namespace cbm::algo
23{
24
25 namespace detail
26 {
27
29 fles::Subsystem system; // subsystem
30 size_t numComponents = 0; // number of components used
31 size_t numMs = 0; // number of microslices
32 size_t sizeBytesIn = 0; // total size of microslice contents
33 size_t sizeBytesOut = 0; // total size of unpacked digis
34 size_t errInvalidSysVer = 0;
35 size_t errInvalidEqId = 0;
36
37 double ExpansionFactor() const { return sizeBytesIn > 0 ? static_cast<double>(sizeBytesOut) / sizeBytesIn : 0.0; }
38 };
39
45 struct MSData {
46 std::vector<fles::MicrosliceDescriptor> msDesc; // microslice descriptors
47 std::vector<const u8*> msContent; // pointer to microslice contents
48
49 UnpackMonitorBase monitor; // monitoring data
50
51 MSData(const fles::Timeslice& ts, fles::Subsystem system, gsl::span<u16> legalEqIds);
52 ~MSData() = default;
53 };
54
55 } // namespace detail
56
57 template<class MSMonitor>
59 std::vector<MSMonitor> msMonitor; // monitoring data per microslice
60 };
61
62 template<class MSAux>
63 struct UnpackAux {
64 std::vector<MSAux> msAux; // auxiliary data per microslice
65 };
66
67 struct UnpackKey {
70
71 UnpackKey(u16 eqId_, u8 sysVer_) : eqId(eqId_), sysVer(sysVer_) {}
72 UnpackKey(const fles::MicrosliceDescriptor& msDesc) : eqId(msDesc.eq_id), sysVer(msDesc.sys_ver) {}
73
74 bool operator<(const UnpackKey& other) const
75 {
76 return eqId < other.eqId || (eqId == other.eqId && sysVer < other.sysVer);
77 }
78 };
79
80 template<class Digi, class MSMonitor, class MSAux>
82 protected:
85 using Result_t = std::tuple<PODVector<Digi>, Monitor_t, Aux_t>;
87
88 std::map<UnpackKey, std::unique_ptr<Unpack_t>> fAlgos; //< Equipment id to unpacker map. Filled by child class!
89
90 Result_t DoUnpack(const fles::Subsystem subsystem, const fles::Timeslice& ts) const
91 {
92 xpu::scoped_timer t_(fles::to_string(subsystem));
93 auto legalEqIds = GetEqIds();
94
95 detail::MSData msData{ts, subsystem, gsl::make_span(legalEqIds)};
96 const size_t numMs = msData.monitor.numMs;
97
98 Result_t out;
99 auto& digisOut = std::get<0>(out);
100 auto& monitorOut = std::get<1>(out);
101 auto& auxOut = std::get<2>(out);
102
103 static_cast<detail::UnpackMonitorBase&>(monitorOut) = msData.monitor;
104
105 std::vector<std::vector<Digi>> msDigis(numMs); // unpacked digis per microslice
106 monitorOut.msMonitor.resize(numMs); // monitoring data per microslice
107 auxOut.msAux.resize(numMs); // auxiliary data per microslice
108
109 xpu::t_add_bytes(msData.monitor.sizeBytesIn);
110
111 xpu::push_timer("Unpack");
112 xpu::t_add_bytes(msData.monitor.sizeBytesIn);
113 CBM_PARALLEL_FOR(schedule(dynamic))
114 for (size_t i = 0; i < numMs; i++) {
115 auto& msDesc = msData.msDesc[i];
116 auto algo = fAlgos.find(UnpackKey{msDesc});
117
118 if (algo == fAlgos.end()) {
119 if (!Contains(legalEqIds, msDesc.eq_id)) {
120 L_(error) << "Invalid equip id " << std::hex << int{msDesc.eq_id} << std::dec << " for subsystem "
121 << ToString(subsystem);
122 monitorOut.errInvalidEqId++;
123 }
124 else {
125 L_(error) << "Invalid system version " << std::hex << int{msDesc.sys_ver} << std::dec << " for subsystem "
126 << ToString(subsystem);
127 monitorOut.errInvalidSysVer++;
128 }
129 continue;
130 }
131
132 auto result = (*algo->second)(msData.msContent[i], msData.msDesc[i], ts.start_time());
133 msDigis[i] = std::move(std::get<0>(result));
134 monitorOut.msMonitor[i] = std::move(std::get<1>(result));
135 auxOut.msAux[i] = std::move(std::get<2>(result));
136 }
137 xpu::pop_timer();
138
139 xpu::push_timer("Resize");
140 size_t nDigisTotal = 0;
141 for (const auto& digis : msDigis) {
142 nDigisTotal += digis.size();
143 }
144 digisOut.resize(nDigisTotal);
145 monitorOut.sizeBytesOut = nDigisTotal * sizeof(Digi);
146 xpu::pop_timer();
147
148 xpu::push_timer("Merge");
149 xpu::t_add_bytes(monitorOut.sizeBytesOut);
150 CBM_PARALLEL_FOR(schedule(dynamic))
151 for (size_t i = 0; i < numMs; i++) {
152 size_t offset = 0;
153 for (size_t x = 0; x < i; x++)
154 offset += msDigis[x].size();
155 std::copy(msDigis[i].begin(), msDigis[i].end(), digisOut.begin() + offset);
156 }
157 xpu::pop_timer();
158
159 xpu::push_timer("Sort");
160 xpu::t_add_bytes(monitorOut.sizeBytesOut);
161 DoSort(digisOut);
162 xpu::pop_timer();
163
164 return out;
165 }
166
167 private:
168 void DoSort(gsl::span<Digi> digis) const
169 {
170 Sort(digis.begin(), digis.end(), [](const Digi& a, const Digi& b) { return a.GetTime() < b.GetTime(); });
171 }
172
173 std::vector<u16> GetEqIds() const
174 {
175 std::vector<u16> eqIds;
176 eqIds.reserve(fAlgos.size());
177 for (const auto& [key, algo] : fAlgos) {
178 eqIds.push_back(key.eqId);
179 }
180 return eqIds;
181 }
182
183 std::vector<u8> GetSysVers(u16 eqId) const
184 {
185 std::vector<u8> sysVers;
186 for (const auto& [key, algo] : fAlgos) {
187 if (key.eqId == eqId) {
188 sysVers.push_back(key.sysVer);
189 }
190 }
191 return sysVers;
192 }
193 };
194} // 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.
UnpackMonitor< MSMonitor > Monitor_t
void DoSort(gsl::span< Digi > digis) const
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< Digi >, Monitor_t, Aux_t > Result_t
std::string_view ToString(T t)
Definition EnumDict.h:64
std::uint8_t u8
Definition Definitions.h:17
void Sort(It first, It last, Compare comp)
Wrapper for std::sort.
Definition Algorithm.h:46
std::uint16_t u16
Definition Definitions.h:19
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
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