CMS 3D CMS Logo

HeterogeneousHGCalHEFCellPositionsConditions.cc
Go to the documentation of this file.
3 
6  //HGCalPositions as defined in hgcal_conditions::positions
7  this->sizes_ = calculate_memory_bytes_(cpuPos);
8  this->chunk_ = allocate_memory_(this->sizes_);
11 }
12 
14  size_t chunk = std::accumulate(sz.begin(), sz.end(), 0); //total memory required in bytes
15  cudaCheck(cudaMallocHost(&this->posmap_.x, chunk));
16  return chunk;
17 }
18 
20  const std::vector<size_t>& sz, cpos::HGCalPositionsMapping* cpuPos) {
21  //store cumulative sum in bytes and convert it to sizes in units of C++ typesHEF, i.e., number if items to be transferred to GPU
22  std::vector<size_t> cumsum_sizes(sz.size() + 1, 0); //starting with zero
23  std::partial_sum(sz.begin(), sz.end(), cumsum_sizes.begin() + 1);
24  for (unsigned int i = 1; i < cumsum_sizes.size(); ++i) //start at second element (the first is zero)
25  {
26  size_t types_size = 0;
28  types_size = sizeof(float);
29  else if (cpos::types[i - 1] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
30  types_size = sizeof(int32_t);
31  else if (cpos::types[i - 1] == cpos::HeterogeneousHGCalPositionsType::Uint32_t)
32  types_size = sizeof(uint32_t);
33  else
34  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
35  << "Wrong HeterogeneousHGCalPositionsMapping type";
36  cumsum_sizes[i] /= types_size;
37  }
38 
39  for (unsigned int j = 0; j < sz.size(); ++j) {
40  //setting the pointers
41  if (j != 0) {
42  const unsigned int jm1 = j - 1;
43  const size_t shift = cumsum_sizes[j] - cumsum_sizes[jm1];
46  select_pointer_f_(&this->posmap_, j) = select_pointer_f_(&this->posmap_, jm1) + shift;
48  cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
49  select_pointer_i_(&this->posmap_, j) =
50  reinterpret_cast<int32_t*>(select_pointer_f_(&this->posmap_, jm1) + shift);
51  else if (cpos::types[jm1] == cpos::HeterogeneousHGCalPositionsType::Int32_t and
52  cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
53  select_pointer_i_(&this->posmap_, j) = select_pointer_i_(&this->posmap_, jm1) + shift;
54  else if (cpos::types[jm1] == cpos::HeterogeneousHGCalPositionsType::Int32_t and
55  cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Uint32_t)
56  select_pointer_u_(&this->posmap_, j) =
57  reinterpret_cast<uint32_t*>(select_pointer_i_(&this->posmap_, jm1) + shift);
58  else
59  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
60  << "Wrong HeterogeneousHGCalPositionsMapping type";
61  }
62 
63  //copying the pointers' content
64  if (j >=
65  this->number_position_arrays) //required due to the assymetry between cpos::HeterogeneousHGCalPositionsMapping and cpos::HGCalPositionsMapping
66  {
67  for (unsigned int i = cumsum_sizes[j]; i < cumsum_sizes[j + 1]; ++i) {
68  unsigned int index = i - cumsum_sizes[j];
70  select_pointer_f_(&this->posmap_, j)[index] =
72  } else if (cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Int32_t) {
73  select_pointer_i_(&this->posmap_, j)[index] =
75  } else if (cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Uint32_t) {
76  select_pointer_u_(&this->posmap_, j)[index] =
78  } else
79  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
80  << "Wrong HeterogeneousHGCalPositions type";
81  }
82  }
83  }
84 }
85 
87  const cpos::HGCalPositionsMapping* cpuPos) {
88  this->posmap_.waferSize = cpuPos->waferSize;
90  this->posmap_.firstLayer = cpuPos->firstLayer;
91  this->posmap_.lastLayer = cpuPos->lastLayer;
92  this->posmap_.waferMin = cpuPos->waferMin;
93  this->posmap_.waferMax = cpuPos->waferMax;
94  this->nelems_posmap_ = cpuPos->detid.size();
95 }
96 
99  size_t npointers = cpos::types.size();
100  std::vector<size_t> sizes(npointers);
101  for (unsigned int i = 0; i < npointers; ++i) {
102  const unsigned detid_index = 4;
103  const unsigned nlayers_index = 3;
105  sizes[i] = select_pointer_u_(cpuPos, detid_index)
106  .size(); //x and y position array will have the same size as the detid array
108  sizes[i] = select_pointer_i_(cpuPos, nlayers_index).size(); //z position's size is equal to the #layers
110  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
111  << "Wrong HeterogeneousHGCalPositions type (Float)";
112  else if (cpos::types[i] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
113  sizes[i] = select_pointer_i_(cpuPos, i - this->number_position_arrays).size();
114  else if (cpos::types[i] == cpos::HeterogeneousHGCalPositionsType::Uint32_t)
115  sizes[i] = select_pointer_u_(cpuPos, detid_index).size();
116  }
117 
118  std::vector<size_t> sizes_units(npointers);
119  for (unsigned int i = 0; i < npointers; ++i) {
121  sizes_units[i] = sizeof(float);
122  else if (cpos::types[i] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
123  sizes_units[i] = sizeof(int32_t);
124  else if (cpos::types[i] == cpos::HeterogeneousHGCalPositionsType::Uint32_t)
125  sizes_units[i] = sizeof(uint32_t);
126  }
127 
128  //element by element multiplication
129  this->sizes_.resize(npointers);
130  std::transform(sizes.begin(), sizes.end(), sizes_units.begin(), this->sizes_.begin(), std::multiplies<size_t>());
131  return this->sizes_;
132 }
133 
135  cudaCheck(cudaFreeHost(this->posmap_.x));
136 }
137 
138 //I could use template specializations
139 //try to use std::variant in the future to avoid similar functions with different return values
141  cpos::HeterogeneousHGCalPositionsMapping* cpuObject, const unsigned int& item) const {
142  switch (item) {
143  case 0:
144  return cpuObject->x;
145  case 1:
146  return cpuObject->y;
147  case 2:
148  return cpuObject->zLayer;
149  default:
150  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
151  << "select_pointer_f(heterogeneous): no item (typed " << item << ").";
152  return cpuObject->x;
153  }
154 }
155 
157  cpos::HGCalPositionsMapping* cpuObject, const unsigned int& item) {
158  switch (item) {
159  case 0:
160  return cpuObject->zLayer;
161  default:
162  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
163  << "select_pointer_f(non-heterogeneous): no item (typed " << item << ").";
164  return cpuObject->zLayer;
165  }
166 }
167 
169  cpos::HeterogeneousHGCalPositionsMapping* cpuObject, const unsigned int& item) const {
170  switch (item) {
171  case 3:
172  return cpuObject->nCellsLayer;
173  case 4:
174  return cpuObject->nCellsWaferUChunk;
175  case 5:
176  return cpuObject->nCellsHexagon;
177  default:
178  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
179  << "select_pointer_i(heterogeneous): no item (typed " << item << ").";
180  return cpuObject->nCellsHexagon;
181  }
182 }
183 
185  cpos::HGCalPositionsMapping* cpuObject, const unsigned int& item) {
186  switch (item) {
187  case 1:
188  return cpuObject->nCellsLayer;
189  case 2:
190  return cpuObject->nCellsWaferUChunk;
191  case 3:
192  return cpuObject->nCellsHexagon;
193  default:
194  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
195  << "select_pointer_i(non-heterogeneous): no item (typed " << item << ").";
196  return cpuObject->nCellsHexagon;
197  }
198 }
199 
201  cpos::HeterogeneousHGCalPositionsMapping* cpuObject, const unsigned int& item) const {
202  switch (item) {
203  case 6:
204  return cpuObject->detid;
205  default:
206  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
207  << "select_pointer_u(heterogeneous): no item (typed " << item << ").";
208  return cpuObject->detid;
209  }
210 }
211 
213  cpos::HGCalPositionsMapping* cpuObject, const unsigned int& item) {
214  switch (item) {
215  case 4:
216  return cpuObject->detid;
217  default:
218  throw cms::Exception("HeterogeneousHGCalHEFCellPositionsConditions")
219  << "select_pointer_u(non-heterogeneous): no item (typed " << item << ").";
220  return cpuObject->detid;
221  }
222 }
223 
226  // cms::cuda::ESProduct<T> essentially holds an array of GPUData objects,
227  // one per device. If the data have already been transferred to the
228  // current device (or the transfer has been queued), the helper just
229  // returns a reference to that GPUData object. Otherwise, i.e. data are
230  // not yet on the current device, the helper calls the lambda to do the
231  // necessary memory allocations and to queue the transfers.
232  auto const& data = gpuData_.dataForCurrentDeviceAsync(stream, [this](GPUData& data, cudaStream_t stream) {
233  // Allocate the payload object on pinned host memory.
235  // Allocate the payload array(s) on device memory.
236  cudaCheck(cudaMalloc(&(data.host->posmap.x), this->chunk_));
237  // Complete the host-side information on the payload
238  data.host->posmap.waferSize = this->posmap_.waferSize;
240  data.host->posmap.firstLayer = this->posmap_.firstLayer;
241  data.host->posmap.lastLayer = this->posmap_.lastLayer;
242  data.host->posmap.waferMax = this->posmap_.waferMax;
243  data.host->posmap.waferMin = this->posmap_.waferMin;
244  data.host->nelems_posmap = this->nelems_posmap_;
245 
246  //(set the pointers of the positions' mapping)
247  size_t sfloat = sizeof(float);
248  size_t sint32 = sizeof(int32_t);
249  for (unsigned int j = 0; j < this->sizes_.size() - 1; ++j) {
252  select_pointer_f_(&(data.host->posmap), j + 1) =
253  select_pointer_f_(&(data.host->posmap), j) + (this->sizes_[j] / sfloat);
255  cpos::types[j + 1] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
256  select_pointer_i_(&(data.host->posmap), j + 1) =
257  reinterpret_cast<int32_t*>(select_pointer_f_(&(data.host->posmap), j) + (this->sizes_[j] / sfloat));
258  else if (cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Int32_t and
259  cpos::types[j + 1] == cpos::HeterogeneousHGCalPositionsType::Int32_t)
260  select_pointer_i_(&(data.host->posmap), j + 1) =
261  select_pointer_i_(&(data.host->posmap), j) + (this->sizes_[j] / sint32);
262  else if (cpos::types[j] == cpos::HeterogeneousHGCalPositionsType::Int32_t and
263  cpos::types[j + 1] == cpos::HeterogeneousHGCalPositionsType::Uint32_t)
264  select_pointer_u_(&(data.host->posmap), j + 1) =
265  reinterpret_cast<uint32_t*>(select_pointer_i_(&(data.host->posmap), j) + (this->sizes_[j] / sint32));
266  }
267 
268  // Allocate the payload object on the device memory.
270 
271  // Transfer the payload, first the array(s) ...
272  //Important: The transfer does *not* start at posmap.x because the positions are not known in the CPU side!
273  size_t non_position_memory_size_to_transfer =
274  this->chunk_ - this->number_position_arrays * this->nelems_posmap_ *
275  sfloat; //size in bytes occupied by the non-position information
276  cudaCheck(cudaMemcpyAsync(data.host->posmap.zLayer,
277  this->posmap_.zLayer,
278  non_position_memory_size_to_transfer,
279  cudaMemcpyHostToDevice,
280  stream));
281 
282  // ... and then the payload object
283  cudaCheck(cudaMemcpyAsync(data.device,
284  data.host,
286  cudaMemcpyHostToDevice,
287  stream));
288 
289  //Fill x and y positions in the GPU
291  km.fill_positions(data.device);
292  }); //gpuData_.dataForCurrentDeviceAsync
293 
294  // Returns the payload object on the memory of the current device
295  return data.device;
296 }
297 
298 // Destructor frees all member pointers
300  if (host != nullptr) {
301  cudaCheck(cudaFree(host->posmap.x));
302  cudaCheck(cudaFreeHost(host));
303  }
304  cudaCheck(cudaFree(device));
305 }
positions::HeterogeneousHGCalPositionsMapping posmap
hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct * device
uint32_t *& select_pointer_u_(cpos::HeterogeneousHGCalPositionsMapping *, const unsigned int &) const
void fill_positions(const hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct *)
vecVecTString chunk(vecTString in, Int_t nchunk)
Definition: stringutil.cc:99
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
void transfer_data_to_heterogeneous_pointers_(const std::vector< size_t > &, cpos::HGCalPositionsMapping *)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
float *& select_pointer_f_(cpos::HeterogeneousHGCalPositionsMapping *, const unsigned int &) const
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
static unsigned int const shift
void transfer_data_to_heterogeneous_vars_(const cpos::HGCalPositionsMapping *)
#define cudaCheck(ARG,...)
Definition: cudaCheck.h:69
int32_t *& select_pointer_i_(cpos::HeterogeneousHGCalPositionsMapping *, const unsigned int &) const
std::vector< size_t > calculate_memory_bytes_(cpos::HGCalPositionsMapping *)
hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct const * getHeterogeneousConditionsESProductAsync(cudaStream_t stream) const
hgcal_conditions::HeterogeneousHEFCellPositionsConditionsESProduct * host
unsigned transform(const HcalDetId &id, unsigned transformCode)