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 board, const std::vector<uint64_t>& load)
134  {
135  edm::LogInfo("AMC") << "Adding board " << board << " with payload size " << load.size();
136  // Start by indexing with 1
137  payload_.push_back(amc::Packet(payload_.size() + 1, board, load));
138  }
139 
140  bool
141  Packet::parse(const uint64_t *data, unsigned int size)
142  {
143  // Need at least a header and trailer
144  // TODO check if this can be removed
145  if (size < 2) {
146  edm::LogError("AMC") << "AMC13 packet size too small";
147  return false;
148  }
149 
150  auto block_start = data;
151  header_ = Header(data++);
152 
153  if (!header_.valid()) {
154  edm::LogError("AMC")
155  << "Invalid header for AMC13 packet: "
156  << "format version " << header_.getFormatVersion()
157  << ", " << header_.getNumberOfAMCs()
158  << " AMC packets, orbit " << header_.getOrbitNumber();
159  return false;
160  }
161 
162  if (size < 2 + header_.getNumberOfAMCs())
163  return false;
164 
165  // Initial filling of AMC payloads. First, get the headers. The
166  // first payload follows afterwards.
167  for (unsigned int i = 0; i < header_.getNumberOfAMCs(); ++i) {
168  payload_.push_back(amc::Packet(data++));
169  }
170 
171  unsigned int tot_size = 0; // total payload size
172  unsigned int tot_nblocks = 0; // total blocks of payload
173  unsigned int maxblocks = 0; // counting the # of amc13 header/trailers (1 ea per block)
174 
175  for (const auto& amc: payload_) {
176  tot_size += amc.header().getSize();
177  tot_nblocks += amc.header().getBlocks();
178  maxblocks = std::max(maxblocks, amc.header().getBlocks());
179  }
180 
181  unsigned int words = tot_size + // payload size
182  tot_nblocks + // AMC headers
183  2 * maxblocks; // AMC13 headers
184 
185  if (size < words) {
186  edm::LogError("L1T")
187  << "Encountered AMC 13 packet with "
188  << size << " words, "
189  << "but expected "
190  << words << " words: "
191  << tot_size << " payload words, "
192  << tot_nblocks << " AMC header words, and 2 AMC 13 header words.";
193  return false;
194  }
195 
196  // Read in the first AMC block and append the payload to the
197  // corresponding AMC packet.
198  for (auto& amc: payload_) {
199  amc.addPayload(data, amc.header().getBlockSize());
200  data += amc.header().getBlockSize();
201  }
202  auto block_end = data;
203 
204  Trailer t(data++);
205 
206  std::string check(reinterpret_cast<const char*>(block_start), reinterpret_cast<const char*>(block_end));
207  cms::CRC32Calculator crc(check);
208 
209  if (crc.checksum() != t.getCRC()) {
210  edm::LogWarning("L1T") << "Mismatch in checksums for block 0";
211  }
212 
213  if (t.getBlock() != 0 ) {
214  edm::LogWarning("L1T")
215  << "Block trailer mismatch: "
216  << "expected block 0, but trailer is for block "
217  << t.getBlock();
218  }
219 
220  // Read in remaining AMC blocks
221  for (unsigned int b = 1; b < maxblocks; ++b) {
222  block_start = data;
223 
224  Header block_h(data++);
225  std::vector<amc::Header> headers;
226 
227  for (unsigned int i = 0; i < block_h.getNumberOfAMCs(); ++i)
228  headers.push_back(amc::Header(data++));
229 
230  for (const auto& amc: headers) {
231  payload_[amc.getAMCNumber() - 1].addPayload(data, amc.getBlockSize());
232  data += amc.getBlockSize();
233  }
234 
235  block_end = data;
236 
237  t = Trailer(data++);
238 
239  check = std::string(reinterpret_cast<const char*>(block_start), reinterpret_cast<const char*>(block_end));
240  crc = cms::CRC32Calculator(check);
241 
242  if (crc.checksum() != t.getCRC()) {
243  edm::LogWarning("L1T") << "Mismatch in checksums for block " << b;
244  }
245 
246  if (t.getBlock() != 0 ) {
247  edm::LogWarning("L1T")
248  << "Block trailer mismatch: "
249  << "expected block " << b
250  << ", but trailer is for block " << t.getBlock();
251  }
252  }
253 
254  return true;
255  }
256 
257  unsigned int
259  {
260  unsigned int maxblocks = 0;
261 
262  for (const auto& amc: payload_)
263  maxblocks = std::max(maxblocks, amc.blocks());
264 
265  return maxblocks;
266  }
267 
268  unsigned int
269  Packet::size() const
270  {
271  unsigned int words = 0;
272  unsigned int blocks = 0;
273  unsigned int maxblocks = 0;
274 
275  for (const auto& amc: payload_) {
276  words += amc.size();
277  blocks += amc.blocks();
278  maxblocks = std::max(maxblocks, amc.blocks());
279  }
280 
281  // Size is total amount of words + # of blocks for AMC headers + # of
282  // maxblocks for AMC13 block header, trailer
283  return words + blocks + maxblocks * 2;
284  }
285 
286  bool
287  Packet::write(const edm::Event& ev, unsigned char * ptr, unsigned int size) const
288  {
289  if (size < this->size() * 8)
290  return false;
291 
292  if (size % 8 != 0)
293  return false;
294 
295  uint64_t * data = reinterpret_cast<uint64_t*>(ptr);
296 
297  for (unsigned int b = 0; b < blocks(); ++b) {
298  uint64_t * block_start = data;
299 
300  std::vector<uint64_t> block_headers;
301  std::vector<uint64_t> block_load;
302  for (const auto& amc: payload_) {
303  edm::LogInfo("AMC")
304  << "Considering block " << b
305  << " for payload " << amc.header().getBoardID()
306  << " with size " << amc.size()
307  << " and " << amc.blocks() << " blocks";
308  if (amc.blocks() < b + 1)
309  continue;
310 
311  block_headers.push_back(amc.header(b));
312  auto words = amc.block(b);
313  block_load.insert(block_load.end(), words.begin(), words.end());
314  }
315 
316  if (b == 0) {
317  amc13::Header h(block_headers.size(), ev.orbitNumber());
318  edm::LogInfo("AMC")
319  << "Writing header for AMC13 packet: "
320  << "format version " << h.getFormatVersion()
321  << ", " << h.getNumberOfAMCs()
322  << " AMC packets, orbit " << h.getOrbitNumber();
323  }
324 
325  *(data++) = amc13::Header(block_headers.size(), ev.orbitNumber()).raw();
326 
327  block_headers.insert(block_headers.end(), block_load.begin(), block_load.end());
328  for (const auto& word: block_headers)
329  *(data++) = word;
330 
331  std::string dstring(reinterpret_cast<char*>(block_start), reinterpret_cast<char*>(data));
332  cms::CRC32Calculator crc(dstring);
333  *(data++) = Trailer(crc.checksum(), b, ev.id().event(), ev.bunchCrossing()).raw();
334  }
335 
336  return true;
337  }
338 }
EventNumber_t event() const
Definition: EventID.h:41
void add(unsigned int board, const std::vector< uint64_t > &load)
Definition: AMCSpec.cc:133
int i
Definition: DBlmapReader.cc:9
Header header_
Definition: AMCSpec.h:141
static const unsigned int AmcNo_mask
Definition: AMCSpec.h:41
static const unsigned int OrN_shift
Definition: AMCSpec.h:96
unsigned int getBlockSize() const
Definition: AMCSpec.cc:64
static const unsigned int BoardID_shift
Definition: AMCSpec.h:42
static const unsigned int LV1_mask
Definition: AMCSpec.h:123
static const unsigned int Size_shift
Definition: AMCSpec.h:36
static const unsigned int fov
Definition: AMCSpec.h:99
unsigned int size() const
Definition: AMCSpec.cc:269
unsigned int getCRC() const
Definition: AMCSpec.h:110
unsigned int blocks() const
Definition: AMCSpec.cc:258
static const unsigned int Size_mask
Definition: AMCSpec.h:37
static const unsigned int nAMC_mask
Definition: AMCSpec.h:95
static const unsigned int CRC_mask
Definition: AMCSpec.h:119
static const unsigned int BlkNo_mask
Definition: AMCSpec.h:121
int bunchCrossing() const
Definition: EventBase.h:62
unsigned int getBlocks() const
Definition: AMCSpec.cc:52
static const unsigned int BX_mask
Definition: AMCSpec.h:125
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:102
Trailer(const uint64_t *data)
Definition: AMCSpec.h:107
static const unsigned int CRC_bit_shift
Definition: AMCSpec.h:51
void addPayload(const uint64_t *, unsigned int)
Definition: AMCSpec.cc:81
static const unsigned int BlkNo_mask
Definition: AMCSpec.h:39
std::vector< amc::Packet > payload_
Definition: AMCSpec.h:145
unsigned int getBlock() const
Definition: AMCSpec.h:111
uint64_t data_
Definition: AMCSpec.h:127
bool check(const std::string &)
static const unsigned int Length_bit_shift
Definition: AMCSpec.h:45
static const unsigned int uFOV_shift
Definition: AMCSpec.h:92
double amc
Definition: hdecay.h:20
unsigned int getSegmented() const
Definition: AMCSpec.h:33
static const unsigned int BX_shift
Definition: AMCSpec.h:124
def load
Definition: svgfig.py:546
bool write(const edm::Event &ev, unsigned char *ptr, unsigned int size) const
Definition: AMCSpec.cc:287
static const unsigned int uFOV_mask
Definition: AMCSpec.h:93
static const unsigned int AmcNo_shift
Definition: AMCSpec.h:40
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:46
int orbitNumber() const
Definition: EventBase.h:63
uint64_t data_
Definition: AMCSpec.h:53
static const unsigned int BoardID_mask
Definition: AMCSpec.h:43
static const unsigned int Enabled_bit_shift
Definition: AMCSpec.h:48
unsigned int size() const
Definition: AMCSpec.h:68
static const unsigned int Present_bit_shift
Definition: AMCSpec.h:49
unsigned int getOrbitNumber() const
Definition: AMCSpec.h:89
static const unsigned int max_amc
Definition: AMCSpec.h:100
unsigned long long uint64_t
Definition: Time.h:15
static const unsigned int Segmented_bit_shift
Definition: AMCSpec.h:47
unsigned int getSize() const
Definition: AMCSpec.h:31
double b
Definition: hdecay.h:120
static const unsigned int nAMC_shift
Definition: AMCSpec.h:94
unsigned int getMore() const
Definition: AMCSpec.h:32
static const unsigned int LV1_shift
Definition: AMCSpec.h:122
static const unsigned int BlkNo_shift
Definition: AMCSpec.h:120
Header header_
Definition: AMCSpec.h:68
unsigned int getNumberOfAMCs() const
Definition: AMCSpec.h:88
unsigned int getFormatVersion() const
Definition: AMCSpec.h:87
edm::EventID id() const
Definition: EventBase.h:56
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:141
static const unsigned int BlkNo_shift
Definition: AMCSpec.h:38
static const unsigned int CRC_shift
Definition: AMCSpec.h:118
std::uint32_t checksum()
Packet(const uint64_t *d)
Definition: AMCSpec.h:58
Header(const uint64_t *data)
Definition: AMCSpec.h:17
tuple size
Write out results.
static const unsigned int Valid_bit_shift
Definition: AMCSpec.h:50
static const unsigned int OrN_mask
Definition: AMCSpec.h:97
std::vector< uint64_t > payload_
Definition: AMCSpec.h:72