Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-10 02:50:54

0001 #include "CUDADataFormats/Common/interface/Product.h"
0002 #include "CUDADataFormats/SiPixelDigi/interface/SiPixelDigisCUDA.h"
0003 #include "DataFormats/SiPixelDigi/interface/SiPixelDigisSoA.h"
0004 #include "FWCore/Framework/interface/EventSetup.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007 #include "FWCore/Framework/interface/stream/EDProducer.h"
0008 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "HeterogeneousCore/CUDACore/interface/ScopedContext.h"
0012 #include "HeterogeneousCore/CUDAUtilities/interface/host_unique_ptr.h"
0013 
0014 class SiPixelDigisSoAFromCUDA : public edm::stream::EDProducer<edm::ExternalWork> {
0015 public:
0016   explicit SiPixelDigisSoAFromCUDA(const edm::ParameterSet& iConfig);
0017   ~SiPixelDigisSoAFromCUDA() override = default;
0018 
0019   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0020 
0021 private:
0022   void acquire(const edm::Event& iEvent,
0023                const edm::EventSetup& iSetup,
0024                edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
0025   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0026 
0027   edm::EDGetTokenT<cms::cuda::Product<SiPixelDigisCUDA>> digiGetToken_;
0028   edm::EDPutTokenT<SiPixelDigisSoA> digiPutToken_;
0029 
0030   cms::cuda::host::unique_ptr<uint16_t[]> store_;
0031 
0032   int nDigis_;
0033 };
0034 
0035 SiPixelDigisSoAFromCUDA::SiPixelDigisSoAFromCUDA(const edm::ParameterSet& iConfig)
0036     : digiGetToken_(consumes<cms::cuda::Product<SiPixelDigisCUDA>>(iConfig.getParameter<edm::InputTag>("src"))),
0037       digiPutToken_(produces<SiPixelDigisSoA>()) {}
0038 
0039 void SiPixelDigisSoAFromCUDA::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0040   edm::ParameterSetDescription desc;
0041   desc.add<edm::InputTag>("src", edm::InputTag("siPixelClustersCUDA"));
0042   descriptions.addWithDefaultLabel(desc);
0043 }
0044 
0045 void SiPixelDigisSoAFromCUDA::acquire(const edm::Event& iEvent,
0046                                       const edm::EventSetup& iSetup,
0047                                       edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
0048   // Do the transfer in a CUDA stream parallel to the computation CUDA stream
0049   cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), std::move(waitingTaskHolder)};
0050 
0051   const auto& gpuDigis = ctx.get(iEvent, digiGetToken_);
0052 
0053   nDigis_ = gpuDigis.nDigis();
0054   store_ = gpuDigis.copyAllToHostAsync(ctx.stream());
0055 }
0056 
0057 void SiPixelDigisSoAFromCUDA::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0058   // The following line copies the data from the pinned host memory to
0059   // regular host memory. In principle that feels unnecessary (why not
0060   // just use the pinned host memory?). There are a few arguments for
0061   // doing it though
0062   // - Now can release the pinned host memory back to the (caching) allocator
0063   //   * if we'd like to keep the pinned memory, we'd need to also
0064   //     keep the CUDA stream around as long as that, or allow pinned
0065   //     host memory to be allocated without a CUDA stream
0066   // - What if a CPU algorithm would produce the same SoA? We can't
0067   //   use cudaMallocHost without a GPU...
0068 
0069   auto tmp_view = SiPixelDigisCUDASOAView(store_, nDigis_, SiPixelDigisCUDASOAView::StorageLocationHost::kMAX);
0070 
0071   iEvent.emplace(digiPutToken_, nDigis_, tmp_view.pdigi(), tmp_view.rawIdArr(), tmp_view.adc(), tmp_view.clus());
0072 
0073   store_.reset();
0074 }
0075 
0076 // define as framework plugin
0077 DEFINE_FWK_MODULE(SiPixelDigisSoAFromCUDA);