DPC++ Runtime
Runtime libraries for oneAPI DPC++
alloc_base.hpp
Go to the documentation of this file.
1 //==-------- alloc_base.hpp - SYCL annotated usm basic allocation -------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 
13 #include <sycl/queue.hpp>
14 #include <sycl/usm.hpp>
15 
16 namespace sycl {
17 inline namespace _V1 {
18 class device;
19 class context;
20 
21 namespace ext {
22 namespace oneapi {
23 namespace experimental {
24 
26 // Parameterized USM allocation functions with properties support
27 // These functions take a USM kind parameter that specifies the type of USM to
28 // allocate
29 //
30 // Note: this function group is the base implementation of the other annotated
31 // allocation API, and is eventally called by:
32 // 1. "xxx_alloc_annotated" with USM kind in the properties (defined in
33 // alloc_base.hpp)
34 // 2. "xxx_alloc_device_annotated" (defined in alloc_device.hpp)
35 // 3. "xxx_alloc_host_annotated" (defined in alloc_host.hpp)
36 // 4. "xxx_alloc_shared_annotated" (defined in alloc_shared.hpp)
38 template <typename propertyListA = detail::empty_properties_t,
39  typename propertyListB =
40  typename detail::GetCompileTimeProperties<propertyListA>::type>
41 std::enable_if_t<
42  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
43  annotated_ptr<void, propertyListB>>
44 aligned_alloc_annotated(size_t alignment, size_t numBytes,
45  const device &syclDevice, const context &syclContext,
46  sycl::usm::alloc kind,
47  const propertyListA &propList = properties{}) {
48  detail::ValidAllocPropertyList<void, propertyListA>::value;
49 
50  // The input argument `propList` is useful when propertyListA contains valid
51  // runtime properties. While such case is not defined yet, suppress unused
52  // variables warning
53  static_cast<void>(propList);
54 
55  constexpr size_t alignFromPropList =
56  detail::GetAlignFromPropList<propertyListA>::value;
57  const property_list &usmPropList = get_usm_property_list<propertyListA>();
58 
59  if constexpr (detail::HasUsmKind<propertyListA>::value) {
60  constexpr sycl::usm::alloc usmKind =
61  detail::GetUsmKindFromPropList<propertyListA>::value;
62  if (usmKind != kind) {
63  throw sycl::exception(
64  sycl::make_error_code(sycl::errc::invalid),
65  "Input property list of USM allocation function contains usm_kind "
66  "property that conflicts with the usm kind argument");
67  }
68  }
69 
70  if (kind == sycl::usm::alloc::unknown)
71  throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
72  "Unknown USM allocation kind was specified.");
73 
74  void *rawPtr =
75  sycl::aligned_alloc(combine_align(alignment, alignFromPropList), numBytes,
76  syclDevice, syclContext, kind, usmPropList);
77  return annotated_ptr<void, propertyListB>(rawPtr);
78 }
79 
80 template <typename T, typename propertyListA = detail::empty_properties_t,
81  typename propertyListB =
82  typename detail::GetCompileTimeProperties<propertyListA>::type>
83 std::enable_if_t<
84  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
85  annotated_ptr<T, propertyListB>>
86 aligned_alloc_annotated(size_t alignment, size_t count,
87  const device &syclDevice, const context &syclContext,
88  sycl::usm::alloc kind,
89  const propertyListA &propList = properties{}) {
90  detail::ValidAllocPropertyList<T, propertyListA>::value;
91 
92  // The input argument `propList` is useful when propertyListA contains valid
93  // runtime properties. While such case is not defined yet, suppress unused
94  // variables warning
95  static_cast<void>(propList);
96 
97  constexpr size_t alignFromPropList =
98  detail::GetAlignFromPropList<propertyListA>::value;
99  const property_list &usmPropList = get_usm_property_list<propertyListA>();
100 
101  if constexpr (detail::HasUsmKind<propertyListA>::value) {
102  constexpr sycl::usm::alloc usmKind =
103  detail::GetUsmKindFromPropList<propertyListA>::value;
104  if (usmKind != kind) {
105  throw sycl::exception(
106  sycl::make_error_code(sycl::errc::invalid),
107  "Input property list of USM allocation function contains usm_kind "
108  "property that conflicts with the usm kind argument");
109  }
110  }
111 
112  if (kind == sycl::usm::alloc::unknown)
113  throw sycl::exception(sycl::make_error_code(sycl::errc::invalid),
114  "Unknown USM allocation kind was specified.");
115 
116  size_t combinedAlign = combine_align(alignment, alignFromPropList);
117  T *rawPtr = sycl::aligned_alloc<T>(combinedAlign, count, syclDevice,
118  syclContext, kind, usmPropList);
119  return annotated_ptr<T, propertyListB>(rawPtr);
120 }
121 
122 template <typename propertyListA = detail::empty_properties_t,
123  typename propertyListB =
124  typename detail::GetCompileTimeProperties<propertyListA>::type>
125 std::enable_if_t<
126  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
127  annotated_ptr<void, propertyListB>>
128 aligned_alloc_annotated(size_t alignment, size_t numBytes,
129  const queue &syclQueue, sycl::usm::alloc kind,
130  const propertyListA &propList = properties{}) {
131  return aligned_alloc_annotated(alignment, numBytes, syclQueue.get_device(),
132  syclQueue.get_context(), kind, propList);
133 }
134 
135 template <typename T, typename propertyListA = detail::empty_properties_t,
136  typename propertyListB =
137  typename detail::GetCompileTimeProperties<propertyListA>::type>
138 std::enable_if_t<
139  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
140  annotated_ptr<T, propertyListB>>
141 aligned_alloc_annotated(size_t alignment, size_t count, const queue &syclQueue,
142  sycl::usm::alloc kind,
143  const propertyListA &propList = properties{}) {
144  return aligned_alloc_annotated<T>(alignment, count, syclQueue.get_device(),
145  syclQueue.get_context(), kind, propList);
146 }
147 
148 template <typename propertyListA = detail::empty_properties_t,
149  typename propertyListB =
150  typename detail::GetCompileTimeProperties<propertyListA>::type>
151 std::enable_if_t<
152  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
153  annotated_ptr<void, propertyListB>>
154 malloc_annotated(size_t numBytes, const device &syclDevice,
155  const context &syclContext, sycl::usm::alloc kind,
156  const propertyListA &propList = properties{}) {
157  return aligned_alloc_annotated(0, numBytes, syclDevice, syclContext, kind,
158  propList);
159 }
160 
161 template <typename T, typename propertyListA = detail::empty_properties_t,
162  typename propertyListB =
163  typename detail::GetCompileTimeProperties<propertyListA>::type>
164 std::enable_if_t<
165  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
166  annotated_ptr<T, propertyListB>>
167 malloc_annotated(size_t count, const device &syclDevice,
168  const context &syclContext, sycl::usm::alloc kind,
169  const propertyListA &propList = properties{}) {
170  return aligned_alloc_annotated<T>(0, count, syclDevice, syclContext, kind,
171  propList);
172 }
173 
174 template <typename propertyListA = detail::empty_properties_t,
175  typename propertyListB =
176  typename detail::GetCompileTimeProperties<propertyListA>::type>
177 std::enable_if_t<
178  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
179  annotated_ptr<void, propertyListB>>
180 malloc_annotated(size_t numBytes, const queue &syclQueue, sycl::usm::alloc kind,
181  const propertyListA &propList = properties{}) {
182  return malloc_annotated(numBytes, syclQueue.get_device(),
183  syclQueue.get_context(), kind, propList);
184 }
185 
186 template <typename T, typename propertyListA = detail::empty_properties_t,
187  typename propertyListB =
188  typename detail::GetCompileTimeProperties<propertyListA>::type>
189 std::enable_if_t<
190  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
191  annotated_ptr<T, propertyListB>>
192 malloc_annotated(size_t count, const queue &syclQueue, sycl::usm::alloc kind,
193  const propertyListA &propList = properties{}) {
194  return malloc_annotated<T>(count, syclQueue.get_device(),
195  syclQueue.get_context(), kind, propList);
196 }
197 
199 // Additional USM memory allocation functions with properties support that
200 // requires the usm_kind property to be specified on the input property list
201 //
202 // These functions are implemented by extracting the usm kind from the property
203 // list and calling the usm-kind-as-argument version
205 
206 template <typename propertyListA,
207  typename propertyListB =
208  typename detail::GetCompileTimeProperties<propertyListA>::type>
209 std::enable_if_t<
210  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
211  annotated_ptr<void, propertyListB>>
212 malloc_annotated(size_t numBytes, const device &syclDevice,
213  const context &syclContext, const propertyListA &propList) {
214  constexpr sycl::usm::alloc usmKind =
216  static_assert(usmKind != sycl::usm::alloc::unknown,
217  "USM kind is not specified. Please specify it as an argument "
218  "or in the input property list.");
219  return malloc_annotated(numBytes, syclDevice, syclContext, usmKind, propList);
220 }
221 
222 template <typename T, typename propertyListA,
223  typename propertyListB =
224  typename detail::GetCompileTimeProperties<propertyListA>::type>
225 std::enable_if_t<
226  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
227  annotated_ptr<T, propertyListB>>
228 malloc_annotated(size_t count, const device &syclDevice,
229  const context &syclContext, const propertyListA &propList) {
230  constexpr sycl::usm::alloc usmKind =
232  static_assert(usmKind != sycl::usm::alloc::unknown,
233  "USM kind is not specified. Please specify it as an argument "
234  "or in the input property list.");
235  return malloc_annotated<T>(count, syclDevice, syclContext, usmKind, propList);
236 }
237 
238 template <typename propertyListA,
239  typename propertyListB =
240  typename detail::GetCompileTimeProperties<propertyListA>::type>
241 std::enable_if_t<
242  detail::CheckTAndPropLists<void, propertyListA, propertyListB>::value,
243  annotated_ptr<void, propertyListB>>
244 malloc_annotated(size_t numBytes, const queue &syclQueue,
245  const propertyListA &propList) {
246  return malloc_annotated(numBytes, syclQueue.get_device(),
247  syclQueue.get_context(), propList);
248 }
249 
250 template <typename T, typename propertyListA,
251  typename propertyListB =
252  typename detail::GetCompileTimeProperties<propertyListA>::type>
253 std::enable_if_t<
254  detail::CheckTAndPropLists<T, propertyListA, propertyListB>::value,
255  annotated_ptr<T, propertyListB>>
256 malloc_annotated(size_t count, const queue &syclQueue,
257  const propertyListA &propList) {
258  return malloc_annotated<T>(count, syclQueue.get_device(),
259  syclQueue.get_context(), propList);
260 }
261 
262 } // namespace experimental
263 } // namespace oneapi
264 } // namespace ext
265 } // namespace _V1
266 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:50
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
Objects of the property_list class are containers for the SYCL properties.
Encapsulates a single SYCL queue which schedules kernels on a SYCL device.
Definition: queue.hpp:105
device get_device() const
Definition: queue.cpp:76
context get_context() const
Definition: queue.cpp:74
properties< std::tuple<> > empty_properties_t
Definition: properties.hpp:207
constexpr alignment_key::value_t< K > alignment
Definition: properties.hpp:75
size_t combine_align(size_t alignA, size_t alignB)
Definition: alloc_util.hpp:241
std::enable_if_t< detail::CheckTAndPropLists< void, propertyListA, propertyListB >::value, annotated_ptr< void, propertyListB > > aligned_alloc_annotated(size_t alignment, size_t numBytes, const device &syclDevice, const context &syclContext, sycl::usm::alloc kind, const propertyListA &propList=properties{})
Definition: alloc_base.hpp:44
std::enable_if_t< detail::CheckTAndPropLists< void, propertyListA, propertyListB >::value, annotated_ptr< void, propertyListB > > malloc_annotated(size_t numBytes, const device &syclDevice, const context &syclContext, sycl::usm::alloc kind, const propertyListA &propList=properties{})
Definition: alloc_base.hpp:154
void * aligned_alloc(size_t alignment, size_t size, const device &dev, const context &ctxt, usm::alloc kind, const detail::code_location &CodeLoc=detail::code_location::current())
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:93
Definition: access.hpp:18