From c607f8ad4a64b6bf09ea42cf07510370a5573ad8 Mon Sep 17 00:00:00 2001 From: Matti Kortelainen Date: Thu, 9 Nov 2023 17:11:13 +0100 Subject: [PATCH 1/2] Allow Portable{Collection,Object} to be used also independently of ALPAKA_ACCELERATOR_NAMESPACE --- .../Portable/interface/PortableCollection.h | 4 ++- .../interface/PortableHostCollection.h | 10 ++++++++ .../Portable/interface/PortableHostObject.h | 10 ++++++++ .../Portable/interface/PortableObject.h | 4 +-- .../interface/alpaka/PortableCollection.h | 5 +++- .../interface/alpaka/PortableObject.h | 5 +++- DataFormats/Portable/test/BuildFile.xml | 5 ++++ .../Portable/test/portableCollectionOnHost.cc | 25 +++++++++++++++++++ .../Portable/test/portableObjectOnHost.cc | 23 +++++++++++++++++ DataFormats/Portable/test/test_catch2_main.cc | 2 ++ 10 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 DataFormats/Portable/test/BuildFile.xml create mode 100644 DataFormats/Portable/test/portableCollectionOnHost.cc create mode 100644 DataFormats/Portable/test/portableObjectOnHost.cc create mode 100644 DataFormats/Portable/test/test_catch2_main.cc diff --git a/DataFormats/Portable/interface/PortableCollection.h b/DataFormats/Portable/interface/PortableCollection.h index 86d117c02c81d..9a0498944688d 100644 --- a/DataFormats/Portable/interface/PortableCollection.h +++ b/DataFormats/Portable/interface/PortableCollection.h @@ -1,13 +1,15 @@ #ifndef DataFormats_Portable_interface_PortableCollection_h #define DataFormats_Portable_interface_PortableCollection_h +#include + #include "HeterogeneousCore/AlpakaInterface/interface/traits.h" namespace traits { // trait for a generic SoA-based product template >> - class PortableCollectionTrait; + struct PortableCollectionTrait; } // namespace traits diff --git a/DataFormats/Portable/interface/PortableHostCollection.h b/DataFormats/Portable/interface/PortableHostCollection.h index 8b098688455e8..e73e70e724bb6 100644 --- a/DataFormats/Portable/interface/PortableHostCollection.h +++ b/DataFormats/Portable/interface/PortableHostCollection.h @@ -6,6 +6,7 @@ #include +#include "DataFormats/Portable/interface/PortableCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/host.h" #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" @@ -86,4 +87,13 @@ class PortableHostCollection { View view_; //! }; +// Make PortableCollection alias template to work also +// independently of ALPAKA_ACCELERATOR_NAMESPACE +namespace traits { + template + struct PortableCollectionTrait { + using CollectionType = PortableHostCollection; + }; +} // namespace traits + #endif // DataFormats_Portable_interface_PortableHostCollection_h diff --git a/DataFormats/Portable/interface/PortableHostObject.h b/DataFormats/Portable/interface/PortableHostObject.h index 348da4f8c505d..c0f476d2f2d2a 100644 --- a/DataFormats/Portable/interface/PortableHostObject.h +++ b/DataFormats/Portable/interface/PortableHostObject.h @@ -7,6 +7,7 @@ #include +#include "DataFormats/Portable/interface/PortableObject.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/host.h" #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" @@ -78,4 +79,13 @@ class PortableHostObject { Product* product_; }; +// Make PortableObject alias template to work also +// independently of ALPAKA_ACCELERATOR_NAMESPACE +namespace traits { + template + struct PortableObjectTrait { + using ProductType = PortableHostObject; + }; +} // namespace traits + #endif // DataFormats_Portable_interface_PortableHostObject_h diff --git a/DataFormats/Portable/interface/PortableObject.h b/DataFormats/Portable/interface/PortableObject.h index 90a33b49d0f0a..a4737e67e7dd7 100644 --- a/DataFormats/Portable/interface/PortableObject.h +++ b/DataFormats/Portable/interface/PortableObject.h @@ -3,13 +3,13 @@ #include -#include "HeterogeneousCore/AlpakaInterface/interface/traits.h" +#include namespace traits { // trait for a generic SoA-based product template >> - class PortableObjectTrait; + struct PortableObjectTrait; } // namespace traits diff --git a/DataFormats/Portable/interface/alpaka/PortableCollection.h b/DataFormats/Portable/interface/alpaka/PortableCollection.h index 0a6abad96dfaf..232f0eefdd038 100644 --- a/DataFormats/Portable/interface/alpaka/PortableCollection.h +++ b/DataFormats/Portable/interface/alpaka/PortableCollection.h @@ -33,15 +33,18 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } // namespace ALPAKA_ACCELERATOR_NAMESPACE +// For DevHost the specialisation is already done in the PortableHostCollection.h +#ifndef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED namespace traits { // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE template - class PortableCollectionTrait { + struct PortableCollectionTrait { using CollectionType = ALPAKA_ACCELERATOR_NAMESPACE::PortableCollection; }; } // namespace traits +#endif namespace cms::alpakatools { template diff --git a/DataFormats/Portable/interface/alpaka/PortableObject.h b/DataFormats/Portable/interface/alpaka/PortableObject.h index 9b7ba65f8a460..f58c487be7dd9 100644 --- a/DataFormats/Portable/interface/alpaka/PortableObject.h +++ b/DataFormats/Portable/interface/alpaka/PortableObject.h @@ -33,15 +33,18 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { } // namespace ALPAKA_ACCELERATOR_NAMESPACE +// For DevHost the specialisation is already done in the PortableHostCollection.h +#ifndef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED namespace traits { // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE template - class PortableObjectTrait { + struct PortableObjectTrait { using ProductType = ALPAKA_ACCELERATOR_NAMESPACE::PortableObject; }; } // namespace traits +#endif namespace cms::alpakatools { template diff --git a/DataFormats/Portable/test/BuildFile.xml b/DataFormats/Portable/test/BuildFile.xml new file mode 100644 index 0000000000000..ef2f6603f62cc --- /dev/null +++ b/DataFormats/Portable/test/BuildFile.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/DataFormats/Portable/test/portableCollectionOnHost.cc b/DataFormats/Portable/test/portableCollectionOnHost.cc new file mode 100644 index 0000000000000..aa3d56f9d0539 --- /dev/null +++ b/DataFormats/Portable/test/portableCollectionOnHost.cc @@ -0,0 +1,25 @@ +#include + +#include "DataFormats/Portable/interface/PortableCollection.h" +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/SoATemplate/interface/SoACommon.h" +#include "DataFormats/SoATemplate/interface/SoALayout.h" +#include "DataFormats/SoATemplate/interface/SoAView.h" + +namespace { + GENERATE_SOA_LAYOUT(TestLayout, SOA_COLUMN(double, x), SOA_COLUMN(int32_t, id)) + + using TestSoA = TestLayout<>; + + constexpr auto s_tag = "[PortableCollection]"; +} // namespace + +// This test is currently mostly about the code compiling +TEST_CASE("Use of PortableCollection on host code", s_tag) { + auto const size = 10; + PortableCollection coll(size, cms::alpakatools::host()); + + SECTION("Tests") { REQUIRE(coll->metadata().size() == size); } + + static_assert(std::is_same_v, PortableHostCollection>); +} diff --git a/DataFormats/Portable/test/portableObjectOnHost.cc b/DataFormats/Portable/test/portableObjectOnHost.cc new file mode 100644 index 0000000000000..698605b57f465 --- /dev/null +++ b/DataFormats/Portable/test/portableObjectOnHost.cc @@ -0,0 +1,23 @@ +#include + +#include "DataFormats/Portable/interface/PortableObject.h" +#include "DataFormats/Portable/interface/PortableHostObject.h" + +namespace { + struct Test { + int a; + float b; + }; + + constexpr auto s_tag = "[PortableObject]"; +} // namespace + +// This test is currently mostly about the code compiling +TEST_CASE("Use of PortableObject on host code", s_tag) { + PortableObject obj(cms::alpakatools::host()); + obj->a = 42; + + SECTION("Tests") { REQUIRE(obj->a == 42); } + + static_assert(std::is_same_v, PortableHostObject>); +} diff --git a/DataFormats/Portable/test/test_catch2_main.cc b/DataFormats/Portable/test/test_catch2_main.cc new file mode 100644 index 0000000000000..b3143fbb1788b --- /dev/null +++ b/DataFormats/Portable/test/test_catch2_main.cc @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include From 1143991b0e5c92f27219d93f011059b7dc947ce6 Mon Sep 17 00:00:00 2001 From: Matti Kortelainen Date: Wed, 8 Nov 2023 18:57:12 +0100 Subject: [PATCH 2/2] Simplify the definition of Portable{Collection,Object} alias templates Also move the CopyTo{Host,Device} specialisations to interface/ as they are independent from ALPAKA_ACCELERATOR_NAMESPACE. --- .../Portable/interface/PortableCollection.h | 39 ++++++++++++- .../interface/PortableHostCollection.h | 10 ---- .../Portable/interface/PortableHostObject.h | 10 ---- .../Portable/interface/PortableObject.h | 43 ++++++++++++++- .../interface/alpaka/PortableCollection.h | 55 +------------------ .../interface/alpaka/PortableObject.h | 55 +------------------ 6 files changed, 81 insertions(+), 131 deletions(-) diff --git a/DataFormats/Portable/interface/PortableCollection.h b/DataFormats/Portable/interface/PortableCollection.h index 9a0498944688d..abc64b99cb0d3 100644 --- a/DataFormats/Portable/interface/PortableCollection.h +++ b/DataFormats/Portable/interface/PortableCollection.h @@ -3,13 +3,24 @@ #include -#include "HeterogeneousCore/AlpakaInterface/interface/traits.h" +#include "DataFormats/Portable/interface/PortableHostCollection.h" +#include "DataFormats/Portable/interface/PortableDeviceCollection.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h" namespace traits { // trait for a generic SoA-based product template >> - struct PortableCollectionTrait; + struct PortableCollectionTrait { + using CollectionType = PortableDeviceCollection; + }; + + // specialise for host device + template + struct PortableCollectionTrait { + using CollectionType = PortableHostCollection; + }; } // namespace traits @@ -17,4 +28,28 @@ namespace traits { template >> using PortableCollection = typename traits::PortableCollectionTrait::CollectionType; +// define how to copy PortableCollection between host and device +namespace cms::alpakatools { + template + struct CopyToHost> { + template + static auto copyAsync(TQueue& queue, PortableDeviceCollection const& srcData) { + PortableHostCollection dstData(srcData->metadata().size(), queue); + alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); + return dstData; + } + }; + + template + struct CopyToDevice> { + template + static auto copyAsync(TQueue& queue, PortableHostCollection const& srcData) { + using TDevice = typename alpaka::trait::DevType::type; + PortableDeviceCollection dstData(srcData->metadata().size(), queue); + alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); + return dstData; + } + }; +} // namespace cms::alpakatools + #endif // DataFormats_Portable_interface_PortableCollection_h diff --git a/DataFormats/Portable/interface/PortableHostCollection.h b/DataFormats/Portable/interface/PortableHostCollection.h index e73e70e724bb6..8b098688455e8 100644 --- a/DataFormats/Portable/interface/PortableHostCollection.h +++ b/DataFormats/Portable/interface/PortableHostCollection.h @@ -6,7 +6,6 @@ #include -#include "DataFormats/Portable/interface/PortableCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/host.h" #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" @@ -87,13 +86,4 @@ class PortableHostCollection { View view_; //! }; -// Make PortableCollection alias template to work also -// independently of ALPAKA_ACCELERATOR_NAMESPACE -namespace traits { - template - struct PortableCollectionTrait { - using CollectionType = PortableHostCollection; - }; -} // namespace traits - #endif // DataFormats_Portable_interface_PortableHostCollection_h diff --git a/DataFormats/Portable/interface/PortableHostObject.h b/DataFormats/Portable/interface/PortableHostObject.h index c0f476d2f2d2a..348da4f8c505d 100644 --- a/DataFormats/Portable/interface/PortableHostObject.h +++ b/DataFormats/Portable/interface/PortableHostObject.h @@ -7,7 +7,6 @@ #include -#include "DataFormats/Portable/interface/PortableObject.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" #include "HeterogeneousCore/AlpakaInterface/interface/host.h" #include "HeterogeneousCore/AlpakaInterface/interface/memory.h" @@ -79,13 +78,4 @@ class PortableHostObject { Product* product_; }; -// Make PortableObject alias template to work also -// independently of ALPAKA_ACCELERATOR_NAMESPACE -namespace traits { - template - struct PortableObjectTrait { - using ProductType = PortableHostObject; - }; -} // namespace traits - #endif // DataFormats_Portable_interface_PortableHostObject_h diff --git a/DataFormats/Portable/interface/PortableObject.h b/DataFormats/Portable/interface/PortableObject.h index a4737e67e7dd7..c9aadb160bb05 100644 --- a/DataFormats/Portable/interface/PortableObject.h +++ b/DataFormats/Portable/interface/PortableObject.h @@ -5,16 +5,53 @@ #include +#include "DataFormats/Portable/interface/PortableHostObject.h" +#include "DataFormats/Portable/interface/PortableDeviceObject.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" +#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h" + namespace traits { - // trait for a generic SoA-based product + // trait for a generic struct-based product template >> - struct PortableObjectTrait; + struct PortableObjectTrait { + using ProductType = PortableDeviceObject; + }; + + // specialise for host device + template + struct PortableObjectTrait { + using ProductType = PortableHostObject; + }; } // namespace traits -// type alias for a generic SoA-based product +// type alias for a generic struct-based product template >> using PortableObject = typename traits::PortableObjectTrait::ProductType; +// define how to copy PortableObject between host and device +namespace cms::alpakatools { + template + struct CopyToHost> { + template + static auto copyAsync(TQueue& queue, PortableDeviceObject const& srcData) { + PortableHostObject dstData(queue); + alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); + return dstData; + } + }; + + template + struct CopyToDevice> { + template + static auto copyAsync(TQueue& queue, PortableHostObject const& srcData) { + using TDevice = typename alpaka::trait::DevType::type; + PortableDeviceObject dstData(queue); + alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); + return dstData; + } + }; +} // namespace cms::alpakatools + #endif // DataFormats_Portable_interface_PortableObject_h diff --git a/DataFormats/Portable/interface/alpaka/PortableCollection.h b/DataFormats/Portable/interface/alpaka/PortableCollection.h index 232f0eefdd038..1f9fa22e49cd8 100644 --- a/DataFormats/Portable/interface/alpaka/PortableCollection.h +++ b/DataFormats/Portable/interface/alpaka/PortableCollection.h @@ -4,11 +4,7 @@ #include #include "DataFormats/Portable/interface/PortableCollection.h" -#include "DataFormats/Portable/interface/PortableHostCollection.h" -#include "DataFormats/Portable/interface/PortableDeviceCollection.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" -#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" -#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h" // This header is not used by PortableCollection, but is included here to automatically // provide its content to users of ALPAKA_ACCELERATOR_NAMESPACE::PortableCollection. @@ -16,57 +12,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { -#if defined ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED - // ... or any other CPU-based accelerators - - // generic SoA-based product in host memory - template - using PortableCollection = ::PortableHostCollection; - -#else - - // generic SoA-based product in device memory + // generic SoA-based product in the device (that may be host) memory template - using PortableCollection = ::PortableDeviceCollection; - -#endif // ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED + using PortableCollection = ::PortableCollection; } // namespace ALPAKA_ACCELERATOR_NAMESPACE -// For DevHost the specialisation is already done in the PortableHostCollection.h -#ifndef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED -namespace traits { - - // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE - template - struct PortableCollectionTrait { - using CollectionType = ALPAKA_ACCELERATOR_NAMESPACE::PortableCollection; - }; - -} // namespace traits -#endif - -namespace cms::alpakatools { - template - struct CopyToHost> { - template - static auto copyAsync(TQueue& queue, PortableDeviceCollection const& srcData) { - PortableHostCollection dstData(srcData->metadata().size(), queue); - alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); - return dstData; - } - }; - - template - struct CopyToDevice> { - template - static auto copyAsync(TQueue& queue, PortableHostCollection const& srcData) { - using TDevice = typename alpaka::trait::DevType::type; - PortableDeviceCollection dstData(srcData->metadata().size(), queue); - alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); - return dstData; - } - }; -} // namespace cms::alpakatools - #endif // DataFormats_Portable_interface_alpaka_PortableCollection_h diff --git a/DataFormats/Portable/interface/alpaka/PortableObject.h b/DataFormats/Portable/interface/alpaka/PortableObject.h index f58c487be7dd9..417173176b203 100644 --- a/DataFormats/Portable/interface/alpaka/PortableObject.h +++ b/DataFormats/Portable/interface/alpaka/PortableObject.h @@ -4,11 +4,7 @@ #include #include "DataFormats/Portable/interface/PortableObject.h" -#include "DataFormats/Portable/interface/PortableHostObject.h" -#include "DataFormats/Portable/interface/PortableDeviceObject.h" #include "HeterogeneousCore/AlpakaInterface/interface/config.h" -#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h" -#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h" // This header is not used by PortableObject, but is included here to automatically // provide its content to users of ALPAKA_ACCELERATOR_NAMESPACE::PortableObject. @@ -16,57 +12,10 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE { -#if defined ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED - // ... or any other CPU-based accelerators - - // generic SoA-based product in host memory - template - using PortableObject = ::PortableHostObject; - -#else - - // generic SoA-based product in device memory + // generic struct-based product in the device (that may be host) memory template - using PortableObject = ::PortableDeviceObject; - -#endif // ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED + using PortableObject = ::PortableObject; } // namespace ALPAKA_ACCELERATOR_NAMESPACE -// For DevHost the specialisation is already done in the PortableHostCollection.h -#ifndef ALPAKA_ACC_CPU_B_SEQ_T_SEQ_ENABLED -namespace traits { - - // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE - template - struct PortableObjectTrait { - using ProductType = ALPAKA_ACCELERATOR_NAMESPACE::PortableObject; - }; - -} // namespace traits -#endif - -namespace cms::alpakatools { - template - struct CopyToHost> { - template - static auto copyAsync(TQueue& queue, PortableDeviceObject const& srcData) { - PortableHostObject dstData(queue); - alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); - return dstData; - } - }; - - template - struct CopyToDevice> { - template - static auto copyAsync(TQueue& queue, PortableHostObject const& srcData) { - using TDevice = typename alpaka::trait::DevType::type; - PortableDeviceObject dstData(queue); - alpaka::memcpy(queue, dstData.buffer(), srcData.buffer()); - return dstData; - } - }; -} // namespace cms::alpakatools - #endif // DataFormats_Portable_interface_alpaka_PortableObject_h