diff --git a/HeterogeneousCore/AlpakaCore/plugins/AlpakaBackendFilter.cc b/HeterogeneousCore/AlpakaCore/plugins/AlpakaBackendFilter.cc new file mode 100644 index 0000000000000..5d6a037e8e74e --- /dev/null +++ b/HeterogeneousCore/AlpakaCore/plugins/AlpakaBackendFilter.cc @@ -0,0 +1,48 @@ +#include +#include +#include + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/global/EDFilter.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "HeterogeneousCore/AlpakaInterface/interface/Backend.h" + +class AlpakaBackendFilter : public edm::global::EDFilter<> { +public: + explicit AlpakaBackendFilter(edm::ParameterSet const& config) + : producer_(consumes(config.getParameter("producer"))), backends_{} { + for (auto const& backend : config.getParameter>("backends")) { + backends_[static_cast(cms::alpakatools::toBackend(backend))] = true; + } + } + + bool filter(edm::StreamID sid, edm::Event& event, edm::EventSetup const& setup) const final { + return backends_[event.get(producer_)]; + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + const edm::EDGetTokenT producer_; + std::array(cms::alpakatools::Backend::size)> backends_; +}; + +void AlpakaBackendFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("producer", edm::InputTag("alpakaBackendProducer", "backend")) + ->setComment( + "Use the 'backend' instance label to read the backend indicator that is implicitly produced by every alpaka " + "EDProducer."); + desc.add>("backends", {"SerialSync"}) + ->setComment("Valid backends are 'SerialSync', 'CudaAsync', 'ROCmAsync', and 'TbbAsync'."); + descriptions.addWithDefaultLabel(desc); + descriptions.setComment( + "This EDFilter accepts events if the alpaka EDProducer 'producer' was run on a backend among those listed by the " + "'backends' parameter."); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +DEFINE_FWK_MODULE(AlpakaBackendFilter); diff --git a/HeterogeneousCore/AlpakaCore/plugins/BuildFile.xml b/HeterogeneousCore/AlpakaCore/plugins/BuildFile.xml index 80f1acb621283..006fa4ca8679c 100644 --- a/HeterogeneousCore/AlpakaCore/plugins/BuildFile.xml +++ b/HeterogeneousCore/AlpakaCore/plugins/BuildFile.xml @@ -3,5 +3,17 @@ + + + + + + + + + + + + diff --git a/HeterogeneousCore/AlpakaCore/plugins/alpaka/AlpakaBackendProducer.cc b/HeterogeneousCore/AlpakaCore/plugins/alpaka/AlpakaBackendProducer.cc new file mode 100644 index 0000000000000..a09fa075fe245 --- /dev/null +++ b/HeterogeneousCore/AlpakaCore/plugins/alpaka/AlpakaBackendProducer.cc @@ -0,0 +1,31 @@ +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/Event.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/EventSetup.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/global/EDProducer.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + + class AlpakaBackendProducer : public global::EDProducer<> { + public: + AlpakaBackendProducer(edm::ParameterSet const& config){}; + + void produce(edm::StreamID sid, device::Event& event, device::EventSetup const&) const override {} + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + descriptions.addWithDefaultLabel(desc); + descriptions.setComment( + "The alpaka EDProducer does not have any explicit products. " + "Its only purpose is to produce a 'backend' value."); + } + }; + +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/MakerMacros.h" +DEFINE_FWK_ALPAKA_MODULE(AlpakaBackendProducer); diff --git a/HeterogeneousCore/AlpakaCore/test/BuildFile.xml b/HeterogeneousCore/AlpakaCore/test/BuildFile.xml new file mode 100644 index 0000000000000..558acc941298c --- /dev/null +++ b/HeterogeneousCore/AlpakaCore/test/BuildFile.xml @@ -0,0 +1,3 @@ + + + diff --git a/HeterogeneousCore/AlpakaCore/test/testAlpakaBackendFilter.py b/HeterogeneousCore/AlpakaCore/test/testAlpakaBackendFilter.py new file mode 100644 index 0000000000000..0ff16f161be9c --- /dev/null +++ b/HeterogeneousCore/AlpakaCore/test/testAlpakaBackendFilter.py @@ -0,0 +1,46 @@ +import os +import sys + +# choose a different alpaka backend depending on the SCRAM test being run +try: + backend = os.environ['SCRAM_ALPAKA_BACKEND'] +except: + backend = 'SerialSync' + +# map the alpaka backends to the process accelerators +accelerators = { + 'SerialSync': 'cpu', + 'CudaAsync': 'gpu-nvidia', + 'ROCmAsync': 'gpu-amd' +} + +print(f"Testing the alpaka backend {backend} using the process accelerator {accelerators[backend]}") + +import FWCore.ParameterSet.Config as cms +from HeterogeneousCore.AlpakaCore.functions import * + +process = cms.Process('Test') + +process.options.accelerators = [ accelerators[backend] ] + +process.maxEvents.input = 10 + +process.source = cms.Source('EmptySource') + +process.load('Configuration.StandardSequences.Accelerators_cff') +process.load('HeterogeneousCore.AlpakaCore.ProcessAcceleratorAlpaka_cfi') + +process.alpakaBackendProducer = cms.EDProducer('AlpakaBackendProducer@alpaka') + +process.alpakaBackendFilter = cms.EDFilter('AlpakaBackendFilter', + producer = cms.InputTag('alpakaBackendProducer', 'backend'), + backends = cms.vstring(backend) +) + +process.mustRun = cms.EDProducer("edmtest::MustRunIntProducer", ivalue=cms.int32(1)) +process.mustNotRun = cms.EDProducer("FailingProducer") + +process.SelectedBackend = cms.Path(process.alpakaBackendProducer + process.alpakaBackendFilter + process.mustRun) +process.AnyOtherBackend = cms.Path(process.alpakaBackendProducer + ~process.alpakaBackendFilter + process.mustNotRun) + +process.options.wantSummary = True