CMS 3D CMS Logo

HeterogeneousHGCalEEConditions.cc
Go to the documentation of this file.
2 
3 namespace {
4  double*& select_pointer_d(cp::HeterogeneousHGCalEEParameters* cpuObject, const unsigned& item) {
5  switch (item) {
6  case 0:
7  return cpuObject->cellFineX_;
8  case 1:
9  return cpuObject->cellFineY_;
10  case 2:
11  return cpuObject->cellCoarseX_;
12  case 3:
13  return cpuObject->cellCoarseY_;
14  default:
15  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper") << "select_pointer_d(heterogeneous): no item.";
16  return cpuObject->cellCoarseY_;
17  }
18  }
19 
20  const std::vector<double>& select_pointer_d(const HGCalParameters* cpuObject, const unsigned& item) {
21  switch (item) {
22  case 0:
23  return cpuObject->cellFineX_;
24  case 1:
25  return cpuObject->cellFineY_;
26  case 2:
27  return cpuObject->cellCoarseX_;
28  case 3:
29  return cpuObject->cellCoarseY_;
30  default:
31  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper")
32  << "select_pointer_d(non-heterogeneous): no item.";
33  return cpuObject->cellCoarseY_;
34  }
35  }
36 
37  int32_t*& select_pointer_i(cp::HeterogeneousHGCalEEParameters* cpuObject, const unsigned& item) {
38  switch (item) {
39  case 4:
40  return cpuObject->waferTypeL_;
41  default:
42  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper") << "select_pointer_i(heterogeneous): no item.";
43  return cpuObject->waferTypeL_;
44  }
45  }
46 
47  const std::vector<int32_t>& select_pointer_i(const HGCalParameters* cpuObject, const unsigned& item) {
48  switch (item) {
49  case 4:
50  return cpuObject->waferTypeL_;
51  default:
52  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper")
53  << "select_pointer_i(non-heterogeneous): no item.";
54  return cpuObject->waferTypeL_;
55  }
56  }
57 } // namespace
58 
60  calculate_memory_bytes(cpuHGCalParameters);
61 
62  chunk_ = std::accumulate(this->sizes_.begin(), this->sizes_.end(), 0); //total memory required in bytes
63  cudaCheck(cudaMallocHost(&this->params_.cellFineX_, chunk_));
64 
65  //store cumulative sum in bytes and convert it to sizes in units of C++ typesEE, i.e., number if items to be transferred to GPU
66  std::vector<size_t> cumsum_sizes(this->sizes_.size() + 1, 0); //starting with zero
67  std::partial_sum(this->sizes_.begin(), this->sizes_.end(), cumsum_sizes.begin() + 1);
68  for (unsigned i(1); i < cumsum_sizes.size(); ++i) //start at second element (the first is zero)
69  {
70  unsigned typesEEsize(0);
72  typesEEsize = sizeof(double);
73  else if (cp::typesEE[i - 1] == cp::HeterogeneousHGCalEEParametersType::Int32_t)
74  typesEEsize = sizeof(int32_t);
75  else
76  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper") << "Wrong HeterogeneousHGCalParameters type";
77  cumsum_sizes[i] /= typesEEsize;
78  }
79 
80  for (unsigned j(0); j < this->sizes_.size(); ++j) {
81  //setting the pointers
82  if (j != 0) {
83  const unsigned jm1(j - 1);
86  ::select_pointer_d(&this->params_, j) = ::select_pointer_d(&this->params_, jm1) + this->sizes_[jm1];
88  cp::typesEE[j] == cp::HeterogeneousHGCalEEParametersType::Int32_t)
89  ::select_pointer_i(&this->params_, j) =
90  reinterpret_cast<int32_t*>(::select_pointer_d(&this->params_, jm1) + this->sizes_[jm1]);
91  }
92 
93  //copying the pointers' content
94  for (unsigned i(cumsum_sizes[j]); i < cumsum_sizes[j + 1]; ++i) {
95  unsigned index(i - cumsum_sizes[j]);
97  ::select_pointer_d(&this->params_, j)[index] = ::select_pointer_d(cpuHGCalParameters, j)[index];
98  } else if (cp::typesEE[j] == cp::HeterogeneousHGCalEEParametersType::Int32_t)
99  ::select_pointer_i(&this->params_, j)[index] = ::select_pointer_i(cpuHGCalParameters, j)[index];
100  else
101  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper") << "Wrong HeterogeneousHGCalParameters type";
102  }
103  }
104 }
105 
107  size_t npointers = hgcal_conditions::parameters::typesEE.size();
108  std::vector<size_t> sizes(npointers);
109  for (unsigned i(0); i < npointers; ++i) {
111  sizes[i] = ::select_pointer_d(cpuHGCalParameters, i).size();
112  else
113  sizes[i] = ::select_pointer_i(cpuHGCalParameters, i).size();
114  }
115 
116  std::vector<size_t> sizes_units(npointers);
117  for (unsigned i(0); i < npointers; ++i) {
119  sizes_units[i] = sizeof(double);
120  else if (cp::typesEE[i] == cp::HeterogeneousHGCalEEParametersType::Int32_t)
121  sizes_units[i] = sizeof(int32_t);
122  }
123 
124  //element by element multiplication
125  this->sizes_.resize(npointers);
126  std::transform(sizes.begin(), sizes.end(), sizes_units.begin(), this->sizes_.begin(), std::multiplies<size_t>());
127 }
128 
130  cudaCheck(cudaFreeHost(this->params_.cellFineX_));
131 }
132 
133 //I could use template specializations
134 //try to use std::variant in the future to avoid similar functions with different return values
135 
138  // cms::cuda::ESProduct<T> essentially holds an array of GPUData objects,
139  // one per device. If the data have already been transferred to the
140  // current device (or the transfer has been queued), the helper just
141  // returns a reference to that GPUData object. Otherwise, i.e. data are
142  // not yet on the current device, the helper calls the lambda to do the
143  // necessary memory allocations and to queue the transfers.
144  auto const& data = gpuData_.dataForCurrentDeviceAsync(stream, [this](GPUData& data, cudaStream_t stream) {
145  // Allocate the payload object on pinned host memory.
147  // Allocate the payload array(s) on device memory.
148  cudaCheck(cudaMalloc(&(data.host->params.cellFineX_), chunk_));
149 
150  // Allocate the payload object on the device memory.
152  // Transfer the payload, first the array(s) ...
153  cudaCheck(cudaMemcpyAsync(
154  data.host->params.cellFineX_, this->params_.cellFineX_, chunk_, cudaMemcpyHostToDevice, stream));
155 
156  for (unsigned j(0); j < this->sizes_.size() - 1; ++j) {
159  ::select_pointer_d(&(data.host->params), j + 1) = ::select_pointer_d(&(data.host->params), j) + this->sizes_[j];
161  cp::typesEE[j + 1] == cp::HeterogeneousHGCalEEParametersType::Int32_t)
162  ::select_pointer_i(&(data.host->params), j + 1) =
163  reinterpret_cast<int32_t*>(::select_pointer_d(&(data.host->params), j) + this->sizes_[j]);
164  else
165  throw cms::Exception("HeterogeneousHGCalEEConditionsWrapper")
166  << "compare this functions' logic with hgcal_conditions::parameters::typesEE";
167  }
168 
169  // ... and then the payload object
170  cudaCheck(cudaMemcpyAsync(data.device,
171  data.host,
173  cudaMemcpyHostToDevice,
174  stream));
175  }); //gpuData_.dataForCurrentDeviceAsync
176 
177  // Returns the payload object on the memory of the current device
178  return data.device;
179 }
180 
181 // Destructor frees all member pointers
183  if (host != nullptr) {
184  cudaCheck(cudaFree(host->params.cellFineX_));
185  cudaCheck(cudaFreeHost(host));
186  }
187  cudaCheck(cudaFree(device));
188 }
hgcal_conditions::HeterogeneousEEConditionsESProduct * host
parameters::HeterogeneousHGCalEEParameters params
std::vector< double > cellFineY_
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
std::vector< double > cellCoarseX_
hgcal_conditions::HeterogeneousEEConditionsESProduct const * getHeterogeneousConditionsESProductAsync(cudaStream_t stream) const
const std::array< HeterogeneousHGCalEEParametersType, 5 > typesEE
Definition: HGCConditions.h:91
cp::HeterogeneousHGCalEEParameters params_
std::vector< double > cellFineX_
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
#define cudaCheck(ARG,...)
Definition: cudaCheck.h:69
std::vector< double > cellCoarseY_
std::vector< int > waferTypeL_
hgcal_conditions::HeterogeneousEEConditionsESProduct * device
unsigned transform(const HcalDetId &id, unsigned transformCode)