Copyright © 2023 Intel Corporation. All rights reserved.
Khronos® is a registered trademark and SYCL™ and SPIR™ are trademarks of The Khronos Group Inc. OpenCL™ is a trademark of Apple Inc. used by permission by Khronos.
To report problems with this extension, please open a new issue at:
This extension is written against the SYCL 2020 revision 8 specification. All references below to the "core SYCL specification" or to section numbers in the SYCL specification refer to that revision.
This extension also depends on the following other SYCL extensions:
This is an experimental extension specification, intended to provide early access to features and gather community feedback. Interfaces defined in this specification are implemented in DPC++, but they are not finalized and may change incompatibly in future versions of DPC++ without prior notice. Shipping software products should not rely on APIs defined in this specification.
The APIs in this extension may be used only on a device that has
aspect::ext_oneapi_virtual_mem. The application must check that the devices
in the corresponding context have this aspect before using any of the APIs
introduced in this extension. If the application fails to do this, the
implementation throws a synchronous exception with the
errc::feature_not_supported error code.
This extension adds the notion of "virtual memory ranges" to SYCL, introducing a way to map an address range onto multiple allocations of physical memory, allowing users to avoid expensive reallocations and potentially running out of device memory while relocating the corresponding memory.
This extension provides a feature-test macro as described in the core SYCL
specification. An implementation supporting this extension must predefine the
macro SYCL_EXT_ONEAPI_VIRTUAL_MEM to one of the values defined in the table
below. Applications can test for the existence of this macro to determine if
the implementation supports this feature, or applications can test the macro’s
value to determine which of the extension’s features the implementation
supports.
| Value | Description |
|---|---|
1 |
The APIs of this experimental extension are not versioned, so the feature-test macro always has this value. |
Support for the features introduced in this extension can be queried using the
new aspect::ext_oneapi_virtual_mem defined as:
namespace sycl {
enum class aspect : /* unspecified */ {
...
ext_oneapi_virtual_mem
}
} // namespace syclWorking with virtual address ranges and the underlying physical memory requires the user to align and adjust in accordance with a specified minimum granularity.
The interfaces make the distinction between device granularity, which is the granularity required for physical memory allocations, and context granularity, which is the granularity required for virtual memory range reservations.
The queries provide both a minimum and a recommended granularity. The minimum device granularity is the smallest granularity that is supported for physical memory allocations, and the minimum context granularity is the smallest granularity that is supported from virtual memory range reservations. However, the recommended granularity may be larger than these minimums and may provide better performance.
The interfaces for querying these granularities are defined as:
namespace sycl::ext::oneapi::experimental {
enum class granularity_mode : /*unspecified*/ {
minimum,
recommended
};
size_t get_mem_granularity(const device &syclDevice, const context &syclContext,
granularity_mode mode = granularity_mode::recommended);
size_t get_mem_granularity(const context &syclContext,
granularity_mode mode = granularity_mode::recommended);
} // namespace sycl::ext::oneapi::experimental| Function | Description |
|---|---|
|
Returns the granularity of physical memory allocations on If |
|
Returns the granularity of virtual memory range reservations in the
If any device in |
Virtual address ranges are represented by a uintptr_t and a number of bytes
reserved for it. The uintptr_t must be aligned in accordance with the minimum
granularity of the corresponding context, as queried through
get_mem_granularity, and likewise the number of bytes must be a multiple of
this granularity. It is the responsibility of the user to manage the
constituents of any virtual address range they reserve.
The interfaces for reserving, freeing, and manipulating the access mode of a virtual address range are defined as:
namespace sycl::ext::oneapi::experimental {
uintptr_t reserve_virtual_mem(uintptr_t start, size_t numBytes, const context &syclContext);
uintptr_t reserve_virtual_mem(size_t numBytes, const context &syclContext);
void free_virtual_mem(uintptr_t ptr, size_t numBytes, const context &syclContext);
} // namespace sycl::ext::oneapi::experimental| Function | Description |
|---|---|
|
Reserves a virtual memory range in
If any of the devices in |
|
Same as |
|
Frees a virtual memory range specified by The virtual memory range must not currently be mapped to physical memory. A call to this function with a mapped virtual memory range results in undefined behavior. |
To represent the underlying physical device memory a virtual address is mapped
to, the physical_mem class is added. This new class is defined as:
namespace sycl::ext::oneapi::experimental {
enum class address_access_mode : /*unspecified*/ {
none,
read,
read_write
};
class physical_mem {
public:
template<typename PropertyListT = empty_properties_t>
physical_mem(const device &syclDevice, const context &syclContext, size_t numBytes,
PropertyListT props = {});
template<typename PropertyListT = empty_properties_t>
physical_mem(const queue &syclQueue, size_t numBytes, PropertyListT props = {});
/* -- common interface members -- */
void *map(uintptr_t ptr, size_t numBytes, address_access_mode mode, size_t offset = 0) const;
context get_context() const;
device get_device() const;
size_t size() const noexcept;
};
} // namespace sycl::ext::oneapi::experimentalphysical_mem has common reference semantics, as described in
section 4.5.2. Common reference semantics.
| Member function | Description |
|---|---|
|
Constructs a This will allocate If If the constructor is unable to allocate the required memory on
|
|
Same as |
|
Maps a virtual memory range, specified by It is required that If If other devices in the context associated with this instance of The returned pointer is equivalent to Writing to any address in the virtual memory range with access mode set to
An accessible pointer behaves the same as a pointer to device USM memory and can be used in place of a device USM pointer in any interface accepting one. A virtual memory range cannot be simultaneously mapped to more than one physical memory region. Likewise, multiple virtual memory ranges cannot be mapped onto the same physical memory region. Attempting to violate either of these restrictions will result in undefined behavior. |
|
Returns the SYCL context associated with the instance of |
|
Returns the SYCL device associated with the instance of |
|
Returns the size of the corresponding physical memory in bytes. |
Virtual memory address ranges are mapped to the a physical_mem through the
map member functions, where the access mode can also be specified.
To further get or set the access mode of a mapped virtual address range, the
user does not need to know the associated physical_mem and can just call the
following free functions.
namespace sycl::ext::oneapi::experimental {
void set_access_mode(const void *ptr, size_t numBytes, address_access_mode mode, const context &syclContext);
address_access_mode get_access_mode(const void *ptr, size_t numBytes, const context &syclContext);
void unmap(const void *ptr, size_t numBytes, const context &syclContext);
} // namespace sycl::ext::oneapi::experimental| Function | Description |
|---|---|
|
Changes the access mode of a mapped virtual memory range specified by If If other devices in The virtual memory range specified by Writing to any address in the virtual memory range with access mode set to
An accessible pointer behaves the same as a pointer to device USM memory and can be used in place of a device USM pointer in any interface accepting one. |
|
Returns the access mode of the mapped virtual memory range specified by The virtual memory range specified by |
|
Unmaps the range specified by After this call, the full range will again be ready to be mapped through a call
to [Note: Unmapping ranges that span multiple contiguous mapped ranges is not supported. Doing so will result in undefined behavior. This restriction may be lifted in the future. — end note] [Note: The destructor for |