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