Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:45:19

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