diff --git a/DataFormats/BeamSpot/plugins/BuildFile.xml b/DataFormats/BeamSpot/plugins/BuildFile.xml
index fb0d04138c776..e44b8170bd266 100644
--- a/DataFormats/BeamSpot/plugins/BuildFile.xml
+++ b/DataFormats/BeamSpot/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/BeamSpot/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/BeamSpot/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..c72d53adc73ed
--- /dev/null
+++ b/DataFormats/BeamSpot/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/BeamSpot/interface/alpaka/BeamSpotDevice.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(BeamSpotDevice);
diff --git a/DataFormats/EcalDigi/plugins/BuildFile.xml b/DataFormats/EcalDigi/plugins/BuildFile.xml
index 500770828ac90..5435a558786a9 100644
--- a/DataFormats/EcalDigi/plugins/BuildFile.xml
+++ b/DataFormats/EcalDigi/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/EcalDigi/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/EcalDigi/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..198b397cb647a
--- /dev/null
+++ b/DataFormats/EcalDigi/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/EcalDigi/interface/alpaka/EcalDigiDeviceCollection.h"
+#include "DataFormats/EcalDigi/interface/alpaka/EcalDigiPhase2DeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(EcalDigiDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(EcalDigiPhase2DeviceCollection);
diff --git a/DataFormats/EcalRecHit/plugins/BuildFile.xml b/DataFormats/EcalRecHit/plugins/BuildFile.xml
index ee7c656ef4f71..c4e18d6203b84 100644
--- a/DataFormats/EcalRecHit/plugins/BuildFile.xml
+++ b/DataFormats/EcalRecHit/plugins/BuildFile.xml
@@ -3,3 +3,9 @@
+
+
+
+
+
+
diff --git a/DataFormats/EcalRecHit/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/EcalRecHit/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..b716a3b99a2ea
--- /dev/null
+++ b/DataFormats/EcalRecHit/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/EcalRecHit/interface/alpaka/EcalRecHitDeviceCollection.h"
+#include "DataFormats/EcalRecHit/interface/alpaka/EcalUncalibratedRecHitDeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(EcalRecHitDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(EcalUncalibratedRecHitDeviceCollection);
diff --git a/DataFormats/HGCalDigi/plugins/BuildFile.xml b/DataFormats/HGCalDigi/plugins/BuildFile.xml
index f22493a26579e..e78b43afc1749 100644
--- a/DataFormats/HGCalDigi/plugins/BuildFile.xml
+++ b/DataFormats/HGCalDigi/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/HGCalDigi/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/HGCalDigi/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..fbc2e7d8d8c1c
--- /dev/null
+++ b/DataFormats/HGCalDigi/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,8 @@
+#include "DataFormats/HGCalDigi/interface/alpaka/HGCalDigiDevice.h"
+#include "DataFormats/HGCalDigi/interface/alpaka/HGCalECONDPacketInfoDevice.h"
+#include "DataFormats/HGCalDigi/interface/alpaka/HGCalFEDPacketInfoDevice.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hgcaldigi::HGCalDigiDevice);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hgcaldigi::HGCalECONDPacketInfoDevice);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hgcaldigi::HGCalFEDPacketInfoDevice);
diff --git a/DataFormats/HGCalReco/plugins/BuildFile.xml b/DataFormats/HGCalReco/plugins/BuildFile.xml
index 1171aee28adb6..2e4bb422d2949 100644
--- a/DataFormats/HGCalReco/plugins/BuildFile.xml
+++ b/DataFormats/HGCalReco/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/HGCalReco/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/HGCalReco/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..bb0b22d0498d2
--- /dev/null
+++ b/DataFormats/HGCalReco/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,8 @@
+#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoAClustersDeviceCollection.h"
+#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsExtraDeviceCollection.h"
+#include "DataFormats/HGCalReco/interface/alpaka/HGCalSoARecHitsDeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(HGCalSoAClustersDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(HGCalSoARecHitsExtraDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(HGCalSoARecHitsDeviceCollection);
diff --git a/DataFormats/HcalDigi/plugins/BuildFile.xml b/DataFormats/HcalDigi/plugins/BuildFile.xml
index a627d6e7e1a0a..9fe9065002388 100644
--- a/DataFormats/HcalDigi/plugins/BuildFile.xml
+++ b/DataFormats/HcalDigi/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/HcalDigi/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/HcalDigi/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..cea62bac1fe9d
--- /dev/null
+++ b/DataFormats/HcalDigi/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,5 @@
+#include "DataFormats/HcalDigi/interface/alpaka/HcalDigiDeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hcal::Phase0DigiDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hcal::Phase1DigiDeviceCollection);
diff --git a/DataFormats/HcalRecHit/plugins/BuildFile.xml b/DataFormats/HcalRecHit/plugins/BuildFile.xml
index 07725848fdb30..85446ad991e7f 100644
--- a/DataFormats/HcalRecHit/plugins/BuildFile.xml
+++ b/DataFormats/HcalRecHit/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/HcalRecHit/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/HcalRecHit/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..76d4f0a4b69ed
--- /dev/null
+++ b/DataFormats/HcalRecHit/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/HcalRecHit/interface/alpaka/HcalRecHitDeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(hcal::RecHitDeviceCollection);
diff --git a/DataFormats/ParticleFlowReco/plugins/BuildFile.xml b/DataFormats/ParticleFlowReco/plugins/BuildFile.xml
index e20859b77da70..0d7521b2511fa 100644
--- a/DataFormats/ParticleFlowReco/plugins/BuildFile.xml
+++ b/DataFormats/ParticleFlowReco/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/ParticleFlowReco/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/ParticleFlowReco/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..13b2aa9d7aaa8
--- /dev/null
+++ b/DataFormats/ParticleFlowReco/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,13 @@
+// Include the Eigen core library before including the SoA definitions
+#include
+
+#include "DataFormats/ParticleFlowReco/interface/alpaka/CaloRecHitDeviceCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/alpaka/PFClusterDeviceCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/alpaka/PFRecHitFractionDeviceCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/alpaka/PFRecHitDeviceCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::CaloRecHitDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::PFClusterDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::PFRecHitFractionDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::PFRecHitDeviceCollection);
diff --git a/DataFormats/Portable/interface/PortableDeviceCollection.h b/DataFormats/Portable/interface/PortableDeviceCollection.h
index ec357e8ecdcc0..76c1c556bb11b 100644
--- a/DataFormats/Portable/interface/PortableDeviceCollection.h
+++ b/DataFormats/Portable/interface/PortableDeviceCollection.h
@@ -12,6 +12,7 @@
#include "DataFormats/Common/interface/Uninitialized.h"
#include "DataFormats/Portable/interface/PortableCollectionCommon.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -146,4 +147,38 @@ class PortableDeviceCollection {
View view_; //!
};
+namespace ngt {
+
+ // Specialize MemoryCopyTraits for PortableDeviceCollection
+ template
+ struct MemoryCopyTraits> {
+ using value_type = PortableDeviceCollection;
+
+ // Properties are the collection size: T::size_type, or std::array for SoABlocks.
+ using Properties = decltype(std::declval()->metadata().size());
+
+ static Properties properties(value_type const& object) { return object->metadata().size(); }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& size) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in global device memory
+ object = value_type(queue, size);
+ }
+
+ static std::vector> regions(value_type& object) {
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(value_type const& object) {
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+} // namespace ngt
+
#endif // DataFormats_Portable_interface_PortableDeviceCollection_h
diff --git a/DataFormats/Portable/interface/PortableDeviceObject.h b/DataFormats/Portable/interface/PortableDeviceObject.h
index 5cbd139a59752..4618c2d26eb95 100644
--- a/DataFormats/Portable/interface/PortableDeviceObject.h
+++ b/DataFormats/Portable/interface/PortableDeviceObject.h
@@ -8,6 +8,7 @@
#include
#include "DataFormats/Common/interface/Uninitialized.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -80,4 +81,28 @@ class PortableDeviceObject {
std::optional buffer_;
};
+namespace ngt {
+
+ // Specialize MemoryCopyTraits for PortableDeviceObject
+ template
+ struct MemoryCopyTraits> {
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, PortableDeviceObject& object) {
+ // Replace the default-constructed empty object with one where the
+ // buffer has been allocated in global device memory
+ object = PortableDeviceObject(queue);
+ }
+
+ static std::vector> regions(PortableDeviceObject& object) {
+ return {{reinterpret_cast(object.data()), sizeof(T)}};
+ }
+
+ static std::vector> regions(PortableDeviceObject const& object) {
+ return {{reinterpret_cast(object.data()), sizeof(T)}};
+ }
+ };
+
+} // namespace ngt
+
#endif // DataFormats_Portable_interface_PortableDeviceObject_h
diff --git a/DataFormats/Portable/interface/PortableHostCollection.h b/DataFormats/Portable/interface/PortableHostCollection.h
index c793fbf6d87fb..52c7c1720b660 100644
--- a/DataFormats/Portable/interface/PortableHostCollection.h
+++ b/DataFormats/Portable/interface/PortableHostCollection.h
@@ -200,8 +200,17 @@ namespace ngt {
// The properties needed to initialize a new PrortableHostCollection are just its size.
static Properties properties(value_type const& object) { return object->metadata().size(); }
- // Replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory.
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& size) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory.
+ object = value_type(queue, size);
+ }
+
static void initialize(value_type& object, Properties const& size) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
object = value_type(cms::alpakatools::host(), size);
}
diff --git a/DataFormats/Portable/interface/PortableHostObject.h b/DataFormats/Portable/interface/PortableHostObject.h
index 1c39278be414b..48cba17f51662 100644
--- a/DataFormats/Portable/interface/PortableHostObject.h
+++ b/DataFormats/Portable/interface/PortableHostObject.h
@@ -121,11 +121,21 @@ namespace ngt {
template
struct MemoryCopyTraits> {
- // This specialisation requires a initialize() method, but does not need to pass any parameters to it.
+ // This specialisation requires an initialize() method, but does not need to
+ // pass any parameters to it.
using Properties = void;
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, PortableHostObject& object) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory
+ object = PortableHostObject(queue);
+ }
+
static void initialize(PortableHostObject& object) {
- // Replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory.
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
object = PortableHostObject(cms::alpakatools::host());
}
diff --git a/DataFormats/PortableTestObjects/plugins/BuildFile.xml b/DataFormats/PortableTestObjects/plugins/BuildFile.xml
index bac81f07c93fc..67e28a8fa6daf 100644
--- a/DataFormats/PortableTestObjects/plugins/BuildFile.xml
+++ b/DataFormats/PortableTestObjects/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/PortableTestObjects/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/PortableTestObjects/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..9ebb83cb1c748
--- /dev/null
+++ b/DataFormats/PortableTestObjects/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,20 @@
+#include "DataFormats/PortableTestObjects/interface/alpaka/ImageDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/LogitsDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/MaskDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/MultiHeadNetDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/ParticleDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/SimpleNetDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/TestDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/TestDeviceObject.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::ImageDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::LogitsDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::MaskDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::MultiHeadNetDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::ParticleDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::SimpleNetDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::TestDeviceCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::TestDeviceCollection2);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::TestDeviceCollection3);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(portabletest::TestDeviceObject);
diff --git a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersDevice.h b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersDevice.h
index 5e3755d3d78a8..c0cb96fcb6998 100644
--- a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersDevice.h
+++ b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersDevice.h
@@ -9,6 +9,7 @@
#include "DataFormats/Portable/interface/PortableDeviceCollection.h"
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h"
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersSoA.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h"
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
@@ -18,11 +19,11 @@ class SiPixelClustersDevice : public PortableDeviceCollection{edm::kUninitialized} {}
template
- explicit SiPixelClustersDevice(size_t maxModules, TQueue queue)
+ explicit SiPixelClustersDevice(TQueue queue, size_t maxModules)
: PortableDeviceCollection(queue, maxModules + 1) {}
// Constructor which specifies the SoA size
- explicit SiPixelClustersDevice(size_t maxModules, TDev const &device)
+ explicit SiPixelClustersDevice(TDev const& device, size_t maxModules)
: PortableDeviceCollection(device, maxModules + 1) {}
void setNClusters(uint32_t nClusters, int32_t offsetBPIX2) {
@@ -38,4 +39,45 @@ class SiPixelClustersDevice : public PortableDeviceCollection
+ struct MemoryCopyTraits> {
+ using value_type = SiPixelClustersDevice;
+
+ struct Properties {
+ int size;
+ uint32_t nClusters;
+ int32_t offsetBPIX2;
+ };
+
+ static Properties properties(value_type const& object) {
+ return {object->metadata().size() - 1, object.nClusters(), object.offsetBPIX2()};
+ }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& prop) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in device global memory.
+ object = value_type(queue, prop.size);
+ object.setNClusters(prop.nClusters, prop.offsetBPIX2);
+ }
+
+ static std::vector> regions(value_type& object) {
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(value_type const& object) {
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+
+} // namespace ngt
+
#endif // DataFormats_SiPixelClusterSoA_interface_SiPixelClustersDevice_h
diff --git a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
index b35413e0fc33c..91044d31c210c 100644
--- a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
+++ b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
@@ -14,11 +14,20 @@
// See: https://github.com/cms-sw/cmssw/pull/40465#discussion_r1067364306
class SiPixelClustersHost : public PortableHostCollection {
public:
- SiPixelClustersHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ explicit SiPixelClustersHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
- // FIXME add an explicit overload for the host case
+ // Constructor for code that does not use alpaka explicitly, using the global "host" object returned by cms::alpakatools::host(), construct the object in pageable system memory.
+ explicit SiPixelClustersHost(size_t maxModules)
+ : PortableHostCollection(cms::alpakatools::host(), maxModules + 1) {}
+
+ // Construct the object in pageable system memory.
+ explicit SiPixelClustersHost(alpaka_common::DevHost const& host, size_t maxModules)
+ : PortableHostCollection(host, maxModules + 1) {}
+
+ // Construct the object in pinned host memory associated to the given work queue, accessible by the queue's device.
template
- explicit SiPixelClustersHost(size_t maxModules, TQueue queue)
+ requires(alpaka::isQueue)
+ explicit SiPixelClustersHost(TQueue queue, size_t maxModules)
: PortableHostCollection(queue, maxModules + 1) {}
void setNClusters(uint32_t nClusters, int32_t offsetBPIX2) {
@@ -51,8 +60,18 @@ namespace ngt {
}
static void initialize(value_type& object, Properties const& prop) {
- // replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory
- object = value_type(prop.size, cms::alpakatools::host());
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
+ object = value_type(cms::alpakatools::host(), prop.size);
+ object.setNClusters(prop.nClusters, prop.offsetBPIX2);
+ }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& prop) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory.
+ object = value_type(queue, prop.size);
object.setNClusters(prop.nClusters, prop.offsetBPIX2);
}
diff --git a/DataFormats/SiPixelClusterSoA/interface/alpaka/SiPixelClustersSoACollection.h b/DataFormats/SiPixelClusterSoA/interface/alpaka/SiPixelClustersSoACollection.h
index 2563f08810eca..d2af62faf77c2 100644
--- a/DataFormats/SiPixelClusterSoA/interface/alpaka/SiPixelClustersSoACollection.h
+++ b/DataFormats/SiPixelClusterSoA/interface/alpaka/SiPixelClustersSoACollection.h
@@ -21,7 +21,7 @@ namespace cms::alpakatools {
template
static auto copyAsync(TQueue &queue, SiPixelClustersDevice const &srcData) {
// SiPixelClustersHost and SiPixelClustersDevice have a capacity larger than the ctor argument by one
- SiPixelClustersHost dstData(srcData->metadata().size() - 1, queue);
+ SiPixelClustersHost dstData(queue, srcData->metadata().size() - 1);
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
dstData.setNClusters(srcData.nClusters(), srcData.offsetBPIX2());
#ifdef GPU_DEBUG //keeping this untiil copies are in the Tracer
diff --git a/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml b/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml
index 373ad21b5af1b..516ca76281cff 100644
--- a/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml
+++ b/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/SiPixelClusterSoA/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/SiPixelClusterSoA/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..c0493fa10a264
--- /dev/null
+++ b/DataFormats/SiPixelClusterSoA/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/SiPixelClusterSoA/interface/alpaka/SiPixelClustersSoACollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(SiPixelClustersSoACollection);
diff --git a/DataFormats/SiPixelClusterSoA/test/alpaka/Clusters_test.cc b/DataFormats/SiPixelClusterSoA/test/alpaka/Clusters_test.cc
index 26d0c656016a3..10bcb78b620e6 100644
--- a/DataFormats/SiPixelClusterSoA/test/alpaka/Clusters_test.cc
+++ b/DataFormats/SiPixelClusterSoA/test/alpaka/Clusters_test.cc
@@ -33,12 +33,12 @@ int main() {
{
// Instantiate tracks on device. PortableDeviceCollection allocates
// SoA on device automatically.
- SiPixelClustersSoACollection clusters_d(100, queue);
+ SiPixelClustersSoACollection clusters_d(queue, 100);
testClusterSoA::runKernels(clusters_d.view(), queue);
// Instantate tracks on host. This is where the data will be
// copied to from device.
- SiPixelClustersHost clusters_h(clusters_d.view().metadata().size(), queue);
+ SiPixelClustersHost clusters_h(queue, clusters_d.view().metadata().size());
std::cout << clusters_h.view().metadata().size() << std::endl;
alpaka::memcpy(queue, clusters_h.buffer(), clusters_d.const_buffer());
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsDevice.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsDevice.h
index ba08151cec922..5c2a9a5387d2b 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsDevice.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsDevice.h
@@ -19,11 +19,11 @@ class SiPixelDigiErrorsDevice : public PortableDeviceCollection{edm::kUninitialized} {}
template
- explicit SiPixelDigiErrorsDevice(size_t maxFedWords, TQueue queue)
+ requires(alpaka::isQueue)
+ explicit SiPixelDigiErrorsDevice(TQueue queue, size_t maxFedWords)
: PortableDeviceCollection(queue, maxFedWords), maxFedWords_(maxFedWords) {}
- // Constructor which specifies the SoA size
- explicit SiPixelDigiErrorsDevice(size_t maxFedWords, TDev const& device)
+ explicit SiPixelDigiErrorsDevice(TDev const& device, size_t maxFedWords)
: PortableDeviceCollection(device, maxFedWords) {}
auto maxFedWords() const { return maxFedWords_; }
@@ -32,4 +32,39 @@ class SiPixelDigiErrorsDevice : public PortableDeviceCollection
+ struct MemoryCopyTraits> {
+ using value_type = SiPixelDigiErrorsDevice;
+ struct Properties {
+ int maxFedWords;
+ };
+
+ static Properties properties(value_type const& object) { return {object.maxFedWords()}; }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& props) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in device global memory.
+ object = value_type(queue, props.maxFedWords);
+ }
+
+ static std::vector> regions(value_type& object) {
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(value_type const& object) {
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+
+} // namespace ngt
+
#endif // DataFormats_SiPixelDigiSoA_interface_SiPixelDigiErrorsDevice_h
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
index 228161219f875..718ef99e5e7d7 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
@@ -15,10 +15,25 @@
class SiPixelDigiErrorsHost : public PortableHostCollection {
public:
- SiPixelDigiErrorsHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ explicit SiPixelDigiErrorsHost(edm::Uninitialized)
+ : PortableHostCollection{edm::kUninitialized} {}
+ // Constructor for code that does not use alpaka explicitly, using the global
+ // "host" object returned by cms::alpakatools::host().
+ // Construct the object in pageable host memory.
+ explicit SiPixelDigiErrorsHost(size_t maxFedWords)
+ : PortableHostCollection(cms::alpakatools::host(), maxFedWords),
+ maxFedWords_(maxFedWords) {}
+
+ // Construct the object in pageable host memory.
+ explicit SiPixelDigiErrorsHost(alpaka_common::DevHost const& host, size_t maxFedWords)
+ : PortableHostCollection(host, maxFedWords), maxFedWords_(maxFedWords) {}
+
+ // Construct the object in pinned host memory associated to the given work
+ // queue, accessible by the queue's device.
template
- explicit SiPixelDigiErrorsHost(int maxFedWords, TQueue queue)
+ requires(alpaka::isQueue)
+ explicit SiPixelDigiErrorsHost(TQueue queue, int maxFedWords)
: PortableHostCollection(queue, maxFedWords), maxFedWords_(maxFedWords) {}
int maxFedWords() const { return maxFedWords_; }
@@ -27,7 +42,7 @@ class SiPixelDigiErrorsHost : public PortableHostCollection
@@ -40,8 +55,17 @@ namespace ngt {
static Properties properties(value_type const& object) { return {object.maxFedWords()}; }
static void initialize(value_type& object, Properties const& props) {
- // replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory
- object = value_type(props.maxFedWords, cms::alpakatools::host());
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
+ object = value_type(cms::alpakatools::host(), props.maxFedWords);
+ }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& props) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory.
+ object = value_type(queue, props.maxFedWords);
}
static std::vector> regions(value_type& object) {
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisDevice.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisDevice.h
index dde2dd2d20c80..2ae9037c5c06c 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisDevice.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisDevice.h
@@ -13,14 +13,15 @@
template
class SiPixelDigisDevice : public PortableDeviceCollection {
public:
- SiPixelDigisDevice(edm::Uninitialized) : PortableDeviceCollection{edm::kUninitialized} {}
+ explicit SiPixelDigisDevice(edm::Uninitialized)
+ : PortableDeviceCollection{edm::kUninitialized} {}
template
- explicit SiPixelDigisDevice(size_t maxFedWords, TQueue queue)
+ requires(alpaka::isQueue)
+ explicit SiPixelDigisDevice(TQueue queue, size_t maxFedWords)
: PortableDeviceCollection(queue, maxFedWords + 1) {}
- // Constructor which specifies the SoA size
- explicit SiPixelDigisDevice(size_t maxFedWords, TDev const &device)
+ explicit SiPixelDigisDevice(TDev const& device, size_t maxFedWords)
: PortableDeviceCollection(device, maxFedWords + 1) {}
void setNModules(uint32_t nModules) { nModules_h = nModules; }
@@ -32,4 +33,41 @@ class SiPixelDigisDevice : public PortableDeviceCollection
+ struct MemoryCopyTraits> {
+ using value_type = SiPixelDigisDevice;
+ struct Properties {
+ uint32_t nDigis;
+ uint32_t nModules;
+ };
+
+ static Properties properties(value_type const& object) { return {object.nDigis(), object.nModules()}; }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& props) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in global device memory.
+ object = value_type(queue, props.nDigis);
+ object.setNModules(props.nModules);
+ }
+
+ static std::vector> regions(value_type& object) {
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(value_type const& object) {
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+
+} // namespace ngt
+
#endif // DataFormats_SiPixelDigiSoA_interface_SiPixelDigisDevice_h
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
index 167ce5be60402..4949634fd4b09 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
@@ -11,10 +11,23 @@
// See: https://github.com/cms-sw/cmssw/pull/40465#discussion_r1067364306
class SiPixelDigisHost : public PortableHostCollection {
public:
- SiPixelDigisHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ explicit SiPixelDigisHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ // Constructor for code that does not use alpaka explicitly, using the global
+ // "host" object returned by cms::alpakatools::host().
+ // Construct the object in pageable host memory.
+ explicit SiPixelDigisHost(size_t maxFedWords)
+ : PortableHostCollection(cms::alpakatools::host(), maxFedWords + 1) {}
+
+ // Construct the object in pageable host memory.
+ explicit SiPixelDigisHost(alpaka_common::DevHost const& host, size_t maxFedWords)
+ : PortableHostCollection(host, maxFedWords + 1) {}
+
+ // Construct the object in pinned host memory associated to the given work
+ // queue, accessible by the queue's device.
template
- explicit SiPixelDigisHost(size_t maxFedWords, TQueue queue)
+ requires(alpaka::isQueue)
+ explicit SiPixelDigisHost(TQueue queue, size_t maxFedWords)
: PortableHostCollection(queue, maxFedWords + 1) {}
void setNModules(uint32_t nModules) { nModules_h = nModules; }
@@ -40,8 +53,18 @@ namespace ngt {
static Properties properties(value_type const& object) { return {object.nDigis(), object.nModules()}; }
static void initialize(value_type& object, Properties const& props) {
- // replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory
- object = value_type(props.nDigis, cms::alpakatools::host());
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
+ object = value_type(cms::alpakatools::host(), props.nDigis);
+ object.setNModules(props.nModules);
+ }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& props) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory.
+ object = value_type(queue, props.nDigis);
object.setNModules(props.nModules);
}
diff --git a/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigiErrorsSoACollection.h b/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigiErrorsSoACollection.h
index 673a22bd23a1e..626fbba001fe2 100644
--- a/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigiErrorsSoACollection.h
+++ b/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigiErrorsSoACollection.h
@@ -6,11 +6,10 @@
#include
#include "DataFormats/Portable/interface/alpaka/PortableCollection.h"
-#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h"
#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsDevice.h"
-#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
-#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
+#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h"
+#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
namespace ALPAKA_ACCELERATOR_NAMESPACE {
@@ -24,11 +23,8 @@ namespace cms::alpakatools {
struct CopyToHost> {
template
static auto copyAsync(TQueue& queue, SiPixelDigiErrorsDevice const& srcData) {
- SiPixelDigiErrorsHost dstData(srcData.maxFedWords(), queue);
+ SiPixelDigiErrorsHost dstData(queue, srcData.maxFedWords());
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
-#ifdef GPU_DEBUG
- printf("SiPixelDigiErrorsSoACollection: I'm copying to host.\n");
-#endif
return dstData;
}
};
diff --git a/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigisSoACollection.h b/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigisSoACollection.h
index 6bc853a7970df..19d7c3dc9a853 100644
--- a/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigisSoACollection.h
+++ b/DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigisSoACollection.h
@@ -23,7 +23,7 @@ namespace cms::alpakatools {
struct CopyToHost> {
template
static auto copyAsync(TQueue &queue, SiPixelDigisDevice const &srcData) {
- SiPixelDigisHost dstData(srcData.view().metadata().size() - 1, queue);
+ SiPixelDigisHost dstData(queue, srcData.view().metadata().size() - 1);
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
dstData.setNModules(srcData.nModules());
return dstData;
diff --git a/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml b/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml
index 30b51a75552e9..24566f93d9519 100644
--- a/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml
+++ b/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/SiPixelDigiSoA/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/SiPixelDigiSoA/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..32fa6373548f4
--- /dev/null
+++ b/DataFormats/SiPixelDigiSoA/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigiErrorsSoACollection.h"
+#include "DataFormats/SiPixelDigiSoA/interface/alpaka/SiPixelDigisSoACollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(SiPixelDigiErrorsSoACollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(SiPixelDigisSoACollection);
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.cc b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.cc
index 7ce777b619aca..50ffeabe38e28 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.cc
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.cc
@@ -34,12 +34,12 @@ int main() {
{
// Instantiate tracks on device. PortableDeviceCollection allocates
// SoA on device automatically.
- SiPixelDigiErrorsSoACollection digiErrors_d(1000, queue);
- testDigisSoA::runKernels(digiErrors_d.view(), queue);
+ SiPixelDigiErrorsSoACollection digiErrors_d(queue, 1000);
+ testDigisSoA::runKernels(queue, digiErrors_d.view());
// Instantate tracks on host. This is where the data will be
// copied to from device.
- SiPixelDigiErrorsHost digiErrors_h(digiErrors_d.view().metadata().size(), queue);
+ SiPixelDigiErrorsHost digiErrors_h(queue, digiErrors_d.view().metadata().size());
alpaka::memcpy(queue, digiErrors_h.buffer(), digiErrors_d.const_buffer());
std::cout << "digiErrors_h.view().metadata().size(): " << digiErrors_h.view().metadata().size() << std::endl;
std::cout << "digiErrors_h.view()[100].pixelErrors().rawId: " << digiErrors_h.view()[100].pixelErrors().rawId
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.dev.cc b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.dev.cc
index 4ebedcb322558..7efcec13c3787 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.dev.cc
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.dev.cc
@@ -37,7 +37,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA {
}
};
- void runKernels(SiPixelDigiErrorsSoAView digiErrors_view, Queue& queue) {
+ void runKernels(Queue& queue, SiPixelDigiErrorsSoAView digiErrors_view) {
uint32_t items = 64;
uint32_t groups = cms::alpakatools::divide_up_by(digiErrors_view.metadata().size(), items);
auto workDiv = cms::alpakatools::make_workdiv(groups, items);
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.h b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.h
index 679ee9636b320..0b98ffbdea032 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.h
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/DigiErrors_test.h
@@ -6,7 +6,7 @@
namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA {
- void runKernels(SiPixelDigiErrorsSoAView digiErrors_view, Queue& queue);
+ void runKernels(Queue& queue, SiPixelDigiErrorsSoAView digiErrors_view);
} // namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.cc b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.cc
index f0914cab8277c..a97b66201f12a 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.cc
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.cc
@@ -34,12 +34,12 @@ int main() {
{
// Instantiate tracks on device. PortableDeviceCollection allocates
// SoA on device automatically.
- SiPixelDigisSoACollection digis_d(1000, queue);
- testDigisSoA::runKernels(digis_d.view(), queue);
+ SiPixelDigisSoACollection digis_d(queue, 1000);
+ testDigisSoA::runKernels(queue, digis_d.view());
// Instantate tracks on host. This is where the data will be
// copied to from device.
- SiPixelDigisHost digis_h(digis_d.view().metadata().size(), queue);
+ SiPixelDigisHost digis_h(queue, digis_d.view().metadata().size());
std::cout << digis_h.view().metadata().size() << std::endl;
alpaka::memcpy(queue, digis_h.buffer(), digis_d.const_buffer());
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.dev.cc b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.dev.cc
index 9d783655a3f33..de9b3cfac48a4 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.dev.cc
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.dev.cc
@@ -34,7 +34,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA {
}
};
- void runKernels(SiPixelDigisSoAView digi_view, Queue& queue) {
+ void runKernels(Queue& queue, SiPixelDigisSoAView digi_view) {
uint32_t items = 64;
uint32_t groups = cms::alpakatools::divide_up_by(digi_view.metadata().size(), items);
auto workDiv = cms::alpakatools::make_workdiv(groups, items);
diff --git a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.h b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.h
index fbe2ffecc0f79..026a5692bbddb 100644
--- a/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.h
+++ b/DataFormats/SiPixelDigiSoA/test/alpaka/Digis_test.h
@@ -6,7 +6,7 @@
namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA {
- void runKernels(SiPixelDigisSoAView digis_view, Queue& queue);
+ void runKernels(Queue& queue, SiPixelDigisSoAView digis_view);
} // namespace ALPAKA_ACCELERATOR_NAMESPACE::testDigisSoA
diff --git a/DataFormats/TrackSoA/plugins/BuildFile.xml b/DataFormats/TrackSoA/plugins/BuildFile.xml
index e2d5a430d6ae4..72968939bb9ef 100644
--- a/DataFormats/TrackSoA/plugins/BuildFile.xml
+++ b/DataFormats/TrackSoA/plugins/BuildFile.xml
@@ -3,3 +3,9 @@
+
+
+
+
+
+
diff --git a/DataFormats/TrackSoA/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/TrackSoA/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..35ee64a006aaf
--- /dev/null
+++ b/DataFormats/TrackSoA/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/TrackSoA/interface/alpaka/TracksSoACollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::TracksSoACollection);
diff --git a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsDevice.h b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsDevice.h
index 6f78f83df95d2..15c41d6aa5de8 100644
--- a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsDevice.h
+++ b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsDevice.h
@@ -41,7 +41,7 @@ namespace reco {
// Constructor from clusters
template
- explicit TrackingRecHitDevice(TQueue queue, SiPixelClustersDevice const &clusters)
+ explicit TrackingRecHitDevice(TQueue queue, SiPixelClustersDevice const& clusters)
: HitPortableCollectionDevice(queue, clusters.nClusters(), clusters.view().metadata().size()),
offsetBPIX2_{clusters.offsetBPIX2()} {
auto hitsView = this->view().trackingHits();
@@ -78,4 +78,40 @@ namespace reco {
};
} // namespace reco
-#endif // DataFormats_RecHits_interface_TrackingRecHitSoADevice_h
+namespace ngt {
+
+ template
+ struct MemoryCopyTraits> {
+ using value_type = reco::TrackingRecHitDevice;
+
+ struct Properties {
+ uint32_t nHits;
+ uint32_t nModules;
+ };
+
+ static Properties properties(value_type const& object) { return {object.nHits(), object.nModules()}; }
+
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& prop) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in device global memory.
+ object = value_type(queue, prop.nHits, prop.nModules);
+ }
+
+ static std::vector> regions(value_type& object) {
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(value_type const& object) {
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+
+} // namespace ngt
+
+#endif // DataFormats_TrackingRecHitSoA_interface_TrackingRecHitSoADevice_h
diff --git a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
index ca13dd0d8ff80..c0f388b2ce228 100644
--- a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
+++ b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
@@ -22,17 +22,29 @@ namespace reco {
class TrackingRecHitHost : public HitPortableCollectionHost {
public:
- TrackingRecHitHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ explicit TrackingRecHitHost(edm::Uninitialized)
+ : PortableHostCollection{edm::kUninitialized} {}
+
+ // Constructor which specifies only the SoA size, to be used when copying
+ // the results from the device to the host.
+ // Construct the object in pageable system memory.
+ explicit TrackingRecHitHost(alpaka_common::DevHost const& host, uint32_t nHits, uint32_t nModules)
+ : HitPortableCollectionHost(host, nHits, nModules + 1) {}
+ // Why this +1? See TrackingRecHitDevice.h constructor for an explanation
- // Constructor which specifies only the SoA size, to be used when copying the results from the device to the host
- // FIXME add an explicit overload for the host case
+ // Constructor which specifies only the SoA size, to be used when copying
+ // the results from the device to the host.
+ // Construct the object in pinned host memory associated to the given work
+ // queue, accessible by the queue's device.
template
+ requires(alpaka::isQueue)
explicit TrackingRecHitHost(TQueue queue, uint32_t nHits, uint32_t nModules)
: HitPortableCollectionHost(queue, nHits, nModules + 1) {}
// Why this +1? See TrackingRecHitDevice.h constructor for an explanation
// Constructor from clusters
template
+ requires(alpaka::isQueue)
explicit TrackingRecHitHost(TQueue queue, SiPixelClustersHost const& clusters)
: HitPortableCollectionHost(queue, clusters.nClusters(), clusters.view().metadata().size()) {
auto hitsView = view().trackingHits();
@@ -74,10 +86,19 @@ namespace ngt {
static Properties properties(value_type const& object) { return {object.nHits(), object.nModules()}; }
static void initialize(value_type& object, Properties const& prop) {
- // replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pageable host memory.
object = value_type(cms::alpakatools::host(), prop.nHits, prop.nModules);
}
+ template
+ requires(alpaka::isQueue)
+ static void initialize(TQueue& queue, value_type& object, Properties const& prop) {
+ // Replace the default-constructed empty object with one where the buffer
+ // has been allocated in pinned host memory.
+ object = value_type(queue, prop.nHits, prop.nModules);
+ }
+
static std::vector> regions(value_type& object) {
std::byte* address = reinterpret_cast(object.buffer().data());
size_t size = alpaka::getExtentProduct(object.buffer());
diff --git a/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml b/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml
index d1a16495ee94e..d0ee409c3c83c 100644
--- a/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml
+++ b/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/TrackingRecHitSoA/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/TrackingRecHitSoA/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..ff080ccab5de4
--- /dev/null
+++ b/DataFormats/TrackingRecHitSoA/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/TrackingRecHitSoA/interface/alpaka/TrackingRecHitsSoACollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::TrackingRecHitsSoACollection);
diff --git a/DataFormats/TrackingRecHitSoA/test/alpaka/Hits_test.cc b/DataFormats/TrackingRecHitSoA/test/alpaka/Hits_test.cc
index 2c70c326ba5b0..46d471a59b1d3 100644
--- a/DataFormats/TrackingRecHitSoA/test/alpaka/Hits_test.cc
+++ b/DataFormats/TrackingRecHitSoA/test/alpaka/Hits_test.cc
@@ -38,7 +38,7 @@ int main() {
int32_t offset = 100;
uint32_t nModules = 200;
- SiPixelClustersSoACollection clusters(nModules, queue);
+ SiPixelClustersSoACollection clusters(queue, nModules);
clusters.setNClusters(nHits, offset);
auto moduleStartH = cms::alpakatools::make_host_buffer(queue, nModules + 1);
diff --git a/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h b/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h
index 57f2511b72d7a..e56b6a0e9fdb9 100644
--- a/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h
+++ b/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h
@@ -54,36 +54,38 @@ namespace ngt {
// Checks if the properties method is defined
template
- concept HasTrivialCopyProperties = requires(T const& object) { MemoryCopyTraits::properties(object); };
+ concept HasTrivialCopyProperties = requires(T const& object) { ngt::MemoryCopyTraits::properties(object); };
// Get the return type of properties(...), if it exists.
template
- requires HasTrivialCopyProperties
- using TrivialCopyProperties = decltype(MemoryCopyTraits::properties(std::declval()));
+ requires ngt::HasTrivialCopyProperties
+ using TrivialCopyProperties = decltype(ngt::MemoryCopyTraits::properties(std::declval()));
// Checks if the declaration of initialize(...) is consistent with the presence or absence of properties.
template
concept HasValidInitialize =
// does not have properties(...) and initialize(object) takes a single argument, or
- (not HasTrivialCopyProperties and requires(T& object) { MemoryCopyTraits::initialize(object); }) or
+ (not ngt::HasTrivialCopyProperties and
+ requires(T& object) { ngt::MemoryCopyTraits::initialize(object); }) or
// does have properties(...) and initialize(object, props) takes two arguments
- (HasTrivialCopyProperties and
- requires(T& object, TrivialCopyProperties props) { MemoryCopyTraits::initialize(object, props); });
+ (ngt::HasTrivialCopyProperties and requires(T& object, ngt::TrivialCopyProperties props) {
+ ngt::MemoryCopyTraits::initialize(object, props);
+ });
// Checks for const and non const memory regions
template
concept HasRegions = requires(T& object, T const& const_object) {
- MemoryCopyTraits::regions(object);
- MemoryCopyTraits::regions(const_object);
+ ngt::MemoryCopyTraits::regions(object);
+ ngt::MemoryCopyTraits::regions(const_object);
};
// Checks if there is a valid specialisation of MemoryCopyTraits for a type T
template
concept HasMemoryCopyTraits =
// Has memory regions declared and
- (HasRegions) and
+ (ngt::HasRegions) and
// has either no initialize(...) or a valid one
- (not requires { &MemoryCopyTraits::initialize; } or HasValidInitialize);
+ (not requires { &ngt::MemoryCopyTraits::initialize; } or ngt::HasValidInitialize);
// Checks if finalize(...) is defined
template
diff --git a/DataFormats/TrivialSerialisation/test/BuildFile.xml b/DataFormats/TrivialSerialisation/test/BuildFile.xml
index 5da9ef00be32e..1ffe7d7e317ff 100644
--- a/DataFormats/TrivialSerialisation/test/BuildFile.xml
+++ b/DataFormats/TrivialSerialisation/test/BuildFile.xml
@@ -2,3 +2,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DataFormats/TrivialSerialisation/test/alpaka/test_catch2_MemoryCopyTraitsPortable.dev.cc b/DataFormats/TrivialSerialisation/test/alpaka/test_catch2_MemoryCopyTraitsPortable.dev.cc
new file mode 100644
index 0000000000000..0ba52aee959e9
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/test/alpaka/test_catch2_MemoryCopyTraitsPortable.dev.cc
@@ -0,0 +1,363 @@
+#include
+#include
+
+#include
+
+#include
+
+#include
+
+#include "DataFormats/Portable/interface/PortableCollection.h"
+#include "DataFormats/Portable/interface/PortableHostCollection.h"
+#include "DataFormats/Portable/interface/PortableHostObject.h"
+#include "DataFormats/PortableTestObjects/interface/TestSoA.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/TestDeviceCollection.h"
+#include "DataFormats/PortableTestObjects/interface/alpaka/TestDeviceObject.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
+#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
+
+using namespace ALPAKA_ACCELERATOR_NAMESPACE;
+namespace alpaka_portable_test = ALPAKA_ACCELERATOR_NAMESPACE::portabletest;
+
+/*
+ * Catch2 tests for MemoryCopyTraits specializations of portable types.
+ *
+ * This test verifies that:
+ * - PortableHostCollection has valid MemoryCopyTraits with Properties and initialize()
+ * - PortableHostObject has valid MemoryCopyTraits with initialize() but no Properties
+ * - PortableDeviceCollection has valid MemoryCopyTraits with Properties and initialize()
+ * - PortableDeviceObject has valid MemoryCopyTraits with initialize() but no Properties
+ * - Multi-block collections (SoABlocks2, SoABlocks3) have valid MemoryCopyTraits
+ *
+ * It also tests that data can be correctly copied using the MemoryCopyTraits interface
+ * for both host and device portable types.
+ */
+
+TEST_CASE("Test MemoryCopyTraits with portable types", "[MemoryCopyTraits][Portable]") {
+ auto const& devices = cms::alpakatools::devices();
+ if (devices.empty()) {
+ FAIL("No devices available for the " EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) " backend");
+ }
+
+ SECTION("PortableHostCollection checks") {
+ using HostCollectionType = PortableHostCollection>;
+
+ // PortableHostCollection should have MemoryCopyTraits
+ static_assert(::ngt::HasMemoryCopyTraits);
+ // It should have Properties (the size)
+ static_assert(::ngt::HasTrivialCopyProperties);
+ // It should have a valid initialize()
+ static_assert(::ngt::HasValidInitialize);
+ // It should have regions
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("PortableHostObject checks") {
+ using HostObjectType = PortableHostObject;
+
+ // PortableHostObject should have MemoryCopyTraits
+ static_assert(::ngt::HasMemoryCopyTraits);
+ // It should not have Properties
+ static_assert(not ::ngt::HasTrivialCopyProperties);
+ // It should have regions
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("PortableDeviceCollection checks") {
+ using DeviceCollectionType = alpaka_portable_test::TestDeviceCollection;
+
+ // PortableDeviceCollection should have MemoryCopyTraits
+ static_assert(::ngt::HasMemoryCopyTraits);
+ // It should have Properties (the size)
+ static_assert(::ngt::HasTrivialCopyProperties);
+ // It should have regions
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("PortableDeviceObject checks") {
+ using DeviceObjectType = alpaka_portable_test::TestDeviceObject;
+
+ // PortableDeviceObject should have MemoryCopyTraits
+ static_assert(::ngt::HasMemoryCopyTraits);
+ // It should not have Properties
+ static_assert(not ::ngt::HasTrivialCopyProperties);
+ // It should have regions
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("Multi-block PortableHostCollection checks") {
+ // SoABlocks2
+ using HostCollection2Type = PortableHostCollection;
+ static_assert(::ngt::HasMemoryCopyTraits);
+ static_assert(::ngt::HasTrivialCopyProperties);
+ static_assert(::ngt::HasRegions);
+
+ // SoABlocks3
+ using HostCollection3Type = PortableHostCollection;
+ static_assert(::ngt::HasMemoryCopyTraits);
+ static_assert(::ngt::HasTrivialCopyProperties);
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("Multi-block PortableDeviceCollection checks") {
+ using DeviceCollection2Type = alpaka_portable_test::TestDeviceCollection2;
+ static_assert(::ngt::HasMemoryCopyTraits);
+ static_assert(::ngt::HasTrivialCopyProperties);
+ static_assert(::ngt::HasRegions);
+
+ using DeviceCollection3Type = alpaka_portable_test::TestDeviceCollection3;
+ static_assert(::ngt::HasMemoryCopyTraits);
+ static_assert(::ngt::HasTrivialCopyProperties);
+ static_assert(::ngt::HasRegions);
+ }
+
+ SECTION("PortableHostCollection copy via MemoryCopyTraits") {
+ using HostCollectionType = PortableHostCollection>;
+ const int size = 10;
+
+ for (auto const& device : devices) {
+ Queue queue(device);
+
+ // Create a source collection and fill it with data
+ HostCollectionType source(queue, size);
+ source.view().r() = 3.14;
+ for (int i = 0; i < size; i++) {
+ source.view()[i].x() = i * 10.0 + 1;
+ source.view()[i].y() = i * 10.0 + 2;
+ source.view()[i].z() = i * 10.0 + 3;
+ source.view()[i].id() = i;
+ source.view()[i].flags() = std::array{
+ {static_cast(i), static_cast(i + 1), static_cast(i + 2), static_cast(i + 3)}};
+ source.view()[i].m = Eigen::Matrix::Identity() * i;
+ }
+
+ // Get properties from source
+ auto props = ::ngt::MemoryCopyTraits::properties(source);
+ REQUIRE(props == size);
+
+ // Create a clone and initialize it
+ HostCollectionType clone(edm::kUninitialized);
+ ::ngt::MemoryCopyTraits::initialize(clone, props);
+
+ // Get regions and copy
+ auto sources_regions = ::ngt::MemoryCopyTraits::regions(std::as_const(source));
+ auto targets_regions = ::ngt::MemoryCopyTraits::regions(clone);
+
+ REQUIRE(sources_regions.size() == targets_regions.size());
+ REQUIRE(sources_regions.size() == 1);
+ REQUIRE(sources_regions[0].size_bytes() == targets_regions[0].size_bytes());
+
+ std::memcpy(targets_regions[0].data(), sources_regions[0].data(), sources_regions[0].size_bytes());
+
+ // Verify clone
+ REQUIRE(clone.const_view().r() == source.const_view().r());
+ for (int i = 0; i < size; i++) {
+ REQUIRE(clone.const_view()[i].x() == source.const_view()[i].x());
+ REQUIRE(clone.const_view()[i].y() == source.const_view()[i].y());
+ REQUIRE(clone.const_view()[i].z() == source.const_view()[i].z());
+ REQUIRE(clone.const_view()[i].id() == source.const_view()[i].id());
+ REQUIRE(clone.const_view()[i].flags() == source.const_view()[i].flags());
+ REQUIRE(clone.const_view()[i].m() == source.const_view()[i].m());
+ }
+ }
+ }
+
+ SECTION("PortableHostObject copy via MemoryCopyTraits") {
+ using HostObjectType = PortableHostObject;
+
+ for (auto const& device : devices) {
+ Queue queue(device);
+
+ // Create source object
+ HostObjectType source(cms::alpakatools::host());
+ source->x = 5.0;
+ source->y = 12.0;
+ source->z = 13.0;
+ source->id = 42;
+
+ // Create an uninitialized clone
+ HostObjectType clone(edm::kUninitialized);
+ ::ngt::MemoryCopyTraits::initialize(clone);
+
+ // Get regions and copy
+ auto sources_regions = ::ngt::MemoryCopyTraits::regions(std::as_const(source));
+ auto targets_regions = ::ngt::MemoryCopyTraits::regions(clone);
+
+ REQUIRE(sources_regions.size() == targets_regions.size());
+ REQUIRE(sources_regions.size() == 1);
+ REQUIRE(sources_regions[0].size_bytes() == sizeof(alpaka_portable_test::TestStruct));
+ REQUIRE(targets_regions[0].size_bytes() == sizeof(alpaka_portable_test::TestStruct));
+
+ std::memcpy(targets_regions[0].data(), sources_regions[0].data(), sources_regions[0].size_bytes());
+
+ // Verify clone
+ REQUIRE(clone->x == 5.0);
+ REQUIRE(clone->y == 12.0);
+ REQUIRE(clone->z == 13.0);
+ REQUIRE(clone->id == 42);
+ }
+ }
+
+ SECTION("PortableDeviceCollection copy via MemoryCopyTraits") {
+ using DeviceCollectionType = alpaka_portable_test::TestDeviceCollection;
+ using HostCollectionType = PortableHostCollection>;
+ const int size = 10;
+
+ for (auto const& device : devices) {
+ Queue queue(device);
+
+ // Create a reference host collection with known data
+ HostCollectionType refHost(queue, size);
+ refHost.view().r() = 2.71;
+ for (int i = 0; i < size; i++) {
+ refHost.view()[i].x() = i * 100.0;
+ refHost.view()[i].y() = i * 200.0;
+ refHost.view()[i].z() = i * 300.0;
+ refHost.view()[i].id() = i + 100;
+ refHost.view()[i].flags() = std::array{
+ {static_cast(i), static_cast(i + 1), static_cast(i + 2), static_cast(i + 3)}};
+ refHost.view()[i].m = Eigen::Matrix::Identity() * i;
+ }
+
+ // Create a device collection and copy the reference data to it
+ DeviceCollectionType source(queue, size);
+ alpaka::memcpy(queue, source.buffer(), refHost.buffer());
+ alpaka::wait(queue);
+
+ // Get properties
+ auto props = ::ngt::MemoryCopyTraits::properties(source);
+ REQUIRE(props == size);
+
+ // Create a clone on device
+ DeviceCollectionType clone(edm::kUninitialized);
+ ::ngt::MemoryCopyTraits::initialize(queue, clone, props);
+
+ // Get regions and copy (device-to-device via alpaka)
+ auto sources_regions = ::ngt::MemoryCopyTraits::regions(std::as_const(source));
+ auto targets_regions = ::ngt::MemoryCopyTraits::regions(clone);
+
+ REQUIRE(sources_regions.size() == targets_regions.size());
+ for (size_t i = 0; i < sources_regions.size(); ++i) {
+ REQUIRE(sources_regions[i].size_bytes() == targets_regions[i].size_bytes());
+ auto src_view = alpaka::createView(device, sources_regions[i].data(), sources_regions[i].size_bytes());
+ auto trg_view = alpaka::createView(device, targets_regions[i].data(), targets_regions[i].size_bytes());
+ alpaka::memcpy(queue, trg_view, src_view);
+ }
+ alpaka::wait(queue);
+
+ // Copy the clone back to host to verify
+ HostCollectionType verifyHost(queue, size);
+ alpaka::memcpy(queue, verifyHost.buffer(), clone.buffer());
+ alpaka::wait(queue);
+
+ REQUIRE(verifyHost.const_view().r() == refHost.const_view().r());
+ for (int i = 0; i < size; i++) {
+ REQUIRE(verifyHost.const_view()[i].x() == refHost.const_view()[i].x());
+ REQUIRE(verifyHost.const_view()[i].y() == refHost.const_view()[i].y());
+ REQUIRE(verifyHost.const_view()[i].z() == refHost.const_view()[i].z());
+ REQUIRE(verifyHost.const_view()[i].id() == refHost.const_view()[i].id());
+ REQUIRE(verifyHost.const_view()[i].flags() == refHost.const_view()[i].flags());
+ }
+ }
+ }
+
+ SECTION("PortableDeviceObject copy via MemoryCopyTraits") {
+ using DeviceObjectType = alpaka_portable_test::TestDeviceObject;
+
+ for (auto const& device : devices) {
+ Queue queue(device);
+
+ // Create source object on host, copy to device
+ PortableHostObject hostSource(queue);
+ hostSource->x = 1.0;
+ hostSource->y = 2.0;
+ hostSource->z = 3.0;
+ hostSource->id = 99;
+
+ DeviceObjectType source(queue);
+ alpaka::memcpy(queue, source.buffer(), hostSource.buffer());
+ alpaka::wait(queue);
+
+ // Create an uninitialized clone
+ DeviceObjectType clone(edm::kUninitialized);
+ ::ngt::MemoryCopyTraits::initialize(queue, clone);
+
+ // Get regions and copy
+ auto sources_regions = ::ngt::MemoryCopyTraits::regions(std::as_const(source));
+ auto targets_regions = ::ngt::MemoryCopyTraits::regions(clone);
+
+ REQUIRE(sources_regions.size() == 1);
+ REQUIRE(targets_regions.size() == 1);
+ REQUIRE(sources_regions[0].size_bytes() == sizeof(alpaka_portable_test::TestStruct));
+
+ auto src_view = alpaka::createView(device, sources_regions[0].data(), sources_regions[0].size_bytes());
+ auto trg_view = alpaka::createView(device, targets_regions[0].data(), targets_regions[0].size_bytes());
+ alpaka::memcpy(queue, trg_view, src_view);
+ alpaka::wait(queue);
+
+ // Copy clone back to host and verify
+ PortableHostObject hostClone(queue);
+ alpaka::memcpy(queue, hostClone.buffer(), clone.buffer());
+ alpaka::wait(queue);
+
+ REQUIRE(hostClone->x == 1.0);
+ REQUIRE(hostClone->y == 2.0);
+ REQUIRE(hostClone->z == 3.0);
+ REQUIRE(hostClone->id == 99);
+ }
+ }
+
+ SECTION("Multi-block PortableHostCollection copy via MemoryCopyTraits") {
+ using HostCollection2Type = PortableHostCollection;
+ const int size1 = 8;
+ const int size2 = 12;
+
+ for (auto const& device : devices) {
+ Queue queue(device);
+
+ // Create source with two blocks
+ HostCollection2Type source(queue, size1, size2);
+ source.view().first().r() = 1.23;
+ source.view().second().r2() = 4.56;
+ for (int i = 0; i < size1; i++) {
+ source.view().first()[i].x() = i * 1.0;
+ source.view().first()[i].id() = i;
+ }
+ for (int i = 0; i < size2; i++) {
+ source.view().second()[i].x2() = i * 2.0;
+ source.view().second()[i].id2() = i + 100;
+ }
+
+ // Get properties
+ auto props = ::ngt::MemoryCopyTraits::properties(source);
+ REQUIRE(props[0] == size1);
+ REQUIRE(props[1] == size2);
+
+ // Create clone and initialize
+ HostCollection2Type clone(edm::kUninitialized);
+ ::ngt::MemoryCopyTraits::initialize(clone, props);
+
+ // Copy regions
+ auto sources_regions = ::ngt::MemoryCopyTraits::regions(std::as_const(source));
+ auto targets_regions = ::ngt::MemoryCopyTraits::regions(clone);
+
+ REQUIRE(sources_regions.size() == targets_regions.size());
+ for (size_t i = 0; i < sources_regions.size(); ++i) {
+ REQUIRE(sources_regions[i].size_bytes() == targets_regions[i].size_bytes());
+ std::memcpy(targets_regions[i].data(), sources_regions[i].data(), sources_regions[i].size_bytes());
+ }
+
+ // Verify
+ REQUIRE(clone.const_view().first().r() == 1.23);
+ REQUIRE(clone.const_view().second().r2() == 4.56);
+ for (int i = 0; i < size1; i++) {
+ REQUIRE(clone.const_view().first()[i].x() == i * 1.0);
+ REQUIRE(clone.const_view().first()[i].id() == i);
+ }
+ for (int i = 0; i < size2; i++) {
+ REQUIRE(clone.const_view().second()[i].x2() == i * 2.0);
+ REQUIRE(clone.const_view().second()[i].id2() == i + 100);
+ }
+ }
+ }
+}
diff --git a/DataFormats/VertexSoA/plugins/BuildFile.xml b/DataFormats/VertexSoA/plugins/BuildFile.xml
index 9967a9fbb7ed1..53ccfa799df99 100644
--- a/DataFormats/VertexSoA/plugins/BuildFile.xml
+++ b/DataFormats/VertexSoA/plugins/BuildFile.xml
@@ -3,3 +3,10 @@
+
+
+
+
+
+
+
diff --git a/DataFormats/VertexSoA/plugins/alpaka/TrivialSerialisation.cc b/DataFormats/VertexSoA/plugins/alpaka/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..d81108e1f7410
--- /dev/null
+++ b/DataFormats/VertexSoA/plugins/alpaka/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/VertexSoA/interface/alpaka/ZVertexSoACollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/alpaka/SerialiserFactoryDevice.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN_DEVICE(reco::ZVertexSoACollection);
diff --git a/HeterogeneousCore/TrivialSerialisation/BuildFile.xml b/HeterogeneousCore/TrivialSerialisation/BuildFile.xml
index 6eeacf9dd884c..d7bfd7e7d5267 100644
--- a/HeterogeneousCore/TrivialSerialisation/BuildFile.xml
+++ b/HeterogeneousCore/TrivialSerialisation/BuildFile.xml
@@ -1,7 +1,11 @@
+
+
+
+
diff --git a/HeterogeneousCore/TrivialSerialisation/interface/Common.h b/HeterogeneousCore/TrivialSerialisation/interface/Common.h
new file mode 100644
index 0000000000000..7a04a21926958
--- /dev/null
+++ b/HeterogeneousCore/TrivialSerialisation/interface/Common.h
@@ -0,0 +1,51 @@
+#ifndef HeterogeneousCore_TrivialSerialisation_interface_Common_h
+#define HeterogeneousCore_TrivialSerialisation_interface_Common_h
+
+#include
+#include
+#include