diff --git a/DataFormats/Portable/interface/PortableCollection.h b/DataFormats/Portable/interface/PortableCollection.h index 86d117c02c81d..abc64b99cb0d3 100644 --- a/DataFormats/Portable/interface/PortableCollection.h +++ b/DataFormats/Portable/interface/PortableCollection.h @@ -1,13 +1,26 @@ #ifndef DataFormats_Portable_interface_PortableCollection_h #define DataFormats_Portable_interface_PortableCollection_h -#include "HeterogeneousCore/AlpakaInterface/interface/traits.h" +#include + +#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 >> - class PortableCollectionTrait; + struct PortableCollectionTrait { + using CollectionType = PortableDeviceCollection; + }; + + // specialise for host device + template + struct PortableCollectionTrait { + using CollectionType = PortableHostCollection; + }; } // namespace traits @@ -15,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/PortableObject.h b/DataFormats/Portable/interface/PortableObject.h index 90a33b49d0f0a..c9aadb160bb05 100644 --- a/DataFormats/Portable/interface/PortableObject.h +++ b/DataFormats/Portable/interface/PortableObject.h @@ -3,18 +3,55 @@ #include -#include "HeterogeneousCore/AlpakaInterface/interface/traits.h" +#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 >> - class 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 0a6abad96dfaf..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,54 +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 -namespace traits { - - // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE - template - class PortableCollectionTrait { - using CollectionType = ALPAKA_ACCELERATOR_NAMESPACE::PortableCollection; - }; - -} // namespace traits - -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 9b7ba65f8a460..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,54 +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 -namespace traits { - - // specialise the trait for the device provided by the ALPAKA_ACCELERATOR_NAMESPACE - template - class PortableObjectTrait { - using ProductType = ALPAKA_ACCELERATOR_NAMESPACE::PortableObject; - }; - -} // namespace traits - -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 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