DPC++ Runtime
Runtime libraries for oneAPI DPC++
usm_impl.cpp
Go to the documentation of this file.
1 //==---------------- usm_impl.cpp - USM API Utils -------------*- C++ -*---==//
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 #include <detail/queue_impl.hpp>
10 #include <detail/usm/usm_impl.hpp>
11 #include <sycl/context.hpp>
13 #include <sycl/detail/os_util.hpp>
14 #include <sycl/detail/pi.hpp>
15 #include <sycl/device.hpp>
18 #include <sycl/usm.hpp>
19 
20 #include <array>
21 #include <cassert>
22 #include <cstdlib>
23 #include <memory>
24 
25 #ifdef XPTI_ENABLE_INSTRUMENTATION
26 // Include the headers necessary for emitting
27 // traces using the trace framework
28 #include "xpti/xpti_trace_framework.hpp"
29 #include <detail/xpti_registry.hpp>
30 #endif
31 
32 namespace sycl {
33 inline namespace _V1 {
34 
36 
37 namespace detail {
38 #ifdef XPTI_ENABLE_INSTRUMENTATION
39 extern xpti::trace_event_data_t *GSYCLGraphEvent;
40 #endif
41 namespace usm {
42 
43 void *alignedAllocHost(size_t Alignment, size_t Size, const context &Ctxt,
44  alloc Kind, const property_list &PropList,
45  const detail::code_location &CodeLoc) {
46 #ifdef XPTI_ENABLE_INSTRUMENTATION
47  // Stash the code location information and propagate
48  detail::tls_code_loc_t CL(CodeLoc);
49  XPTIScope PrepareNotify((void *)alignedAllocHost,
50  (uint16_t)xpti::trace_point_type_t::node_create,
51  SYCL_MEM_ALLOC_STREAM_NAME, "malloc_host");
52  PrepareNotify.addMetadata([&](auto TEvent) {
53  xpti::addMetadata(TEvent, "sycl_device_name", std::string("Host"));
54  xpti::addMetadata(TEvent, "sycl_device", 0);
55  xpti::addMetadata(TEvent, "memory_size", Size);
56  });
57  // Notify XPTI about the memset submission
58  PrepareNotify.notify();
59  // Emit a begin/end scope for this call
60  PrepareNotify.scopedNotify(
61  (uint16_t)xpti::trace_point_type_t::mem_alloc_begin);
62 #endif
63  const auto &devices = Ctxt.get_devices();
64  if (!std::any_of(devices.begin(), devices.end(), [&](const auto &device) {
65  return device.has(sycl::aspect::usm_host_allocations);
66  })) {
67  throw sycl::exception(
68  sycl::errc::feature_not_supported,
69  "No device in this context supports USM host allocations!");
70  }
71  void *RetVal = nullptr;
72  if (Size == 0)
73  return nullptr;
74 
75  std::shared_ptr<context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
76  pi_context C = CtxImpl->getHandleRef();
77  const PluginPtr &Plugin = CtxImpl->getPlugin();
78  pi_result Error = PI_ERROR_INVALID_VALUE;
79 
80  switch (Kind) {
81  case alloc::host: {
82  std::array<pi_usm_mem_properties, 3> Props;
83  auto PropsIter = Props.begin();
84 
85  if (PropList.has_property<
87  Ctxt.get_platform().has_extension(
88  "cl_intel_mem_alloc_buffer_location")) {
89  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
90  *PropsIter++ = PropList
93  .get_buffer_location();
94  }
95 
96  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
97  *PropsIter++ = 0; // null-terminate property list
98 
99  Error = Plugin->call_nocheck<PiApiKind::piextUSMHostAlloc>(
100  &RetVal, C, Props.data(), Size, Alignment);
101 
102  break;
103  }
104  case alloc::device:
105  case alloc::shared:
106  case alloc::unknown: {
107  RetVal = nullptr;
108  Error = PI_ERROR_INVALID_VALUE;
109  break;
110  }
111  }
112 
113  // Error is for debugging purposes.
114  // The spec wants a nullptr returned, not an exception.
115  if (Error != PI_SUCCESS)
116  return nullptr;
117 #ifdef XPTI_ENABLE_INSTRUMENTATION
118  xpti::addMetadata(PrepareNotify.traceEvent(), "memory_ptr",
119  reinterpret_cast<size_t>(RetVal));
120 #endif
121  return RetVal;
122 }
123 
124 void *alignedAllocInternal(size_t Alignment, size_t Size,
125  const context_impl *CtxImpl,
126  const device_impl *DevImpl, alloc Kind,
127  const property_list &PropList) {
128  if (Kind == alloc::device &&
129  !DevImpl->has(sycl::aspect::usm_device_allocations)) {
130  throw sycl::exception(sycl::errc::feature_not_supported,
131  "Device does not support USM device allocations!");
132  }
133  if (Kind == alloc::shared &&
134  !DevImpl->has(sycl::aspect::usm_shared_allocations)) {
135  throw sycl::exception(sycl::errc::feature_not_supported,
136  "Device does not support shared USM allocations!");
137  }
138  void *RetVal = nullptr;
139  if (Size == 0)
140  return nullptr;
141 
142  pi_context C = CtxImpl->getHandleRef();
143  const PluginPtr &Plugin = CtxImpl->getPlugin();
144  pi_result Error = PI_ERROR_INVALID_VALUE;
145  pi_device Id;
146 
147  switch (Kind) {
148  case alloc::device: {
149  Id = DevImpl->getHandleRef();
150 
151  std::array<pi_usm_mem_properties, 3> Props;
152  auto PropsIter = Props.begin();
153 
154  // Buffer location is only supported on FPGA devices
155  if (PropList.has_property<
157  DevImpl->has_extension("cl_intel_mem_alloc_buffer_location")) {
158  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
159  *PropsIter++ = PropList
162  .get_buffer_location();
163  }
164 
165  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
166  *PropsIter++ = 0; // null-terminate property list
167 
168  Error = Plugin->call_nocheck<PiApiKind::piextUSMDeviceAlloc>(
169  &RetVal, C, Id, Props.data(), Size, Alignment);
170 
171  break;
172  }
173  case alloc::shared: {
174  Id = DevImpl->getHandleRef();
175 
176  std::array<pi_usm_mem_properties, 5> Props;
177  auto PropsIter = Props.begin();
178 
179  if (PropList.has_property<
181  *PropsIter++ = PI_MEM_ALLOC_FLAGS;
182  *PropsIter++ = PI_MEM_ALLOC_DEVICE_READ_ONLY;
183  }
184 
185  if (PropList.has_property<
187  DevImpl->has_extension("cl_intel_mem_alloc_buffer_location")) {
188  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
189  *PropsIter++ = PropList
192  .get_buffer_location();
193  }
194 
195  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
196  *PropsIter++ = 0; // null-terminate property list
197 
198  Error = Plugin->call_nocheck<PiApiKind::piextUSMSharedAlloc>(
199  &RetVal, C, Id, Props.data(), Size, Alignment);
200 
201  break;
202  }
203  case alloc::host:
204  case alloc::unknown: {
205  RetVal = nullptr;
206  Error = PI_ERROR_INVALID_VALUE;
207  break;
208  }
209  }
210 
211  // Error is for debugging purposes.
212  // The spec wants a nullptr returned, not an exception.
213  if (Error != PI_SUCCESS)
214  return nullptr;
215  return RetVal;
216 }
217 
218 void *alignedAlloc(size_t Alignment, size_t Size, const context &Ctxt,
219  const device &Dev, alloc Kind, const property_list &PropList,
220  const detail::code_location &CodeLoc) {
221 #ifdef XPTI_ENABLE_INSTRUMENTATION
222  // Stash the code location information and propagate
223  detail::tls_code_loc_t CL(CodeLoc);
224  XPTIScope PrepareNotify((void *)alignedAlloc,
225  (uint16_t)xpti::trace_point_type_t::node_create,
226  SYCL_MEM_ALLOC_STREAM_NAME, "usm::alignedAlloc");
227  PrepareNotify.addMetadata([&](auto TEvent) {
228  xpti::addMetadata(TEvent, "sycl_device_name",
229  Dev.get_info<info::device::name>());
230  // Need to determine how to get the device handle reference
231  // xpti::addMetadata(TEvent, "sycl_device", Dev.getHandleRef()));
232  xpti::addMetadata(TEvent, "memory_size", Size);
233  });
234  // Notify XPTI about the memset submission
235  PrepareNotify.notify();
236  // Emit a begin/end scope for this call
237  PrepareNotify.scopedNotify(
238  (uint16_t)xpti::trace_point_type_t::mem_alloc_begin);
239 #endif
240  void *RetVal =
242  getSyclObjImpl(Dev).get(), Kind, PropList);
243 #ifdef XPTI_ENABLE_INSTRUMENTATION
244  xpti::addMetadata(PrepareNotify.traceEvent(), "memory_ptr",
245  reinterpret_cast<size_t>(RetVal));
246 #endif
247  return RetVal;
248 }
249 
250 void freeInternal(void *Ptr, const context_impl *CtxImpl) {
251  if (Ptr == nullptr)
252  return;
253  pi_context C = CtxImpl->getHandleRef();
254  const PluginPtr &Plugin = CtxImpl->getPlugin();
255  Plugin->call<PiApiKind::piextUSMFree>(C, Ptr);
256 }
257 
258 void free(void *Ptr, const context &Ctxt,
259  const detail::code_location &CodeLoc) {
260 #ifdef XPTI_ENABLE_INSTRUMENTATION
261  // Stash the code location information and propagate
262  detail::tls_code_loc_t CL(CodeLoc);
263  XPTIScope PrepareNotify((void *)free,
264  (uint16_t)xpti::trace_point_type_t::node_create,
265  SYCL_MEM_ALLOC_STREAM_NAME, "usm::free");
266  PrepareNotify.addMetadata([&](auto TEvent) {
267  xpti::addMetadata(TEvent, "memory_ptr", reinterpret_cast<size_t>(Ptr));
268  });
269  // Notify XPTI about the memset submission
270  PrepareNotify.notify();
271  // Emit a begin/end scope for this call
272  PrepareNotify.scopedNotify(
273  (uint16_t)xpti::trace_point_type_t::mem_release_begin);
274 #endif
276 }
277 
278 } // namespace usm
279 } // namespace detail
280 
281 void *malloc_device(size_t Size, const device &Dev, const context &Ctxt,
282  const detail::code_location &CodeLoc) {
283  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::device,
284  property_list{}, CodeLoc);
285 }
286 
287 void *malloc_device(size_t Size, const device &Dev, const context &Ctxt,
288  const property_list &PropList,
289  const detail::code_location &CodeLoc) {
290  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::device, PropList,
291  CodeLoc);
292 }
293 
294 void *malloc_device(size_t Size, const queue &Q,
295  const detail::code_location &CodeLoc) {
296  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
297  alloc::device, property_list{}, CodeLoc);
298 }
299 
300 void *malloc_device(size_t Size, const queue &Q, const property_list &PropList,
301  const detail::code_location &CodeLoc) {
302  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
303  alloc::device, PropList, CodeLoc);
304 }
305 
306 void *aligned_alloc_device(size_t Alignment, size_t Size, const device &Dev,
307  const context &Ctxt,
308  const detail::code_location &CodeLoc) {
309  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::device,
310  property_list{}, CodeLoc);
311 }
312 
313 void *aligned_alloc_device(size_t Alignment, size_t Size, const device &Dev,
314  const context &Ctxt, const property_list &PropList,
315  const detail::code_location &CodeLoc) {
316  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::device,
317  PropList, CodeLoc);
318 }
319 
320 void *aligned_alloc_device(size_t Alignment, size_t Size, const queue &Q,
321  const detail::code_location &CodeLoc) {
323  Q.get_device(), alloc::device,
324  property_list{}, CodeLoc);
325 }
326 
327 void *aligned_alloc_device(size_t Alignment, size_t Size, const queue &Q,
328  const property_list &PropList,
329  const detail::code_location &CodeLoc) {
330  return detail::usm::alignedAlloc(Alignment, Size, Q.get_context(),
331  Q.get_device(), alloc::device, PropList,
332  CodeLoc);
333 }
334 
335 void free(void *ptr, const context &Ctxt,
336  const detail::code_location &CodeLoc) {
337  return detail::usm::free(ptr, Ctxt, CodeLoc);
338 }
339 
340 void free(void *ptr, const queue &Q, const detail::code_location &CodeLoc) {
341  return detail::usm::free(ptr, Q.get_context(), CodeLoc);
342 }
343 
344 void *malloc_host(size_t Size, const context &Ctxt,
345  const detail::code_location &CodeLoc) {
346  return detail::usm::alignedAllocHost(0, Size, Ctxt, alloc::host,
347  property_list{}, CodeLoc);
348 }
349 
350 void *malloc_host(size_t Size, const context &Ctxt,
351  const property_list &PropList,
352  const detail::code_location &CodeLoc) {
353  return detail::usm::alignedAllocHost(0, Size, Ctxt, alloc::host, PropList,
354  CodeLoc);
355 }
356 
357 void *malloc_host(size_t Size, const queue &Q,
358  const detail::code_location &CodeLoc) {
359  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), alloc::host,
360  property_list{}, CodeLoc);
361 }
362 
363 void *malloc_host(size_t Size, const queue &Q, const property_list &PropList,
364  const detail::code_location &CodeLoc) {
365  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), alloc::host,
366  PropList, CodeLoc);
367 }
368 
369 void *malloc_shared(size_t Size, const device &Dev, const context &Ctxt,
370  const detail::code_location &CodeLoc) {
371  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::shared,
372  property_list{}, CodeLoc);
373 }
374 
375 void *malloc_shared(size_t Size, const device &Dev, const context &Ctxt,
376  const property_list &PropList,
377  const detail::code_location &CodeLoc) {
378  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::shared, PropList,
379  CodeLoc);
380 }
381 
382 void *malloc_shared(size_t Size, const queue &Q,
383  const detail::code_location &CodeLoc) {
384  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
385  alloc::shared, property_list{}, CodeLoc);
386 }
387 
388 void *malloc_shared(size_t Size, const queue &Q, const property_list &PropList,
389  const detail::code_location &CodeLoc) {
390  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
391  alloc::shared, PropList, CodeLoc);
392 }
393 
394 void *aligned_alloc_host(size_t Alignment, size_t Size, const context &Ctxt,
395  const detail::code_location &CodeLoc) {
396  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, alloc::host,
397  property_list{}, CodeLoc);
398 }
399 
400 void *aligned_alloc_host(size_t Alignment, size_t Size, const context &Ctxt,
401  const property_list &PropList,
402  const detail::code_location &CodeLoc) {
403  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, alloc::host,
404  PropList, CodeLoc);
405 }
406 
407 void *aligned_alloc_host(size_t Alignment, size_t Size, const queue &Q,
408  const detail::code_location &CodeLoc) {
410  alloc::host, property_list{}, CodeLoc);
411 }
412 
413 void *aligned_alloc_host(size_t Alignment, size_t Size, const queue &Q,
414  const property_list &PropList,
415  const detail::code_location &CodeLoc) {
416  return detail::usm::alignedAllocHost(Alignment, Size, Q.get_context(),
417  alloc::host, PropList, CodeLoc);
418 }
419 
420 void *aligned_alloc_shared(size_t Alignment, size_t Size, const device &Dev,
421  const context &Ctxt,
422  const detail::code_location &CodeLoc) {
423  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::shared,
424  property_list{}, CodeLoc);
425 }
426 
427 void *aligned_alloc_shared(size_t Alignment, size_t Size, const device &Dev,
428  const context &Ctxt, const property_list &PropList,
429  const detail::code_location &CodeLoc) {
430  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::shared,
431  PropList, CodeLoc);
432 }
433 
434 void *aligned_alloc_shared(size_t Alignment, size_t Size, const queue &Q,
435  const detail::code_location &CodeLoc) {
437  Q.get_device(), alloc::shared,
438  property_list{}, CodeLoc);
439 }
440 
441 void *aligned_alloc_shared(size_t Alignment, size_t Size, const queue &Q,
442  const property_list &PropList,
443  const detail::code_location &CodeLoc) {
444  return detail::usm::alignedAlloc(Alignment, Size, Q.get_context(),
445  Q.get_device(), alloc::shared, PropList,
446  CodeLoc);
447 }
448 
449 // single form
450 
451 void *malloc(size_t Size, const device &Dev, const context &Ctxt, alloc Kind,
452  const property_list &PropList,
453  const detail::code_location &CodeLoc) {
454  if (Kind == alloc::host)
455  return detail::usm::alignedAllocHost(0, Size, Ctxt, Kind, PropList,
456  CodeLoc);
457  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, Kind, PropList, CodeLoc);
458 }
459 
460 void *malloc(size_t Size, const device &Dev, const context &Ctxt, alloc Kind,
461  const detail::code_location &CodeLoc) {
462  if (Kind == alloc::host)
463  return detail::usm::alignedAllocHost(0, Size, Ctxt, Kind, property_list{},
464  CodeLoc);
465  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, Kind, property_list{},
466  CodeLoc);
467 }
468 
469 void *malloc(size_t Size, const queue &Q, alloc Kind,
470  const detail::code_location &CodeLoc) {
471  if (Kind == alloc::host)
472  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), Kind,
473  property_list{}, CodeLoc);
474  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
475  Kind, property_list{}, CodeLoc);
476 }
477 
478 void *malloc(size_t Size, const queue &Q, alloc Kind,
479  const property_list &PropList,
480  const detail::code_location &CodeLoc) {
481  if (Kind == alloc::host)
482  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), Kind,
483  PropList, CodeLoc);
484  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
485  Kind, PropList, CodeLoc);
486 }
487 
488 void *aligned_alloc(size_t Alignment, size_t Size, const device &Dev,
489  const context &Ctxt, alloc Kind,
490  const detail::code_location &CodeLoc) {
491  if (Kind == alloc::host)
492  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, Kind,
493  property_list{}, CodeLoc);
494 
495  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, Kind,
496  property_list{}, CodeLoc);
497 }
498 
499 void *aligned_alloc(size_t Alignment, size_t Size, const device &Dev,
500  const context &Ctxt, alloc Kind,
501  const property_list &PropList,
502  const detail::code_location &CodeLoc) {
503  if (Kind == alloc::host)
504  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, Kind, PropList,
505  CodeLoc);
506  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, Kind, PropList,
507  CodeLoc);
508 }
509 
510 void *aligned_alloc(size_t Alignment, size_t Size, const queue &Q, alloc Kind,
511  const detail::code_location &CodeLoc) {
512  if (Kind == alloc::host)
513  return detail::usm::alignedAllocHost(Alignment, Size, Q.get_context(), Kind,
514  property_list{}, CodeLoc);
516  Q.get_device(), Kind, property_list{},
517  CodeLoc);
518 }
519 
520 void *aligned_alloc(size_t Alignment, size_t Size, const queue &Q, alloc Kind,
521  const property_list &PropList,
522  const detail::code_location &CodeLoc) {
523  if (Kind == alloc::host)
524  return detail::usm::alignedAllocHost(Alignment, Size, Q.get_context(), Kind,
525  PropList, CodeLoc);
527  Q.get_device(), Kind, PropList, CodeLoc);
528 }
529 
530 // Pointer queries
536 alloc get_pointer_type(const void *Ptr, const context &Ctxt) {
537  if (!Ptr)
538  return alloc::unknown;
539 
540  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
541 
542  pi_context PICtx = CtxImpl->getHandleRef();
543  pi_usm_type AllocTy;
544 
545  // query type using PI function
546  const detail::PluginPtr &Plugin = CtxImpl->getPlugin();
548  Plugin->call_nocheck<detail::PiApiKind::piextUSMGetMemAllocInfo>(
549  PICtx, Ptr, PI_MEM_ALLOC_TYPE, sizeof(pi_usm_type), &AllocTy,
550  nullptr);
551 
552  // PI_ERROR_INVALID_VALUE means USM doesn't know about this ptr
553  if (Err == PI_ERROR_INVALID_VALUE)
554  return alloc::unknown;
555  // otherwise PI_SUCCESS is expected
556  if (Err != PI_SUCCESS) {
557  throw detail::set_pi_error(
558  exception(make_error_code(errc::runtime), "get_pointer_type() failed"),
559  Err);
560  }
561 
562  alloc ResultAlloc;
563  switch (AllocTy) {
564  case PI_MEM_TYPE_HOST:
565  ResultAlloc = alloc::host;
566  break;
567  case PI_MEM_TYPE_DEVICE:
568  ResultAlloc = alloc::device;
569  break;
570  case PI_MEM_TYPE_SHARED:
571  ResultAlloc = alloc::shared;
572  break;
573  default:
574  ResultAlloc = alloc::unknown;
575  break;
576  }
577 
578  return ResultAlloc;
579 }
580 
585 device get_pointer_device(const void *Ptr, const context &Ctxt) {
586  // Check if ptr is a valid USM pointer
587  if (get_pointer_type(Ptr, Ctxt) == alloc::unknown)
589  "Ptr not a valid USM allocation!");
590 
591  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
592 
593  // Check if ptr is a host allocation
594  if (get_pointer_type(Ptr, Ctxt) == alloc::host) {
595  auto Devs = CtxImpl->getDevices();
596  if (Devs.size() == 0)
598  "No devices in passed context!");
599 
600  // Just return the first device in the context
601  return Devs[0];
602  }
603 
604  pi_context PICtx = CtxImpl->getHandleRef();
605  pi_device DeviceId;
606 
607  // query device using PI function
608  const detail::PluginPtr &Plugin = CtxImpl->getPlugin();
610  PICtx, Ptr, PI_MEM_ALLOC_DEVICE, sizeof(pi_device), &DeviceId, nullptr);
611 
612  // The device is not necessarily a member of the context, it could be a
613  // member's descendant instead. Fetch the corresponding device from the cache.
614  std::shared_ptr<detail::platform_impl> PltImpl = CtxImpl->getPlatformImpl();
615  std::shared_ptr<detail::device_impl> DevImpl =
616  PltImpl->getDeviceImpl(DeviceId);
617  if (DevImpl)
618  return detail::createSyclObjFromImpl<device>(DevImpl);
620  "Cannot find device associated with USM allocation!");
621 }
622 
623 // Device copy enhancement APIs, prepare_for and release_from USM.
624 
625 static void prepare_for_usm_device_copy(const void *Ptr, size_t Size,
626  const context &Ctxt) {
627  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
628  pi_context PICtx = CtxImpl->getHandleRef();
629  // Call the PI function
630  const detail::PluginPtr &Plugin = CtxImpl->getPlugin();
631  Plugin->call<detail::PiApiKind::piextUSMImport>(Ptr, Size, PICtx);
632 }
633 
634 static void release_from_usm_device_copy(const void *Ptr, const context &Ctxt) {
635  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
636  pi_context PICtx = CtxImpl->getHandleRef();
637  // Call the PI function
638  const detail::PluginPtr &Plugin = CtxImpl->getPlugin();
639  Plugin->call<detail::PiApiKind::piextUSMRelease>(Ptr, PICtx);
640 }
641 
642 namespace ext::oneapi::experimental {
643 void prepare_for_device_copy(const void *Ptr, size_t Size,
644  const context &Ctxt) {
645  prepare_for_usm_device_copy(Ptr, Size, Ctxt);
646 }
647 
648 void prepare_for_device_copy(const void *Ptr, size_t Size, const queue &Queue) {
649  prepare_for_usm_device_copy(Ptr, Size, Queue.get_context());
650 }
651 
652 void release_from_device_copy(const void *Ptr, const context &Ctxt) {
653  release_from_usm_device_copy(Ptr, Ctxt);
654 }
655 
656 void release_from_device_copy(const void *Ptr, const queue &Queue) {
658 }
659 } // namespace ext::oneapi::experimental
660 
661 } // namespace _V1
662 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:50
std::vector< device > get_devices() const
Gets devices associated with this SYCL context.
Definition: context.cpp:115
platform get_platform() const
Gets platform associated with this SYCL context.
Definition: context.cpp:111
const PluginPtr & getPlugin() const
sycl::detail::pi::PiContext & getHandleRef()
Gets the underlying context object (if any) without reference count modification.
bool has(aspect Aspect) const
Indicates if the SYCL device has the given feature.
sycl::detail::pi::PiDevice & getHandleRef()
Get reference to PI device.
Definition: device_impl.hpp:67
bool has_extension(const std::string &ExtensionName) const
Check SYCL extension support by device.
Data type that manages the code_location information in TLS.
Definition: common.hpp:129
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
detail::is_device_info_desc< Param >::return_type get_info() const
Queries this SYCL device for information requested by the template parameter param.
Definition: device.hpp:215
Objects of the property_list class are containers for the SYCL properties.
bool has_property() const noexcept
Encapsulates a single SYCL queue which schedules kernels on a SYCL device.
Definition: queue.hpp:110
device get_device() const
Definition: queue.cpp:76
context get_context() const
Definition: queue.cpp:74
void * alignedAllocHost(size_t Alignment, size_t Bytes, const context &Ctxt, sycl::usm::alloc Kind, const code_location &CL)
void freeInternal(void *Ptr, const context_impl *CtxImpl)
Definition: usm_impl.cpp:250
void * alignedAlloc(size_t Alignment, size_t Bytes, const context &Ctxt, const device &Dev, sycl::usm::alloc Kind, const code_location &CL)
void free(void *Ptr, const context &Ctxt, const code_location &CL)
Definition: usm_impl.cpp:258
void * alignedAllocInternal(size_t Alignment, size_t Size, const context_impl *CtxImpl, const device_impl *DevImpl, alloc Kind, const property_list &PropList)
Definition: usm_impl.cpp:124
decltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
Definition: impl_utils.hpp:31
constexpr auto SYCL_MEM_ALLOC_STREAM_NAME
exception set_pi_error(exception &&e, pi_int32 pi_err)
Definition: exception.hpp:159
std::shared_ptr< plugin > PluginPtr
Definition: pi.hpp:47
constexpr buffer_location_key::value_t< N > buffer_location
void prepare_for_device_copy(const void *Ptr, size_t Size, const context &Context)
Definition: usm_impl.cpp:643
void release_from_device_copy(const void *Ptr, const context &Context)
Definition: usm_impl.cpp:652
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())
void * aligned_alloc_host(size_t alignment, size_t size, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:394
usm::alloc get_pointer_type(const void *ptr, const context &ctxt)
Query the allocation type from a USM pointer.
Definition: usm_impl.cpp:536
void * aligned_alloc_shared(size_t alignment, size_t size, const device &dev, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:420
void * malloc_shared(size_t size, const device &dev, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:369
static void release_from_usm_device_copy(const void *Ptr, const context &Ctxt)
Definition: usm_impl.cpp:634
pointer get() const
Definition: multi_ptr.hpp:544
device get_pointer_device(const void *ptr, const context &ctxt)
Queries the device against which the pointer was allocated Throws an exception with errc::invalid err...
Definition: usm_impl.cpp:585
void * aligned_alloc_device(size_t alignment, size_t size, const device &dev, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:306
void * malloc_device(size_t size, const device &dev, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:281
void * malloc(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:64
void * malloc_host(size_t size, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:344
static void prepare_for_usm_device_copy(const void *Ptr, size_t Size, const context &Ctxt)
Definition: usm_impl.cpp:625
sycl::usm::alloc alloc
Definition: usm_impl.cpp:35
void free(void *ptr, const context &ctxt, const detail::code_location &CodeLoc=detail::code_location::current())
Definition: usm_impl.cpp:335
Definition: access.hpp:18
_pi_result
Definition: pi.h:274
constexpr pi_usm_mem_properties PI_MEM_USM_ALLOC_BUFFER_LOCATION
Definition: pi.h:877
pi_result piextUSMFree(pi_context context, void *ptr)
Indicates that the allocated USM memory is no longer needed on the runtime side.
Definition: pi_cuda.cpp:919
constexpr pi_usm_mem_properties PI_MEM_ALLOC_FLAGS
Definition: pi.h:869
pi_result piextUSMImport(const void *ptr, size_t size, pi_context context)
Import host system memory into USM.
Definition: pi_cuda.cpp:1009
pi_result piextUSMHostAlloc(void **result_ptr, pi_context context, pi_usm_mem_properties *properties, size_t size, pi_uint32 alignment)
Allocates host memory accessible by the device.
Definition: pi_cuda.cpp:912
_pi_usm_type
Definition: pi.h:2152
@ PI_MEM_TYPE_SHARED
Definition: pi.h:2156
@ PI_MEM_TYPE_DEVICE
Definition: pi.h:2155
@ PI_MEM_TYPE_HOST
Definition: pi.h:2154
pi_result piextUSMRelease(const void *ptr, pi_context context)
Release host system memory from USM.
Definition: pi_cuda.cpp:1013
_pi_device * pi_device
Definition: pi.h:1302
constexpr pi_usm_mem_properties PI_MEM_ALLOC_DEVICE_READ_ONLY
Definition: pi.h:875
pi_result piextUSMDeviceAlloc(void **result_ptr, pi_context context, pi_device device, pi_usm_mem_properties *properties, size_t size, pi_uint32 alignment)
Allocates device memory.
Definition: pi_cuda.cpp:884
@ PI_MEM_ALLOC_TYPE
Definition: pi.h:2146
@ PI_MEM_ALLOC_DEVICE
Definition: pi.h:2149
pi_result piextUSMSharedAlloc(void **result_ptr, pi_context context, pi_device device, pi_usm_mem_properties *properties, size_t size, pi_uint32 alignment)
Allocates memory accessible on both host and device.
Definition: pi_cuda.cpp:893
pi_result piextUSMGetMemAllocInfo(pi_context context, const void *ptr, pi_mem_alloc_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
API to query information about USM allocated pointers Valid Queries: PI_MEM_ALLOC_TYPE returns host/d...
Definition: pi_cuda.cpp:1001
_pi_usm_type pi_usm_type
Definition: pi.h:2169
C++ wrapper of extern "C" PI interfaces.
bool any_of(const simd_mask< _Tp, _Abi > &) noexcept