Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-03-29 07:47:34

0001 #include <cuda_runtime.h>
0002 
0003 #include "CUDADataFormats/Common/interface/Product.h"
0004 #include "DataFormats/Common/interface/Handle.h"
0005 #include "FWCore/Framework/interface/ESHandle.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/EventSetup.h"
0008 #include "FWCore/Framework/interface/MakerMacros.h"
0009 #include "FWCore/Framework/interface/global/EDProducer.h"
0010 #include "FWCore/Framework/interface/ConsumesCollector.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0014 #include "FWCore/Utilities/interface/InputTag.h"
0015 #include "FWCore/PluginManager/interface/ModuleDef.h"
0016 #include "FWCore/Utilities/interface/EDGetToken.h"
0017 #include "FWCore/Utilities/interface/RunningAverage.h"
0018 #include "HeterogeneousCore/CUDACore/interface/ScopedContext.h"
0019 
0020 #include "gpuVertexFinder.h"
0021 
0022 #undef PIXVERTEX_DEBUG_PRODUCE
0023 
0024 class PixelVertexProducerCUDA : public edm::global::EDProducer<> {
0025 public:
0026   explicit PixelVertexProducerCUDA(const edm::ParameterSet& iConfig);
0027   ~PixelVertexProducerCUDA() override = default;
0028 
0029   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0030 
0031 private:
0032   void produceOnGPU(edm::StreamID streamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const;
0033   void produceOnCPU(edm::StreamID streamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const;
0034   void produce(edm::StreamID streamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const override;
0035 
0036   bool onGPU_;
0037 
0038   edm::EDGetTokenT<cms::cuda::Product<PixelTrackHeterogeneous>> tokenGPUTrack_;
0039   edm::EDPutTokenT<ZVertexCUDAProduct> tokenGPUVertex_;
0040   edm::EDGetTokenT<PixelTrackHeterogeneous> tokenCPUTrack_;
0041   edm::EDPutTokenT<ZVertexHeterogeneous> tokenCPUVertex_;
0042 
0043   const gpuVertexFinder::Producer gpuAlgo_;
0044 
0045   // Tracking cuts before sending tracks to vertex algo
0046   const float ptMin_;
0047   const float ptMax_;
0048 };
0049 
0050 PixelVertexProducerCUDA::PixelVertexProducerCUDA(const edm::ParameterSet& conf)
0051     : onGPU_(conf.getParameter<bool>("onGPU")),
0052       gpuAlgo_(conf.getParameter<bool>("oneKernel"),
0053                conf.getParameter<bool>("useDensity"),
0054                conf.getParameter<bool>("useDBSCAN"),
0055                conf.getParameter<bool>("useIterative"),
0056                conf.getParameter<int>("minT"),
0057                conf.getParameter<double>("eps"),
0058                conf.getParameter<double>("errmax"),
0059                conf.getParameter<double>("chi2max")),
0060       ptMin_(conf.getParameter<double>("PtMin")),  // 0.5 GeV
0061       ptMax_(conf.getParameter<double>("PtMax"))   // 75. GeV
0062 {
0063   if (onGPU_) {
0064     tokenGPUTrack_ =
0065         consumes<cms::cuda::Product<PixelTrackHeterogeneous>>(conf.getParameter<edm::InputTag>("pixelTrackSrc"));
0066     tokenGPUVertex_ = produces<ZVertexCUDAProduct>();
0067   } else {
0068     tokenCPUTrack_ = consumes<PixelTrackHeterogeneous>(conf.getParameter<edm::InputTag>("pixelTrackSrc"));
0069     tokenCPUVertex_ = produces<ZVertexHeterogeneous>();
0070   }
0071 }
0072 
0073 void PixelVertexProducerCUDA::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0074   edm::ParameterSetDescription desc;
0075 
0076   // Only one of these three algos can be used at once.
0077   // Maybe this should become a Plugin Factory
0078   desc.add<bool>("onGPU", true);
0079   desc.add<bool>("oneKernel", true);
0080   desc.add<bool>("useDensity", true);
0081   desc.add<bool>("useDBSCAN", false);
0082   desc.add<bool>("useIterative", false);
0083 
0084   desc.add<int>("minT", 2);          // min number of neighbours to be "core"
0085   desc.add<double>("eps", 0.07);     // max absolute distance to cluster
0086   desc.add<double>("errmax", 0.01);  // max error to be "seed"
0087   desc.add<double>("chi2max", 9.);   // max normalized distance to cluster
0088 
0089   desc.add<double>("PtMin", 0.5);
0090   desc.add<double>("PtMax", 75.);
0091   desc.add<edm::InputTag>("pixelTrackSrc", edm::InputTag("pixelTracksCUDA"));
0092 
0093   auto label = "pixelVerticesCUDA";
0094   descriptions.add(label, desc);
0095 }
0096 
0097 void PixelVertexProducerCUDA::produceOnGPU(edm::StreamID streamID,
0098                                            edm::Event& iEvent,
0099                                            const edm::EventSetup& iSetup) const {
0100   edm::Handle<cms::cuda::Product<PixelTrackHeterogeneous>> hTracks;
0101   iEvent.getByToken(tokenGPUTrack_, hTracks);
0102 
0103   cms::cuda::ScopedContextProduce ctx{*hTracks};
0104   auto const* tracks = ctx.get(*hTracks).get();
0105 
0106   assert(tracks);
0107 
0108   ctx.emplace(iEvent, tokenGPUVertex_, gpuAlgo_.makeAsync(ctx.stream(), tracks, ptMin_, ptMax_));
0109 }
0110 
0111 void PixelVertexProducerCUDA::produceOnCPU(edm::StreamID streamID,
0112                                            edm::Event& iEvent,
0113                                            const edm::EventSetup& iSetup) const {
0114   auto const* tracks = iEvent.get(tokenCPUTrack_).get();
0115   assert(tracks);
0116 
0117 #ifdef PIXVERTEX_DEBUG_PRODUCE
0118   auto const& tsoa = *tracks;
0119   auto maxTracks = tsoa.stride();
0120   std::cout << "size of SoA " << sizeof(tsoa) << " stride " << maxTracks << std::endl;
0121 
0122   int32_t nt = 0;
0123   for (int32_t it = 0; it < maxTracks; ++it) {
0124     auto nHits = tsoa.nHits(it);
0125     assert(nHits == int(tsoa.hitIndices.size(it)));
0126     if (nHits == 0)
0127       break;  // this is a guard: maybe we need to move to nTracks...
0128     nt++;
0129   }
0130   std::cout << "found " << nt << " tracks in cpu SoA for Vertexing at " << tracks << std::endl;
0131 #endif  // PIXVERTEX_DEBUG_PRODUCE
0132 
0133   iEvent.emplace(tokenCPUVertex_, gpuAlgo_.make(tracks, ptMin_, ptMax_));
0134 }
0135 
0136 void PixelVertexProducerCUDA::produce(edm::StreamID streamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0137   if (onGPU_) {
0138     produceOnGPU(streamID, iEvent, iSetup);
0139   } else {
0140     produceOnCPU(streamID, iEvent, iSetup);
0141   }
0142 }
0143 
0144 DEFINE_FWK_MODULE(PixelVertexProducerCUDA);