ATLAS Offline Software
NeighArr.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 //
4 // Dear emacs, this is -*- c++ -*-
5 //
6 
7 #ifndef CALORECGPU_NEIGHARR_H
8 #define CALORECGPU_NEIGHARR_H
9 
10 #include "BaseDefinitions.h"
11 
12 #include <climits>
13 //For CHAR_BIT
14 
15 
16 namespace CaloRecGPU
17 {
18 
26  struct NeighOffset
27  {
28  using carrier = unsigned long long int;
30 
31  protected:
32 
33  constexpr static carrier s_numbers_to_keep = NumNeighOptions - 1;
34  //This is the number of cell offsets we actually need to keep.
35 
36  constexpr static int s_bits_per_offset = 5;
37  constexpr static int s_bits_per_last_offset = 6;
38  constexpr static int s_more_bits_begin = 9;
39  //We start giving an extra bit to the offsets from
40  //the 9th number (corresponding to prevSuperCalo)
41  //since corners3D can push some cells to have more than 32 neighbours.
42 
43 
44  constexpr static carrier s_offset_mask = 0x1FULL;
45  constexpr static carrier s_offset_mask_last = 0x3FULL;
46  constexpr static carrier s_offset_delta_pattern = 0x0208210842108421ULL;
47  //This has one set bit every five,
48  //except for the last three, that are one every six.
49 
50  constexpr static carrier s_last_bit_mask = 0x8000000000000000ULL;
51  //This last bit is not currently used,
52  //might be used as a flag if a use case comes up.
53 
55 
56  static_assert( s_more_bits_begin * s_bits_per_offset +
58  1 < sizeof(carrier) * CHAR_BIT, "All the offsets must fit within the carrier!" );
59 
60  public:
61 
62  constexpr operator carrier () const
63  {
64  return value;
65  }
66 
67  constexpr NeighOffset (const carrier v): value(v)
68  {
69  }
70 
71  constexpr NeighOffset & operator = (const carrier v)
72  {
73  value = v;
74  return (*this);
75  }
76 
77  constexpr int get_number(const int i) const
78  {
79  carrier ret = value /*& s_only_numbers_mask*/;
80  //Not necessary to mask since we mask the result anyway.
81 
82  if (i >= s_more_bits_begin)
83  {
84  ret = ret >> (s_bits_per_offset * s_more_bits_begin);
85  ret = ret >> (s_bits_per_last_offset * (i - s_more_bits_begin));
86  ret &= s_offset_mask_last;
87  }
88  else
89  {
90  ret = ret >> (s_bits_per_offset * i);
91  ret &= s_offset_mask;
92  }
93  return (uint32_t) ret;
94  }
95 
96  constexpr int get_start_cell (const int option) const
97  {
98  if (option == 0)
99  {
100  return 0;
101  }
102  /*else if (option < 0 || option >= NumNeighOptions)
103  {
104  return -1;
105  }*/
106  else
107  {
108  return get_number(option - 1);
109  }
110  }
111 
115  constexpr int get_end_cell (const int option) const
116  {
117  /*
118  if (option < 0 || option >= NumNeighOptions)
119  {
120  return -1;
121  }
122  else
123  {*/
124  return get_number(option);
125  /*}*/
126  }
127 
128  constexpr int get_total_number() const
129  {
130  return get_number(NumNeighOptions - 1);
131  }
132 
133  constexpr int get_num_cells (const int option) const
134  {
135  return this->get_end_cell(option) - this->get_start_cell(option);
136  }
137 
144  static constexpr carrier offset_delta(const int i)
145  {
146  carrier mask = 0xFFFFFFFFFFFFFFFFULL;
147  if (i >= s_more_bits_begin)
148  {
149  // coverity[overflow_const]
151  // coverity[overflow_const]
153  }
154  else
155  {
156  // coverity[overflow_const]
157  mask = mask << (s_bits_per_offset * i);
158  }
159 
160  //Suppressing coverity errors here since
161  //adding zeros to the beginning of the mask
162  //and ignoring the higher level bits
163  //is precisely the desired behaviour.
164 
166  return s_offset_delta_pattern & mask;
167  }
168  };
169 
170  struct NeighArr
171  {
174  //In most use cases so far,
175  //we have to take neighbour options
176  //into account, which makes this
177  //much more performant
178  //than the alternative...
179 
180 
181  constexpr int get_total_number_of_neighbours(const int cell) const
182  {
183  const NeighOffset neigh_off = offsets[cell];
184  return neigh_off.get_total_number();
185  }
186 
187  constexpr int get_neighbour(const int cell, const int neigh_number) const
188  {
189  return cells[cell][neigh_number];
190  }
191 
192  constexpr void set_neighbour(const int cell, const int neigh_number, const int neigh_v)
193  {
194  cells[cell][neigh_number] = neigh_v;
195  }
196 
202  constexpr int get_neighbours(const unsigned int neigh_options, const int cell, int * neigh_arr) const
203  {
204  const NeighOffset neigh_off = offsets[cell];
205 
206  int neigh_arr_len = 0;
207  int limit = 0;
208  int neigh = 0;
209 
210  for (int i = 0; i < NumNeighOptions; ++i)
211  {
212  limit = neigh_off.get_end_cell(i);
213  if ( neigh_options & (1U << i) )
214  {
215  for (; neigh < limit; ++neigh)
216  {
217  neigh_arr[neigh_arr_len] = cells[cell][neigh];
218  ++neigh_arr_len;
219  }
220  }
221  neigh = limit;
222  }
223  return neigh_arr_len;
224  }
225 
226  constexpr int get_number_of_neighbours(const unsigned int neigh_options, const int cell) const
227  {
228  const NeighOffset neigh_off = offsets[cell];
229  int ret = 0;
230  for (int i = 0; i < NumNeighOptions; ++i)
231  {
232  if ( neigh_options & (1U << i) )
233  {
234  ret += neigh_off.get_num_cells(i);
235  }
236  }
237  return ret;
238  }
239  };
240 
242  {
245 
246  constexpr int get_option(const int pair) const
247  {
248  //Number of pairs at the end of each neighbour option.
249  //Hardcoded for performance reasons.
250  //Since (CPU) geometry description
251  //might end up seeing some changes
252  //in the not so distant future
253  //to harmonize with our data structures,
254  //we could consider some sort of code generation...
255  constexpr int s_pairs_end[NumNeighOptions] = {184128, 368256, 551424, 733312, 1483056, 1960492, 2437928, 2438824, 2439720, 2500008, 2530412, 2560816};
256  for (int i = 0; i < NumNeighOptions; ++i)
257  {
258  if (pair < s_pairs_end[i])
259  {
260  return i;
261  }
262  }
263  return -1;
264  }
265 
266  constexpr bool is_valid(const int pair, const unsigned int options, const bool limited_PS, const bool limited_HECIW_FCal) const
267  {
268  const int opt_idx = get_option(pair);
269  if (opt_idx < 0 || !(options & (1U << opt_idx)) )
270  {
271  return false;
272  }
273 
274  //nextInSampl, the neighbour option used
275  //for the PS and HECIW_FCal limited cells.
276  constexpr int limited_option = 6;
277 
278  //Number of pairs within each neighbour option
279  //above which the neighbours contain
280  //PS and HECIW_FCal limited cells.
281  //Hardcoded for performance reasons.
282  //Since (CPU) geometry description
283  //might end up seeing some changes
284  //in the not so distant future
285  //to harmonize with our data structures,
286  //we could consider some sort of code generation...
287  constexpr int s_PS_start[NumNeighOptions] = {173888, 358016, 541056, 723584, 1432784, 1954480, 2364410, 2438696, 2439336, 2500008, 2529160, 2559756};
288  constexpr int s_HECIW_FCal_start[NumNeighOptions] = {183232, 367360, 550272, 732672, 1469392, 1954480, 2435450, 2438824, 2439720, 2500008, 2529160, 2559756};
289 
290  if (limited_PS && opt_idx != limited_option)
291  {
292  if (pair >= s_PS_start[opt_idx] && pair < s_HECIW_FCal_start[opt_idx])
293  {
294  return false;
295  }
296  }
297 
298  if (limited_HECIW_FCal && opt_idx != limited_option)
299  {
300  if (pair >= s_HECIW_FCal_start[opt_idx])
301  {
302  return false;
303  }
304  }
305 
306  return true;
307 
308  }
309 
310  };
311 
312 }
313 #endif //CALORECGPU_NEIGHARR_H
CaloRecGPU::NeighOffset::s_only_numbers_mask
constexpr static carrier s_only_numbers_mask
Definition: NeighArr.h:54
CaloRecGPU::NeighPairsArr::is_valid
constexpr bool is_valid(const int pair, const unsigned int options, const bool limited_PS, const bool limited_HECIW_FCal) const
Definition: NeighArr.h:266
CaloRecGPU::NeighOffset::value
carrier value
Definition: NeighArr.h:29
CaloRecGPU::NExactPairs
constexpr int NExactPairs
Definition: BaseDefinitions.h:37
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
CaloRecGPU::NeighOffset::offset_delta
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
CaloRecGPU::NeighOffset::s_more_bits_begin
constexpr static int s_more_bits_begin
Definition: NeighArr.h:38
CaloRecGPU::NeighOffset::operator=
constexpr NeighOffset & operator=(const carrier v)
Definition: NeighArr.h:71
CaloRecGPU::NeighOffset::s_bits_per_last_offset
constexpr static int s_bits_per_last_offset
Definition: NeighArr.h:37
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
CaloRecGPU::NeighOffset::get_end_cell
constexpr int get_end_cell(const int option) const
To clarify, this cell no longer corresponds to the option, so it's one past the end (like the end ite...
Definition: NeighArr.h:115
CaloRecGPU::NeighPairsArr::cell_A
int cell_A[NExactPairs]
Definition: NeighArr.h:243
CaloRecGPU::NeighArr::offsets
NeighOffset::carrier offsets[NCaloCells]
Definition: NeighArr.h:172
CaloRecGPU::NeighPairsArr::get_option
constexpr int get_option(const int pair) const
Definition: NeighArr.h:246
CaloRecGPU::NeighOffset::get_start_cell
constexpr int get_start_cell(const int option) const
Definition: NeighArr.h:96
CaloRecGPU::NeighArr::get_neighbour
constexpr int get_neighbour(const int cell, const int neigh_number) const
Definition: NeighArr.h:187
python.utils.AtlRunQueryLookup.mask
string mask
Definition: AtlRunQueryLookup.py:460
CaloRecGPU::NeighOffset
Definition: NeighArr.h:27
CaloRecGPU::NeighArr::get_neighbours
constexpr int get_neighbours(const unsigned int neigh_options, const int cell, int *neigh_arr) const
Places the neighbours according to the option(s) in neigh_options in the array and returns the number...
Definition: NeighArr.h:202
CaloRecGPU::NeighArr
Definition: NeighArr.h:171
CaloRecGPU::NeighOffset::s_offset_delta_pattern
constexpr static carrier s_offset_delta_pattern
Definition: NeighArr.h:46
CaloRecGPU::NeighOffset::s_bits_per_offset
constexpr static int s_bits_per_offset
Definition: NeighArr.h:36
CaloRecGPU::NeighOffset::get_number
constexpr int get_number(const int i) const
Definition: NeighArr.h:77
CaloRecGPU::NeighOffset::NeighOffset
constexpr NeighOffset(const carrier v)
Definition: NeighArr.h:67
CaloRecGPU::NeighOffset::carrier
unsigned long long int carrier
Definition: NeighArr.h:28
CaloRecGPU::NeighArr::set_neighbour
constexpr void set_neighbour(const int cell, const int neigh_number, const int neigh_v)
Definition: NeighArr.h:192
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloRecGPU::NeighArr::get_total_number_of_neighbours
constexpr int get_total_number_of_neighbours(const int cell) const
Definition: NeighArr.h:181
CaloRecGPU::NeighOffset::s_offset_mask
constexpr static carrier s_offset_mask
Definition: NeighArr.h:44
CaloRecGPU::NeighOffset::get_total_number
constexpr int get_total_number() const
Definition: NeighArr.h:128
python.AtlRunQueryLib.options
options
Definition: AtlRunQueryLib.py:379
CaloRecGPU::NCaloCells
constexpr int NCaloCells
Definition: BaseDefinitions.h:13
CaloRecGPU::NMaxNeighbours
constexpr int NMaxNeighbours
Definition: BaseDefinitions.h:12
CaloRecGPU::NeighPairsArr
Definition: NeighArr.h:242
CaloRecGPU::NeighPairsArr::cell_B
int cell_B[NExactPairs]
Definition: NeighArr.h:244
python.PyAthena.v
v
Definition: PyAthena.py:154
CaloRecGPU::NeighArr::cells
int cells[NCaloCells][NMaxNeighbours]
Definition: NeighArr.h:173
CaloRecGPU::NumNeighOptions
constexpr int NumNeighOptions
Definition: BaseDefinitions.h:47
CaloRecGPU::NeighOffset::s_offset_mask_last
constexpr static carrier s_offset_mask_last
Definition: NeighArr.h:45
CaloRecGPU::NeighOffset::s_last_bit_mask
constexpr static carrier s_last_bit_mask
Definition: NeighArr.h:50
CaloRecGPU::NeighOffset::s_numbers_to_keep
constexpr static carrier s_numbers_to_keep
Definition: NeighArr.h:33
CaloRecGPU::NeighArr::get_number_of_neighbours
constexpr int get_number_of_neighbours(const unsigned int neigh_options, const int cell) const
Definition: NeighArr.h:226
CaloRecGPU
Definition: BaseDefinitions.h:11
updateCoolNtuple.limit
int limit
Definition: updateCoolNtuple.py:45
CaloRecGPU::NeighOffset::get_num_cells
constexpr int get_num_cells(const int option) const
Definition: NeighArr.h:133
BaseDefinitions.h