Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-14 02:50:07

0001 #include <iostream>
0002 #include <utility>
0003 
0004 #include "CUDADataFormats/EcalDigi/interface/DigisCollection.h"
0005 #include "CondFormats/DataRecord/interface/EcalMappingElectronicsRcd.h"
0006 #include "CondFormats/EcalObjects/interface/ElectronicsMappingGPU.h"
0007 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
0008 #include "DataFormats/EcalDigi/interface/EcalDataFrame.h"
0009 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0010 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0011 #include "FWCore/Framework/interface/Event.h"
0012 #include "FWCore/Framework/interface/EventSetup.h"
0013 #include "FWCore/Framework/interface/MakerMacros.h"
0014 #include "FWCore/Framework/interface/stream/EDProducer.h"
0015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0016 #include "HeterogeneousCore/CUDACore/interface/ScopedContext.h"
0017 #include "HeterogeneousCore/CUDAUtilities/interface/HostAllocator.h"
0018 #include "HeterogeneousCore/CUDAUtilities/interface/cudaCheck.h"
0019 
0020 #include "DeclsForKernels.h"
0021 #include "UnpackGPU.h"
0022 
0023 class EcalCPUDigisProducer : public edm::stream::EDProducer<edm::ExternalWork> {
0024 public:
0025   explicit EcalCPUDigisProducer(edm::ParameterSet const& ps);
0026   ~EcalCPUDigisProducer() override = default;
0027   static void fillDescriptions(edm::ConfigurationDescriptions&);
0028 
0029 private:
0030   void acquire(edm::Event const&, edm::EventSetup const&, edm::WaitingTaskWithArenaHolder) override;
0031   void produce(edm::Event&, edm::EventSetup const&) override;
0032 
0033   template <typename ProductType, typename... ARGS>
0034   edm::EDPutTokenT<ProductType> dummyProduces(ARGS&&... args) {
0035     return (produceDummyIntegrityCollections_) ? produces<ProductType>(std::forward<ARGS>(args)...)
0036                                                : edm::EDPutTokenT<ProductType>{};
0037   }
0038 
0039 private:
0040   // input digi collections in GPU-friendly format
0041   using InputProduct = cms::cuda::Product<ecal::DigisCollection<calo::common::DevStoragePolicy>>;
0042   edm::EDGetTokenT<InputProduct> digisInEBToken_;
0043   edm::EDGetTokenT<InputProduct> digisInEEToken_;
0044 
0045   // output digi collections in legacy format
0046   edm::EDPutTokenT<EBDigiCollection> digisOutEBToken_;
0047   edm::EDPutTokenT<EEDigiCollection> digisOutEEToken_;
0048 
0049   // whether to produce dummy integrity collections
0050   bool produceDummyIntegrityCollections_;
0051 
0052   // dummy producer collections
0053   edm::EDPutTokenT<EBSrFlagCollection> ebSrFlagToken_;
0054   edm::EDPutTokenT<EESrFlagCollection> eeSrFlagToken_;
0055 
0056   // dummy integrity for xtal data
0057   edm::EDPutTokenT<EBDetIdCollection> ebIntegrityGainErrorsToken_;
0058   edm::EDPutTokenT<EBDetIdCollection> ebIntegrityGainSwitchErrorsToken_;
0059   edm::EDPutTokenT<EBDetIdCollection> ebIntegrityChIdErrorsToken_;
0060 
0061   // dummy integrity for xtal data - EE specific (to be rivisited towards EB+EE common collection)
0062   edm::EDPutTokenT<EEDetIdCollection> eeIntegrityGainErrorsToken_;
0063   edm::EDPutTokenT<EEDetIdCollection> eeIntegrityGainSwitchErrorsToken_;
0064   edm::EDPutTokenT<EEDetIdCollection> eeIntegrityChIdErrorsToken_;
0065 
0066   // dummy integrity errors
0067   edm::EDPutTokenT<EcalElectronicsIdCollection> integrityTTIdErrorsToken_;
0068   edm::EDPutTokenT<EcalElectronicsIdCollection> integrityZSXtalIdErrorsToken_;
0069   edm::EDPutTokenT<EcalElectronicsIdCollection> integrityBlockSizeErrorsToken_;
0070 
0071   edm::EDPutTokenT<EcalPnDiodeDigiCollection> pnDiodeDigisToken_;
0072 
0073   // dummy TCC collections
0074   edm::EDPutTokenT<EcalTrigPrimDigiCollection> ecalTriggerPrimitivesToken_;
0075   edm::EDPutTokenT<EcalPSInputDigiCollection> ecalPseudoStripInputsToken_;
0076 
0077   // FIXME better way to pass pointers from acquire to produce?
0078   std::vector<uint32_t, cms::cuda::HostAllocator<uint32_t>> idsebtmp, idseetmp;
0079   std::vector<uint16_t, cms::cuda::HostAllocator<uint16_t>> dataebtmp, dataeetmp;
0080 };
0081 
0082 void EcalCPUDigisProducer::fillDescriptions(edm::ConfigurationDescriptions& confDesc) {
0083   edm::ParameterSetDescription desc;
0084 
0085   desc.add<edm::InputTag>("digisInLabelEB", edm::InputTag{"ecalRawToDigiGPU", "ebDigis"});
0086   desc.add<edm::InputTag>("digisInLabelEE", edm::InputTag{"ecalRawToDigiGPU", "eeDigis"});
0087   desc.add<std::string>("digisOutLabelEB", "ebDigis");
0088   desc.add<std::string>("digisOutLabelEE", "eeDigis");
0089 
0090   desc.add<bool>("produceDummyIntegrityCollections", false);
0091 
0092   std::string label = "ecalCPUDigisProducer";
0093   confDesc.add(label, desc);
0094 }
0095 
0096 EcalCPUDigisProducer::EcalCPUDigisProducer(const edm::ParameterSet& ps)
0097     :  // input digi collections in GPU-friendly format
0098       digisInEBToken_{consumes<InputProduct>(ps.getParameter<edm::InputTag>("digisInLabelEB"))},
0099       digisInEEToken_{consumes<InputProduct>(ps.getParameter<edm::InputTag>("digisInLabelEE"))},
0100 
0101       // output digi collections in legacy format
0102       digisOutEBToken_{produces<EBDigiCollection>(ps.getParameter<std::string>("digisOutLabelEB"))},
0103       digisOutEEToken_{produces<EEDigiCollection>(ps.getParameter<std::string>("digisOutLabelEE"))},
0104 
0105       // whether to produce dummy integrity collections
0106       produceDummyIntegrityCollections_{ps.getParameter<bool>("produceDummyIntegrityCollections")},
0107 
0108       // dummy collections
0109       ebSrFlagToken_{dummyProduces<EBSrFlagCollection>()},
0110       eeSrFlagToken_{dummyProduces<EESrFlagCollection>()},
0111 
0112       // dummy integrity for xtal data
0113       ebIntegrityGainErrorsToken_{dummyProduces<EBDetIdCollection>("EcalIntegrityGainErrors")},
0114       ebIntegrityGainSwitchErrorsToken_{dummyProduces<EBDetIdCollection>("EcalIntegrityGainSwitchErrors")},
0115       ebIntegrityChIdErrorsToken_{dummyProduces<EBDetIdCollection>("EcalIntegrityChIdErrors")},
0116 
0117       // dummy integrity for xtal data - EE specific (to be rivisited towards EB+EE common collection)
0118       eeIntegrityGainErrorsToken_{dummyProduces<EEDetIdCollection>("EcalIntegrityGainErrors")},
0119       eeIntegrityGainSwitchErrorsToken_{dummyProduces<EEDetIdCollection>("EcalIntegrityGainSwitchErrors")},
0120       eeIntegrityChIdErrorsToken_{dummyProduces<EEDetIdCollection>("EcalIntegrityChIdErrors")},
0121 
0122       // dummy integrity errors
0123       integrityTTIdErrorsToken_{dummyProduces<EcalElectronicsIdCollection>("EcalIntegrityTTIdErrors")},
0124       integrityZSXtalIdErrorsToken_{dummyProduces<EcalElectronicsIdCollection>("EcalIntegrityZSXtalIdErrors")},
0125       integrityBlockSizeErrorsToken_{dummyProduces<EcalElectronicsIdCollection>("EcalIntegrityBlockSizeErrors")},
0126 
0127       //
0128       pnDiodeDigisToken_{dummyProduces<EcalPnDiodeDigiCollection>()},
0129 
0130       // dummy TCC collections
0131       ecalTriggerPrimitivesToken_{dummyProduces<EcalTrigPrimDigiCollection>("EcalTriggerPrimitives")},
0132       ecalPseudoStripInputsToken_{dummyProduces<EcalPSInputDigiCollection>("EcalPseudoStripInputs")}
0133 // constructor body
0134 {}
0135 
0136 void EcalCPUDigisProducer::acquire(edm::Event const& event,
0137                                    edm::EventSetup const& setup,
0138                                    edm::WaitingTaskWithArenaHolder taskHolder) {
0139   // retrieve data/ctx
0140   auto const& ebdigisProduct = event.get(digisInEBToken_);
0141   auto const& eedigisProduct = event.get(digisInEEToken_);
0142   cms::cuda::ScopedContextAcquire ctx{ebdigisProduct, std::move(taskHolder)};
0143   auto const& ebdigis = ctx.get(ebdigisProduct);
0144   auto const& eedigis = ctx.get(eedigisProduct);
0145 
0146   // resize tmp buffers
0147   dataebtmp.resize(ebdigis.size * EcalDataFrame::MAXSAMPLES);
0148   dataeetmp.resize(eedigis.size * EcalDataFrame::MAXSAMPLES);
0149   idsebtmp.resize(ebdigis.size);
0150   idseetmp.resize(eedigis.size);
0151 
0152   // enqeue transfers
0153   cudaCheck(cudaMemcpyAsync(
0154       dataebtmp.data(), ebdigis.data.get(), dataebtmp.size() * sizeof(uint16_t), cudaMemcpyDeviceToHost, ctx.stream()));
0155   cudaCheck(cudaMemcpyAsync(
0156       dataeetmp.data(), eedigis.data.get(), dataeetmp.size() * sizeof(uint16_t), cudaMemcpyDeviceToHost, ctx.stream()));
0157   cudaCheck(cudaMemcpyAsync(
0158       idsebtmp.data(), ebdigis.ids.get(), idsebtmp.size() * sizeof(uint32_t), cudaMemcpyDeviceToHost, ctx.stream()));
0159   cudaCheck(cudaMemcpyAsync(
0160       idseetmp.data(), eedigis.ids.get(), idseetmp.size() * sizeof(uint32_t), cudaMemcpyDeviceToHost, ctx.stream()));
0161 }
0162 
0163 void EcalCPUDigisProducer::produce(edm::Event& event, edm::EventSetup const& setup) {
0164   // output collections
0165   auto digisEB = std::make_unique<EBDigiCollection>();
0166   auto digisEE = std::make_unique<EEDigiCollection>();
0167   digisEB->resize(idsebtmp.size());
0168   digisEE->resize(idseetmp.size());
0169 
0170   // cast constness away
0171   // use pointers to buffers instead of move operator= semantics
0172   // cause we have different allocators in there...
0173   auto* dataEB = const_cast<uint16_t*>(digisEB->data().data());
0174   auto* dataEE = const_cast<uint16_t*>(digisEE->data().data());
0175   auto* idsEB = const_cast<uint32_t*>(digisEB->ids().data());
0176   auto* idsEE = const_cast<uint32_t*>(digisEE->ids().data());
0177 
0178   // copy data
0179   std::memcpy(dataEB, dataebtmp.data(), dataebtmp.size() * sizeof(uint16_t));
0180   std::memcpy(dataEE, dataeetmp.data(), dataeetmp.size() * sizeof(uint16_t));
0181   std::memcpy(idsEB, idsebtmp.data(), idsebtmp.size() * sizeof(uint32_t));
0182   std::memcpy(idsEE, idseetmp.data(), idseetmp.size() * sizeof(uint32_t));
0183 
0184   digisEB->sort();
0185   digisEE->sort();
0186 
0187   event.put(digisOutEBToken_, std::move(digisEB));
0188   event.put(digisOutEEToken_, std::move(digisEE));
0189 
0190   if (produceDummyIntegrityCollections_) {
0191     // dummy collections
0192     event.emplace(ebSrFlagToken_);
0193     event.emplace(eeSrFlagToken_);
0194     // dummy integrity for xtal data
0195     event.emplace(ebIntegrityGainErrorsToken_);
0196     event.emplace(ebIntegrityGainSwitchErrorsToken_);
0197     event.emplace(ebIntegrityChIdErrorsToken_);
0198     // dummy integrity for xtal data - EE specific (to be rivisited towards EB+EE common collection)
0199     event.emplace(eeIntegrityGainErrorsToken_);
0200     event.emplace(eeIntegrityGainSwitchErrorsToken_);
0201     event.emplace(eeIntegrityChIdErrorsToken_);
0202     // dummy integrity errors
0203     event.emplace(integrityTTIdErrorsToken_);
0204     event.emplace(integrityZSXtalIdErrorsToken_);
0205     event.emplace(integrityBlockSizeErrorsToken_);
0206     //
0207     event.emplace(pnDiodeDigisToken_);
0208     // dummy TCC collections
0209     event.emplace(ecalTriggerPrimitivesToken_);
0210     event.emplace(ecalPseudoStripInputsToken_);
0211   }
0212 }
0213 
0214 DEFINE_FWK_MODULE(EcalCPUDigisProducer);