From 4b74313066f88c81d0d383785cb8dd4dbdbc608e Mon Sep 17 00:00:00 2001 From: AdrianoDee Date: Fri, 8 Nov 2024 15:08:12 +0100 Subject: [PATCH] Fix CopyToDevice for PortableMultiHost + New tests --- .../Portable/interface/PortableCollection.h | 8 +-- .../AlpakaTest/interface/AlpakaESTestData.h | 2 + .../interface/alpaka/AlpakaESTestData.h | 6 ++ .../alpaka/TestAlpakaESProducerAMulti.cc | 60 +++++++++++++++++++ .../alpaka/TestAlpakaGlobalProducer.cc | 4 ++ .../AlpakaTest/src/ES_AlpakaESTestData.cc | 1 + .../src/alpaka/ES_AlpakaESTestData.cc | 1 + .../AlpakaTest/test/testAlpakaModules_cfg.py | 7 ++- 8 files changed, 84 insertions(+), 5 deletions(-) create mode 100644 HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaESProducerAMulti.cc diff --git a/DataFormats/Portable/interface/PortableCollection.h b/DataFormats/Portable/interface/PortableCollection.h index abfffff6ed1d2..e876c1558e96b 100644 --- a/DataFormats/Portable/interface/PortableCollection.h +++ b/DataFormats/Portable/interface/PortableCollection.h @@ -77,12 +77,12 @@ namespace cms::alpakatools { } }; - template - struct CopyToDevice> { + template + struct CopyToDevice> { template - static auto copyAsync(TQueue& queue, PortableHostMultiCollection const& srcData) { + static auto copyAsync(TQueue& queue, PortableHostMultiCollection const& srcData) { using TDevice = typename alpaka::trait::DevType::type; - PortableDeviceMultiCollection dstData(srcData.sizes(), queue); + PortableDeviceMultiCollection dstData(srcData.sizes(), queue); alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); return dstData; } diff --git a/HeterogeneousCore/AlpakaTest/interface/AlpakaESTestData.h b/HeterogeneousCore/AlpakaTest/interface/AlpakaESTestData.h index 9975feda1b92e..5446efb8c83c1 100644 --- a/HeterogeneousCore/AlpakaTest/interface/AlpakaESTestData.h +++ b/HeterogeneousCore/AlpakaTest/interface/AlpakaESTestData.h @@ -14,6 +14,8 @@ namespace cms::alpakatest { using AlpakaESTestDataCHost = PortableHostCollection; using AlpakaESTestDataDHost = PortableHostCollection; + using AlpakaESTestDataACMultiHost = PortableHostMultiCollection; + // Template-over-device model template class AlpakaESTestDataB { diff --git a/HeterogeneousCore/AlpakaTest/interface/alpaka/AlpakaESTestData.h b/HeterogeneousCore/AlpakaTest/interface/alpaka/AlpakaESTestData.h index 71c3b91d8ba2a..a7e31f46cdf63 100644 --- a/HeterogeneousCore/AlpakaTest/interface/alpaka/AlpakaESTestData.h +++ b/HeterogeneousCore/AlpakaTest/interface/alpaka/AlpakaESTestData.h @@ -20,6 +20,11 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { using AlpakaESTestDataEHost = cms::alpakatest::AlpakaESTestDataEHost; using AlpakaESTestDataEDevice = cms::alpakatest::AlpakaESTestDataE; + + using AlpakaESTestDataACMultiHost = cms::alpakatest::AlpakaESTestDataACMultiHost; + using AlpakaESTestDataACMultiDevice = + PortableMultiCollection; + } // namespace ALPAKA_ACCELERATOR_NAMESPACE // check that the portable device collections for the host device are the same as the portable host collections @@ -27,5 +32,6 @@ ASSERT_DEVICE_MATCHES_HOST_COLLECTION(AlpakaESTestDataADevice, cms::alpakatest:: ASSERT_DEVICE_MATCHES_HOST_COLLECTION(AlpakaESTestDataCDevice, cms::alpakatest::AlpakaESTestDataCHost); ASSERT_DEVICE_MATCHES_HOST_COLLECTION(AlpakaESTestDataDDevice, cms::alpakatest::AlpakaESTestDataDHost); ASSERT_DEVICE_MATCHES_HOST_COLLECTION(AlpakaESTestDataEDevice, cms::alpakatest::AlpakaESTestDataEHost); +ASSERT_DEVICE_MATCHES_HOST_COLLECTION(AlpakaESTestDataACMultiDevice, ::cms::alpakatest::AlpakaESTestDataACMultiHost); #endif // HeterogeneousCore_AlpakaTest_interface_alpaka_AlpakaESTestData_h diff --git a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaESProducerAMulti.cc b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaESProducerAMulti.cc new file mode 100644 index 0000000000000..38c5dadae55c1 --- /dev/null +++ b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaESProducerAMulti.cc @@ -0,0 +1,60 @@ +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/ESGetToken.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ESProducer.h" +#include "HeterogeneousCore/AlpakaCore/interface/alpaka/ModuleFactory.h" +#include "HeterogeneousCore/AlpakaInterface/interface/config.h" +#include "HeterogeneousCore/AlpakaInterface/interface/host.h" +#include "HeterogeneousCore/AlpakaInterface/interface/memory.h" +#include "HeterogeneousCore/AlpakaTest/interface/AlpakaESTestRecords.h" +#include "HeterogeneousCore/AlpakaTest/interface/AlpakaESTestSoA.h" +#include "HeterogeneousCore/AlpakaTest/interface/ESTestData.h" +#include "HeterogeneousCore/AlpakaTest/interface/alpaka/AlpakaESTestData.h" + +namespace ALPAKA_ACCELERATOR_NAMESPACE { + /** + * This class is the equivalent of TesAlpakaESProducerA.cc + * for PortableHostMultiCollection. It consumes a standard + * host ESProduct and converts the data into PortableHostMultiCollection, and + * implicitly transfers the data product to device + */ + class TestAlpakaESProducerAMulti : public ESProducer { + public: + TestAlpakaESProducerAMulti(edm::ParameterSet const& iConfig) : ESProducer(iConfig) { + auto cc = setWhatProduced(this); + token_ = cc.consumes(); + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + descriptions.addWithDefaultLabel(desc); + } + + std::optional produce(AlpakaESTestRecordA const& iRecord) { + auto const& input = iRecord.get(token_); + + int const sizeA = 10; + int const sizeC = 100; + // TODO: pinned allocation? + // TODO: cached allocation? + AlpakaESTestDataACMultiHost product({{sizeA, sizeC}}, cms::alpakatools::host()); + auto viewA = product.view< + cms::alpakatest::AlpakaESTestSoAA>(); // this template is not really needed as this is fhe first layout + auto viewC = product.view(); + + for (int i = 0; i < sizeA; ++i) { + viewA[i].z() = input.value() - i; + } + + for (int i = 0; i < sizeC; ++i) { + viewC[i].x() = input.value() + i; + } + + return product; + } + + private: + edm::ESGetToken token_; + }; +} // namespace ALPAKA_ACCELERATOR_NAMESPACE + +DEFINE_FWK_EVENTSETUP_ALPAKA_MODULE(TestAlpakaESProducerAMulti); diff --git a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaGlobalProducer.cc b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaGlobalProducer.cc index 499ce4b522e5f..19340231732b8 100644 --- a/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaGlobalProducer.cc +++ b/HeterogeneousCore/AlpakaTest/plugins/alpaka/TestAlpakaGlobalProducer.cc @@ -22,6 +22,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { public: TestAlpakaGlobalProducer(edm::ParameterSet const& config) : esToken_(esConsumes(config.getParameter("eventSetupSource"))), + esMultiToken_(esConsumes(config.getParameter("eventSetupSourceMulti"))), deviceToken_{produces()}, deviceTokenMulti2_{produces()}, deviceTokenMulti3_{produces()}, @@ -34,6 +35,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { void produce(edm::StreamID, device::Event& iEvent, device::EventSetup const& iSetup) const override { [[maybe_unused]] auto const& esData = iSetup.getData(esToken_); + [[maybe_unused]] auto const& esMultiData = iSetup.getData(esMultiToken_); portabletest::TestDeviceCollection deviceProduct{size_, iEvent.queue()}; portabletest::TestDeviceMultiCollection2 deviceProductMulti2{{{size_, size2_}}, iEvent.queue()}; @@ -52,6 +54,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("eventSetupSource", edm::ESInputTag{}); + desc.add("eventSetupSourceMulti", edm::ESInputTag{}); edm::ParameterSetDescription psetSize; psetSize.add("alpaka_serial_sync"); @@ -64,6 +67,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { private: const device::ESGetToken esToken_; + const device::ESGetToken esMultiToken_; const device::EDPutToken deviceToken_; const device::EDPutToken deviceTokenMulti2_; const device::EDPutToken deviceTokenMulti3_; diff --git a/HeterogeneousCore/AlpakaTest/src/ES_AlpakaESTestData.cc b/HeterogeneousCore/AlpakaTest/src/ES_AlpakaESTestData.cc index b6b2adaa98d81..ed017b50cf873 100644 --- a/HeterogeneousCore/AlpakaTest/src/ES_AlpakaESTestData.cc +++ b/HeterogeneousCore/AlpakaTest/src/ES_AlpakaESTestData.cc @@ -5,6 +5,7 @@ TYPELOOKUP_DATA_REG(cms::alpakatest::AlpakaESTestDataAHost); TYPELOOKUP_DATA_REG(cms::alpakatest::AlpakaESTestDataCHost); TYPELOOKUP_DATA_REG(cms::alpakatest::AlpakaESTestDataDHost); +TYPELOOKUP_DATA_REG(cms::alpakatest::AlpakaESTestDataACMultiHost); // Template-over-device model TYPELOOKUP_DATA_REG(cms::alpakatest::AlpakaESTestDataB); diff --git a/HeterogeneousCore/AlpakaTest/src/alpaka/ES_AlpakaESTestData.cc b/HeterogeneousCore/AlpakaTest/src/alpaka/ES_AlpakaESTestData.cc index f5093b6bf2e9d..a9f0ee95f286a 100644 --- a/HeterogeneousCore/AlpakaTest/src/alpaka/ES_AlpakaESTestData.cc +++ b/HeterogeneousCore/AlpakaTest/src/alpaka/ES_AlpakaESTestData.cc @@ -5,6 +5,7 @@ TYPELOOKUP_ALPAKA_DATA_REG(AlpakaESTestDataADevice); TYPELOOKUP_ALPAKA_DATA_REG(AlpakaESTestDataCDevice); TYPELOOKUP_ALPAKA_DATA_REG(AlpakaESTestDataDDevice); +TYPELOOKUP_ALPAKA_DATA_REG(AlpakaESTestDataACMultiDevice); // Template-over-device model #include "HeterogeneousCore/AlpakaTest/interface/AlpakaESTestData.h" diff --git a/HeterogeneousCore/AlpakaTest/test/testAlpakaModules_cfg.py b/HeterogeneousCore/AlpakaTest/test/testAlpakaModules_cfg.py index 238fee3597e70..62279b26b3010 100644 --- a/HeterogeneousCore/AlpakaTest/test/testAlpakaModules_cfg.py +++ b/HeterogeneousCore/AlpakaTest/test/testAlpakaModules_cfg.py @@ -59,11 +59,16 @@ appendToDataLabel = cms.string("null"), ) +# PortableMultiCollection +from HeterogeneousCore.AlpakaTest.testAlpakaESProducerAMulti_cfi import testAlpakaESProducerAMulti + process.intProduct = cms.EDProducer("IntProducer", ivalue = cms.int32(42)) +process.alpakaESProducerAMulti = testAlpakaESProducerAMulti.clone(appendToDataLabel = cms.string("appendedLabel")) from HeterogeneousCore.AlpakaTest.testAlpakaGlobalProducer_cfi import testAlpakaGlobalProducer process.alpakaGlobalProducer = testAlpakaGlobalProducer.clone( eventSetupSource = cms.ESInputTag("alpakaESProducerA", "appendedLabel"), + eventSetupSourceMulti = cms.ESInputTag("alpakaESProducerAMulti", "appendedLabel"), size = dict( alpaka_serial_sync = 10, alpaka_cuda_async = 20, @@ -146,7 +151,7 @@ if args.processAcceleratorBackend != "": process.ProcessAcceleratorAlpaka.setBackend(args.processAcceleratorBackend) if args.moduleBackend != "": - for name in ["ESProducerA", "ESProducerB", "ESProducerC", "ESProducerD", "ESProducerE", + for name in ["ESProducerA", "ESProducerB", "ESProducerC", "ESProducerD", "ESProducerE", "ESProducerAMulti", "ESProducerNull", "GlobalProducer", "GlobalProducerE", "StreamProducer", "StreamInstanceProducer",