Skip to content

Commit ba05945

Browse files
authored
Merge pull request #46877 from fwyzard/edm_Wraper_AllocateForOverwrite
Let `edm::Wrapper<T>` use the constructor `T{kUninitialized}`
2 parents 16f5cb4 + 4c8434c commit ba05945

29 files changed

+265
-46
lines changed

DataFormats/Common/interface/DeviceProduct.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <cassert>
55
#include <memory>
66

7+
#include "DataFormats/Common/interface/Uninitialized.h"
8+
79
namespace edm {
810
class DeviceProductBase {
911
public:
@@ -45,7 +47,13 @@ namespace edm {
4547
template <typename T>
4648
class DeviceProduct : public DeviceProductBase {
4749
public:
48-
DeviceProduct() = default;
50+
DeviceProduct()
51+
requires(requires { T(); })
52+
= default;
53+
54+
explicit DeviceProduct(edm::Uninitialized)
55+
requires(requires { T(edm::kUninitialized); })
56+
: data_{edm::kUninitialized} {}
4957

5058
template <typename M, typename... Args>
5159
explicit DeviceProduct(std::shared_ptr<M> metadata, Args&&... args)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef DataFormats_Common_interface_Uninitialized_h
2+
#define DataFormats_Common_interface_Uninitialized_h
3+
4+
/* Uninitialized
5+
*
6+
* This is an empty struct used as a tag to signal that a constructor will leave an object (partially) uninitialised,
7+
* with the assumption that it will be overwritten before being used.
8+
* One expected use case is to replace the default constructor used when deserialising objects from a ROOT file.
9+
*/
10+
11+
namespace edm {
12+
13+
struct Uninitialized {};
14+
15+
constexpr inline Uninitialized kUninitialized;
16+
17+
} // namespace edm
18+
19+
#endif // DataFormats_Common_interface_Uninitialized_h

DataFormats/Common/interface/Wrapper.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ Wrapper: A template wrapper around EDProducts to hold the product ID.
77
88
----------------------------------------------------------------------*/
99

10+
#include "DataFormats/Common/interface/Uninitialized.h"
11+
#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
1012
#include "DataFormats/Common/interface/WrapperBase.h"
1113
#include "DataFormats/Common/interface/WrapperDetail.h"
12-
#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h"
1314
#include "DataFormats/Provenance/interface/ProductID.h"
1415
#include "FWCore/Utilities/interface/Visibility.h"
1516

@@ -25,7 +26,7 @@ namespace edm {
2526
public:
2627
typedef T value_type;
2728
typedef T wrapped_type; // used with the dictionary to identify Wrappers
28-
Wrapper() : WrapperBase(), obj(), present(false) {}
29+
Wrapper() : WrapperBase(), obj{construct_()}, present(false) {}
2930
explicit Wrapper(std::unique_ptr<T> ptr);
3031
Wrapper(Wrapper<T> const& rh) = delete; // disallow copy construction
3132
Wrapper<T>& operator=(Wrapper<T> const&) = delete; // disallow assignment
@@ -49,6 +50,14 @@ namespace edm {
4950
CMS_CLASS_VERSION(4)
5051

5152
private:
53+
constexpr T construct_() {
54+
if constexpr (requires { T(); }) {
55+
return T();
56+
} else {
57+
return T(edm::kUninitialized);
58+
}
59+
}
60+
5261
bool isPresent_() const override { return present; }
5362
std::type_info const& dynamicTypeInfo_() const override { return typeid(T); }
5463
std::type_info const& wrappedTypeInfo_() const override { return typeid(Wrapper<T>); }
@@ -78,7 +87,7 @@ namespace edm {
7887
};
7988

8089
template <typename T>
81-
Wrapper<T>::Wrapper(std::unique_ptr<T> ptr) : WrapperBase(), obj(), present(ptr.get() != nullptr) {
90+
Wrapper<T>::Wrapper(std::unique_ptr<T> ptr) : WrapperBase(), obj{construct_()}, present(ptr.get() != nullptr) {
8291
if (present) {
8392
obj = std::move(*ptr);
8493
}
@@ -89,7 +98,7 @@ namespace edm {
8998
Wrapper<T>::Wrapper(Emplace, Args&&... args) : WrapperBase(), obj(std::forward<Args>(args)...), present(true) {}
9099

91100
template <typename T>
92-
Wrapper<T>::Wrapper(T* ptr) : WrapperBase(), present(ptr != 0), obj() {
101+
Wrapper<T>::Wrapper(T* ptr) : WrapperBase(), present(ptr != 0), obj{construct_()} {
93102
std::unique_ptr<T> temp(ptr);
94103
if (present) {
95104
obj = std::move(*ptr);
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,32 @@
1-
/*
2-
* CMSSW
3-
*
4-
*/
5-
61
#include <cassert>
72
#include <iostream>
83
#include <memory>
94
#include <vector>
10-
#include "catch.hpp"
5+
6+
#include <catch.hpp>
117

128
#include "DataFormats/Common/interface/Wrapper.h"
139

1410
class CopyNoMove {
1511
public:
16-
CopyNoMove() {}
12+
CopyNoMove() = default;
1713
CopyNoMove(CopyNoMove const&) { /* std::cout << "copied\n"; */ }
1814
CopyNoMove& operator=(CopyNoMove const&) { /*std::cout << "assigned\n";*/ return *this; }
19-
20-
private:
2115
};
2216

2317
class MoveNoCopy {
2418
public:
25-
MoveNoCopy() {}
19+
MoveNoCopy() = default;
2620
MoveNoCopy(MoveNoCopy const&) = delete;
2721
MoveNoCopy& operator=(MoveNoCopy const&) = delete;
2822
MoveNoCopy(MoveNoCopy&&) { /* std::cout << "moved\n";*/ }
2923
MoveNoCopy& operator=(MoveNoCopy&&) { /* std::cout << "moved\n";*/ return *this; }
24+
};
3025

31-
private:
26+
class NoDefaultCtor {
27+
public:
28+
NoDefaultCtor() = delete;
29+
NoDefaultCtor(edm::Uninitialized) {}
3230
};
3331

3432
TEST_CASE("test Wrapper", "[Wrapper]") {
@@ -44,4 +42,7 @@ TEST_CASE("test Wrapper", "[Wrapper]") {
4442
edm::Wrapper<std::vector<double>> wrap3(std::move(thing3));
4543
REQUIRE(wrap3->size() == 10);
4644
REQUIRE(thing3.get() == 0);
45+
46+
auto thing4 = std::make_unique<NoDefaultCtor>(edm::kUninitialized);
47+
edm::Wrapper<NoDefaultCtor> wrap4(std::move(thing4));
4748
}

DataFormats/Portable/interface/PortableDeviceCollection.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77

88
#include <alpaka/alpaka.hpp>
99

10+
#include "DataFormats/Common/interface/Uninitialized.h"
11+
#include "DataFormats/Portable/interface/PortableCollectionCommon.h"
1012
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
1113
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
12-
#include "DataFormats/Portable/interface/PortableCollectionCommon.h"
1314

1415
// generic SoA-based product in device memory
1516
template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
@@ -24,7 +25,9 @@ class PortableDeviceCollection {
2425
using Buffer = cms::alpakatools::device_buffer<TDev, std::byte[]>;
2526
using ConstBuffer = cms::alpakatools::const_device_buffer<TDev, std::byte[]>;
2627

27-
PortableDeviceCollection() = default;
28+
PortableDeviceCollection() = delete;
29+
30+
explicit PortableDeviceCollection(edm::Uninitialized) noexcept {}
2831

2932
PortableDeviceCollection(int32_t elements, TDev const& device)
3033
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(device, Layout::computeDataSize(elements))},
@@ -144,7 +147,9 @@ class PortableDeviceMultiCollection {
144147
}
145148

146149
public:
147-
PortableDeviceMultiCollection() = default;
150+
PortableDeviceMultiCollection() = delete;
151+
152+
explicit PortableDeviceMultiCollection(edm::Uninitialized) noexcept {};
148153

149154
PortableDeviceMultiCollection(int32_t elements, TDev const& device)
150155
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(device, Layout<>::computeDataSize(elements))},

DataFormats/Portable/interface/PortableDeviceObject.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <alpaka/alpaka.hpp>
99

10+
#include "DataFormats/Common/interface/Uninitialized.h"
1011
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
1112
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
1213

@@ -21,7 +22,9 @@ class PortableDeviceObject {
2122
using Buffer = cms::alpakatools::device_buffer<TDev, Product>;
2223
using ConstBuffer = cms::alpakatools::const_device_buffer<TDev, Product>;
2324

24-
PortableDeviceObject() = default;
25+
PortableDeviceObject() = delete;
26+
27+
PortableDeviceObject(edm::Uninitialized) {}
2528

2629
PortableDeviceObject(TDev const& device)
2730
// allocate global device memory

DataFormats/Portable/interface/PortableHostCollection.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66

77
#include <alpaka/alpaka.hpp>
88

9+
#include "DataFormats/Common/interface/Uninitialized.h"
10+
#include "DataFormats/Portable/interface/PortableCollectionCommon.h"
911
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
1012
#include "HeterogeneousCore/AlpakaInterface/interface/host.h"
1113
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
12-
#include "DataFormats/Portable/interface/PortableCollectionCommon.h"
1314

1415
// generic SoA-based product in host memory
1516
template <typename T>
@@ -21,7 +22,9 @@ class PortableHostCollection {
2122
using Buffer = cms::alpakatools::host_buffer<std::byte[]>;
2223
using ConstBuffer = cms::alpakatools::const_host_buffer<std::byte[]>;
2324

24-
PortableHostCollection() = default;
25+
PortableHostCollection() = delete;
26+
27+
explicit PortableHostCollection(edm::Uninitialized) noexcept {};
2528

2629
PortableHostCollection(int32_t elements, alpaka_common::DevHost const& host)
2730
// allocate pageable host memory
@@ -154,7 +157,9 @@ class PortableHostMultiCollection {
154157
}
155158

156159
public:
157-
PortableHostMultiCollection() = default;
160+
PortableHostMultiCollection() = delete;
161+
162+
explicit PortableHostMultiCollection(edm::Uninitialized) noexcept {};
158163

159164
PortableHostMultiCollection(int32_t elements, alpaka_common::DevHost const& host)
160165
// allocate pageable host memory

DataFormats/Portable/interface/PortableHostObject.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <alpaka/alpaka.hpp>
99

10+
#include "DataFormats/Common/interface/Uninitialized.h"
1011
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
1112
#include "HeterogeneousCore/AlpakaInterface/interface/host.h"
1213
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
@@ -19,7 +20,9 @@ class PortableHostObject {
1920
using Buffer = cms::alpakatools::host_buffer<Product>;
2021
using ConstBuffer = cms::alpakatools::const_host_buffer<Product>;
2122

22-
PortableHostObject() = default;
23+
PortableHostObject() = delete;
24+
25+
PortableHostObject(edm::Uninitialized) noexcept {}
2326

2427
PortableHostObject(alpaka_common::DevHost const& host)
2528
// allocate pageable host memory

DataFormats/SiPixelClusterSoA/interface/SiPixelClustersDevice.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22
#define DataFormats_SiPixelClusterSoA_interface_SiPixelClustersDevice_h
33

44
#include <cstdint>
5+
56
#include <alpaka/alpaka.hpp>
6-
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
7-
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h"
7+
8+
#include "DataFormats/Common/interface/Uninitialized.h"
89
#include "DataFormats/Portable/interface/PortableDeviceCollection.h"
10+
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h"
911
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersSoA.h"
1012
#include "HeterogeneousCore/AlpakaInterface/interface/CopyToHost.h"
13+
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
1114

1215
template <typename TDev>
1316
class SiPixelClustersDevice : public PortableDeviceCollection<SiPixelClustersSoA, TDev> {
1417
public:
15-
SiPixelClustersDevice() = default;
18+
SiPixelClustersDevice(edm::Uninitialized) : PortableDeviceCollection<SiPixelClustersSoA, TDev>{edm::kUninitialized} {}
1619

1720
template <typename TQueue>
1821
explicit SiPixelClustersDevice(size_t maxModules, TQueue queue)

DataFormats/SiPixelClusterSoA/interface/SiPixelClustersHost.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
#define DataFormats_SiPixelClusterSoA_interface_SiPixelClustersHost_h
33

44
#include <alpaka/alpaka.hpp>
5-
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
5+
6+
#include "DataFormats/Common/interface/Uninitialized.h"
67
#include "DataFormats/Portable/interface/PortableHostCollection.h"
78
#include "DataFormats/SiPixelClusterSoA/interface/SiPixelClustersSoA.h"
9+
#include "HeterogeneousCore/AlpakaInterface/interface/config.h"
810

911
// TODO: The class is created via inheritance of the PortableCollection.
1012
// This is generally discouraged, and should be done via composition.
1113
// See: https://github.com/cms-sw/cmssw/pull/40465#discussion_r1067364306
1214
class SiPixelClustersHost : public PortableHostCollection<SiPixelClustersSoA> {
1315
public:
14-
SiPixelClustersHost() = default;
16+
SiPixelClustersHost(edm::Uninitialized) : PortableHostCollection<SiPixelClustersSoA>{edm::kUninitialized} {}
1517

1618
template <typename TQueue>
1719
explicit SiPixelClustersHost(size_t maxModules, TQueue queue)

0 commit comments

Comments
 (0)