Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:26:19

0001 // C++ includes
0002 #include <memory>
0003 #include <string>
0004 #include <vector>
0005 
0006 // CMSSW includes
0007 #include "CUDADataFormats/Common/interface/Product.h"
0008 #include "CUDADataFormats/SiPixelCluster/interface/SiPixelClustersCUDA.h"
0009 #include "CUDADataFormats/SiPixelCluster/interface/gpuClusteringConstants.h"
0010 #include "CUDADataFormats/SiPixelDigi/interface/SiPixelDigiErrorsCUDA.h"
0011 #include "CUDADataFormats/SiPixelDigi/interface/SiPixelDigisCUDA.h"
0012 #include "CalibTracker/Records/interface/SiPixelGainCalibrationForHLTGPURcd.h"
0013 #include "CalibTracker/SiPixelESProducers/interface/SiPixelGainCalibrationForHLTGPU.h"
0014 #include "CalibTracker/SiPixelESProducers/interface/SiPixelROCsStatusAndMappingWrapper.h"
0015 #include "CondFormats/DataRecord/interface/SiPixelFedCablingMapRcd.h"
0016 #include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h"
0017 #include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingTree.h"
0018 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0019 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0020 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0021 #include "EventFilter/SiPixelRawToDigi/interface/PixelDataFormatter.h"
0022 #include "EventFilter/SiPixelRawToDigi/interface/PixelUnpackingRegions.h"
0023 #include "FWCore/Framework/interface/ConsumesCollector.h"
0024 #include "FWCore/Framework/interface/ESHandle.h"
0025 #include "FWCore/Framework/interface/ESTransientHandle.h"
0026 #include "FWCore/Framework/interface/ESWatcher.h"
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030 #include "FWCore/Framework/interface/stream/EDProducer.h"
0031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0032 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0033 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0034 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0035 #include "FWCore/ServiceRegistry/interface/Service.h"
0036 #include "Geometry/CommonTopologies/interface/SimplePixelTopology.h"
0037 #include "HeterogeneousCore/CUDACore/interface/ScopedContext.h"
0038 #include "HeterogeneousCore/CUDAServices/interface/CUDAInterface.h"
0039 #include "RecoLocalTracker/SiPixelClusterizer/interface/SiPixelClusterThresholds.h"
0040 #include "RecoTracker/Record/interface/CkfComponentsRecord.h"
0041 
0042 // local includes
0043 #include "SiPixelRawToClusterGPUKernel.h"
0044 
0045 template <typename TrackerTraits>
0046 class SiPixelRawToClusterCUDAT : public edm::stream::EDProducer<edm::ExternalWork> {
0047 public:
0048   explicit SiPixelRawToClusterCUDAT(const edm::ParameterSet& iConfig);
0049   ~SiPixelRawToClusterCUDAT() override = default;
0050 
0051   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0052   using GPUAlgo = pixelgpudetails::SiPixelRawToClusterGPUKernel<TrackerTraits>;
0053 
0054 private:
0055   void acquire(const edm::Event& iEvent,
0056                const edm::EventSetup& iSetup,
0057                edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
0058   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0059 
0060   edm::EDGetTokenT<FEDRawDataCollection> rawGetToken_;
0061 
0062   edm::EDPutTokenT<cms::cuda::Product<SiPixelDigisCUDA>> digiPutToken_;
0063   edm::EDPutTokenT<cms::cuda::Product<SiPixelDigiErrorsCUDA>> digiErrorPutToken_;
0064   edm::EDPutTokenT<cms::cuda::Product<SiPixelClustersCUDA>> clusterPutToken_;
0065 
0066   cms::cuda::ContextState ctxState_;
0067 
0068   edm::ESWatcher<SiPixelFedCablingMapRcd> recordWatcher_;
0069   edm::ESGetToken<SiPixelROCsStatusAndMappingWrapper, CkfComponentsRecord> gpuMapToken_;
0070   edm::ESGetToken<SiPixelGainCalibrationForHLTGPU, SiPixelGainCalibrationForHLTGPURcd> gainsToken_;
0071   edm::ESGetToken<SiPixelFedCablingMap, SiPixelFedCablingMapRcd> cablingMapToken_;
0072 
0073   std::unique_ptr<SiPixelFedCablingTree> cabling_;
0074   std::vector<unsigned int> fedIds_;
0075   const SiPixelFedCablingMap* cablingMap_ = nullptr;
0076   std::unique_ptr<PixelUnpackingRegions> regions_;
0077 
0078   GPUAlgo gpuAlgo_;
0079   PixelDataFormatter::Errors errors_;
0080 
0081   const bool includeErrors_;
0082   const bool useQuality_;
0083   uint32_t nDigis_;
0084   const SiPixelClusterThresholds clusterThresholds_;
0085 };
0086 
0087 template <typename TrackerTraits>
0088 SiPixelRawToClusterCUDAT<TrackerTraits>::SiPixelRawToClusterCUDAT(const edm::ParameterSet& iConfig)
0089     : rawGetToken_(consumes<FEDRawDataCollection>(iConfig.getParameter<edm::InputTag>("InputLabel"))),
0090       digiPutToken_(produces<cms::cuda::Product<SiPixelDigisCUDA>>()),
0091       clusterPutToken_(produces<cms::cuda::Product<SiPixelClustersCUDA>>()),
0092       gpuMapToken_(esConsumes<SiPixelROCsStatusAndMappingWrapper, CkfComponentsRecord>()),
0093       gainsToken_(esConsumes<SiPixelGainCalibrationForHLTGPU, SiPixelGainCalibrationForHLTGPURcd>()),
0094       cablingMapToken_(esConsumes<SiPixelFedCablingMap, SiPixelFedCablingMapRcd>(
0095           edm::ESInputTag("", iConfig.getParameter<std::string>("CablingMapLabel")))),
0096       includeErrors_(iConfig.getParameter<bool>("IncludeErrors")),
0097       useQuality_(iConfig.getParameter<bool>("UseQualityInfo")),
0098       clusterThresholds_{iConfig.getParameter<int32_t>("clusterThreshold_layer1"),
0099                          iConfig.getParameter<int32_t>("clusterThreshold_otherLayers"),
0100                          static_cast<float>(iConfig.getParameter<double>("VCaltoElectronGain")),
0101                          static_cast<float>(iConfig.getParameter<double>("VCaltoElectronGain_L1")),
0102                          static_cast<float>(iConfig.getParameter<double>("VCaltoElectronOffset")),
0103                          static_cast<float>(iConfig.getParameter<double>("VCaltoElectronOffset_L1"))} {
0104   if (includeErrors_) {
0105     digiErrorPutToken_ = produces<cms::cuda::Product<SiPixelDigiErrorsCUDA>>();
0106   }
0107 
0108   // regions
0109   if (!iConfig.getParameter<edm::ParameterSet>("Regions").getParameterNames().empty()) {
0110     regions_ = std::make_unique<PixelUnpackingRegions>(iConfig, consumesCollector());
0111   }
0112 }
0113 
0114 template <typename TrackerTraits>
0115 void SiPixelRawToClusterCUDAT<TrackerTraits>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0116   edm::ParameterSetDescription desc;
0117   desc.add<bool>("IncludeErrors", true);
0118   desc.add<bool>("UseQualityInfo", false);
0119   // Note: this parameter is obsolete: it is ignored and will have no effect.
0120   // It is kept to avoid breaking older configurations, and will not be printed in the generated cfi.py file.
0121   desc.addOptionalNode(edm::ParameterDescription<uint32_t>("MaxFEDWords", 0, true), false)
0122       ->setComment("This parameter is obsolete and will be ignored.");
0123   //Clustering Thresholds
0124   desc.add<int32_t>("clusterThreshold_layer1", gpuClustering::clusterThresholdLayerOne);
0125   desc.add<int32_t>("clusterThreshold_otherLayers", gpuClustering::clusterThresholdOtherLayers);
0126   desc.add<double>("VCaltoElectronGain", 47.f);
0127   desc.add<double>("VCaltoElectronGain_L1", 50.f);
0128   desc.add<double>("VCaltoElectronOffset", -60.f);
0129   desc.add<double>("VCaltoElectronOffset_L1", -670.f);
0130   desc.add<edm::InputTag>("InputLabel", edm::InputTag("rawDataCollector"));
0131   {
0132     edm::ParameterSetDescription psd0;
0133     psd0.addOptional<std::vector<edm::InputTag>>("inputs");
0134     psd0.addOptional<std::vector<double>>("deltaPhi");
0135     psd0.addOptional<std::vector<double>>("maxZ");
0136     psd0.addOptional<edm::InputTag>("beamSpot");
0137     desc.add<edm::ParameterSetDescription>("Regions", psd0)
0138         ->setComment("## Empty Regions PSet means complete unpacking");
0139   }
0140   desc.add<std::string>("CablingMapLabel", "")->setComment("CablingMap label");  //Tav
0141   descriptions.addWithDefaultLabel(desc);
0142 }
0143 
0144 template <typename TrackerTraits>
0145 void SiPixelRawToClusterCUDAT<TrackerTraits>::acquire(const edm::Event& iEvent,
0146                                                       const edm::EventSetup& iSetup,
0147                                                       edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
0148   cms::cuda::ScopedContextAcquire ctx{iEvent.streamID(), std::move(waitingTaskHolder), ctxState_};
0149 
0150   auto hgpuMap = iSetup.getHandle(gpuMapToken_);
0151   if (hgpuMap->hasQuality() != useQuality_) {
0152     throw cms::Exception("LogicError")
0153         << "UseQuality of the module (" << useQuality_
0154         << ") differs the one from SiPixelROCsStatusAndMappingWrapper. Please fix your configuration.";
0155   }
0156   // get the GPU product already here so that the async transfer can begin
0157   const auto* gpuMap = hgpuMap->getGPUProductAsync(ctx.stream());
0158 
0159   auto hgains = iSetup.getHandle(gainsToken_);
0160   // get the GPU product already here so that the async transfer can begin
0161   const auto* gpuGains = hgains->getGPUProductAsync(ctx.stream());
0162 
0163   cms::cuda::device::unique_ptr<unsigned char[]> modulesToUnpackRegional;
0164   const unsigned char* gpuModulesToUnpack;
0165 
0166   if (regions_) {
0167     regions_->run(iEvent, iSetup);
0168     LogDebug("SiPixelRawToCluster") << "region2unpack #feds: " << regions_->nFEDs();
0169     LogDebug("SiPixelRawToCluster") << "region2unpack #modules (BPIX,EPIX,total): " << regions_->nBarrelModules() << " "
0170                                     << regions_->nForwardModules() << " " << regions_->nModules();
0171     modulesToUnpackRegional = hgpuMap->getModToUnpRegionalAsync(*(regions_->modulesToUnpack()), ctx.stream());
0172     gpuModulesToUnpack = modulesToUnpackRegional.get();
0173   } else {
0174     gpuModulesToUnpack = hgpuMap->getModToUnpAllAsync(ctx.stream());
0175   }
0176 
0177   // initialize cabling map or update if necessary
0178   if (recordWatcher_.check(iSetup)) {
0179     // cabling map, which maps online address (fed->link->ROC->local pixel) to offline (DetId->global pixel)
0180     auto cablingMap = iSetup.getTransientHandle(cablingMapToken_);
0181     cablingMap_ = cablingMap.product();
0182     fedIds_ = cablingMap->fedIds();
0183     cabling_ = cablingMap->cablingTree();
0184     LogDebug("map version:") << cabling_->version();
0185   }
0186 
0187   const auto& buffers = iEvent.get(rawGetToken_);
0188 
0189   errors_.clear();
0190 
0191   // GPU specific: Data extraction for RawToDigi GPU
0192   unsigned int wordCounter = 0;
0193   unsigned int fedCounter = 0;
0194   bool errorsInEvent = false;
0195 
0196   std::vector<unsigned int> index(fedIds_.size(), 0);
0197   std::vector<cms_uint32_t const*> start(fedIds_.size(), nullptr);
0198   std::vector<ptrdiff_t> words(fedIds_.size(), 0);
0199 
0200   // In CPU algorithm this loop is part of PixelDataFormatter::interpretRawData()
0201   ErrorChecker errorcheck;
0202   for (uint32_t i = 0; i < fedIds_.size(); ++i) {
0203     const int fedId = fedIds_[i];
0204     if (regions_ && !regions_->mayUnpackFED(fedId))
0205       continue;
0206 
0207     // for GPU
0208     // first 150 index stores the fedId and next 150 will store the
0209     // start index of word in that fed
0210     assert(fedId >= FEDNumbering::MINSiPixeluTCAFEDID);
0211     fedCounter++;
0212 
0213     // get event data for this fed
0214     const FEDRawData& rawData = buffers.FEDData(fedId);
0215 
0216     // GPU specific
0217     int nWords = rawData.size() / sizeof(cms_uint64_t);
0218     if (nWords == 0) {
0219       continue;
0220     }
0221 
0222     // check CRC bit
0223     const cms_uint64_t* trailer = reinterpret_cast<const cms_uint64_t*>(rawData.data()) + (nWords - 1);
0224     if (not errorcheck.checkCRC(errorsInEvent, fedId, trailer, errors_)) {
0225       continue;
0226     }
0227 
0228     // check headers
0229     const cms_uint64_t* header = reinterpret_cast<const cms_uint64_t*>(rawData.data());
0230     header--;
0231     bool moreHeaders = true;
0232     while (moreHeaders) {
0233       header++;
0234       bool headerStatus = errorcheck.checkHeader(errorsInEvent, fedId, header, errors_);
0235       moreHeaders = headerStatus;
0236     }
0237 
0238     // check trailers
0239     bool moreTrailers = true;
0240     trailer++;
0241     while (moreTrailers) {
0242       trailer--;
0243       bool trailerStatus = errorcheck.checkTrailer(errorsInEvent, fedId, nWords, trailer, errors_);
0244       moreTrailers = trailerStatus;
0245     }
0246 
0247     const cms_uint32_t* bw = (const cms_uint32_t*)(header + 1);
0248     const cms_uint32_t* ew = (const cms_uint32_t*)(trailer);
0249 
0250     assert(0 == (ew - bw) % 2);
0251     index[i] = wordCounter;
0252     start[i] = bw;
0253     words[i] = (ew - bw);
0254     wordCounter += (ew - bw);
0255 
0256   }  // end of for loop
0257 
0258   nDigis_ = wordCounter;
0259 
0260   if (nDigis_ == 0)
0261     return;
0262 
0263   // copy the FED data to a single cpu buffer
0264   typename GPUAlgo::WordFedAppender wordFedAppender(nDigis_, ctx.stream());
0265   for (uint32_t i = 0; i < fedIds_.size(); ++i) {
0266     wordFedAppender.initializeWordFed(fedIds_[i], index[i], start[i], words[i]);
0267   }
0268 
0269   gpuAlgo_.makePhase1ClustersAsync(clusterThresholds_,
0270                                    gpuMap,
0271                                    gpuModulesToUnpack,
0272                                    gpuGains,
0273                                    wordFedAppender,
0274                                    std::move(errors_),
0275                                    wordCounter,
0276                                    fedCounter,
0277                                    useQuality_,
0278                                    includeErrors_,
0279                                    edm::MessageDrop::instance()->debugEnabled,
0280                                    ctx.stream());
0281 }
0282 
0283 template <typename TrackerTraits>
0284 void SiPixelRawToClusterCUDAT<TrackerTraits>::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0285   cms::cuda::ScopedContextProduce ctx{ctxState_};
0286 
0287   if (nDigis_ == 0) {
0288     // Cannot use the default constructor here, as it would not allocate memory.
0289     // In the case of no digis, clusters_d are not being instantiated, but are
0290     // still used downstream to initialize TrackingRecHitSoADevice. If there
0291     // are no valid pointers to clusters' Collection columns, instantiation
0292     // of TrackingRecHits fail. Example: workflow 11604.0
0293     SiPixelDigisCUDA digis_d = SiPixelDigisCUDA(nDigis_, ctx.stream());
0294     SiPixelClustersCUDA clusters_d = SiPixelClustersCUDA(pixelTopology::Phase1::numberOfModules, ctx.stream());
0295     ctx.emplace(iEvent, digiPutToken_, std::move(digis_d));
0296     ctx.emplace(iEvent, clusterPutToken_, std::move(clusters_d));
0297     if (includeErrors_) {
0298       ctx.emplace(iEvent, digiErrorPutToken_, SiPixelDigiErrorsCUDA{});
0299     }
0300     return;
0301   }
0302 
0303   auto tmp = gpuAlgo_.getResults();
0304   ctx.emplace(iEvent, digiPutToken_, std::move(tmp.first));
0305   ctx.emplace(iEvent, clusterPutToken_, std::move(tmp.second));
0306   if (includeErrors_) {
0307     ctx.emplace(iEvent, digiErrorPutToken_, gpuAlgo_.getErrors());
0308   }
0309 }
0310 
0311 // define as framework plugin
0312 using SiPixelRawToClusterCUDAPhase1 = SiPixelRawToClusterCUDAT<pixelTopology::Phase1>;
0313 DEFINE_FWK_MODULE(SiPixelRawToClusterCUDAPhase1);
0314 using SiPixelRawToClusterCUDAHIonPhase1 = SiPixelRawToClusterCUDAT<pixelTopology::HIonPhase1>;
0315 DEFINE_FWK_MODULE(SiPixelRawToClusterCUDAHIonPhase1);