Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:15:44

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Framework/interface/Frameworkfwd.h"
0003 #include "FWCore/Framework/interface/MakerMacros.h"
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0007 #include "FWCore/ServiceRegistry/interface/Service.h"
0008 
0009 #include "CUDADataFormats/Common/interface/Product.h"
0010 #include "HeterogeneousCore/CUDAUtilities/interface/cudaCheck.h"
0011 #include "HeterogeneousCore/CUDACore/interface/ScopedContext.h"
0012 #include "HeterogeneousCore/CUDACore/interface/ContextState.h"
0013 #include "HeterogeneousCore/CUDAServices/interface/CUDAInterface.h"
0014 #include "HeterogeneousCore/CUDATest/interface/Thing.h"
0015 #include "HeterogeneousCore/CUDAUtilities/interface/host_noncached_unique_ptr.h"
0016 
0017 #include "TestCUDAProducerGPUKernel.h"
0018 
0019 class TestCUDAProducerGPUEW : public edm::stream::EDProducer<edm::ExternalWork> {
0020 public:
0021   explicit TestCUDAProducerGPUEW(edm::ParameterSet const& iConfig);
0022   ~TestCUDAProducerGPUEW() override = default;
0023 
0024   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0025 
0026   void acquire(edm::Event const& iEvent,
0027                edm::EventSetup const& iSetup,
0028                edm::WaitingTaskWithArenaHolder waitingTaskHolder) override;
0029   void produce(edm::Event& iEvent, edm::EventSetup const& iSetup) override;
0030 
0031 private:
0032   std::string const label_;
0033   edm::EDGetTokenT<cms::cuda::Product<cms::cudatest::Thing>> const srcToken_;
0034   edm::EDPutTokenT<cms::cuda::Product<cms::cudatest::Thing>> const dstToken_;
0035   TestCUDAProducerGPUKernel gpuAlgo_;
0036   cms::cuda::ContextState ctxState_;
0037   cms::cuda::device::unique_ptr<float[]> devicePtr_;
0038   cms::cuda::host::noncached::unique_ptr<float> hostData_;
0039 };
0040 
0041 TestCUDAProducerGPUEW::TestCUDAProducerGPUEW(edm::ParameterSet const& iConfig)
0042     : label_{iConfig.getParameter<std::string>("@module_label")},
0043       srcToken_{consumes<cms::cuda::Product<cms::cudatest::Thing>>(iConfig.getParameter<edm::InputTag>("src"))},
0044       dstToken_{produces<cms::cuda::Product<cms::cudatest::Thing>>()} {
0045   edm::Service<CUDAInterface> cuda;
0046   if (cuda and cuda->enabled()) {
0047     hostData_ = cms::cuda::make_host_noncached_unique<float>();
0048   }
0049 }
0050 
0051 void TestCUDAProducerGPUEW::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0052   edm::ParameterSetDescription desc;
0053   desc.add<edm::InputTag>("src", edm::InputTag());
0054   descriptions.addWithDefaultLabel(desc);
0055   descriptions.setComment(
0056       "This EDProducer is part of the TestCUDAProducer* family. It models a GPU algorithm this is not the first "
0057       "algorithm in the chain of the GPU EDProducers, and that transfers some data from GPU to CPU and thus needs to "
0058       "synchronize GPU and CPU. The synchronization is implemented with the ExternalWork extension. Produces "
0059       "cms::cuda::Product<cms::cuda::Thing>.");
0060 }
0061 
0062 void TestCUDAProducerGPUEW::acquire(edm::Event const& iEvent,
0063                                     edm::EventSetup const& iSetup,
0064                                     edm::WaitingTaskWithArenaHolder waitingTaskHolder) {
0065   edm::LogVerbatim("TestCUDAProducerGPUEW") << label_ << " TestCUDAProducerGPUEW::acquire begin event "
0066                                             << iEvent.id().event() << " stream " << iEvent.streamID();
0067 
0068   auto const& in = iEvent.get(srcToken_);
0069   cms::cuda::ScopedContextAcquire ctx{in, std::move(waitingTaskHolder), ctxState_};
0070   cms::cudatest::Thing const& input = ctx.get(in);
0071 
0072   devicePtr_ = gpuAlgo_.runAlgo(label_, input.get(), ctx.stream());
0073   // Mimick the need to transfer some of the GPU data back to CPU to
0074   // be used for something within this module, or to be put in the
0075   // event.
0076   cudaCheck(
0077       cudaMemcpyAsync(hostData_.get(), devicePtr_.get() + 10, sizeof(float), cudaMemcpyDeviceToHost, ctx.stream()));
0078   edm::LogVerbatim("TestCUDAProducerGPUEW") << label_ << " TestCUDAProducerGPUEW::acquire end event "
0079                                             << iEvent.id().event() << " stream " << iEvent.streamID();
0080 }
0081 
0082 void TestCUDAProducerGPUEW::produce(edm::Event& iEvent, edm::EventSetup const& iSetup) {
0083   edm::LogVerbatim("TestCUDAProducerGPUEW")
0084       << label_ << " TestCUDAProducerGPUEW::produce begin event " << iEvent.id().event() << " stream "
0085       << iEvent.streamID() << " 10th element " << *hostData_;
0086 
0087   cms::cuda::ScopedContextProduce ctx{ctxState_};
0088 
0089   ctx.emplace(iEvent, dstToken_, std::move(devicePtr_));
0090 
0091   edm::LogVerbatim("TestCUDAProducerGPUEW") << label_ << " TestCUDAProducerGPUEW::produce end event "
0092                                             << iEvent.id().event() << " stream " << iEvent.streamID();
0093 }
0094 
0095 DEFINE_FWK_MODULE(TestCUDAProducerGPUEW);