Skip to content

Commit eaa2ed7

Browse files
committed
[SYCL] Add support for buffer::use_pinned_host_memory property
1 parent 85839f8 commit eaa2ed7

File tree

11 files changed

+183
-37
lines changed

11 files changed

+183
-37
lines changed

sycl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ include(AddSYCLExecutable)
1414
set(SYCL_MAJOR_VERSION 2)
1515
set(SYCL_MINOR_VERSION 1)
1616
set(SYCL_PATCH_VERSION 0)
17-
set(SYCL_DEV_ABI_VERSION 0)
17+
set(SYCL_DEV_ABI_VERSION 1)
1818
if (SYCL_ADD_DEV_VERSION_POSTFIX)
1919
set(SYCL_VERSION_POSTFIX "-${SYCL_DEV_ABI_VERSION}")
2020
endif()
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
= SYCL Proposals: Use Pinned Host Memory Property
2+
Vlad Romanov <vlad[email protected]>
3+
v0.1
4+
:source-highlighter: pygments
5+
:icons: font
6+
== Introduction
7+
This document describes an extension that introduces a +sycl::oneapi::property::buffer::use_pinned_host_memory+ property for the `sycl::buffer`. Some SYCL backends can accelerate copies between host and device by allocating pinned memory. The property can be passed to the `sycl::buffer` constructor in order to enable such an allocation.
8+
9+
== Name Strings
10+
11+
+SYCL_INTEL_use_pinned_host_memory+
12+
13+
== Use Pinned Host Memory Property
14+
15+
.Proposed Buffer Property
16+
[cols="^50,50",options="header"]
17+
|===
18+
19+
|Property |Description
20+
|`syc::oneapi::property::buffer::use_pinned_host_memory`
21+
| The `use_pinned_host_memory` property adds the requirement that the SYCL runtime must allocate host pinned memory for the `sycl::buffer`. The property cannot be used with the `sycl::buffer` constructors that take hostData parameter, an invalid_object_error SYCL exception must be thrown in this case.
22+
|===

sycl/include/CL/sycl/detail/buffer_impl.hpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,39 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT {
4545
public:
4646
buffer_impl(size_t SizeInBytes, size_t, const property_list &Props,
4747
unique_ptr_class<SYCLMemObjAllocator> Allocator)
48-
: BaseT(SizeInBytes, Props, std::move(Allocator)) {}
48+
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
49+
50+
if (Props.has_property<sycl::property::buffer::use_host_ptr>())
51+
throw sycl::invalid_object_error(
52+
"The use_host_ptr property requires host pointer to be provided",
53+
PI_INVALID_OPERATION);
54+
}
4955

5056
buffer_impl(void *HostData, size_t SizeInBytes, size_t RequiredAlign,
5157
const property_list &Props,
5258
unique_ptr_class<SYCLMemObjAllocator> Allocator)
5359
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
60+
61+
if (Props.has_property<
62+
sycl::oneapi::property::buffer::use_pinned_host_memory>())
63+
throw sycl::invalid_object_error(
64+
"The use_pinned_host_memory cannot be used with host pointer",
65+
PI_INVALID_OPERATION);
66+
5467
BaseT::handleHostData(HostData, RequiredAlign);
5568
}
5669

5770
buffer_impl(const void *HostData, size_t SizeInBytes, size_t RequiredAlign,
5871
const property_list &Props,
5972
unique_ptr_class<SYCLMemObjAllocator> Allocator)
6073
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
74+
75+
if (Props.has_property<
76+
sycl::oneapi::property::buffer::use_pinned_host_memory>())
77+
throw sycl::invalid_object_error(
78+
"The use_pinned_host_memory cannot be used with host pointer",
79+
PI_INVALID_OPERATION);
80+
6181
BaseT::handleHostData(HostData, RequiredAlign);
6282
}
6383

@@ -66,6 +86,13 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT {
6686
size_t RequiredAlign, const property_list &Props,
6787
unique_ptr_class<SYCLMemObjAllocator> Allocator)
6888
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
89+
90+
if (Props.has_property<
91+
sycl::oneapi::property::buffer::use_pinned_host_memory>())
92+
throw sycl::invalid_object_error(
93+
"The use_pinned_host_memory cannot be used with host pointer",
94+
PI_INVALID_OPERATION);
95+
6996
BaseT::handleHostData(HostData, RequiredAlign);
7097
}
7198

@@ -79,6 +106,12 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT {
79106
const property_list &Props,
80107
unique_ptr_class<SYCLMemObjAllocator> Allocator)
81108
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
109+
110+
if (Props.has_property<sycl::property::buffer::use_host_ptr>())
111+
throw sycl::invalid_object_error("Buffer constructor from a pair of iterator "
112+
"values cannot have the use_host_ptr property.",
113+
PI_INVALID_OPERATION);
114+
82115
BaseT::handleHostData(First, Last, RequiredAlign);
83116
}
84117

@@ -92,6 +125,12 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT {
92125
const property_list &Props,
93126
unique_ptr_class<SYCLMemObjAllocator> Allocator)
94127
: BaseT(SizeInBytes, Props, std::move(Allocator)) {
128+
129+
if (Props.has_property<sycl::property::buffer::use_host_ptr>())
130+
throw sycl::invalid_object_error("Buffer constructor from a pair of iterator "
131+
"values cannot have the use_host_ptr property.",
132+
PI_INVALID_OPERATION);
133+
95134
BaseT::handleHostData(First, Last, RequiredAlign);
96135
}
97136

sycl/include/CL/sycl/detail/memory_manager.hpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <CL/sycl/detail/cl.h>
1313
#include <CL/sycl/detail/export.hpp>
1414
#include <CL/sycl/detail/sycl_mem_obj_i.hpp>
15+
#include <CL/sycl/property_list.hpp>
1516
#include <CL/sycl/range.hpp>
1617

1718
#include <memory>
@@ -71,6 +72,7 @@ class __SYCL_EXPORT MemoryManager {
7172
bool HostPtrReadOnly, size_t Size,
7273
const EventImplPtr &InteropEvent,
7374
const ContextImplPtr &InteropContext,
75+
const sycl::property_list &PropsList,
7476
RT::PiEvent &OutEventToWait);
7577

7678
// Allocates images in specified context taking into account situations such
@@ -80,29 +82,34 @@ class __SYCL_EXPORT MemoryManager {
8082
ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *UserPtr,
8183
bool HostPtrReadOnly, size_t Size, const RT::PiMemImageDesc &Desc,
8284
const RT::PiMemImageFormat &Format, const EventImplPtr &InteropEvent,
83-
const ContextImplPtr &InteropContext, RT::PiEvent &OutEventToWait);
85+
const ContextImplPtr &InteropContext,
86+
const sycl::property_list &PropsList, RT::PiEvent &OutEventToWait);
8487

8588
// Releases memory object(buffer or image). TargetContext should be device
8689
// one(not host).
8790
static void releaseMemObj(ContextImplPtr TargetContext, SYCLMemObjI *MemObj,
8891
void *MemAllocation, void *UserPtr);
8992

9093
static void *allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr,
91-
bool HostPtrReadOnly, size_t Size);
94+
bool HostPtrReadOnly, size_t Size,
95+
const sycl::property_list &PropsList);
9296

9397
static void *allocateInteropMemObject(ContextImplPtr TargetContext,
9498
void *UserPtr,
9599
const EventImplPtr &InteropEvent,
96100
const ContextImplPtr &InteropContext,
101+
const sycl::property_list &PropsList,
97102
RT::PiEvent &OutEventToWait);
98103

99104
static void *allocateImageObject(ContextImplPtr TargetContext, void *UserPtr,
100105
bool HostPtrReadOnly,
101106
const RT::PiMemImageDesc &Desc,
102-
const RT::PiMemImageFormat &Format);
107+
const RT::PiMemImageFormat &Format,
108+
const sycl::property_list &PropsList);
103109

104110
static void *allocateBufferObject(ContextImplPtr TargetContext, void *UserPtr,
105-
bool HostPtrReadOnly, const size_t Size);
111+
bool HostPtrReadOnly, const size_t Size,
112+
const sycl::property_list &PropsList);
106113

107114
// Copies memory between: host and device, host and host,
108115
// device and device if memory objects bound to the one context.

sycl/include/CL/sycl/property_list.hpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class noinit;
4747

4848
namespace detail {
4949

50+
// Will be aliased in the sycl::oneapi::property namespace
51+
namespace buffer_ {
52+
class use_pinned_host_memory;
53+
}
54+
5055
// List of all properties' IDs.
5156
enum PropKind {
5257
// Buffer properties
@@ -66,6 +71,8 @@ enum PropKind {
6671
// Accessor
6772
NoInit,
6873

74+
BufferUsePinnedHostMemory,
75+
6976
PropKindSize
7077
};
7178

@@ -148,6 +155,8 @@ RegisterProp(PropKind::ImageContextBound, image::context_bound);
148155
RegisterProp(PropKind::BufferUseHostPtr, buffer::use_host_ptr);
149156
RegisterProp(PropKind::BufferUseMutex, buffer::use_mutex);
150157
RegisterProp(PropKind::BufferContextBound, buffer::context_bound);
158+
RegisterProp(PropKind::BufferUsePinnedHostMemory,
159+
buffer_::use_pinned_host_memory);
151160

152161
// Queue
153162
RegisterProp(PropKind::QueueEnableProfiling, queue::enable_profiling);
@@ -212,8 +221,16 @@ class context_bound
212221
public:
213222
context_bound(cl::sycl::context Context) : ContextBoundBase(Context) {}
214223
};
224+
215225
} // namespace buffer
216226

227+
namespace detail {
228+
namespace buffer_ {
229+
class use_pinned_host_memory
230+
: public detail::Prop<detail::PropKind::BufferUsePinnedHostMemory> {};
231+
} // namespace buffer
232+
} // namespace detail
233+
217234
namespace queue {
218235
class enable_profiling
219236
: public detail::Prop<detail::PropKind::QueueEnableProfiling> {};
@@ -225,6 +242,15 @@ class noinit : public detail::Prop<detail::PropKind::NoInit> {};
225242

226243
} // namespace property
227244

245+
namespace oneapi {
246+
namespace property {
247+
namespace buffer {
248+
using use_pinned_host_memory =
249+
sycl::property::detail::buffer_::use_pinned_host_memory;
250+
} // namespace buffer
251+
} // namespace property
252+
} // namespace oneapi
253+
228254
#if __cplusplus > 201402L
229255

230256
inline constexpr property::noinit noinit;
@@ -280,17 +306,16 @@ class property_list {
280306
}
281307

282308
template <typename propertyT> propertyT get_property() const {
283-
static_assert((int)(propertyT::getKind()) <=
284-
property::detail::PropKind::PropKindSize,
285-
"Invalid option passed.");
286-
const auto &PropHolder = std::get<(int)(propertyT::getKind())>(m_PropsList);
287-
if (PropHolder.isInitialized()) {
288-
return PropHolder.getProp();
309+
if (!has_property<propertyT>()) {
310+
throw sycl::invalid_object_error();
289311
}
290-
throw invalid_object_error();
312+
const auto &PropHolder = std::get<(int)(propertyT::getKind())>(m_PropsList);
313+
return PropHolder.getProp();
291314
}
292315

293316
template <typename propertyT> bool has_property() const {
317+
if ((int)(propertyT::getKind()) > property::detail::PropKind::PropKindSize)
318+
return false;
294319
return std::get<(int)(propertyT::getKind())>(m_PropsList).isInitialized();
295320
}
296321

sycl/source/detail/buffer_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void *buffer_impl::allocateMem(ContextImplPtr Context, bool InitFromUserData,
2929

3030
return MemoryManager::allocateMemBuffer(
3131
std::move(Context), this, UserPtr, BaseT::MHostPtrReadOnly,
32-
BaseT::getSize(), BaseT::MInteropEvent, BaseT::MInteropContext,
32+
BaseT::getSize(), BaseT::MInteropEvent, BaseT::MInteropContext, MProps,
3333
OutEventToWait);
3434
}
3535
} // namespace detail

sycl/source/detail/image_impl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ void *image_impl<Dimensions>::allocateMem(ContextImplPtr Context,
325325
return MemoryManager::allocateMemImage(
326326
std::move(Context), this, UserPtr, BaseT::MHostPtrReadOnly,
327327
BaseT::getSize(), Desc, Format, BaseT::MInteropEvent,
328-
BaseT::MInteropContext, OutEventToWait);
328+
BaseT::MInteropContext, MProps, OutEventToWait);
329329
}
330330

331331
template <int Dimensions>

sycl/source/detail/memory_manager.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ void *MemoryManager::wrapIntoImageBuffer(ContextImplPtr TargetContext,
106106
}
107107

108108
void *MemoryManager::allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr,
109-
bool HostPtrReadOnly, size_t Size) {
109+
bool HostPtrReadOnly, size_t Size,
110+
const sycl::property_list &) {
110111
// Can return user pointer directly if it points to writable memory.
111112
if (UserPtr && HostPtrReadOnly == false)
112113
return UserPtr;
@@ -123,7 +124,7 @@ void *MemoryManager::allocateHostMemory(SYCLMemObjI *MemObj, void *UserPtr,
123124
void *MemoryManager::allocateInteropMemObject(
124125
ContextImplPtr TargetContext, void *UserPtr,
125126
const EventImplPtr &InteropEvent, const ContextImplPtr &InteropContext,
126-
RT::PiEvent &OutEventToWait) {
127+
const sycl::property_list &, RT::PiEvent &OutEventToWait) {
127128
// If memory object is created with interop c'tor.
128129
// Return cl_mem as is if contexts match.
129130
if (TargetContext == InteropContext) {
@@ -144,7 +145,8 @@ void *MemoryManager::allocateInteropMemObject(
144145
void *MemoryManager::allocateImageObject(ContextImplPtr TargetContext,
145146
void *UserPtr, bool HostPtrReadOnly,
146147
const RT::PiMemImageDesc &Desc,
147-
const RT::PiMemImageFormat &Format) {
148+
const RT::PiMemImageFormat &Format,
149+
const sycl::property_list &) {
148150
// Create read_write mem object by default to handle arbitrary uses.
149151
RT::PiMemFlags CreationFlags = PI_MEM_FLAGS_ACCESS_RW;
150152
if (UserPtr)
@@ -159,16 +161,20 @@ void *MemoryManager::allocateImageObject(ContextImplPtr TargetContext,
159161
return NewMem;
160162
}
161163

162-
void *MemoryManager::allocateBufferObject(ContextImplPtr TargetContext,
163-
void *UserPtr, bool HostPtrReadOnly,
164-
const size_t Size) {
164+
void *
165+
MemoryManager::allocateBufferObject(ContextImplPtr TargetContext, void *UserPtr,
166+
bool HostPtrReadOnly, const size_t Size,
167+
const sycl::property_list &PropsList) {
165168
// Create read_write mem object by default to handle arbitrary uses.
166169
RT::PiMemFlags CreationFlags = PI_MEM_FLAGS_ACCESS_RW;
167170
if (UserPtr)
168171
CreationFlags |= HostPtrReadOnly ? PI_MEM_FLAGS_HOST_PTR_COPY
169172
: PI_MEM_FLAGS_HOST_PTR_USE;
173+
else if (PropsList.has_property<
174+
sycl::oneapi::property::buffer::use_pinned_host_memory>())
175+
CreationFlags |= PI_MEM_FLAGS_HOST_PTR_ALLOC;
170176

171-
RT::PiMem NewMem;
177+
RT::PiMem NewMem = nullptr;
172178
const detail::plugin &Plugin = TargetContext->getPlugin();
173179
Plugin.call<PiApiKind::piMemBufferCreate>(
174180
TargetContext->getHandleRef(), CreationFlags, Size, UserPtr, &NewMem);
@@ -180,27 +186,32 @@ void *MemoryManager::allocateMemBuffer(ContextImplPtr TargetContext,
180186
bool HostPtrReadOnly, size_t Size,
181187
const EventImplPtr &InteropEvent,
182188
const ContextImplPtr &InteropContext,
189+
const sycl::property_list &PropsList,
183190
RT::PiEvent &OutEventToWait) {
184191
if (TargetContext->is_host())
185-
return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size);
192+
return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size,
193+
PropsList);
186194
if (UserPtr && InteropContext)
187195
return allocateInteropMemObject(TargetContext, UserPtr, InteropEvent,
188-
InteropContext, OutEventToWait);
189-
return allocateBufferObject(TargetContext, UserPtr, HostPtrReadOnly, Size);
196+
InteropContext, PropsList, OutEventToWait);
197+
return allocateBufferObject(TargetContext, UserPtr, HostPtrReadOnly, Size,
198+
PropsList);
190199
}
191200

192201
void *MemoryManager::allocateMemImage(
193202
ContextImplPtr TargetContext, SYCLMemObjI *MemObj, void *UserPtr,
194203
bool HostPtrReadOnly, size_t Size, const RT::PiMemImageDesc &Desc,
195204
const RT::PiMemImageFormat &Format, const EventImplPtr &InteropEvent,
196-
const ContextImplPtr &InteropContext, RT::PiEvent &OutEventToWait) {
205+
const ContextImplPtr &InteropContext, const sycl::property_list &PropsList,
206+
RT::PiEvent &OutEventToWait) {
197207
if (TargetContext->is_host())
198-
return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size);
208+
return allocateHostMemory(MemObj, UserPtr, HostPtrReadOnly, Size,
209+
PropsList);
199210
if (UserPtr && InteropContext)
200211
return allocateInteropMemObject(TargetContext, UserPtr, InteropEvent,
201-
InteropContext, OutEventToWait);
212+
InteropContext, PropsList, OutEventToWait);
202213
return allocateImageObject(TargetContext, UserPtr, HostPtrReadOnly, Desc,
203-
Format);
214+
Format, PropsList);
204215
}
205216

206217
void *MemoryManager::allocateMemSubBuffer(ContextImplPtr TargetContext,

sycl/test/.clang-format

Lines changed: 0 additions & 2 deletions
This file was deleted.

sycl/test/abi/sycl_symbols_linux.dump

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3721,13 +3721,13 @@ _ZN2cl4sycl6detail12sampler_implD2Ev
37213721
_ZN2cl4sycl6detail12split_stringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc
37223722
_ZN2cl4sycl6detail13MemoryManager12prefetch_usmEPvSt10shared_ptrINS1_10queue_implEEmSt6vectorIP9_pi_eventSaIS9_EERS9_
37233723
_ZN2cl4sycl6detail13MemoryManager13releaseMemObjESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvS8_
3724-
_ZN2cl4sycl6detail13MemoryManager16allocateMemImageESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRK14_pi_image_descRK16_pi_image_formatRKS3_INS1_10event_implEERKS5_RP9_pi_event
3725-
_ZN2cl4sycl6detail13MemoryManager17allocateMemBufferESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRKS3_INS1_10event_implEERKS5_RP9_pi_event
3726-
_ZN2cl4sycl6detail13MemoryManager18allocateHostMemoryEPNS1_11SYCLMemObjIEPvbm
3727-
_ZN2cl4sycl6detail13MemoryManager19allocateImageObjectESt10shared_ptrINS1_12context_implEEPvbRK14_pi_image_descRK16_pi_image_format
3728-
_ZN2cl4sycl6detail13MemoryManager20allocateBufferObjectESt10shared_ptrINS1_12context_implEEPvbm
3724+
_ZN2cl4sycl6detail13MemoryManager19allocateImageObjectESt10shared_ptrINS1_12context_implEEPvbRK14_pi_image_descRK16_pi_image_formatRKNS0_13property_listE
3725+
_ZN2cl4sycl6detail13MemoryManager16allocateMemImageESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRK14_pi_image_descRK16_pi_image_formatRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event
3726+
_ZN2cl4sycl6detail13MemoryManager24allocateInteropMemObjectESt10shared_ptrINS1_12context_implEEPvRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event
3727+
_ZN2cl4sycl6detail13MemoryManager20allocateBufferObjectESt10shared_ptrINS1_12context_implEEPvbmRKNS0_13property_listE
3728+
_ZN2cl4sycl6detail13MemoryManager18allocateHostMemoryEPNS1_11SYCLMemObjIEPvbmRKNS0_13property_listE
3729+
_ZN2cl4sycl6detail13MemoryManager17allocateMemBufferESt10shared_ptrINS1_12context_implEEPNS1_11SYCLMemObjIEPvbmRKS3_INS1_10event_implEERKS5_RKNS0_13property_listERP9_pi_event
37293730
_ZN2cl4sycl6detail13MemoryManager20allocateMemSubBufferESt10shared_ptrINS1_12context_implEEPvmmNS0_5rangeILi3EEESt6vectorIS3_INS1_10event_implEESaISB_EERP9_pi_event
3730-
_ZN2cl4sycl6detail13MemoryManager24allocateInteropMemObjectESt10shared_ptrINS1_12context_implEEPvRKS3_INS1_10event_implEERKS5_RP9_pi_event
37313731
_ZN2cl4sycl6detail13MemoryManager3mapEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEENS0_6access4modeEjNS0_5rangeILi3EEESC_NS0_2idILi3EEEjSt6vectorIP9_pi_eventSaISH_EERSH_
37323732
_ZN2cl4sycl6detail13MemoryManager4copyEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEEjNS0_5rangeILi3EEESA_NS0_2idILi3EEEjS5_S8_jSA_SA_SC_jSt6vectorIP9_pi_eventSaISF_EERSF_
37333733
_ZN2cl4sycl6detail13MemoryManager4fillEPNS1_11SYCLMemObjIEPvSt10shared_ptrINS1_10queue_implEEmPKcjNS0_5rangeILi3EEESC_NS0_2idILi3EEEjSt6vectorIP9_pi_eventSaISH_EERSH_

0 commit comments

Comments
 (0)