CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AMCSpec.cc
Go to the documentation of this file.
5 
6 #define EDM_ML_DEBUG 1
7 
8 namespace amc {
9  Header::Header(unsigned int amc_no, unsigned int board_id, unsigned int size, unsigned int block)
10  {
11  // Determine size
12  unsigned int max_block_no = 0;
13  if (size >= 0x13ff)
14  max_block_no = (size - 1023) / 4096;
15 
16  if (block != max_block_no)
17  size = split_block_size;
18  else if (block != 0)
19  size -= split_block_size * max_block_no;
20 
21  data_ =
22  (static_cast<uint64_t>(size & Size_mask) << Size_shift) |
23  (static_cast<uint64_t>(block & BlkNo_mask) << BlkNo_shift) |
24  (static_cast<uint64_t>(amc_no & AmcNo_mask) << AmcNo_shift) |
25  (static_cast<uint64_t>(board_id & BoardID_mask) << BoardID_shift) |
26  (1llu << Enabled_bit_shift) |
27  (1llu << Present_bit_shift);
28 
29  if (block == getBlocks() - 1) {
30  // Last block
31  data_ |=
32  (1llu << CRC_bit_shift) |
33  (1llu << Valid_bit_shift) |
34  (1llu << Length_bit_shift);
35  }
36 
37  if (block == 0 && getBlocks() == 1) {
38  // Bits already zeroed - only one block
39  } else if (block == 0) {
40  // First of many blocks
41  data_ |= 1llu << More_bit_shift;
42  } else if (block == getBlocks() - 1) {
43  // Last of many blocks
44  data_ |= 1llu << Segmented_bit_shift;
45  } else {
46  // Intermediate of many blocks
47  data_ |= (1llu << More_bit_shift) | (1llu << Segmented_bit_shift);
48  }
49  }
50 
51  unsigned int
53  {
54  // The first block of a segmented event has a size of 1023, all
55  // following have a max size of 4096. Segmentation only happens
56  // for AMC payloads >= 0x13ff 64 bit words.
57  unsigned int size = getSize();
58  if (size >= 0x13ff)
59  return (size - 1023) / 4096 + 1;
60  return 1;
61  }
62 
63  unsigned int
65  {
66  // More and not Segmented means the first of multiple blocks. For
67  // these, getSize() returns the total size of the AMC packet, not the
68  // size of the first block.
69  if (getMore() && !getSegmented())
70  return split_block_size;
71  return getSize();
72  }
73 
74  Packet::Packet(unsigned int amc, unsigned int board, const std::vector<uint64_t>& load) :
75  header_(amc, board, load.size()),
76  payload_(load)
77  {
78  }
79 
80  void
81  Packet::addPayload(const uint64_t * data, unsigned int size)
82  {
83  payload_.insert(payload_.end(), data, data + size);
84  }
85 
86  std::vector<uint64_t>
87  Packet::block(unsigned int id) const
88  {
89  if (id == 0 and id == header_.getBlocks() - 1) {
90  return payload_;
91  } else if (id == header_.getBlocks() - 1) {
92  return std::vector<uint64_t>(payload_.begin() + id * split_block_size, payload_.end());
93  } else {
94  return std::vector<uint64_t>(payload_.begin() + id * split_block_size, payload_.begin() + (id + 1) * split_block_size);
95  }
96  }
97 
98  std::unique_ptr<uint64_t[]>
100  {
101  std::unique_ptr<uint64_t[]> res(new uint64_t[payload_.size()]);
102  for (unsigned int i = 0; i < payload_.size(); ++i)
103  res.get()[i] = payload_[i];
104  return res;
105  }
106 }
107 
108 namespace amc13 {
109  Header::Header(unsigned int namc, unsigned int orbit)
110  {
111  data_ =
112  (static_cast<uint64_t>(namc & nAMC_mask) << nAMC_shift) |
113  (static_cast<uint64_t>(orbit & OrN_mask) << OrN_shift) |
114  (static_cast<uint64_t>(fov & uFOV_mask) << uFOV_shift);
115  }
116 
117  bool
119  {
120  return (getNumberOfAMCs() <= max_amc) && (getFormatVersion() == fov);
121  }
122 
123  Trailer::Trailer(unsigned int crc, unsigned int blk, unsigned int lv1, unsigned int bx)
124  {
125  data_ =
126  (static_cast<uint64_t>(crc & CRC_mask) << CRC_shift) |
127  (static_cast<uint64_t>(blk & BlkNo_mask) << BlkNo_shift) |
128  (static_cast<uint64_t>(lv1 & LV1_mask) << LV1_shift) |
129  (static_cast<uint64_t>(bx & BX_mask) << BX_shift);
130  }
131 
132  void
133  Packet::add(unsigned int amc_no, unsigned int board, const std::vector<uint64_t>& load)
134  {
135  edm::LogInfo("AMC") << "Adding board " << board << " with payload size " << load.size()
136  << " as payload #" << amc_no;
137  // Start by indexing with 1
138  payload_.push_back(amc::Packet(amc_no, board, load));
139  }
140 
141  bool
142  Packet::parse(const uint64_t *data, unsigned int size)
143  {
144  // Need at least a header and trailer
145  // TODO check if this can be removed
146  if (size < 2) {
147  edm::LogError("AMC") << "AMC13 packet size too small";
148  return false;
149  }
150 
151  auto block_start = data;
152  header_ = Header(data++);
153 
154  if (!header_.valid()) {
155  edm::LogError("AMC")
156  << "Invalid header for AMC13 packet: "
157  << "format version " << header_.getFormatVersion()
158  << ", " << header_.getNumberOfAMCs()
159  << " AMC packets, orbit " << header_.getOrbitNumber();
160  return false;
161  }
162 
163  if (size < 2 + header_.getNumberOfAMCs())
164  return false;
165 
166  // Initial filling of AMC payloads. First, get the headers. The
167  // first payload follows afterwards.
168  for (unsigned int i = 0; i < header_.getNumberOfAMCs(); ++i) {
169  payload_.push_back(amc::Packet(data++));
170  }
171 
172  unsigned int tot_size = 0; // total payload size
173  unsigned int tot_nblocks = 0; // total blocks of payload
174  unsigned int maxblocks = 0; // counting the # of amc13 header/trailers (1 ea per block)
175 
176  for (const auto& amc: payload_) {
177  tot_size += amc.header().getSize();
178  tot_nblocks += amc.header().getBlocks();
179  maxblocks = std::max(maxblocks, amc.header().getBlocks());
180  }
181 
182  unsigned int words = tot_size + // payload size
183  tot_nblocks + // AMC headers
184  2 * maxblocks; // AMC13 headers
185 
186  if (size < words) {
187  edm::LogError("L1T")
188  << "Encountered AMC 13 packet with "
189  << size << " words, "
190  << "but expected "
191  << words << " words: "
192  << tot_size << " payload words, "
193  << tot_nblocks << " AMC header words, and 2 AMC 13 header words.";
194  return false;
195  }
196 
197  // Read in the first AMC block and append the payload to the
198  // corresponding AMC packet.
199  for (auto& amc: payload_) {
200  amc.addPayload(data, amc.header().getBlockSize());
201  data += amc.header().getBlockSize();
202  }
203  auto block_end = data;
204 
205  Trailer t(data++);
206 
207  std::string check(reinterpret_cast<const char*>(block_start), reinterpret_cast<const char*>(block_end));
208  cms::CRC32Calculator crc(check);
209 
210  if (crc.checksum() != t.getCRC()) {
211  edm::LogWarning("L1T") << "Mismatch in checksums for block 0";
212  }
213 
214  if (t.getBlock() != 0 ) {
215  edm::LogWarning("L1T")
216  << "Block trailer mismatch: "
217  << "expected block 0, but trailer is for block "
218  << t.getBlock();
219  }
220 
221  // Read in remaining AMC blocks
222  for (unsigned int b = 1; b < maxblocks; ++b) {
223  block_start = data;
224 
225  Header block_h(data++);
226  std::vector<amc::Header> headers;
227 
228  for (unsigned int i = 0; i < block_h.getNumberOfAMCs(); ++i)
229  headers.push_back(amc::Header(data++));
230 
231  for (const auto& amc: headers) {
232  payload_[amc.getAMCNumber() - 1].addPayload(data, amc.getBlockSize());
233  data += amc.getBlockSize();
234  }
235 
236  block_end = data;
237 
238  t = Trailer(data++);
239 
240  check = std::string(reinterpret_cast<const char*>(block_start), reinterpret_cast<const char*>(block_end));
241  crc = cms::CRC32Calculator(check);
242 
243  if (crc.checksum() != t.getCRC()) {
244  edm::LogWarning("L1T") << "Mismatch in checksums for block " << b;
245  }
246 
247  if (t.getBlock() != 0 ) {
248  edm::LogWarning("L1T")
249  << "Block trailer mismatch: "
250  << "expected block " << b
251  << ", but trailer is for block " << t.getBlock();
252  }
253  }
254 
255  return true;
256  }
257 
258  unsigned int
260  {
261  unsigned int maxblocks = 0;
262 
263  for (const auto& amc: payload_)
264  maxblocks = std::max(maxblocks, amc.blocks());
265 
266  return maxblocks;
267  }
268 
269  unsigned int
270  Packet::size() const
271  {
272  unsigned int words = 0;
273  unsigned int blocks = 0;
274  unsigned int maxblocks = 0;
275 
276  for (const auto& amc: payload_) {
277  words += amc.size();
278  blocks += amc.blocks();
279  maxblocks = std::max(maxblocks, amc.blocks());
280  }
281 
282  // Size is total amount of words + # of blocks for AMC headers + # of
283  // maxblocks for AMC13 block header, trailer
284  return words + blocks + maxblocks * 2;
285  }
286 
287  bool
288  Packet::write(const edm::Event& ev, unsigned char * ptr, unsigned int size) const
289  {
290  if (size < this->size() * 8)
291  return false;
292 
293  if (size % 8 != 0)
294  return false;
295 
296  uint64_t * data = reinterpret_cast<uint64_t*>(ptr);
297 
298  for (unsigned int b = 0; b < blocks(); ++b) {
299  uint64_t * block_start = data;
300 
301  std::vector<uint64_t> block_headers;
302  std::vector<uint64_t> block_load;
303  for (const auto& amc: payload_) {
304  edm::LogInfo("AMC")
305  << "Considering block " << b
306  << " for payload " << amc.header().getBoardID()
307  << " with size " << amc.size()
308  << " and " << amc.blocks() << " blocks";
309  if (amc.blocks() < b + 1)
310  continue;
311 
312  block_headers.push_back(amc.header(b));
313  auto words = amc.block(b);
314  block_load.insert(block_load.end(), words.begin(), words.end());
315  }
316 
317  if (b == 0) {
318  amc13::Header h(block_headers.size(), ev.orbitNumber());
319  edm::LogInfo("AMC")
320  << "Writing header for AMC13 packet: "
321  << "format version " << h.getFormatVersion()
322  << ", " << h.getNumberOfAMCs()
323  << " AMC packets, orbit " << h.getOrbitNumber();
324  }
325 
326  *(data++) = amc13::Header(block_headers.size(), ev.orbitNumber()).raw();
327 
328  block_headers.insert(block_headers.end(), block_load.begin(), block_load.end());
329  for (const auto& word: block_headers)
330  *(data++) = word;
331 
332  std::string dstring(reinterpret_cast<char*>(block_start), reinterpret_cast<char*>(data));
333  cms::CRC32Calculator crc(dstring);
334  *(data++) = Trailer(crc.checksum(), b, ev.id().event(), ev.bunchCrossing()).raw();
335  }
336 
337  return true;
338  }
339 }
EventNumber_t event() const
Definition: EventID.h:41
int i
Definition: DBlmapReader.cc:9
Header header_
Definition: AMCSpec.h:142
static const unsigned int AmcNo_mask
Definition: AMCSpec.h:42
static const unsigned int OrN_shift
Definition: AMCSpec.h:97
unsigned int getBlockSize() const
Definition: AMCSpec.cc:64
static const unsigned int BoardID_shift
Definition: AMCSpec.h:43
static const unsigned int LV1_mask
Definition: AMCSpec.h:124
static const unsigned int Size_shift
Definition: AMCSpec.h:37
static const unsigned int fov
Definition: AMCSpec.h:100
unsigned int size() const
Definition: AMCSpec.cc:270
unsigned int getCRC() const
Definition: AMCSpec.h:111
unsigned int blocks() const
Definition: AMCSpec.cc:259
static const unsigned int Size_mask
Definition: AMCSpec.h:38
static const unsigned int nAMC_mask
Definition: AMCSpec.h:96
static const unsigned int CRC_mask
Definition: AMCSpec.h:120
static const unsigned int BlkNo_mask
Definition: AMCSpec.h:122
int bunchCrossing() const
Definition: EventBase.h:66
unsigned int getBlocks() const
Definition: AMCSpec.cc:52
static const unsigned int BX_mask
Definition: AMCSpec.h:126
std::vector< uint64_t > block(unsigned int id) const
Definition: AMCSpec.cc:87
bool ev
bool valid()
Definition: AMCSpec.cc:118
uint64_t data_
Definition: AMCSpec.h:103
Trailer(const uint64_t *data)
Definition: AMCSpec.h:108
static const unsigned int CRC_bit_shift
Definition: AMCSpec.h:52
void addPayload(const uint64_t *, unsigned int)
Definition: AMCSpec.cc:81
static const unsigned int BlkNo_mask
Definition: AMCSpec.h:40
std::vector< amc::Packet > payload_
Definition: AMCSpec.h:146
unsigned int getBlock() const
Definition: AMCSpec.h:112
uint64_t data_
Definition: AMCSpec.h:128
bool check(const std::string &)
static const unsigned int Length_bit_shift
Definition: AMCSpec.h:46
static const unsigned int uFOV_shift
Definition: AMCSpec.h:93
double amc
Definition: hdecay.h:20
unsigned int getSegmented() const
Definition: AMCSpec.h:34
static const unsigned int BX_shift
Definition: AMCSpec.h:125
def load
Definition: svgfig.py:546
bool write(const edm::Event &ev, unsigned char *ptr, unsigned int size) const
Definition: AMCSpec.cc:288
static const unsigned int uFOV_mask
Definition: AMCSpec.h:94
static const unsigned int AmcNo_shift
Definition: AMCSpec.h:41
static const unsigned int split_block_size
Definition: AMCSpec.h:13
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
static const unsigned int More_bit_shift
Definition: AMCSpec.h:47
int orbitNumber() const
Definition: EventBase.h:67
uint64_t data_
Definition: AMCSpec.h:54
static const unsigned int BoardID_mask
Definition: AMCSpec.h:44
static const unsigned int Enabled_bit_shift
Definition: AMCSpec.h:49
unsigned int size() const
Definition: AMCSpec.h:69
static const unsigned int Present_bit_shift
Definition: AMCSpec.h:50
unsigned int getOrbitNumber() const
Definition: AMCSpec.h:90
static const unsigned int max_amc
Definition: AMCSpec.h:101
unsigned long long uint64_t
Definition: Time.h:15
static const unsigned int Segmented_bit_shift
Definition: AMCSpec.h:48
unsigned int getSize() const
Definition: AMCSpec.h:32
double b
Definition: hdecay.h:120
static const unsigned int nAMC_shift
Definition: AMCSpec.h:95
unsigned int getMore() const
Definition: AMCSpec.h:33
static const unsigned int LV1_shift
Definition: AMCSpec.h:123
static const unsigned int BlkNo_shift
Definition: AMCSpec.h:121
Header header_
Definition: AMCSpec.h:69
unsigned int getNumberOfAMCs() const
Definition: AMCSpec.h:89
unsigned int getFormatVersion() const
Definition: AMCSpec.h:88
edm::EventID id() const
Definition: EventBase.h:60
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
std::unique_ptr< uint64_t[]> data()
Definition: AMCSpec.cc:99
bool parse(const uint64_t *, unsigned int)
Definition: AMCSpec.cc:142
static const unsigned int BlkNo_shift
Definition: AMCSpec.h:39
static const unsigned int CRC_shift
Definition: AMCSpec.h:119
std::uint32_t checksum()
Packet(const uint64_t *d)
Definition: AMCSpec.h:59
void add(unsigned int amc_no, unsigned int board, const std::vector< uint64_t > &load)
Definition: AMCSpec.cc:133
tuple size
Write out results.
static const unsigned int Valid_bit_shift
Definition: AMCSpec.h:51
static const unsigned int OrN_mask
Definition: AMCSpec.h:98
std::vector< uint64_t > payload_
Definition: AMCSpec.h:73