CMS 3D CMS Logo

SiPixelRecHitFromCUDA.cc
Go to the documentation of this file.
1 #include <cuda_runtime.h>
2 
3 #include <fmt/printf.h>
4 
26 
27 template <typename TrackerTraits>
28 class SiPixelRecHitFromCUDAT : public edm::stream::EDProducer<edm::ExternalWork> {
29 public:
30  explicit SiPixelRecHitFromCUDAT(const edm::ParameterSet& iConfig);
31  ~SiPixelRecHitFromCUDAT() override = default;
32 
33  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
34 
37 
38 private:
39  void acquire(edm::Event const& iEvent,
40  edm::EventSetup const& iSetup,
41  edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
42  void produce(edm::Event& iEvent, edm::EventSetup const& iSetup) override;
43 
49 
50  uint32_t nHits_;
53 };
54 
55 template <typename TrackerTraits>
57  : geomToken_(esConsumes()),
58  hitsToken_(consumes<cms::cuda::Product<HitsOnDevice>>(iConfig.getParameter<edm::InputTag>("pixelRecHitSrc"))),
59  clusterToken_(consumes<SiPixelClusterCollectionNew>(iConfig.getParameter<edm::InputTag>("src"))),
60  rechitsPutToken_(produces<SiPixelRecHitCollection>()),
61  hostPutToken_(produces<HMSstorage>()) {}
62 
63 template <typename TrackerTraits>
66  desc.add<edm::InputTag>("pixelRecHitSrc", edm::InputTag("siPixelRecHitsPreSplittingCUDA"));
67  desc.add<edm::InputTag>("src", edm::InputTag("siPixelClustersPreSplitting"));
68 
69  descriptions.addWithDefaultLabel(desc);
70 }
71 
72 template <typename TrackerTraits>
74  edm::EventSetup const& iSetup,
75  edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
76  cms::cuda::Product<HitsOnDevice> const& inputDataWrapped = iEvent.get(hitsToken_);
77 
78  cms::cuda::ScopedContextAcquire ctx{inputDataWrapped, std::move(waitingTaskHolder)};
79 
80  auto const& inputData = ctx.get(inputDataWrapped);
81 
82  nHits_ = inputData.nHits();
83  LogDebug("SiPixelRecHitFromCUDA") << "converting " << nHits_ << " Hits";
84 
85  if (0 == nHits_)
86  return;
87  store32_ = inputData.localCoordToHostAsync(ctx.stream());
88 
89  hitsModuleStart_ = inputData.hitsModuleStartToHostAsync(ctx.stream());
90 }
91 
92 template <typename TrackerTraits>
94  // allocate a buffer for the indices of the clusters
96  auto hmsp = std::make_unique<uint32_t[]>(nMaxModules + 1);
97 
99  output.reserve(nMaxModules, nHits_);
100 
101  if (0 == nHits_) {
102  iEvent.emplace(rechitsPutToken_, std::move(output));
103  iEvent.emplace(hostPutToken_, std::move(hmsp));
104  return;
105  }
106  output.reserve(nMaxModules, nHits_);
107 
108  std::copy(hitsModuleStart_.get(), hitsModuleStart_.get() + nMaxModules + 1, hmsp.get());
109  // wrap the buffer in a HostProduct, and move it to the Event, without reallocating the buffer or affecting hitsModuleStart
110  iEvent.emplace(hostPutToken_, std::move(hmsp));
111 
112  auto xl = store32_.get();
113  auto yl = xl + nHits_;
114  auto xe = yl + nHits_;
115  auto ye = xe + nHits_;
116 
117  const TrackerGeometry* geom = &es.getData(geomToken_);
118 
119  edm::Handle<SiPixelClusterCollectionNew> hclusters = iEvent.getHandle(clusterToken_);
120  auto const& input = *hclusters;
121 
122  constexpr uint32_t maxHitsInModule = gpuClustering::maxHitsInModule();
123 
124  int numberOfDetUnits = 0;
125  int numberOfClusters = 0;
126  for (auto const& dsv : input) {
127  numberOfDetUnits++;
128  unsigned int detid = dsv.detId();
129  DetId detIdObject(detid);
130  const GeomDetUnit* genericDet = geom->idToDetUnit(detIdObject);
131  auto gind = genericDet->index();
132  const PixelGeomDetUnit* pixDet = dynamic_cast<const PixelGeomDetUnit*>(genericDet);
133  assert(pixDet);
134  SiPixelRecHitCollection::FastFiller recHitsOnDetUnit(output, detid);
135  auto fc = hitsModuleStart_[gind];
136  auto lc = hitsModuleStart_[gind + 1];
137  auto nhits = lc - fc;
138 
139  assert(lc > fc);
140  LogDebug("SiPixelRecHitFromCUDA") << "in det " << gind << ": conv " << nhits << " hits from " << dsv.size()
141  << " legacy clusters" << ' ' << fc << ',' << lc << "\n";
142  if (nhits > maxHitsInModule)
143  edm::LogWarning("SiPixelRecHitFromCUDA") << fmt::sprintf(
144  "Too many clusters %d in module %d. Only the first %d hits will be converted", nhits, gind, maxHitsInModule);
146 
147  LogDebug("SiPixelRecHitFromCUDA") << "in det " << gind << "conv " << nhits << " hits from " << dsv.size()
148  << " legacy clusters" << ' ' << lc << ',' << fc;
149 
150  if (0 == nhits)
151  continue;
152  auto jnd = [&](int k) { return fc + k; };
153  assert(nhits <= dsv.size());
154  if (nhits != dsv.size()) {
155  edm::LogWarning("GPUHits2CPU") << "nhits!= nclus " << nhits << ' ' << dsv.size();
156  }
157  for (auto const& clust : dsv) {
158  assert(clust.originalId() >= 0);
159  assert(clust.originalId() < dsv.size());
160  if (clust.originalId() >= nhits)
161  continue;
162  auto ij = jnd(clust.originalId());
163  LocalPoint lp(xl[ij], yl[ij]);
164  LocalError le(xe[ij], 0, ye[ij]);
166 
167  numberOfClusters++;
168 
169  /* cpu version.... (for reference)
170  std::tuple<LocalPoint, LocalError, SiPixelRecHitQuality::QualWordType> tuple = cpe_->getParameters( clust, *genericDet );
171  LocalPoint lp( std::get<0>(tuple) );
172  LocalError le( std::get<1>(tuple) );
173  SiPixelRecHitQuality::QualWordType rqw( std::get<2>(tuple) );
174  */
175 
176  // Create a persistent edm::Ref to the cluster
178  // Make a RecHit and add it to the DetSet
179  recHitsOnDetUnit.emplace_back(lp, le, rqw, *genericDet, cluster);
180  // =============================
181 
182  LogDebug("SiPixelRecHitFromCUDA") << "cluster " << numberOfClusters << " at " << lp << ' ' << le;
183 
184  } // <-- End loop on Clusters
185 
186  // LogDebug("SiPixelRecHitGPU")
187  LogDebug("SiPixelRecHitFromCUDA") << "found " << recHitsOnDetUnit.size() << " RecHits on " << detid;
188 
189  } // <-- End loop on DetUnits
190 
191  LogDebug("SiPixelRecHitFromCUDA") << "found " << numberOfDetUnits << " dets, " << numberOfClusters << " clusters";
192 
193  iEvent.emplace(rechitsPutToken_, std::move(output));
194 }
195 
198 
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::Ref< typename HandleT::element_type, typename HandleT::element_type::value_type::value_type > makeRefTo(const HandleT &iHandle, typename HandleT::element_type::value_type::const_iterator itIter)
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
constexpr int nMaxModules
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
int index() const
Definition: GeomDet.h:83
const edm::EDPutTokenT< HMSstorage > hostPutToken_
constexpr uint32_t maxHitsInModule()
const edm::EDGetTokenT< cms::cuda::Product< HitsOnDevice > > hitsToken_
assert(be >=bs)
constexpr uint16_t numberOfModules
static std::string const input
Definition: EdmProvDump.cc:50
const edm::EDPutTokenT< SiPixelRecHitCollection > rechitsPutToken_
const edm::EDGetTokenT< SiPixelClusterCollectionNew > clusterToken_
cms::cuda::host::unique_ptr< uint32_t[]> hitsModuleStart_
SiPixelRecHitFromCUDAT(const edm::ParameterSet &iConfig)
int iEvent
Definition: GenABIO.cc:224
void acquire(edm::Event const &iEvent, edm::EventSetup const &iSetup, edm::WaitingTaskWithArenaHolder waitingTaskHolder) override
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
cms::cuda::host::unique_ptr< float[]> store32_
Namespace of DDCMS conversion namespace.
~SiPixelRecHitFromCUDAT() override=default
Definition: DetId.h:17
void produce(edm::Event &iEvent, edm::EventSetup const &iSetup) override
Pixel cluster – collection of neighboring pixels above threshold.
HLT enums.
void emplace_back(Args &&... args)
std::unique_ptr< T, impl::HostDeleter > unique_ptr
Log< level::Warning, false > LogWarning
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)