Skip to content

Commit 56d06a6

Browse files
[AsyncAlloc][SYCL] Use the SYCL properties extension for memory pool creation (#17955)
Introduce initial_threshold, maximum_size, read_only, and zero_init runtime properties conforming to the SYCL properties extension, and apply these properties to the creation of memory pools. This PR is a draft until the feature has been added to the [sycl_ext_oneapi_async_memory_alloc](#14800) spec. This is an ABI-break but on experimental extension which has been just recently added. --------- Co-authored-by: omarahmed1111 <[email protected]>
1 parent 451ecfb commit 56d06a6

17 files changed

+136
-225
lines changed

sycl/include/sycl/context.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -256,12 +256,6 @@ class __SYCL_EXPORT context : public detail::OwnerLessBase<context> {
256256
ext_oneapi_get_default_memory_pool(const device &dev,
257257
sycl::usm::alloc kind) const;
258258

259-
/// Gets default memory pool associated with the context and allocation kind.
260-
///
261-
/// \return a memory pool associated with this context.
262-
sycl::ext::oneapi::experimental::memory_pool
263-
ext_oneapi_get_default_memory_pool(sycl::usm::alloc kind) const;
264-
265259
private:
266260
/// Constructs a SYCL context object from a valid context_impl instance.
267261
context(std::shared_ptr<detail::context_impl> Impl);

sycl/include/sycl/detail/property_helper.hpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,8 @@ enum DataLessPropKind {
5151
GraphDependOnAllLeaves = 24,
5252
GraphUpdatable = 25,
5353
GraphEnableProfiling = 26,
54-
MemPoolReadOnly = 27,
55-
MemPoolZeroInit = 28,
5654
// Indicates the last known dataless property.
57-
LastKnownDataLessPropKind = 28,
55+
LastKnownDataLessPropKind = 26,
5856
// Exceeding 32 may cause ABI breaking change on some of OSes.
5957
DataLessPropKindSize = 32
6058
};
@@ -69,9 +67,7 @@ enum PropWithDataKind {
6967
AccPropBufferLocation = 5,
7068
QueueComputeIndex = 6,
7169
GraphNodeDependencies = 7,
72-
MemPoolInitialThreshold = 8,
73-
MemPoolMaximumSize = 9,
74-
PropWithDataKindSize = 10
70+
PropWithDataKindSize = 8
7571
};
7672

7773
// Base class for dataless properties, needed to check that the type of an

sycl/include/sycl/ext/oneapi/experimental/async_alloc/memory_pool.hpp

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,39 +24,21 @@ class memory_pool_impl;
2424

2525
/// Memory pool
2626
class __SYCL_EXPORT memory_pool {
27-
2827
public:
29-
// NOT SUPPORTED: Host side pools unsupported.
30-
memory_pool(const sycl::context &, sycl::usm::alloc kind,
31-
const property_list & = {}) {
32-
if (kind == sycl::usm::alloc::device || kind == sycl::usm::alloc::shared)
33-
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
34-
"Device and shared allocation kinds are disallowed "
35-
"without specifying a device!");
36-
if (kind == sycl::usm::alloc::unknown)
37-
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
38-
"Unknown allocation kinds are disallowed!");
39-
40-
throw sycl::exception(
41-
sycl::make_error_code(sycl::errc::feature_not_supported),
42-
"Host allocated pools are unsupported!");
43-
}
44-
28+
template <typename Properties = empty_properties_t,
29+
typename = std::enable_if_t<
30+
detail::all_are_properties_of_v<memory_pool, Properties>>>
4531
memory_pool(const sycl::context &ctx, const sycl::device &dev,
46-
sycl::usm::alloc kind, const property_list &props = {});
32+
sycl::usm::alloc kind, Properties props = {})
33+
: memory_pool(ctx, dev, kind, stripProps(props)) {}
4734

35+
template <typename Properties = empty_properties_t,
36+
typename = std::enable_if_t<
37+
detail::all_are_properties_of_v<memory_pool, Properties>>>
4838
memory_pool(const sycl::queue &q, sycl::usm::alloc kind,
49-
const property_list &props = {})
39+
Properties props = {})
5040
: memory_pool(q.get_context(), q.get_device(), kind, props) {}
5141

52-
// NOT SUPPORTED: Creating a pool from an existing allocation is unsupported.
53-
memory_pool(const sycl::context &, void *, size_t,
54-
const property_list & = {}) {
55-
throw sycl::exception(
56-
sycl::make_error_code(sycl::errc::feature_not_supported),
57-
"Creating a pool from an existing allocation is unsupported!");
58-
}
59-
6042
~memory_pool() = default;
6143

6244
// Copy constructible/assignable, move constructible/assignable.
@@ -79,20 +61,21 @@ class __SYCL_EXPORT memory_pool {
7961

8062
void increase_threshold_to(size_t newThreshold);
8163

82-
// Property getters.
83-
template <typename PropertyT> bool has_property() const noexcept {
84-
return getPropList().template has_property<PropertyT>();
85-
}
86-
template <typename PropertyT> PropertyT get_property() const {
87-
return getPropList().template get_property<PropertyT>();
88-
}
89-
9064
protected:
65+
struct pool_properties {
66+
size_t initial_threshold;
67+
size_t maximum_size;
68+
bool zero_init;
69+
};
70+
9171
std::shared_ptr<detail::memory_pool_impl> impl;
9272

9373
memory_pool(std::shared_ptr<detail::memory_pool_impl> Impl)
9474
: impl(std::move(Impl)) {}
9575

76+
memory_pool(const sycl::context &ctx, const sycl::device &dev,
77+
sycl::usm::alloc kind, pool_properties props);
78+
9679
template <class Obj>
9780
friend const decltype(Obj::impl) &
9881
sycl::detail::getSyclObjImpl(const Obj &SyclObject);
@@ -104,7 +87,23 @@ class __SYCL_EXPORT memory_pool {
10487
friend T sycl::detail::createSyclObjFromImpl(
10588
std::add_lvalue_reference_t<const decltype(T::impl)> ImplObj);
10689

107-
const property_list &getPropList() const;
90+
template <typename Properties> pool_properties stripProps(Properties props) {
91+
pool_properties poolProps{};
92+
if constexpr (decltype(props)::template has_property<initial_threshold>()) {
93+
poolProps.initial_threshold =
94+
props.template get_property<initial_threshold>().value;
95+
}
96+
97+
if constexpr (decltype(props)::template has_property<maximum_size>()) {
98+
poolProps.maximum_size =
99+
props.template get_property<maximum_size>().value;
100+
}
101+
102+
if constexpr (decltype(props)::template has_property<zero_init>()) {
103+
poolProps.zero_init = true;
104+
}
105+
return poolProps;
106+
}
108107
};
109108

110109
} // namespace ext::oneapi::experimental

sycl/include/sycl/ext/oneapi/experimental/async_alloc/memory_pool_properties.hpp

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#pragma once
10-
#include <cstddef>
11-
#include <sycl/properties/property_traits.hpp>
10+
#include <sycl/ext/oneapi/properties/property.hpp>
1211

1312
namespace sycl {
1413
inline namespace _V1 {
@@ -17,64 +16,64 @@ namespace ext::oneapi::experimental {
1716
// Forward declare memory_pool.
1817
class memory_pool;
1918

20-
namespace property::memory_pool {
21-
2219
// Property that determines the initial threshold of a memory pool.
23-
struct initial_threshold : public sycl::detail::PropertyWithData<
24-
sycl::detail::MemPoolInitialThreshold> {
25-
initial_threshold(size_t initialThreshold)
26-
: initialThreshold(initialThreshold) {};
27-
size_t get_initial_threshold() { return initialThreshold; }
28-
29-
private:
30-
size_t initialThreshold;
20+
struct initial_threshold
21+
: detail::run_time_property_key<initial_threshold,
22+
detail::PropKind::InitialThreshold> {
23+
initial_threshold(size_t initialThreshold) : value(initialThreshold) {}
24+
size_t value;
3125
};
3226

27+
using initial_threshold_key = initial_threshold;
28+
inline bool operator==(const initial_threshold &lhs,
29+
const initial_threshold &rhs) {
30+
return lhs.value == rhs.value;
31+
}
32+
inline bool operator!=(const initial_threshold &lhs,
33+
const initial_threshold &rhs) {
34+
return !(lhs == rhs);
35+
}
36+
3337
// Property that determines the maximum size of a memory pool.
3438
struct maximum_size
35-
: public sycl::detail::PropertyWithData<sycl::detail::MemPoolMaximumSize> {
36-
maximum_size(size_t maxSize) : maxSize(maxSize) {};
37-
size_t get_maximum_size() { return maxSize; }
38-
39-
private:
40-
size_t maxSize;
39+
: detail::run_time_property_key<maximum_size,
40+
detail::PropKind::MaximumSize> {
41+
maximum_size(size_t maxSize) : value(maxSize) {}
42+
size_t value;
4143
};
4244

43-
// Property that provides a performance hint that all allocations from this pool
44-
// will only be read from within SYCL kernel functions.
45-
struct read_only
46-
: public sycl::detail::DataLessProperty<sycl::detail::MemPoolReadOnly> {
47-
read_only() = default;
48-
};
45+
using maximum_size_key = maximum_size;
46+
inline bool operator==(const maximum_size &lhs, const maximum_size &rhs) {
47+
return lhs.value == rhs.value;
48+
}
49+
inline bool operator!=(const maximum_size &lhs, const maximum_size &rhs) {
50+
return !(lhs == rhs);
51+
}
4952

50-
// Property that initial allocations to a pool (not subsequent allocations
51-
// from prior frees) are iniitialised to zero.
53+
// Property that initial allocations to a pool (not subsequent allocations from
54+
// prior frees) are iniitialised to zero.
55+
// enum class zero_init_enum { none, zero_init };
5256
struct zero_init
53-
: public sycl::detail::DataLessProperty<sycl::detail::MemPoolZeroInit> {
54-
zero_init() = default;
57+
: detail::run_time_property_key<zero_init, detail::PropKind::ZeroInit> {
58+
zero_init() {};
5559
};
56-
} // namespace property::memory_pool
57-
} // namespace ext::oneapi::experimental
5860

59-
template <>
60-
struct is_property<
61-
sycl::ext::oneapi::experimental::property::memory_pool::initial_threshold>
62-
: std::true_type {};
61+
using zero_init_key = zero_init;
62+
inline bool operator==(const zero_init &, const zero_init &) { return true; }
63+
inline bool operator!=(const zero_init &lhs, const zero_init &rhs) {
64+
return !(lhs == rhs);
65+
}
6366

6467
template <>
65-
struct is_property<
66-
sycl::ext::oneapi::experimental::property::memory_pool::maximum_size>
67-
: std::true_type {};
68+
struct is_property_key_of<initial_threshold_key, memory_pool> : std::true_type {
69+
};
6870

6971
template <>
70-
struct is_property<
71-
sycl::ext::oneapi::experimental::property::memory_pool::read_only>
72-
: std::true_type {};
72+
struct is_property_key_of<maximum_size_key, memory_pool> : std::true_type {};
7373

7474
template <>
75-
struct is_property<
76-
sycl::ext::oneapi::experimental::property::memory_pool::zero_init>
77-
: std::true_type {};
75+
struct is_property_key_of<zero_init_key, memory_pool> : std::true_type {};
7876

77+
} // namespace ext::oneapi::experimental
7978
} // namespace _V1
8079
} // namespace sycl

sycl/include/sycl/ext/oneapi/properties/property.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,11 @@ enum PropKind : uint32_t {
225225
Unaliased = 80,
226226
EventMode = 81,
227227
NativeLocalBlockIO = 82,
228+
InitialThreshold = 83,
229+
MaximumSize = 84,
230+
ZeroInit = 85,
228231
// PropKindSize must always be the last value.
229-
PropKindSize = 83,
232+
PropKindSize = 86,
230233
};
231234

232235
template <typename PropertyT> struct PropertyToKind {

sycl/source/context.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,6 @@ const property_list &context::getPropList() const {
135135
sycl::ext::oneapi::experimental::memory_pool
136136
context::ext_oneapi_get_default_memory_pool(const device &dev,
137137
sycl::usm::alloc kind) const {
138-
if (kind == sycl::usm::alloc::host)
139-
throw sycl::exception(
140-
sycl::make_error_code(sycl::errc::invalid),
141-
"Default host memory pool requested but device supplied!");
142138
if (kind == sycl::usm::alloc::unknown)
143139
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
144140
"Unknown allocation kinds are disallowed!");
@@ -153,20 +149,5 @@ context::ext_oneapi_get_default_memory_pool(const device &dev,
153149
impl->get_default_memory_pool(*this, dev, kind));
154150
}
155151

156-
sycl::ext::oneapi::experimental::memory_pool
157-
context::ext_oneapi_get_default_memory_pool(sycl::usm::alloc kind) const {
158-
if (kind == sycl::usm::alloc::device || kind == sycl::usm::alloc::shared)
159-
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
160-
"Device and shared allocation kinds are disallowed "
161-
"without specifying a device!");
162-
if (kind == sycl::usm::alloc::unknown)
163-
throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
164-
"Unknown allocation kinds are disallowed!");
165-
166-
throw sycl::exception(
167-
sycl::make_error_code(sycl::errc::feature_not_supported),
168-
"Host allocated pools are unsupported!");
169-
}
170-
171152
} // namespace _V1
172153
} // namespace sycl

sycl/source/detail/context_impl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
#include <detail/context_impl.hpp>
1010
#include <detail/context_info.hpp>
1111
#include <detail/event_info.hpp>
12+
#include <detail/memory_pool_impl.hpp>
1213
#include <detail/platform_impl.hpp>
1314
#include <detail/queue_impl.hpp>
1415
#include <sycl/detail/common.hpp>
1516
#include <sycl/detail/ur.hpp>
1617
#include <sycl/device.hpp>
1718
#include <sycl/exception.hpp>
1819
#include <sycl/exception_list.hpp>
20+
#include <sycl/ext/oneapi/experimental/async_alloc/memory_pool.hpp>
1921
#include <sycl/info/info_desc.hpp>
2022
#include <sycl/platform.hpp>
2123
#include <sycl/property_list.hpp>
@@ -590,7 +592,7 @@ context_impl::get_default_memory_pool(const context &Context,
590592
auto MemPoolImplPtr = std::make_shared<
591593
sycl::ext::oneapi::experimental::detail::memory_pool_impl>(
592594
Context, Device, sycl::usm::alloc::device, PoolHandle,
593-
true /*Default pool*/, property_list{});
595+
true /*Default pool*/);
594596

595597
// Hold onto a weak_ptr of the memory_pool_impl. Prevents circular
596598
// dependencies between the context_impl and memory_pool_impl.

sycl/source/detail/graph_memory_pool.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,10 @@ graph_mem_pool::malloc(size_t Size, usm::alloc AllocType,
3333
AllocInfo.Kind = AllocType;
3434
// Collect relevant properties from memory pool
3535
if (MemPool) {
36-
const auto &PropList = MemPool->getPropList();
37-
if (PropList.has_property<property::memory_pool::zero_init>()) {
36+
auto Props = MemPool->getProps();
37+
if (Props.zero_init) {
3838
AllocInfo.ZeroInit = true;
3939
}
40-
if (PropList.has_property<property::memory_pool::read_only>()) {
41-
AllocInfo.ReadOnly = true;
42-
}
4340
}
4441

4542
switch (AllocType) {

sycl/source/detail/memory_pool.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ __SYCL_EXPORT size_t memory_pool::get_threshold() const {
2727
return impl->get_threshold();
2828
}
2929

30-
const property_list &memory_pool::getPropList() const {
31-
return impl->getPropList();
32-
}
33-
3430
__SYCL_EXPORT size_t memory_pool::get_reserved_size_current() const {
3531
return impl->get_reserved_size_current();
3632
}
@@ -45,22 +41,17 @@ __SYCL_EXPORT void memory_pool::increase_threshold_to(size_t newThreshold) {
4541
impl->set_new_threshold(newThreshold);
4642
}
4743

48-
__SYCL_EXPORT memory_pool::memory_pool(const sycl::context &ctx,
49-
const sycl::device &dev,
50-
sycl::usm::alloc kind,
51-
const property_list &props) {
52-
53-
if (kind == sycl::usm::alloc::host)
54-
throw sycl::exception(
55-
sycl::make_error_code(sycl::errc::invalid),
56-
"Host allocated memory pools selected but device supplied!");
57-
44+
memory_pool::memory_pool(const sycl::context &ctx, const sycl::device &dev,
45+
sycl::usm::alloc kind,
46+
memory_pool::pool_properties props) {
5847
if (kind != sycl::usm::alloc::device)
5948
throw sycl::exception(
6049
sycl::make_error_code(sycl::errc::feature_not_supported),
6150
"Only device allocated memory pools are supported!");
6251

63-
impl = std::make_shared<detail::memory_pool_impl>(ctx, dev, kind, props);
52+
detail::pool_properties poolProps{props.initial_threshold, props.maximum_size,
53+
props.zero_init};
54+
impl = std::make_shared<detail::memory_pool_impl>(ctx, dev, kind, poolProps);
6455
}
6556

6657
} // namespace ext::oneapi::experimental

0 commit comments

Comments
 (0)