ATLAS Offline Software
Loading...
Searching...
No Matches
BasicConstantGPUDataExporter Class Reference

Standard tool to export calorimeter geometry and cell noise to GPU. More...

#include <BasicConstantGPUDataExporter.h>

Inheritance diagram for BasicConstantGPUDataExporter:
Collaboration diagram for BasicConstantGPUDataExporter:

Public Member Functions

 BasicConstantGPUDataExporter (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize () override
virtual StatusCode convert (CaloRecGPU::ConstantDataHolder &constant_data, const bool override_keep_CPU_info) const override
virtual StatusCode convert (const EventContext &ctx, CaloRecGPU::ConstantDataHolder &constant_data, const bool override_keep_CPU_info) const override
virtual StatusCode finalize () override
virtual ~BasicConstantGPUDataExporter ()=default

Protected Member Functions

void record_times (const size_t event_num, const std::vector< size_t > &times) const
template<class ... Args>
void record_times (const size_t event_num, const size_t &value) const
template<class ... Args>
void record_times (const size_t event_num, const size_t &value, Args &&... args) const
void print_times (const std::string &header, const size_t time_size) const

Protected Attributes

std::shared_mutex m_timeMutex
 Mutex that is locked when recording times.
std::vector< size_t > m_times ATLAS_THREAD_SAFE
 Vector to hold execution times to be recorded if necessary.
std::vector< size_t > m_eventNumbers ATLAS_THREAD_SAFE
 Vector to hold the event numbers to be recorded if necessary.
Gaudi::Property< bool > m_measureTimes
 If true, times are recorded to the file given by m_timeFileName.
Gaudi::Property< std::string > m_timeFileName
 File to which times should be saved.

Private Member Functions

void record_times_helper (const size_t) const
template<class Arg>
void record_times_helper (const size_t index, Arg &&arg) const
template<class ... Args>
void record_times_helper (size_t index, Args &&... args) const

Private Attributes

Gaudi::Property< bool > m_keepCPUData {this, "KeepCPUData", true, "Keep CPU version of GPU data format"}
 If true, do not delete the CPU version of the GPU-friendly data representation.
SG::ReadCondHandleKey< CaloNoisem_noiseCDOKey {this, "CaloNoiseKey", "totalNoise", "SG Key of CaloNoise data object"}
 Key of the CaloNoise Conditions data object.
SG::ReadCondHandleKey< CaloDetDescrManagerm_caloMgrKey
 Key for the CaloDetDescrManager in the Condition Store.
bool m_hasBeenInitialized

Detailed Description

Standard tool to export calorimeter geometry and cell noise to GPU.

Author
Nuno Fernandes nuno..nosp@m.dos..nosp@m.santo.nosp@m.s.fe.nosp@m.rnand.nosp@m.es@c.nosp@m.ern.c.nosp@m.h
Date
29 May 2022

For the time being, this must be run on first event, so that the noise tool exists and so on. Hopefully we can find a way around this in the future.

Definition at line 28 of file BasicConstantGPUDataExporter.h.

Constructor & Destructor Documentation

◆ BasicConstantGPUDataExporter()

BasicConstantGPUDataExporter::BasicConstantGPUDataExporter ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 24 of file BasicConstantGPUDataExporter.cxx.

24 :
25 base_class(type, name, parent),
26 CaloGPUTimed(this),
28{
29}
CaloGPUTimed(T *ptr)

◆ ~BasicConstantGPUDataExporter()

virtual BasicConstantGPUDataExporter::~BasicConstantGPUDataExporter ( )
virtualdefault

Member Function Documentation

◆ convert() [1/2]

StatusCode BasicConstantGPUDataExporter::convert ( CaloRecGPU::ConstantDataHolder & constant_data,
const bool override_keep_CPU_info ) const
overridevirtual

Definition at line 48 of file BasicConstantGPUDataExporter.cxx.

49{
50 ATH_MSG_ERROR("BasicConstantGPUDataExporter (" << this->name() << ") must be used with the "
51 "GPU data preparation happening on the first event.");
52
53 return StatusCode::FAILURE;
54}
#define ATH_MSG_ERROR(x)

◆ convert() [2/2]

StatusCode BasicConstantGPUDataExporter::convert ( const EventContext & ctx,
CaloRecGPU::ConstantDataHolder & constant_data,
const bool override_keep_CPU_info ) const
overridevirtual

Definition at line 56 of file BasicConstantGPUDataExporter.cxx.

57{
58 using clock_type = boost::chrono::thread_clock;
59 auto time_cast = [](const auto & before, const auto & after)
60 {
61 return boost::chrono::duration_cast<boost::chrono::microseconds>(after - before).count();
62 };
63
64 auto start = clock_type::now();
65
66 SG::ReadCondHandle<CaloDetDescrManager> caloMgrHandle{m_caloMgrKey, ctx};
67 const CaloDetDescrManager * calo_dd_man = *caloMgrHandle;
68
69 cd.m_geometry.allocate();
70
71 const CaloCell_ID * calo_id = calo_dd_man->getCaloCell_ID();
72
73#if CALORECGPU_ETA_PHI_MAP_DEBUG
74 float min_eta_pos[NumSamplings], max_eta_pos[NumSamplings],
75 min_eta_neg[NumSamplings], max_eta_neg[NumSamplings],
76 min_phi_pos[NumSamplings], max_phi_pos[NumSamplings],
77 min_phi_neg[NumSamplings], max_phi_neg[NumSamplings],
78 min_deta [NumSamplings], min_dphi [NumSamplings],
79 max_deta [NumSamplings], max_dphi [NumSamplings],
80 avg_deta [NumSamplings], avg_dphi [NumSamplings],
81 min_dr [NumSamplings], min_dz [NumSamplings],
82 max_dr [NumSamplings], max_dz [NumSamplings];
83
84 for (int i = 0; i < NumSamplings; ++i)
85 {
86 min_eta_pos[i] = std::numeric_limits<float>::max();
87 max_eta_pos[i] = std::numeric_limits<float>::lowest();
88 min_eta_neg[i] = std::numeric_limits<float>::max();
89 max_eta_neg[i] = std::numeric_limits<float>::lowest();
90 min_phi_pos[i] = std::numeric_limits<float>::max();
91 max_phi_pos[i] = std::numeric_limits<float>::lowest();
92 min_phi_neg[i] = std::numeric_limits<float>::max();
93 max_phi_neg[i] = std::numeric_limits<float>::lowest();
94 min_deta [i] = std::numeric_limits<float>::max();
95 min_dphi [i] = std::numeric_limits<float>::max();
96 max_deta [i] = std::numeric_limits<float>::lowest();
97 max_dphi [i] = std::numeric_limits<float>::lowest();
98 avg_deta [i] = 0.f;
99 avg_dphi [i] = 0.f;
100 min_dr [i] = std::numeric_limits<float>::max();
101 min_dz [i] = std::numeric_limits<float>::max();
102 max_dr [i] = std::numeric_limits<float>::lowest();
103 max_dz [i] = std::numeric_limits<float>::lowest();
104
105 cd.m_geometry->nCellsPerSampling[i] = 0;
106 }
107#else
108 float min_eta[NumSamplings], max_eta[NumSamplings];
109
110 for (int i = 0; i < NumSamplings; ++i)
111 {
112 min_eta[i] = std::numeric_limits<float>::max();
113 max_eta[i] = std::numeric_limits<float>::lowest();
114
115 cd.m_geometry->nCellsPerSampling[i] = 0;
116 }
117#endif
118
119 for (int cell = 0; cell < NCaloCells; ++cell)
120 {
121 const CaloDetDescrElement * caloElement = calo_dd_man->get_element((IdentifierHash) cell);
122
123 const Identifier cell_identifier = calo_id->cell_id((IdentifierHash) cell);
124
125 const int sampling = calo_id->calo_sample(cell_identifier);
126 const int intra_calo_sampling = calo_id->sampling(cell_identifier);
127 const int subcalo = caloElement->getSubCalo();
128 const int region = calo_id->region(cell_identifier);
129
130 const bool is_PS = (subcalo == CaloCell_ID::LAREM && intra_calo_sampling == 0);
131
132 const bool is_HECIW_or_FCAL = ( (subcalo == CaloCell_ID::LARHEC && region == 1 ) ||
133 (subcalo == CaloCell_ID::LARFCAL && intra_calo_sampling > 1 ) );
134
135 cd.m_geometry->otherCellInfo[cell] = OtherCellInfo(sampling,
139 is_PS,
140 is_HECIW_or_FCAL);
141 cd.m_geometry->x[cell] = caloElement->x();
142 cd.m_geometry->y[cell] = caloElement->y();
143 cd.m_geometry->z[cell] = caloElement->z();
144 cd.m_geometry->r[cell] = caloElement->r();
145 cd.m_geometry->eta[cell] = caloElement->eta();
146 cd.m_geometry->phi[cell] = caloElement->phi();
147
148 cd.m_geometry->dx[cell] = caloElement->dx();
149 cd.m_geometry->dy[cell] = caloElement->dy();
150 cd.m_geometry->dz[cell] = caloElement->dz();
151 cd.m_geometry->dr[cell] = caloElement->dr();
152 cd.m_geometry->deta[cell] = caloElement->deta();
153 cd.m_geometry->dphi[cell] = caloElement->dphi();
154
155 cd.m_geometry->volume[cell] = caloElement->volume();
156 cd.m_geometry->neighbours.offsets[cell] = 0;
157
158#if CALORECGPU_ETA_PHI_MAP_DEBUG
159 const float eta_minus = caloElement->eta() - caloElement->deta() / 2;
160 const float eta_plus = caloElement->eta() + caloElement->deta() / 2;
161 const float phi_minus = caloElement->phi() - caloElement->dphi() / 2;
162 const float phi_plus = caloElement->phi() + caloElement->dphi() / 2;
163
164 if (caloElement->eta() >= 0)
165 {
166 min_eta_pos[sampling] = std::min({min_eta_pos[sampling], eta_minus, eta_plus});
167 min_phi_pos[sampling] = std::min({min_phi_pos[sampling], phi_minus, phi_plus});
168 max_eta_pos[sampling] = std::max({max_eta_pos[sampling], eta_minus, eta_plus});
169 max_phi_pos[sampling] = std::max({max_phi_pos[sampling], phi_minus, phi_plus});
170 }
171 else
172 {
173 min_eta_neg[sampling] = std::min({min_eta_neg[sampling], eta_minus, eta_plus});
174 min_phi_neg[sampling] = std::min({min_phi_neg[sampling], phi_minus, phi_plus});
175 max_eta_neg[sampling] = std::max({max_eta_neg[sampling], eta_minus, eta_plus});
176 max_phi_neg[sampling] = std::max({max_phi_neg[sampling], phi_minus, phi_plus});
177 }
178 min_deta[sampling] = std::min(min_deta[sampling], caloElement->deta());
179 min_dphi[sampling] = std::min(min_dphi[sampling], caloElement->dphi());
180 max_deta[sampling] = std::max(max_deta[sampling], caloElement->deta());
181 max_dphi[sampling] = std::max(max_dphi[sampling], caloElement->dphi());
182 min_dr [sampling] = std::min(min_dr [sampling], caloElement->dr ());
183 min_dz [sampling] = std::min(min_dz [sampling], caloElement->dz ());
184 max_dr [sampling] = std::max(max_dr [sampling], caloElement->dr ());
185 max_dz [sampling] = std::max(max_dz [sampling], caloElement->dz ());
186
187 avg_deta[sampling] += caloElement->deta();
188 avg_dphi[sampling] += caloElement->dphi();
189#else
190 const float eta_below = fabsf(caloElement->eta() - caloElement->deta() / 2);
191 const float eta_above = fabsf(caloElement->eta() + caloElement->deta() / 2);
192 min_eta[sampling] = std::min(min_eta[sampling], std::min(eta_below, eta_above));
193 max_eta[sampling] = std::max(max_eta[sampling], std::max(eta_below, eta_above));
194#endif
195
196 cd.m_geometry->nCellsPerSampling[sampling] += 1;
197 }
198
199 auto after_geo = clock_type::now();
200
201 for (int i = 0; i < NumSamplings; ++i)
202 {
203#if CALORECGPU_ETA_PHI_MAP_DEBUG
204 avg_deta[i] /= cd.m_geometry->nCellsPerSampling[i];
205 avg_dphi[i] /= cd.m_geometry->nCellsPerSampling[i];
206 if (cd.m_geometry->nCellsPerSampling[i] > 0)
207 {
208 printf("CALORECGPU ETA PHI MAP DEBUG OUTPUT: %d | %f %f %f %f | %f %f %f %f | %f %f | %f %f | %f %f %d | %f %f | %f %f\n",
209 i, min_eta_neg[i], min_phi_neg[i], max_eta_neg[i], max_phi_neg[i],
210 min_eta_pos[i], min_phi_pos[i], max_eta_pos[i], max_phi_pos[i],
211 min_deta[i], min_dphi[i], max_deta[i], max_dphi[i],
212 avg_deta[i], avg_dphi[i], cd.m_geometry->nCellsPerSampling[i],
213 min_dr[i], min_dz[i], max_dr[i], max_dz[i]);
214 }
215 const float this_min_eta = std::min(fabsf(max_eta_neg[i]), fabsf(min_eta_pos[i]));
216 const float this_max_eta = std::max(fabsf(min_eta_neg[i]), fabsf(max_eta_pos[i]));
217#else
218 const float this_min_eta = min_eta[i];
219 const float this_max_eta = max_eta[i];
220#endif
221
222 if (cd.m_geometry->nCellsPerSampling[i] <= 0)
223 {
224 cd.m_geometry->etaPhiToCell.initialize(i, -1, 1);
225 //Just to prevent NaN.
226 }
227 else
228 {
229 cd.m_geometry->etaPhiToCell.initialize(i, this_min_eta, this_max_eta);
230 }
231 }
232
233 cd.m_geometry->fill_eta_phi_map();
234
235#if CALORECGPU_ETA_PHI_MAP_DEBUG
236 for (int i = 0; i < NumSamplings; ++i)
237 {
238 auto printer = [&](const auto & entry)
239 {
240 printf("CALORECGPU ETA PHI MAP DEBUG OUTPUT: %d | %d\n", i, entry.get_max_real_overlap());
241 };
242
243 cd.m_geometry->etaPhiToCell.apply_to_sampling(i, printer);
244 }
245#endif
246
247 auto after_eta_phi = clock_type::now();
248
249 std::vector<IdentifierHash> neighbour_vector, full_neighs, prev_neighs;
250
251 for (int cell = 0; cell < NCaloCells; ++cell)
252 {
253 for (int neigh_bit_set = 0; neigh_bit_set < NumNeighOptions; ++neigh_bit_set)
254 {
255 const unsigned int curr_neigh_opt = (1U << neigh_bit_set);
256
257 if (curr_neigh_opt == LArNeighbours::corners2D || curr_neigh_opt == LArNeighbours::corners3D)
258 //Scanning the ATLAS codebase, neighbour handling has special cases
259 //for all2D (LarFCAL_Base_ID.cxx, LArMiniFCAL_ID.cxx, Tile_Base_ID.cxx)
260 //and all3DwithCorners (Tile_Base_ID.cxx), which include
261 //neighbours not returned when just the constituent bits are set separately.
262 //As an imperfect workaround, we stuff them in the immediately previous option
263 //(corners, for both 2D and 3D).
264 {
265 if (curr_neigh_opt == LArNeighbours::corners2D)
266 {
267 calo_id->get_neighbours((IdentifierHash) cell,
269 full_neighs);
270 }
271 else /*if (curr_neigh_opt == LArNeighbours::corners3D)*/
272 {
273 calo_id->get_neighbours((IdentifierHash) cell,
275 prev_neighs);
276 calo_id->get_neighbours((IdentifierHash) cell,
278 neighbour_vector);
279 //We will exclude the cells that could come from later options
280 //(it seems, from Tile_Base_ID.cxx, all3DwithCorners will give more than super3D),
281 //which... might make some sense, but seems unexpected.
282
283
284 std::sort(neighbour_vector.begin(), neighbour_vector.end());
285 std::sort(prev_neighs.begin(), prev_neighs.end());
286
287 full_neighs.clear();
288
289 std::set_difference( prev_neighs.begin(), prev_neighs.end(),
290 neighbour_vector.begin(), neighbour_vector.end(),
291 std::back_inserter(full_neighs) );
292
293 }
294
295 prev_neighs.resize(cd.m_geometry->neighbours.get_total_number_of_neighbours(cell));
296 //We want to add just the neighbours that are not part of this.
297
298 for (size_t neigh = 0; neigh < prev_neighs.size(); ++neigh)
299 {
300 prev_neighs[neigh] = cd.m_geometry->neighbours.get_neighbour(cell, neigh);
301 }
302
303 std::sort(full_neighs.begin(), full_neighs.end());
304 std::sort(prev_neighs.begin(), prev_neighs.end());
305
306 neighbour_vector.clear();
307
308 std::set_difference( full_neighs.begin(), full_neighs.end(),
309 prev_neighs.begin(), prev_neighs.end(),
310 std::back_inserter(neighbour_vector) );
311 }
312 else
313 {
314 calo_id->get_neighbours((IdentifierHash) cell, (LArNeighbours::neighbourOption) curr_neigh_opt, neighbour_vector);
315 }
316
317 std::sort(neighbour_vector.begin(), neighbour_vector.end());
318
319 const int neighs_start = cd.m_geometry->neighbours.get_total_number_of_neighbours(cell);
320
321 for (size_t neigh_num = 0; neigh_num < neighbour_vector.size(); ++neigh_num)
322 {
323 cd.m_geometry->neighbours.set_neighbour(cell, neighs_start + neigh_num, neighbour_vector[neigh_num]);
324 }
325
326 cd.m_geometry->neighbours.offsets[cell] += NeighOffset::offset_delta(neigh_bit_set) * neighbour_vector.size();
327
328 }
329 }
330
331#if CALORECGPU_ADD_FULL_PAIRS_LIST_TO_CONSTANT_INFORMATION
332
333//Note: the commented out code is used to output the hard-coded numbers
334//in NeighPairsArr. For the time being, it should remain here until
335//a more definitive solution for the geometry is found.
336
337 {
338 int num_pairs = 0;
339
340 auto add_neighbours = [&](const int cell, const unsigned int curr_neigh_opt)
341 {
342 int neighbours[NMaxNeighbours];
343
344 const int num_neighs = cd.m_geometry->neighbours.get_neighbours(curr_neigh_opt, cell, neighbours);
345
346 for (int neigh = 0; neigh < num_neighs; ++neigh)
347 {
348 cd.m_geometry->neighPairs.cell_A[num_pairs] = cell;
349 cd.m_geometry->neighPairs.cell_B[num_pairs] = neighbours[neigh];
350 ++num_pairs;
351 }
352 };
353
354 for (int neigh_bit_set = 0; neigh_bit_set < NumNeighOptions; ++neigh_bit_set)
355 {
356 const unsigned int curr_neigh_opt = (1U << neigh_bit_set);
357
358 for (int cell = 0; cell < NCaloCells; ++cell)
359 {
360 if (cd.m_geometry->is_PS(cell) || cd.m_geometry->is_HECIW_or_FCal(cell))
361 {
362 continue;
363 }
364
365 add_neighbours(cell, curr_neigh_opt);
366 }
367
368 //const int PS_start = num_pairs;
369
370 for (int cell = 0; cell < NCaloCells; ++cell)
371 {
372 if (!cd.m_geometry->is_PS(cell))
373 {
374 continue;
375 }
376
377 add_neighbours(cell, curr_neigh_opt);
378 }
379
380 //const int HECIW_FCal_start = num_pairs;
381
382 for (int cell = 0; cell < NCaloCells; ++cell)
383 {
384 if (!cd.m_geometry->is_HECIW_or_FCal(cell))
385 {
386 continue;
387 }
388
389 add_neighbours(cell, curr_neigh_opt);
390 }
391
392 //std::cout << neigh_bit_set << " " << num_pairs << " " << PS_start << " " << HECIW_FCal_start << std::endl;
393 }
394 }
395#endif
396
397 auto after_pairs = clock_type::now();
398
399 /*
400 //Useful output for debugging and studying regularities in calorimeter geometry...
401
402 std::cout << "ID\tCaloSample\tSampling\tRegion\tSubCalo";
403 for (int j = 0; j < NumNeighOptions; ++j)
404 {
405 std::cout << "\tn_" << j;
406 }
407 std::cout << "\tn_total\tOffset" << std::endl;
408
409 for (int cell = 0; cell < NCaloCells; ++cell)
410 {
411
412 const CaloDetDescrElement * caloElement = calo_dd_man->get_element((IdentifierHash) cell);
413 std::cout << cell << "\t"
414 << (int) calo_id->calo_sample(calo_id->cell_id((IdentifierHash) cell)) << "\t"
415 << (int) calo_id->sampling(calo_id->cell_id((IdentifierHash) cell)) << "\t"
416 << (int) calo_id->region(calo_id->cell_id((IdentifierHash) cell)) << "\t"
417 << (int) caloElement->getSubCalo();
418
419 const NeighOffset n_off = cd.m_geometry->neighbours.offsets[cell];
420
421 for (int j = 0; j < NumNeighOptions; ++j)
422 {
423 std::cout << "\t" << n_off.get_num_cells(j);
424 }
425
426 std::cout << "\t" << n_off.get_total_number() << "\t" << n_off << std::endl;
427 }
428 // */
429
430 SG::ReadCondHandle<CaloNoise> noise_handle(m_noiseCDOKey, ctx);
431 const CaloNoise * noise_tool = *noise_handle;
432
433 IdentifierHash t_start, t_end;
434 calo_id->calo_cell_hash_range(CaloCell_ID::TILE, t_start, t_end);
435
436 if (t_start != TileCellStart)
437 {
438 ATH_MSG_WARNING("Tile start (" << t_start << ") differs from assumed constant value (" << TileCellStart << ")!");
439 }
440 if (t_end != TileCellAfterEnd)
441 {
442 ATH_MSG_WARNING("Tile end (" << t_end << ") differs from assumed constant value (" << TileCellAfterEnd << ")!");
443 }
444
445 const CaloCondBlobFlt * blob = noise_tool->getTileBlob();
446
447 cd.m_cell_noise.allocate();
448
449 if (!blob)
450 {
451 cd.m_cell_noise->noise_properties = CellNoiseProperties::invalid_value();
452 }
453 else
454 {
455 cd.m_cell_noise->noise_properties = CellNoiseProperties(blob->getObjVersion(), noise_tool->getNoiseType());
456 }
457
458 cd.m_cell_noise->luminosity = noise_tool->getLumi();
459
460 for (int cell = 0; cell < int(t_start); ++cell)
461 {
462 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
463 {
464 cd.m_cell_noise->noise[cell][gain_state] = noise_tool->larStorage()[(gain_state > 2 ? 0 : gain_state)][cell];
465 }
466 }
467 for (int cell = t_start; cell < int(t_end); ++cell)
468 {
469 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
470 {
471 cd.m_cell_noise->noise[cell][gain_state] = noise_tool->tileStorage()[gain_state][cell - t_start];
472 cd.m_cell_noise->double_gaussian_constants[0][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 2);
473 cd.m_cell_noise->double_gaussian_constants[1][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 3);
474 cd.m_cell_noise->double_gaussian_constants[2][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 4);
475 cd.m_cell_noise->double_gaussian_constants[3][cell - t_start][gain_state] = blob->getData(cell - t_start, gain_state, 1);
476 }
477 }
478 for (int cell = t_end; cell < NCaloCells; ++cell)
479 {
480 for (int gain_state = 0; gain_state < CaloRecGPU::NumGainStates; ++gain_state)
481 {
482 cd.m_cell_noise->noise[cell][gain_state] = 0;
483 }
484 }
485
486 auto after_noise = clock_type::now();
487
488 cd.sendToGPU(!(m_keepCPUData || keep_CPU_info));
489
490
491 auto after_send = clock_type::now();
492
493 if (m_measureTimes)
494 {
495 record_times(ctx.evt(),
496 time_cast(start, after_geo),
497 time_cast(after_geo, after_eta_phi),
498 time_cast(after_eta_phi, after_pairs),
499 time_cast(after_pairs, after_noise),
500 time_cast(after_noise, after_send)
501 );
502 }
503
504 return StatusCode::SUCCESS;
505
506}
#define ATH_MSG_WARNING(x)
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Key for the CaloDetDescrManager in the Condition Store.
Gaudi::Property< bool > m_keepCPUData
If true, do not delete the CPU version of the GPU-friendly data representation.
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
int sampling(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
int get_neighbours(const IdentifierHash caloHash, const LArNeighbours::neighbourOption &option, std::vector< IdentifierHash > &neighbourList) const
access to hashes for neighbours return == 0 for neighbours found
void calo_cell_hash_range(const Identifier id, IdentifierHash &caloCellMin, IdentifierHash &caloCellMax) const
to loop on 'global' cell hashes of one sub-calorimeter alone
int region(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
int calo_sample(const Identifier id) const
returns an int taken from Sampling enum and describing the subCalo to which the Id belongs.
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
const CaloCell_ID * getCaloCell_ID() const
get calo cell ID helper
Gaudi::Property< bool > m_measureTimes
If true, times are recorded to the file given by m_timeFileName.
void record_times(const size_t event_num, const std::vector< size_t > &times) const
const CaloCondBlobFlt * getTileBlob() const
Definition CaloNoise.h:84
boost::multi_array< float, 2 > & larStorage()
Non-const accessor to underlying storage for filling:
Definition CaloNoise.h:72
NOISETYPE getNoiseType() const
Definition CaloNoise.h:88
float getLumi() const
Definition CaloNoise.h:86
boost::multi_array< float, 2 > & tileStorage()
Definition CaloNoise.h:73
static constexpr int from_region_enum(const int region)
static constexpr int from_subcalo_enum(const int subcalo)
static constexpr int from_intra_calorimeter_sampling_enum(const int sampling)
constexpr int NumSamplings
constexpr int NMaxNeighbours
constexpr int TileCellAfterEnd
constexpr int NumNeighOptions
constexpr int NCaloCells
constexpr int TileCellStart
constexpr int NumGainStates
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
static constexpr carrier invalid_value()
static constexpr carrier offset_delta(const int i)
Returns, for each i, what must be added to the offset to increase the stores numbers appropriately wh...
Definition NeighArr.h:144

◆ finalize()

StatusCode BasicConstantGPUDataExporter::finalize ( )
overridevirtual

Definition at line 508 of file BasicConstantGPUDataExporter.cxx.

509{
510
511 if (m_measureTimes)
512 {
513 print_times("Basic_Geometry Eta_Phi_Map_Finalize Pairs Noise Transfer_to_GPU", 5);
514 }
515 return StatusCode::SUCCESS;
516}
void print_times(const std::string &header, const size_t time_size) const

◆ initialize()

StatusCode BasicConstantGPUDataExporter::initialize ( )
overridevirtual

Definition at line 31 of file BasicConstantGPUDataExporter.cxx.

32{
34 {
35 ATH_MSG_INFO("Initializing data tool again...");
36 return StatusCode::SUCCESS;
37 }
38
39 ATH_CHECK(m_noiseCDOKey.initialize());
40
41 ATH_CHECK(m_caloMgrKey.initialize());
42
44
45 return StatusCode::SUCCESS;
46}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)

◆ print_times()

void CaloGPUTimed::print_times ( const std::string & header,
const size_t time_size ) const
inlineprotectedinherited

Definition at line 143 of file CaloGPUTimed.h.

144 {
145 std::shared_lock<std::shared_mutex> lock(m_timeMutex);
146
147 if (m_timeFileName.size() == 0)
148 {
149 return;
150 }
151
152 std::vector<size_t> indices(m_eventNumbers.size());
153
154 std::iota(indices.begin(), indices.end(), 0);
155 std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b)
156 {
157 return m_eventNumbers[a] < m_eventNumbers[b];
158 }
159 );
160 std::ofstream out(m_timeFileName);
161
162 out << "Event_Number Total " << header << "\n";
163
164 for (const size_t idx : indices)
165 {
166 out << m_eventNumbers[idx] << " ";
167
168 size_t total = 0;
169
170 for (size_t i = 0; i < time_size; ++i)
171 {
172 total += m_times[idx * time_size + i];
173 }
174
175 out << total << " ";
176
177 for (size_t i = 0; i < time_size; ++i)
178 {
179 out << m_times[idx * time_size + i] << " ";
180 }
181 out << "\n";
182 }
183
184 out << std::endl;
185
186 out.close();
187 }
static Double_t a
Gaudi::Property< std::string > m_timeFileName
File to which times should be saved.
std::shared_mutex m_timeMutex
Mutex that is locked when recording times.
std::pair< long int, long int > indices

◆ record_times() [1/3]

template<class ... Args>
void CaloGPUTimed::record_times ( const size_t event_num,
const size_t & value ) const
inlineprotectedinherited

Definition at line 105 of file CaloGPUTimed.h.

106 {
107 const size_t time_size = 1;
108
109 size_t old_size;
110
111 {
112 std::unique_lock<std::shared_mutex> lock(m_timeMutex);
113 old_size = m_times.size();
114 m_times.resize(old_size + time_size);
115 m_eventNumbers.push_back(event_num);
116 }
117 {
118 std::shared_lock<std::shared_mutex> lock(m_timeMutex);
119 record_times_helper(old_size, value);
120 }
121 }
void record_times_helper(const size_t) const

◆ record_times() [2/3]

template<class ... Args>
void CaloGPUTimed::record_times ( const size_t event_num,
const size_t & value,
Args &&... args ) const
inlineprotectedinherited

Definition at line 124 of file CaloGPUTimed.h.

125 {
126 const size_t time_size = sizeof...(args) + 1;
127
128 size_t old_size;
129
130 {
131 std::unique_lock<std::shared_mutex> lock(m_timeMutex);
132 old_size = m_times.size();
133 m_times.resize(old_size + time_size);
134 m_eventNumbers.push_back(event_num);
135 }
136 {
137 std::shared_lock<std::shared_mutex> lock(m_timeMutex);
138 record_times_helper(old_size, value, std::forward<Args>(args)...);
139 }
140
141 }

◆ record_times() [3/3]

void CaloGPUTimed::record_times ( const size_t event_num,
const std::vector< size_t > & times ) const
inlineprotectedinherited

Definition at line 86 of file CaloGPUTimed.h.

87 {
88 size_t old_size;
89 {
90 std::unique_lock<std::shared_mutex> lock(m_timeMutex);
91 old_size = m_times.size();
92 m_times.resize(old_size + times.size());
93 m_eventNumbers.push_back(event_num);
94 }
95 {
96 std::shared_lock<std::shared_mutex> lock(m_timeMutex);
97 for (size_t i = 0; i < times.size(); ++i)
98 {
99 m_times[old_size + i] = times[i];
100 }
101 }
102 }

◆ record_times_helper() [1/3]

template<class Arg>
void CaloGPUTimed::record_times_helper ( const size_t index,
Arg && arg ) const
inlineprivateinherited

Definition at line 70 of file CaloGPUTimed.h.

71 {
72 // coverity[missing_lock]
73 m_times[index] = std::forward<Arg>(arg);
74
75 //This is called within a function that holds the lock itself.
76 }
str index
Definition DeMoScan.py:362

◆ record_times_helper() [2/3]

void CaloGPUTimed::record_times_helper ( const size_t ) const
inlineprivateinherited

Definition at line 64 of file CaloGPUTimed.h.

65 {
66 //Do nothing
67 }

◆ record_times_helper() [3/3]

template<class ... Args>
void CaloGPUTimed::record_times_helper ( size_t index,
Args &&... args ) const
inlineprivateinherited

Definition at line 79 of file CaloGPUTimed.h.

80 {
81 (record_times_helper(index++, std::forward<Args>(args)), ...);
82 }

Member Data Documentation

◆ ATLAS_THREAD_SAFE [1/2]

std::vector<size_t> m_times CaloGPUTimed::ATLAS_THREAD_SAFE
mutableprotectedinherited

Vector to hold execution times to be recorded if necessary.

Definition at line 35 of file CaloGPUTimed.h.

◆ ATLAS_THREAD_SAFE [2/2]

std::vector<size_t> m_eventNumbers CaloGPUTimed::ATLAS_THREAD_SAFE
mutableprotectedinherited

Vector to hold the event numbers to be recorded if necessary.

Definition at line 40 of file CaloGPUTimed.h.

◆ m_caloMgrKey

SG::ReadCondHandleKey<CaloDetDescrManager> BasicConstantGPUDataExporter::m_caloMgrKey
private
Initial value:
{this, "CaloDetDescrManager", "CaloDetDescrManager",
"SG Key for CaloDetDescrManager in the Condition Store"}

Key for the CaloDetDescrManager in the Condition Store.

Definition at line 62 of file BasicConstantGPUDataExporter.h.

62 {this, "CaloDetDescrManager", "CaloDetDescrManager",
63 "SG Key for CaloDetDescrManager in the Condition Store"};

◆ m_hasBeenInitialized

bool BasicConstantGPUDataExporter::m_hasBeenInitialized
private

Definition at line 66 of file BasicConstantGPUDataExporter.h.

◆ m_keepCPUData

Gaudi::Property<bool> BasicConstantGPUDataExporter::m_keepCPUData {this, "KeepCPUData", true, "Keep CPU version of GPU data format"}
private

If true, do not delete the CPU version of the GPU-friendly data representation.

Defaults to false.

Definition at line 52 of file BasicConstantGPUDataExporter.h.

52{this, "KeepCPUData", true, "Keep CPU version of GPU data format"};

◆ m_measureTimes

Gaudi::Property<bool> CaloGPUTimed::m_measureTimes
protectedinherited

If true, times are recorded to the file given by m_timeFileName.

Defaults to false.

Definition at line 46 of file CaloGPUTimed.h.

◆ m_noiseCDOKey

SG::ReadCondHandleKey<CaloNoise> BasicConstantGPUDataExporter::m_noiseCDOKey {this, "CaloNoiseKey", "totalNoise", "SG Key of CaloNoise data object"}
private

Key of the CaloNoise Conditions data object.

Typical values are '"electronicNoise', 'pileupNoise', or '"totalNoise' (default)

Definition at line 57 of file BasicConstantGPUDataExporter.h.

57{this, "CaloNoiseKey", "totalNoise", "SG Key of CaloNoise data object"};

◆ m_timeFileName

Gaudi::Property<std::string> CaloGPUTimed::m_timeFileName
protectedinherited

File to which times should be saved.

Definition at line 50 of file CaloGPUTimed.h.

◆ m_timeMutex

std::shared_mutex CaloGPUTimed::m_timeMutex
mutableprotectedinherited

Mutex that is locked when recording times.

Definition at line 32 of file CaloGPUTimed.h.


The documentation for this class was generated from the following files: