diff --git a/DataFormats/BeamSpot/plugins/BuildFile.xml b/DataFormats/BeamSpot/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..fb0d04138c776
--- /dev/null
+++ b/DataFormats/BeamSpot/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/BeamSpot/plugins/TrivialSerialisation.cc b/DataFormats/BeamSpot/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..46ba35e9926e6
--- /dev/null
+++ b/DataFormats/BeamSpot/plugins/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/BeamSpot/interface/BeamSpotHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(BeamSpotHost);
diff --git a/DataFormats/EcalDigi/plugins/BuildFile.xml b/DataFormats/EcalDigi/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..500770828ac90
--- /dev/null
+++ b/DataFormats/EcalDigi/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/EcalDigi/plugins/TrivialSerialisation.cc b/DataFormats/EcalDigi/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..b189c5ec3a5fe
--- /dev/null
+++ b/DataFormats/EcalDigi/plugins/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/EcalDigi/interface/EcalDigiHostCollection.h"
+#include "DataFormats/EcalDigi/interface/EcalDigiPhase2HostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(EcalDigiHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(EcalDigiPhase2HostCollection);
diff --git a/DataFormats/EcalRecHit/plugins/BuildFile.xml b/DataFormats/EcalRecHit/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..ee7c656ef4f71
--- /dev/null
+++ b/DataFormats/EcalRecHit/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/EcalRecHit/plugins/TrivialSerialisation.cc b/DataFormats/EcalRecHit/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..adc2c817de023
--- /dev/null
+++ b/DataFormats/EcalRecHit/plugins/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/EcalRecHit/interface/EcalRecHitHostCollection.h"
+#include "DataFormats/EcalRecHit/interface/EcalUncalibratedRecHitHostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(EcalRecHitHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(EcalUncalibratedRecHitHostCollection);
diff --git a/DataFormats/HGCalDigi/plugins/BuildFile.xml b/DataFormats/HGCalDigi/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..f22493a26579e
--- /dev/null
+++ b/DataFormats/HGCalDigi/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/HGCalDigi/plugins/TrivialSerialisation.cc b/DataFormats/HGCalDigi/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..7b9d0eeb8d342
--- /dev/null
+++ b/DataFormats/HGCalDigi/plugins/TrivialSerialisation.cc
@@ -0,0 +1,8 @@
+#include "DataFormats/HGCalDigi/interface/HGCalDigiHost.h"
+#include "DataFormats/HGCalDigi/interface/HGCalECONDPacketInfoHost.h"
+#include "DataFormats/HGCalDigi/interface/HGCalFEDPacketInfoHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hgcaldigi::HGCalDigiHost);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hgcaldigi::HGCalECONDPacketInfoHost);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hgcaldigi::HGCalFEDPacketInfoHost);
diff --git a/DataFormats/HGCalReco/plugins/BuildFile.xml b/DataFormats/HGCalReco/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..1171aee28adb6
--- /dev/null
+++ b/DataFormats/HGCalReco/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/HGCalReco/plugins/TrivialSerialisation.cc b/DataFormats/HGCalReco/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..c3bd30fcba8e0
--- /dev/null
+++ b/DataFormats/HGCalReco/plugins/TrivialSerialisation.cc
@@ -0,0 +1,10 @@
+#include "DataFormats/HGCalReco/interface/HGCalSoAClustersHostCollection.h"
+#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsExtraHostCollection.h"
+#include "DataFormats/HGCalReco/interface/HGCalSoARecHitsHostCollection.h"
+#include "DataFormats/HGCalReco/interface/MtdHostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(HGCalSoAClustersHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(HGCalSoARecHitsExtraHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(HGCalSoARecHitsHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(MtdHostCollection);
diff --git a/DataFormats/HcalDigi/plugins/BuildFile.xml b/DataFormats/HcalDigi/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..a627d6e7e1a0a
--- /dev/null
+++ b/DataFormats/HcalDigi/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/HcalDigi/plugins/TrivialSerialisation.cc b/DataFormats/HcalDigi/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..22c6683ef6c24
--- /dev/null
+++ b/DataFormats/HcalDigi/plugins/TrivialSerialisation.cc
@@ -0,0 +1,5 @@
+#include "DataFormats/HcalDigi/interface/HcalDigiHostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hcal::Phase0DigiHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hcal::Phase1DigiHostCollection);
diff --git a/DataFormats/HcalRecHit/plugins/BuildFile.xml b/DataFormats/HcalRecHit/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..07725848fdb30
--- /dev/null
+++ b/DataFormats/HcalRecHit/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/HcalRecHit/plugins/TrivialSerialisation.cc b/DataFormats/HcalRecHit/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..b4ff719665537
--- /dev/null
+++ b/DataFormats/HcalRecHit/plugins/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/HcalRecHit/interface/HcalRecHitHostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(hcal::RecHitHostCollection);
diff --git a/DataFormats/ParticleFlowReco/plugins/BuildFile.xml b/DataFormats/ParticleFlowReco/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..e20859b77da70
--- /dev/null
+++ b/DataFormats/ParticleFlowReco/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/ParticleFlowReco/plugins/TrivialSerialisation.cc b/DataFormats/ParticleFlowReco/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..b212bcc08db16
--- /dev/null
+++ b/DataFormats/ParticleFlowReco/plugins/TrivialSerialisation.cc
@@ -0,0 +1,13 @@
+// Include the Eigen core library before including the SoA definitions
+#include
+
+#include "DataFormats/ParticleFlowReco/interface/CaloRecHitHostCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/PFClusterHostCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/PFRecHitFractionHostCollection.h"
+#include "DataFormats/ParticleFlowReco/interface/PFRecHitHostCollection.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::CaloRecHitHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::PFClusterHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::PFRecHitFractionHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::PFRecHitHostCollection);
diff --git a/DataFormats/ParticleFlowReco/src/alpaka/classes_cuda.h b/DataFormats/ParticleFlowReco/src/alpaka/classes_cuda.h
index 806574361dbf1..75dc8a747a97a 100644
--- a/DataFormats/ParticleFlowReco/src/alpaka/classes_cuda.h
+++ b/DataFormats/ParticleFlowReco/src/alpaka/classes_cuda.h
@@ -1,4 +1,4 @@
-// Include Eigen core library before include the SoA definitions
+// Include the Eigen core library before including the SoA definitions
#include
#include "DataFormats/Common/interface/DeviceProduct.h"
diff --git a/DataFormats/ParticleFlowReco/src/alpaka/classes_rocm.h b/DataFormats/ParticleFlowReco/src/alpaka/classes_rocm.h
index 806574361dbf1..75dc8a747a97a 100644
--- a/DataFormats/ParticleFlowReco/src/alpaka/classes_rocm.h
+++ b/DataFormats/ParticleFlowReco/src/alpaka/classes_rocm.h
@@ -1,4 +1,4 @@
-// Include Eigen core library before include the SoA definitions
+// Include the Eigen core library before including the SoA definitions
#include
#include "DataFormats/Common/interface/DeviceProduct.h"
diff --git a/DataFormats/ParticleFlowReco/src/classes_serial.cc b/DataFormats/ParticleFlowReco/src/classes_serial.cc
index 18a4bc88acf51..82a8cab3cd150 100644
--- a/DataFormats/ParticleFlowReco/src/classes_serial.cc
+++ b/DataFormats/ParticleFlowReco/src/classes_serial.cc
@@ -1,4 +1,4 @@
-// Include Eigen core library before include the SoA definitions
+// Include the Eigen core library before including the SoA definitions
#include
#include "DataFormats/ParticleFlowReco/interface/CaloRecHitHostCollection.h"
diff --git a/DataFormats/ParticleFlowReco/src/classes_serial.h b/DataFormats/ParticleFlowReco/src/classes_serial.h
index d1b0d6d93a0c1..1ab95b775a7f3 100644
--- a/DataFormats/ParticleFlowReco/src/classes_serial.h
+++ b/DataFormats/ParticleFlowReco/src/classes_serial.h
@@ -1,4 +1,4 @@
-// Include Eigen core library before include the SoA definitions
+// Include the Eigen core library before including the SoA definitions
#include
#include "DataFormats/Common/interface/Wrapper.h"
diff --git a/DataFormats/Portable/BuildFile.xml b/DataFormats/Portable/BuildFile.xml
index ff3cadd88a5d7..462238bf544f0 100644
--- a/DataFormats/Portable/BuildFile.xml
+++ b/DataFormats/Portable/BuildFile.xml
@@ -1,4 +1,6 @@
-
+
+
+
diff --git a/DataFormats/Portable/interface/PortableCollection.h b/DataFormats/Portable/interface/PortableCollection.h
index 8cedd9eabc7a0..182d2726c2cbb 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
-#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/Portable/interface/PortableDeviceCollection.h"
-#include "HeterogeneousCore/AlpakaInterface/interface/concepts.h"
+#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h"
+#include "HeterogeneousCore/AlpakaInterface/interface/concepts.h"
namespace traits {
diff --git a/DataFormats/Portable/interface/PortableCollectionCommon.h b/DataFormats/Portable/interface/PortableCollectionCommon.h
index 0c0e0b9fd3d13..65b7c11baeda3 100644
--- a/DataFormats/Portable/interface/PortableCollectionCommon.h
+++ b/DataFormats/Portable/interface/PortableCollectionCommon.h
@@ -1,9 +1,9 @@
#ifndef DataFormats_Portable_interface_PortableCollectionCommon_h
#define DataFormats_Portable_interface_PortableCollectionCommon_h
+#include
#include
#include
-#include
namespace portablecollection {
diff --git a/DataFormats/Portable/interface/PortableDeviceCollection.h b/DataFormats/Portable/interface/PortableDeviceCollection.h
index 5301b9c5022a8..0ccbb648c748d 100644
--- a/DataFormats/Portable/interface/PortableDeviceCollection.h
+++ b/DataFormats/Portable/interface/PortableDeviceCollection.h
@@ -1,8 +1,10 @@
#ifndef DataFormats_Portable_interface_PortableDeviceCollection_h
#define DataFormats_Portable_interface_PortableDeviceCollection_h
+#include
#include
#include
+#include
#include
#include
@@ -217,7 +219,7 @@ class PortableDeviceMultiCollection {
public:
PortableDeviceMultiCollection() = delete;
- explicit PortableDeviceMultiCollection(edm::Uninitialized) noexcept {};
+ explicit PortableDeviceMultiCollection(edm::Uninitialized) noexcept {}
PortableDeviceMultiCollection(int32_t elements, TDev const& device)
: buffer_{cms::alpakatools::make_device_buffer(device, Layout<>::computeDataSize(elements))},
diff --git a/DataFormats/Portable/interface/PortableHostCollection.h b/DataFormats/Portable/interface/PortableHostCollection.h
index 33f908a42e11a..869598e880c59 100644
--- a/DataFormats/Portable/interface/PortableHostCollection.h
+++ b/DataFormats/Portable/interface/PortableHostCollection.h
@@ -1,14 +1,20 @@
#ifndef DataFormats_Portable_interface_PortableHostCollection_h
#define DataFormats_Portable_interface_PortableHostCollection_h
+#include
#include
#include
+#include
+#include
#include
+#include
+#include
#include
#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/host.h"
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -27,7 +33,7 @@ class PortableHostCollection {
PortableHostCollection() = delete;
- explicit PortableHostCollection(edm::Uninitialized) noexcept {};
+ explicit PortableHostCollection(edm::Uninitialized) noexcept {}
PortableHostCollection(int32_t elements, alpaka_common::DevHost const& host)
requires(!portablecollection::hasBlocksNumber)
@@ -424,4 +430,65 @@ using PortableHostCollection4 = ::PortableHostMultiCollection;
template
using PortableHostCollection5 = ::PortableHostMultiCollection;
+namespace ngt {
+
+ // Specialize the MemoryCopyTraits for PortableHostColletion
+ template
+ struct MemoryCopyTraits> {
+ using value_type = PortableHostCollection;
+ using Properties = int32_t;
+
+ // The properties needed to initialize a new PrortableHostCollection are just its size.
+ static Properties properties(value_type const& object) { return object->metadata().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 system memory.
+ object = value_type(size, cms::alpakatools::host());
+ }
+
+ static std::vector> regions(value_type& object) {
+ // The whole PortableHostCollection is stored in a single contiguous memory region.
+ 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) {
+ // The whole PortableHostCollection is stored in a single contiguous memory region.
+ const std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+ };
+
+ // Specialize the MemoryCopyTraits for PortableHostMultiCollection
+ template
+ struct MemoryCopyTraits> {
+ using value_type = PortableHostMultiCollection;
+ using Properties = typename PortableHostMultiCollection::SizesArray;
+
+ // The properties needed to initialize a new PrortableHostMultiCollection are the sizes of all underlying PortableHostCollections.
+ static Properties properties(PortableHostMultiCollection const& object) { return object.sizes(); }
+
+ static void initialize(PortableHostMultiCollection& object, Properties const& sizes) {
+ // Replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory.
+ object = PortableHostMultiCollection(sizes, cms::alpakatools::host());
+ }
+
+ static std::vector> regions(PortableHostMultiCollection& object) {
+ // The whole PortableHostMultiCollection is stored in a single contiguous memory region.
+ std::byte* address = reinterpret_cast(object.buffer().data());
+ size_t size = alpaka::getExtentProduct(object.buffer());
+ return {{address, size}};
+ }
+
+ static std::vector> regions(PortableHostMultiCollection const& object) {
+ // The whole PortableHostMultiCollection is stored in a single contiguous memory region.
+ 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_PortableHostCollection_h
diff --git a/DataFormats/Portable/interface/PortableHostObject.h b/DataFormats/Portable/interface/PortableHostObject.h
index 30cca9458c2c5..a4f5851c8815d 100644
--- a/DataFormats/Portable/interface/PortableHostObject.h
+++ b/DataFormats/Portable/interface/PortableHostObject.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/host.h"
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -115,4 +116,28 @@ class PortableHostObject {
Product* product_ = nullptr;
};
+// Specialize the MemoryCopyTraits for PortableHostObject
+namespace ngt {
+
+ template
+ struct MemoryCopyTraits> {
+ // This specialisation requires a initialize() method, but does not need to pass any parameters to it.
+ using Properties = void;
+
+ static void initialize(PortableHostObject& object) {
+ // Replace the default-constructed empty object with one where the buffer has been allocated in pageable system memory.
+ object = PortableHostObject(cms::alpakatools::host());
+ }
+
+ static std::vector> regions(PortableHostObject& object) {
+ return {{reinterpret_cast(object.data()), sizeof(T)}};
+ }
+
+ static std::vector> regions(PortableHostObject const& object) {
+ return {{reinterpret_cast(object.data()), sizeof(T)}};
+ }
+ };
+
+} // namespace ngt
+
#endif // DataFormats_Portable_interface_PortableHostObject_h
diff --git a/DataFormats/Portable/interface/PortableObject.h b/DataFormats/Portable/interface/PortableObject.h
index 81e82db700333..31a55e48d1d2c 100644
--- a/DataFormats/Portable/interface/PortableObject.h
+++ b/DataFormats/Portable/interface/PortableObject.h
@@ -5,11 +5,11 @@
#include
-#include "DataFormats/Portable/interface/PortableHostObject.h"
#include "DataFormats/Portable/interface/PortableDeviceObject.h"
-#include "HeterogeneousCore/AlpakaInterface/interface/concepts.h"
+#include "DataFormats/Portable/interface/PortableHostObject.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h"
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h"
+#include "HeterogeneousCore/AlpakaInterface/interface/concepts.h"
namespace traits {
diff --git a/DataFormats/PortableTestObjects/plugins/BuildFile.xml b/DataFormats/PortableTestObjects/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..bac81f07c93fc
--- /dev/null
+++ b/DataFormats/PortableTestObjects/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/PortableTestObjects/plugins/TrivialSerialisation.cc b/DataFormats/PortableTestObjects/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..874b21eb8e1a7
--- /dev/null
+++ b/DataFormats/PortableTestObjects/plugins/TrivialSerialisation.cc
@@ -0,0 +1,20 @@
+#include "DataFormats/PortableTestObjects/interface/ImageHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/LogitsHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/MaskHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/MultiHeadNetHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/ParticleHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/SimpleNetHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/TestHostCollection.h"
+#include "DataFormats/PortableTestObjects/interface/TestHostObject.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::ImageHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::LogitsHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::MaskHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::MultiHeadNetHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::ParticleHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::SimpleNetHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::TestHostCollection);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::TestHostMultiCollection2);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::TestHostMultiCollection3);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(portabletest::TestHostObject);
diff --git a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
index 287c4b3d5319e..28f09a4e60373 100644
--- a/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
+++ b/DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h
@@ -6,6 +6,7 @@
#include "DataFormats/Common/interface/Uninitialized.h"
#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersSoA.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
// TODO: The class is created via inheritance of the PortableCollection.
@@ -15,6 +16,7 @@ class SiPixelClustersHost : public PortableHostCollection {
public:
SiPixelClustersHost(edm::Uninitialized) : PortableHostCollection{edm::kUninitialized} {}
+ // FIXME add an explicit overload for the host case
template
explicit SiPixelClustersHost(size_t maxModules, TQueue queue)
: PortableHostCollection(maxModules + 1, queue) {}
@@ -32,4 +34,41 @@ class SiPixelClustersHost : public PortableHostCollection {
int32_t offsetBPIX2_h = 0;
};
+namespace ngt {
+
+ template <>
+ struct MemoryCopyTraits {
+ using value_type = SiPixelClustersHost;
+
+ 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()};
+ }
+
+ 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());
+ 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_SiPixelClustersHost_h
diff --git a/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml b/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..373ad21b5af1b
--- /dev/null
+++ b/DataFormats/SiPixelClusterSoA/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/SiPixelClusterSoA/plugins/TrivialSerialisation.cc b/DataFormats/SiPixelClusterSoA/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..6cfaa73c5ea53
--- /dev/null
+++ b/DataFormats/SiPixelClusterSoA/plugins/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(SiPixelClustersHost);
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
index 1150a82046428..c7f55a885e8a3 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h
@@ -9,6 +9,7 @@
#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsSoA.h"
#include "DataFormats/SiPixelRawData/interface/SiPixelErrorCompact.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/SimpleVector.h"
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -26,4 +27,36 @@ class SiPixelDigiErrorsHost : public PortableHostCollection
+ struct MemoryCopyTraits {
+ using value_type = SiPixelDigiErrorsHost;
+ struct Properties {
+ int maxFedWords;
+ };
+
+ 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());
+ }
+
+ 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_SiPixelDigiErrorsHost_h
diff --git a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
index 99b498fc5fe14..0ba4a7ba0416f 100644
--- a/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
+++ b/DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h
@@ -4,6 +4,7 @@
#include "DataFormats/Common/interface/Uninitialized.h"
#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigisSoA.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
// TODO: The class is created via inheritance of the PortableDeviceCollection.
// This is generally discouraged, and should be done via composition.
@@ -25,4 +26,38 @@ class SiPixelDigisHost : public PortableHostCollection {
uint32_t nModules_h = 0;
};
+// Specialize the MemoryCopyTraits for SiPixelDigisHost
+namespace ngt {
+
+ template <>
+ struct MemoryCopyTraits {
+ using value_type = SiPixelDigisHost;
+ struct Properties {
+ uint32_t nDigis;
+ uint32_t nModules;
+ };
+
+ 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());
+ 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_SiPixelDigisHost_h
diff --git a/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml b/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..30b51a75552e9
--- /dev/null
+++ b/DataFormats/SiPixelDigiSoA/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/SiPixelDigiSoA/plugins/TrivialSerialisation.cc b/DataFormats/SiPixelDigiSoA/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..fd71a296b1a34
--- /dev/null
+++ b/DataFormats/SiPixelDigiSoA/plugins/TrivialSerialisation.cc
@@ -0,0 +1,6 @@
+#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigiErrorsHost.h"
+#include "DataFormats/SiPixelDigiSoA/interface/SiPixelDigisHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(SiPixelDigiErrorsHost);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(SiPixelDigisHost);
diff --git a/DataFormats/TrackSoA/plugins/BuildFile.xml b/DataFormats/TrackSoA/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..e2d5a430d6ae4
--- /dev/null
+++ b/DataFormats/TrackSoA/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/TrackSoA/plugins/TrivialSerialisation.cc b/DataFormats/TrackSoA/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..79e7d0f9c4c0e
--- /dev/null
+++ b/DataFormats/TrackSoA/plugins/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/TrackSoA/interface/TracksHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::TracksHost);
diff --git a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
index 528f1a2205689..cd9998a975a55 100644
--- a/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
+++ b/DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h
@@ -7,8 +7,9 @@
#include "DataFormats/Common/interface/Uninitialized.h"
#include "DataFormats/Portable/interface/PortableHostCollection.h"
-#include "DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsSoA.h"
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h"
+#include "DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsSoA.h"
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
// TODO: The class is created via inheritance of the PortableCollection.
@@ -25,6 +26,7 @@ namespace reco {
: PortableHostMultiCollection{edm::kUninitialized} {}
// 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
template
explicit TrackingRecHitHost(TQueue queue, uint32_t nHits, uint32_t nModules)
: HitPortableCollectionHost({{int(nHits), int(nModules + 1)}}, queue) {}
@@ -32,7 +34,7 @@ namespace reco {
// Constructor from clusters
template
- explicit TrackingRecHitHost(TQueue queue, SiPixelClustersHost const &clusters)
+ explicit TrackingRecHitHost(TQueue queue, SiPixelClustersHost const& clusters)
: HitPortableCollectionHost({{int(clusters.nClusters()), clusters.view().metadata().size()}}, queue) {
auto hitsView = this->template view();
auto modsView = this->template view();
@@ -59,4 +61,37 @@ namespace reco {
} // namespace reco
+namespace ngt {
+
+ template <>
+ struct MemoryCopyTraits {
+ using value_type = reco::TrackingRecHitHost;
+
+ struct Properties {
+ uint32_t nHits;
+ uint32_t nModules;
+ };
+
+ 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
+ object = value_type(cms::alpakatools::host(), 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_TrackingRecHitsHost_h
diff --git a/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml b/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..d1a16495ee94e
--- /dev/null
+++ b/DataFormats/TrackingRecHitSoA/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/TrackingRecHitSoA/plugins/TrivialSerialisation.cc b/DataFormats/TrackingRecHitSoA/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..85530825e35c6
--- /dev/null
+++ b/DataFormats/TrackingRecHitSoA/plugins/TrivialSerialisation.cc
@@ -0,0 +1,4 @@
+#include "DataFormats/TrackingRecHitSoA/interface/TrackingRecHitsHost.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(reco::TrackingRecHitHost);
diff --git a/DataFormats/TrivialSerialisation/BuildFile.xml b/DataFormats/TrivialSerialisation/BuildFile.xml
new file mode 100644
index 0000000000000..f6d0fd47836d2
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/BuildFile.xml
@@ -0,0 +1 @@
+
diff --git a/DataFormats/TrivialSerialisation/README.md b/DataFormats/TrivialSerialisation/README.md
new file mode 100644
index 0000000000000..66e5d60da5f42
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/README.md
@@ -0,0 +1,46 @@
+# `ngt::MemoryCopyTraits`
+
+`struct ngt::MemoryCopyTraits` should be specialised for each type that can
+be safely `memcpy`ed.
+
+The specialisation shall have two static methods
+
+ static std::vector> regions(T& object);
+ static std::vector> regions(T const& object);
+
+that return a `vector` of `span` describing address, size pairs. A type that
+supports this interface can be copied by doing a `memcpy` of all the memory
+areas from a source object to a destination object.
+
+A specialisation may implement the `initialize()` method, to initialize a newly
+allocated object:
+
+ static void initialize(T& object);
+
+
+A specialisation may implement the method `properties()`, which should return
+the properties (_e.g._ number of elements, or size in bytes, _etc_.) of an
+existing object:
+
+ using Properties = ...;
+ static Properties properties(T const& object);
+
+If `properties()` is defined, the value it returns should be passed as the
+second argument to `initialize()`:
+
+ static void initialize(T& object, Properties const& args););
+
+
+A specialisation may provide the method `finalize()`:
+
+ static void finalize(T& object);
+
+If present, it should be called to restore the object invariants after a
+`memcpy` operation.
+
+
+## Specialisations of `ngt::MemoryCopyTraits`
+
+This package provides the specialisation of `ngt::MemoryCopyTraits` for all
+arithmetic types, all `std::vector`s of arithmetic types (except
+`std::vector`), and `std::string`.
diff --git a/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h b/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h
new file mode 100644
index 0000000000000..57f2511b72d7a
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h
@@ -0,0 +1,145 @@
+#ifndef DataFormats_TrivialSerialisation_interface_MemoryCopyTraits_h
+#define DataFormats_TrivialSerialisation_interface_MemoryCopyTraits_h
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace ngt {
+
+ // This struct should be specialised for each type that can be safely memcpy'ed.
+ //
+ // The specialisation shall have two static methods
+ //
+ // static std::vector> regions(T& object);
+ // static std::vector> regions(T const& object);
+ //
+ // that return a vector of address, size pairs. A type that supports this
+ // interface can be copied by doing a memcpy of all the address, size pairs from a
+ // source object to a destination object.
+ //
+ //
+ // A specialisation may implement the method properties(), which returns the
+ // properties of an existing object, which can be used to initialize a newly
+ // allocated copy of the object via the initialize() method.
+ //
+ // using Properties = ...;
+ // static Properties properties(T const& object);
+ //
+ // If properties() is not implemented, the initialize() method takes a single
+ // argument:
+ //
+ // static void initialize(T& object);
+ //
+ // If properties() is implemented, the initialize() method should take as a
+ // second parameter a const reference to a Properties object:
+ //
+ // static void initialize(T& object, Properties const& args);
+ //
+ //
+ // A specialisation can optionally provide a static method
+ //
+ // static void finalize(T& object);
+ //
+ // If present, it should be called to restore the object invariants after a
+ // memcpy operation.
+ //
+
+ template
+ struct MemoryCopyTraits;
+
+ // Checks if the properties method is defined
+ template
+ concept HasTrivialCopyProperties = requires(T const& object) { MemoryCopyTraits::properties(object); };
+
+ // Get the return type of properties(...), if it exists.
+ template
+ requires HasTrivialCopyProperties
+ using TrivialCopyProperties = decltype(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
+ // does have properties(...) and initialize(object, props) takes two arguments
+ (HasTrivialCopyProperties and
+ requires(T& object, TrivialCopyProperties props) { 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);
+ };
+
+ // Checks if there is a valid specialisation of MemoryCopyTraits for a type T
+ template
+ concept HasMemoryCopyTraits =
+ // Has memory regions declared and
+ (HasRegions) and
+ // has either no initialize(...) or a valid one
+ (not requires { &MemoryCopyTraits::initialize; } or HasValidInitialize);
+
+ // Checks if finalize(...) is defined
+ template
+ concept HasTrivialCopyFinalize = requires(T& object) { ngt::MemoryCopyTraits::finalize(object); };
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ // Specialisations for various types
+
+ // Specialisation for arithmetic types
+ template
+ requires std::is_arithmetic_v
+ struct MemoryCopyTraits {
+ static std::vector> regions(T& object) {
+ return {{reinterpret_cast(&object), sizeof(T)}};
+ } // namespace edm
+
+ static std::vector> regions(T const& object) {
+ return {{reinterpret_cast(&object), sizeof(T)}};
+ }
+ };
+
+ // Specialisation for std::string
+ template <>
+ struct MemoryCopyTraits {
+ using Properties = std::string::size_type;
+
+ static Properties properties(std::string const& object) { return object.size(); }
+ static void initialize(std::string& object, Properties const& size) { object.resize(size); }
+
+ static std::vector> regions(std::string& object) {
+ return {{reinterpret_cast(object.data()), object.size() * sizeof(char)}};
+ }
+
+ static std::vector> regions(std::string const& object) {
+ return {{reinterpret_cast(object.data()), object.size() * sizeof(char)}};
+ }
+ };
+
+ // Specialisation for vectors of arithmetic types
+ template
+ requires(std::is_arithmetic_v and not std::is_same_v)
+ struct MemoryCopyTraits> {
+ using Properties = std::vector::size_type;
+
+ static Properties properties(std::vector const& object) { return object.size(); }
+ static void initialize(std::vector& object, Properties const& size) { object.resize(size); }
+
+ static std::vector> regions(std::vector& object) {
+ return {{reinterpret_cast(object.data()), object.size() * sizeof(T)}};
+ }
+
+ static std::vector> regions(std::vector const& object) {
+ return {{reinterpret_cast(object.data()), object.size() * sizeof(T)}};
+ }
+ };
+
+} // namespace ngt
+
+#endif // DataFormats_TrivialSerialisation_interface_MemoryCopyTraits_h
diff --git a/DataFormats/TrivialSerialisation/plugins/BuildFile.xml b/DataFormats/TrivialSerialisation/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..accdcdbae171f
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/plugins/BuildFile.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/DataFormats/TrivialSerialisation/plugins/TrivialSerialisation.cc b/DataFormats/TrivialSerialisation/plugins/TrivialSerialisation.cc
new file mode 100644
index 0000000000000..fb8f9fed24320
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/plugins/TrivialSerialisation.cc
@@ -0,0 +1,41 @@
+#include
+#include
+
+// Including MemoryCopyTraits.h is not necessary, but it is included explicitly
+// because it contains the specialisations used below.
+#include "DataFormats/TrivialSerialisation/interface/MemoryCopyTraits.h"
+#include "HeterogeneousCore/TrivialSerialisation/interface/SerialiserFactory.h"
+
+// Arithmetic types:
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(bool);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(char);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(signed char);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(unsigned char);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(short);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(unsigned short);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(int);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(unsigned int);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(long);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(unsigned long);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(long long);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(unsigned long long);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(float);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(double);
+
+// std::vector of arithmetic types, except for std::vector:
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::vector);
+
+// std::string:
+DEFINE_TRIVIAL_SERIALISER_PLUGIN(std::string);
diff --git a/DataFormats/TrivialSerialisation/test/BuildFile.xml b/DataFormats/TrivialSerialisation/test/BuildFile.xml
new file mode 100644
index 0000000000000..5da9ef00be32e
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/test/BuildFile.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/DataFormats/TrivialSerialisation/test/test_catch2_MemoryCopyTraits.cc b/DataFormats/TrivialSerialisation/test/test_catch2_MemoryCopyTraits.cc
new file mode 100644
index 0000000000000..76efd00a4a4fc
--- /dev/null
+++ b/DataFormats/TrivialSerialisation/test/test_catch2_MemoryCopyTraits.cc
@@ -0,0 +1,328 @@
+#include
+#include
+#include