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>
16 #include <sycl/usm.hpp>
17 
18 #include <array>
19 #include <cassert>
20 #include <cstdlib>
21 #include <memory>
22 
23 #ifdef XPTI_ENABLE_INSTRUMENTATION
24 // Include the headers necessary for emitting
25 // traces using the trace framework
26 #include "xpti/xpti_trace_framework.hpp"
27 #include <detail/xpti_registry.hpp>
28 #endif
29 
30 namespace sycl {
32 
34 
35 namespace detail {
36 #ifdef XPTI_ENABLE_INSTRUMENTATION
37 extern xpti::trace_event_data_t *GSYCLGraphEvent;
38 #endif
39 namespace usm {
40 
41 void *alignedAllocHost(size_t Alignment, size_t Size, const context &Ctxt,
42  alloc Kind, const property_list &PropList,
43  const detail::code_location &CodeLoc) {
44 #ifdef XPTI_ENABLE_INSTRUMENTATION
45  // Stash the code location information and propagate
46  detail::tls_code_loc_t CL(CodeLoc);
47  XPTIScope PrepareNotify((void *)alignedAllocHost,
48  (uint16_t)xpti::trace_point_type_t::node_create,
49  SYCL_MEM_ALLOC_STREAM_NAME, "malloc_host");
50  PrepareNotify.addMetadata([&](auto TEvent) {
51  xpti::addMetadata(TEvent, "sycl_device_name", std::string("Host"));
52  xpti::addMetadata(TEvent, "sycl_device", 0);
53  xpti::addMetadata(TEvent, "memory_size", Size);
54  });
55  // Notify XPTI about the memset submission
56  PrepareNotify.notify();
57  // Emit a begin/end scope for this call
58  PrepareNotify.scopedNotify(
59  (uint16_t)xpti::trace_point_type_t::mem_alloc_begin);
60 #endif
61  void *RetVal = nullptr;
62  if (Size == 0)
63  return nullptr;
64 
65  std::shared_ptr<context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
66  if (CtxImpl->is_host()) {
67  if (!Alignment) {
68  // worst case default
69  Alignment = 128;
70  }
71 
73  try {
74  RetVal = Alloc.allocate(Size);
75  } catch (const std::bad_alloc &) {
76  // Conform with Specification behavior
77  RetVal = nullptr;
78  }
79  } else {
80  pi_context C = CtxImpl->getHandleRef();
81  const detail::plugin &Plugin = CtxImpl->getPlugin();
82  pi_result Error;
83 
84  switch (Kind) {
85  case alloc::host: {
86  std::array<pi_usm_mem_properties, 3> Props;
87  auto PropsIter = Props.begin();
88 
89  if (PropList.has_property<sycl::ext::intel::experimental::property::usm::
90  buffer_location>() &&
91  Ctxt.get_platform().has_extension(
92  "cl_intel_mem_alloc_buffer_location")) {
93  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
94  *PropsIter++ = PropList
97  .get_buffer_location();
98  }
99 
100  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
101  *PropsIter++ = 0; // null-terminate property list
102 
104  &RetVal, C, Props.data(), Size, Alignment);
105 
106  break;
107  }
108  case alloc::device:
109  case alloc::shared:
110  case alloc::unknown: {
111  RetVal = nullptr;
112  Error = PI_ERROR_INVALID_VALUE;
113  break;
114  }
115  }
116 
117  // Error is for debugging purposes.
118  // The spec wants a nullptr returned, not an exception.
119  if (Error != PI_SUCCESS)
120  return nullptr;
121  }
122  return RetVal;
123 }
124 
125 void *alignedAllocInternal(size_t Alignment, size_t Size,
126  const context_impl *CtxImpl,
127  const device_impl *DevImpl, alloc Kind,
128  const property_list &PropList) {
129  void *RetVal = nullptr;
130  if (Size == 0)
131  return nullptr;
132 
133  if (CtxImpl->is_host()) {
134  if (Kind == alloc::unknown) {
135  RetVal = nullptr;
136  } else {
137  if (!Alignment) {
138  // worst case default
139  Alignment = 128;
140  }
141 
143  try {
144  RetVal = Alloc.allocate(Size);
145  } catch (const std::bad_alloc &) {
146  // Conform with Specification behavior
147  RetVal = nullptr;
148  }
149  }
150  } else {
151  pi_context C = CtxImpl->getHandleRef();
152  const detail::plugin &Plugin = CtxImpl->getPlugin();
153  pi_result Error;
154  pi_device Id;
155 
156  switch (Kind) {
157  case alloc::device: {
158  Id = DevImpl->getHandleRef();
159 
160  std::array<pi_usm_mem_properties, 3> Props;
161  auto PropsIter = Props.begin();
162 
163  // Buffer location is only supported on FPGA devices
164  if (PropList.has_property<sycl::ext::intel::experimental::property::usm::
165  buffer_location>() &&
166  DevImpl->has_extension("cl_intel_mem_alloc_buffer_location")) {
167  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
168  *PropsIter++ = PropList
171  .get_buffer_location();
172  }
173 
174  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
175  *PropsIter++ = 0; // null-terminate property list
176 
178  &RetVal, C, Id, Props.data(), Size, Alignment);
179 
180  break;
181  }
182  case alloc::shared: {
183  Id = DevImpl->getHandleRef();
184 
185  std::array<pi_usm_mem_properties, 5> Props;
186  auto PropsIter = Props.begin();
187 
188  if (PropList.has_property<
189  sycl::ext::oneapi::property::usm::device_read_only>()) {
190  *PropsIter++ = PI_MEM_ALLOC_FLAGS;
191  *PropsIter++ = PI_MEM_ALLOC_DEVICE_READ_ONLY;
192  }
193 
194  if (PropList.has_property<sycl::ext::intel::experimental::property::usm::
195  buffer_location>() &&
196  DevImpl->has_extension("cl_intel_mem_alloc_buffer_location")) {
197  *PropsIter++ = PI_MEM_USM_ALLOC_BUFFER_LOCATION;
198  *PropsIter++ = PropList
201  .get_buffer_location();
202  }
203 
204  assert(PropsIter >= Props.begin() && PropsIter < Props.end());
205  *PropsIter++ = 0; // null-terminate property list
206 
208  &RetVal, C, Id, Props.data(), Size, Alignment);
209 
210  break;
211  }
212  case alloc::host:
213  case alloc::unknown: {
214  RetVal = nullptr;
215  Error = PI_ERROR_INVALID_VALUE;
216  break;
217  }
218  }
219 
220  // Error is for debugging purposes.
221  // The spec wants a nullptr returned, not an exception.
222  if (Error != PI_SUCCESS)
223  return nullptr;
224  }
225  return RetVal;
226 }
227 
228 void *alignedAlloc(size_t Alignment, size_t Size, const context &Ctxt,
229  const device &Dev, alloc Kind, const property_list &PropList,
230  const detail::code_location &CodeLoc) {
231 #ifdef XPTI_ENABLE_INSTRUMENTATION
232  // Stash the code location information and propagate
233  detail::tls_code_loc_t CL(CodeLoc);
234  XPTIScope PrepareNotify((void *)alignedAlloc,
235  (uint16_t)xpti::trace_point_type_t::node_create,
236  SYCL_MEM_ALLOC_STREAM_NAME, "usm::alignedAlloc");
237  PrepareNotify.addMetadata([&](auto TEvent) {
238  xpti::addMetadata(TEvent, "sycl_device_name",
239  Dev.get_info<info::device::name>());
240  // Need to determine how to get the device handle reference
241  // xpti::addMetadata(TEvent, "sycl_device", Dev.getHandleRef()));
242  xpti::addMetadata(TEvent, "memory_size", Size);
243  });
244  // Notify XPTI about the memset submission
245  PrepareNotify.notify();
246  // Emit a begin/end scope for this call
247  PrepareNotify.scopedNotify(
248  (uint16_t)xpti::trace_point_type_t::mem_alloc_begin);
249 #endif
250  return alignedAllocInternal(Alignment, Size, getSyclObjImpl(Ctxt).get(),
251  getSyclObjImpl(Dev).get(), Kind, PropList);
252 }
253 
254 void freeInternal(void *Ptr, const context_impl *CtxImpl) {
255  if (Ptr == nullptr)
256  return;
257  if (CtxImpl->is_host()) {
258  // need to use alignedFree here for Windows
259  detail::OSUtil::alignedFree(Ptr);
260  } else {
261  pi_context C = CtxImpl->getHandleRef();
262  const detail::plugin &Plugin = CtxImpl->getPlugin();
263  Plugin.call<PiApiKind::piextUSMFree>(C, Ptr);
264  }
265 }
266 
267 void free(void *Ptr, const context &Ctxt,
268  const detail::code_location &CodeLoc) {
269 #ifdef XPTI_ENABLE_INSTRUMENTATION
270  // Stash the code location information and propagate
271  detail::tls_code_loc_t CL(CodeLoc);
272  XPTIScope PrepareNotify((void *)free,
273  (uint16_t)xpti::trace_point_type_t::node_create,
274  SYCL_MEM_ALLOC_STREAM_NAME, "usm::free");
275  PrepareNotify.addMetadata([&](auto TEvent) {
276  xpti::addMetadata(TEvent, "memory_ptr", reinterpret_cast<size_t>(Ptr));
277  });
278  // Notify XPTI about the memset submission
279  PrepareNotify.notify();
280  // Emit a begin/end scope for this call
281  PrepareNotify.scopedNotify(
282  (uint16_t)xpti::trace_point_type_t::mem_release_begin);
283 #endif
285 }
286 
287 } // namespace usm
288 } // namespace detail
289 
290 void *malloc_device(size_t Size, const device &Dev,
291  const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
292  _CODELOCARG(&CodeLoc);
293  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::device,
294  property_list{}, CodeLoc);
295 }
296 
297 void *malloc_device(size_t Size, const device &Dev, const context &Ctxt,
298  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
299  _CODELOCARG(&CodeLoc);
300  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::device, PropList,
301  CodeLoc);
302 }
303 
304 void *malloc_device(size_t Size, const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
305  _CODELOCARG(&CodeLoc);
306  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
307  alloc::device, property_list{}, CodeLoc);
308 }
309 
310 void *malloc_device(size_t Size, const queue &Q,
311  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
312  _CODELOCARG(&CodeLoc);
313  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
314  alloc::device, PropList, CodeLoc);
315 }
316 
317 void *aligned_alloc_device(size_t Alignment, size_t Size, const device &Dev,
318  const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
319  _CODELOCARG(&CodeLoc);
320  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::device,
321  property_list{}, CodeLoc);
322 }
323 
324 void *
325 aligned_alloc_device(size_t Alignment, size_t Size, const device &Dev,
326  const context &Ctxt,
327  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
328  _CODELOCARG(&CodeLoc);
329  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::device,
330  PropList, CodeLoc);
331 }
332 
333 void *aligned_alloc_device(size_t Alignment, size_t Size,
334  const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
335  _CODELOCARG(&CodeLoc);
337  Q.get_device(), alloc::device,
338  property_list{}, CodeLoc);
339 }
340 
341 void *
342 aligned_alloc_device(size_t Alignment, size_t Size, const queue &Q,
343  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
344  _CODELOCARG(&CodeLoc);
346  Q.get_device(), alloc::device, PropList,
347  CodeLoc);
348 }
349 
350 void free(void *ptr, const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
351  _CODELOCARG(&CodeLoc);
352  return detail::usm::free(ptr, Ctxt, CodeLoc);
353 }
354 
355 void free(void *ptr, const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
356  _CODELOCARG(&CodeLoc);
357  return detail::usm::free(ptr, Q.get_context(), CodeLoc);
358 }
359 
360 void *malloc_host(size_t Size, const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
361  _CODELOCARG(&CodeLoc);
362  return detail::usm::alignedAllocHost(0, Size, Ctxt, alloc::host,
363  property_list{}, CodeLoc);
364 }
365 
366 void *malloc_host(size_t Size, const context &Ctxt,
367  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
368  _CODELOCARG(&CodeLoc);
369  return detail::usm::alignedAllocHost(0, Size, Ctxt, alloc::host, PropList,
370  CodeLoc);
371 }
372 
373 void *malloc_host(size_t Size, const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
374  _CODELOCARG(&CodeLoc);
375  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), alloc::host,
376  property_list{}, CodeLoc);
377 }
378 
379 void *malloc_host(size_t Size, const queue &Q,
380  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
381  _CODELOCARG(&CodeLoc);
382  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), alloc::host,
383  PropList, CodeLoc);
384 }
385 
386 void *malloc_shared(size_t Size, const device &Dev,
387  const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
388  _CODELOCARG(&CodeLoc);
389  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::shared,
390  property_list{}, CodeLoc);
391 }
392 
393 void *malloc_shared(size_t Size, const device &Dev, const context &Ctxt,
394  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
395  _CODELOCARG(&CodeLoc);
396  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, alloc::shared, PropList,
397  CodeLoc);
398 }
399 
400 void *malloc_shared(size_t Size, const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
401  _CODELOCARG(&CodeLoc);
402  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
403  alloc::shared, property_list{}, CodeLoc);
404 }
405 
406 void *malloc_shared(size_t Size, const queue &Q,
407  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
408  _CODELOCARG(&CodeLoc);
409  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
410  alloc::shared, PropList, CodeLoc);
411 }
412 
413 void *aligned_alloc_host(size_t Alignment, size_t Size,
414  const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
415  _CODELOCARG(&CodeLoc);
416  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, alloc::host,
417  property_list{}, CodeLoc);
418 }
419 
420 void *
421 aligned_alloc_host(size_t Alignment, size_t Size, const context &Ctxt,
422  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
423  _CODELOCARG(&CodeLoc);
424  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, alloc::host,
425  PropList, CodeLoc);
426 }
427 
428 void *aligned_alloc_host(size_t Alignment, size_t Size,
429  const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
430  _CODELOCARG(&CodeLoc);
432  alloc::host, property_list{}, CodeLoc);
433 }
434 
435 void *
436 aligned_alloc_host(size_t Alignment, size_t Size, const queue &Q,
437  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
438  _CODELOCARG(&CodeLoc);
440  alloc::host, PropList, CodeLoc);
441 }
442 
443 void *aligned_alloc_shared(size_t Alignment, size_t Size, const device &Dev,
444  const context &Ctxt _CODELOCPARAMDEF(&CodeLoc)) {
445  _CODELOCARG(&CodeLoc);
446  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::shared,
447  property_list{}, CodeLoc);
448 }
449 
450 void *
451 aligned_alloc_shared(size_t Alignment, size_t Size, const device &Dev,
452  const context &Ctxt,
453  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
454  _CODELOCARG(&CodeLoc);
455  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, alloc::shared,
456  PropList, CodeLoc);
457 }
458 
459 void *aligned_alloc_shared(size_t Alignment, size_t Size,
460  const queue &Q _CODELOCPARAMDEF(&CodeLoc)) {
461  _CODELOCARG(&CodeLoc);
463  Q.get_device(), alloc::shared,
464  property_list{}, CodeLoc);
465 }
466 
467 void *
468 aligned_alloc_shared(size_t Alignment, size_t Size, const queue &Q,
469  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
470  _CODELOCARG(&CodeLoc);
472  Q.get_device(), alloc::shared, PropList,
473  CodeLoc);
474 }
475 
476 // single form
477 
478 void *malloc(size_t Size, const device &Dev, const context &Ctxt, alloc Kind,
479  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
480  _CODELOCARG(&CodeLoc);
481  if (Kind == alloc::host)
482  return detail::usm::alignedAllocHost(0, Size, Ctxt, Kind, PropList,
483  CodeLoc);
484  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, Kind, PropList, CodeLoc);
485 }
486 
487 void *malloc(size_t Size, const device &Dev, const context &Ctxt,
488  alloc Kind _CODELOCPARAMDEF(&CodeLoc)) {
489  _CODELOCARG(&CodeLoc);
490  if (Kind == alloc::host)
491  return detail::usm::alignedAllocHost(0, Size, Ctxt, Kind, property_list{},
492  CodeLoc);
493  return detail::usm::alignedAlloc(0, Size, Ctxt, Dev, Kind, property_list{},
494  CodeLoc);
495 }
496 
497 void *malloc(size_t Size, const queue &Q,
498  alloc Kind _CODELOCPARAMDEF(&CodeLoc)) {
499  _CODELOCARG(&CodeLoc);
500  if (Kind == alloc::host)
501  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), Kind,
502  property_list{}, CodeLoc);
503  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
504  Kind, property_list{}, CodeLoc);
505 }
506 
507 void *malloc(size_t Size, const queue &Q, alloc Kind,
508  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
509  _CODELOCARG(&CodeLoc);
510  if (Kind == alloc::host)
511  return detail::usm::alignedAllocHost(0, Size, Q.get_context(), Kind,
512  PropList, CodeLoc);
513  return detail::usm::alignedAlloc(0, Size, Q.get_context(), Q.get_device(),
514  Kind, PropList, CodeLoc);
515 }
516 
517 void *aligned_alloc(size_t Alignment, size_t Size, const device &Dev,
518  const context &Ctxt,
519  alloc Kind _CODELOCPARAMDEF(&CodeLoc)) {
520  _CODELOCARG(&CodeLoc);
521  if (Kind == alloc::host)
522  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, Kind,
523  property_list{}, CodeLoc);
524 
525  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, Kind,
526  property_list{}, CodeLoc);
527 }
528 
529 void *aligned_alloc(size_t Alignment, size_t Size, const device &Dev,
530  const context &Ctxt, alloc Kind,
531  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
532  _CODELOCARG(&CodeLoc);
533  if (Kind == alloc::host)
534  return detail::usm::alignedAllocHost(Alignment, Size, Ctxt, Kind, PropList,
535  CodeLoc);
536  return detail::usm::alignedAlloc(Alignment, Size, Ctxt, Dev, Kind, PropList,
537  CodeLoc);
538 }
539 
540 void *aligned_alloc(size_t Alignment, size_t Size, const queue &Q,
541  alloc Kind _CODELOCPARAMDEF(&CodeLoc)) {
542  _CODELOCARG(&CodeLoc);
543  if (Kind == alloc::host)
544  return detail::usm::alignedAllocHost(Alignment, Size, Q.get_context(), Kind,
545  property_list{}, CodeLoc);
547  Q.get_device(), Kind, property_list{},
548  CodeLoc);
549 }
550 
551 void *aligned_alloc(size_t Alignment, size_t Size, const queue &Q, alloc Kind,
552  const property_list &PropList _CODELOCPARAMDEF(&CodeLoc)) {
553  _CODELOCARG(&CodeLoc);
554  if (Kind == alloc::host)
555  return detail::usm::alignedAllocHost(Alignment, Size, Q.get_context(), Kind,
556  PropList, CodeLoc);
558  Q.get_device(), Kind, PropList, CodeLoc);
559 }
560 
561 // Pointer queries
567 alloc get_pointer_type(const void *Ptr, const context &Ctxt) {
568  if (!Ptr)
569  return alloc::unknown;
570 
571  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
572 
573  // Everything on a host device is just system malloc so call it host
574  if (CtxImpl->is_host())
575  return alloc::host;
576 
577  pi_context PICtx = CtxImpl->getHandleRef();
578  pi_usm_type AllocTy;
579 
580  // query type using PI function
581  const detail::plugin &Plugin = CtxImpl->getPlugin();
582  RT::PiResult Err =
584  PICtx, Ptr, PI_MEM_ALLOC_TYPE, sizeof(pi_usm_type), &AllocTy,
585  nullptr);
586 
587  // PI_ERROR_INVALID_VALUE means USM doesn't know about this ptr
588  if (Err == PI_ERROR_INVALID_VALUE)
589  return alloc::unknown;
590  // otherwise PI_SUCCESS is expected
591  if (Err != PI_SUCCESS) {
592  Plugin.reportPiError(Err, "get_pointer_type()");
593  }
594 
595  alloc ResultAlloc;
596  switch (AllocTy) {
597  case PI_MEM_TYPE_HOST:
598  ResultAlloc = alloc::host;
599  break;
600  case PI_MEM_TYPE_DEVICE:
601  ResultAlloc = alloc::device;
602  break;
603  case PI_MEM_TYPE_SHARED:
604  ResultAlloc = alloc::shared;
605  break;
606  default:
607  ResultAlloc = alloc::unknown;
608  break;
609  }
610 
611  return ResultAlloc;
612 }
613 
618 device get_pointer_device(const void *Ptr, const context &Ctxt) {
619  // Check if ptr is a valid USM pointer
620  if (get_pointer_type(Ptr, Ctxt) == alloc::unknown)
621  throw runtime_error("Ptr not a valid USM allocation!",
622  PI_ERROR_INVALID_VALUE);
623 
624  std::shared_ptr<detail::context_impl> CtxImpl = detail::getSyclObjImpl(Ctxt);
625 
626  // Just return the host device in the host context
627  if (CtxImpl->is_host())
628  return Ctxt.get_devices()[0];
629 
630  // Check if ptr is a host allocation
631  if (get_pointer_type(Ptr, Ctxt) == alloc::host) {
632  auto Devs = CtxImpl->getDevices();
633  if (Devs.size() == 0)
634  throw runtime_error("No devices in passed context!",
635  PI_ERROR_INVALID_VALUE);
636 
637  // Just return the first device in the context
638  return Devs[0];
639  }
640 
641  pi_context PICtx = CtxImpl->getHandleRef();
642  pi_device DeviceId;
643 
644  // query device using PI function
645  const detail::plugin &Plugin = CtxImpl->getPlugin();
647  PICtx, Ptr, PI_MEM_ALLOC_DEVICE, sizeof(pi_device), &DeviceId, nullptr);
648 
649  // The device is not necessarily a member of the context, it could be a
650  // member's descendant instead. Fetch the corresponding device from the cache.
651  std::shared_ptr<detail::platform_impl> PltImpl = CtxImpl->getPlatformImpl();
652  std::shared_ptr<detail::device_impl> DevImpl =
653  PltImpl->getDeviceImpl(DeviceId);
654  if (DevImpl)
655  return detail::createSyclObjFromImpl<device>(DevImpl);
656  throw runtime_error("Cannot find device associated with USM allocation!",
657  PI_ERROR_INVALID_OPERATION);
658 }
659 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
660 } // namespace sycl
sycl::_V1::property_list
Objects of the property_list class are containers for the SYCL properties.
Definition: property_list.hpp:24
sycl::_V1::aligned_alloc_host
void * aligned_alloc_host(size_t Alignment, size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:436
piextUSMFree
pi_result piextUSMFree(pi_context context, void *ptr)
Indicates that the allocated USM memory is no longer needed on the runtime side.
Definition: pi_esimd_emulator.cpp:1943
sycl::_V1::get_pointer_type
usm::alloc get_pointer_type(const void *ptr, const context &ctxt)
Query the allocation type from a USM pointer.
Definition: usm_impl.cpp:567
sycl::_V1::get_pointer_device
device get_pointer_device(const void *ptr, const context &ctxt)
Queries the device against which the pointer was allocated Throws an invalid_object_error if ptr is a...
Definition: usm_impl.cpp:618
sycl::_V1::detail::SYCL_MEM_ALLOC_STREAM_NAME
constexpr auto SYCL_MEM_ALLOC_STREAM_NAME
Definition: xpti_registry.hpp:35
sycl::_V1::aligned_alloc_shared
void * aligned_alloc_shared(size_t Alignment, size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:468
sycl::_V1::ext::oneapi::experimental::buffer_location
constexpr buffer_location_key::value_t< N > buffer_location
Definition: properties.hpp:86
_pi_usm_type
_pi_usm_type
Definition: pi.h:1702
device.hpp
__SYCL_INLINE_VER_NAMESPACE
#define __SYCL_INLINE_VER_NAMESPACE(X)
Definition: defines_elementary.hpp:11
xpti_registry.hpp
_pi_result
_pi_result
Definition: pi.h:140
sycl::_V1::context::get_devices
std::vector< device > get_devices() const
Gets devices associated with this SYCL context.
Definition: context.cpp:139
context.hpp
usm_impl.hpp
os_util.hpp
sycl::_V1::property_list::get_property
PropT get_property() const
Definition: property_list.hpp:40
sycl::_V1::detail::usm::alignedAllocInternal
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:125
sycl
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
usm.hpp
queue_impl.hpp
sycl::_V1::detail::device_impl::has_extension
bool has_extension(const std::string &ExtensionName) const
Check SYCL extension support by device.
Definition: device_impl.cpp:113
pi.hpp
piextUSMSharedAlloc
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_esimd_emulator.cpp:1904
sycl::_V1::malloc_host
void * malloc_host(size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:379
PI_MEM_TYPE_DEVICE
@ PI_MEM_TYPE_DEVICE
Definition: pi.h:1705
piextUSMDeviceAlloc
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_esimd_emulator.cpp:1899
sycl::_V1::malloc
void * malloc(size_t Size, const queue &Q, alloc Kind, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:507
sycl::_V1::detail::context_impl::getHandleRef
RT::PiContext & getHandleRef()
Gets the underlying context object (if any) without reference count modification.
Definition: context_impl.cpp:234
sycl::_V1::detail::aligned_allocator
Definition: aligned_allocator.hpp:23
PI_MEM_ALLOC_DEVICE_READ_ONLY
constexpr pi_usm_mem_properties PI_MEM_ALLOC_DEVICE_READ_ONLY
Definition: pi.h:614
sycl::_V1::detail::usm::alignedAlloc
void * alignedAlloc(size_t Alignment, size_t Size, const context &Ctxt, const device &Dev, alloc Kind, const property_list &PropList, const detail::code_location &CodeLoc)
Definition: usm_impl.cpp:228
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
sycl::_V1::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
sycl::_V1::detail::device_impl::getHandleRef
RT::PiDevice & getHandleRef()
Get reference to PI device.
Definition: device_impl.hpp:65
pi_usm_type
_pi_usm_type pi_usm_type
Definition: pi.h:1719
sycl::_V1::aligned_alloc
void * aligned_alloc(size_t Alignment, size_t Size, const queue &Q, alloc Kind, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:551
sycl::_V1::detail::plugin::reportPiError
void reportPiError(RT::PiResult pi_result, const char *context) const
Definition: plugin.hpp:149
sycl::_V1::detail::pi::PiResult
::pi_result PiResult
Definition: pi.hpp:122
sycl::_V1::queue
Encapsulates a single SYCL queue which schedules kernels on a SYCL device.
Definition: queue.hpp:89
_CODELOCARG
#define _CODELOCARG(a)
Definition: common.hpp:112
sycl::_V1::detail::context_impl::getPlugin
const plugin & getPlugin() const
Definition: context_impl.hpp:109
sycl::_V1::detail::tls_code_loc_t
Data type that manages the code_location information in TLS.
Definition: common.hpp:152
PI_MEM_TYPE_SHARED
@ PI_MEM_TYPE_SHARED
Definition: pi.h:1706
_CODELOCPARAMDEF
#define _CODELOCPARAMDEF(a)
Definition: common.hpp:110
sycl::_V1::ext::oneapi::experimental::detail::Alignment
@ Alignment
Definition: property.hpp:189
sycl::_V1::device
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:49
piextUSMHostAlloc
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_esimd_emulator.cpp:1894
sycl::_V1::detail::device_impl
Definition: device_impl.hpp:36
sycl::_V1::detail::usm::freeInternal
void freeInternal(void *Ptr, const context_impl *CtxImpl)
Definition: usm_impl.cpp:254
piextUSMGetMemAllocInfo
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_esimd_emulator.cpp:2003
aligned_allocator.hpp
sycl::_V1::detail::aligned_allocator::allocate
pointer allocate(size_t Size)
Definition: aligned_allocator.hpp:53
PI_MEM_ALLOC_FLAGS
constexpr pi_usm_mem_properties PI_MEM_ALLOC_FLAGS
Definition: pi.h:608
sycl::_V1::property_list::has_property
bool has_property() const noexcept
Definition: property_list.hpp:48
sycl::_V1::detail::context_impl::is_host
bool is_host() const
Checks if this context is a host context.
Definition: context_impl.cpp:122
sycl::_V1::free
void free(void *ptr, const queue &Q _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:355
sycl::_V1::detail::plugin::call_nocheck
RT::PiResult call_nocheck(ArgsT... Args) const
Calls the PiApi, traces the call, and returns the result.
Definition: plugin.hpp:170
sycl::_V1::queue::get_context
context get_context() const
Definition: queue.cpp:75
sycl::_V1::detail::code_location
Definition: common.hpp:66
sycl::_V1::device::get_info
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.cpp:136
sycl::_V1::detail::plugin::call
void call(ArgsT... Args) const
Calls the API, traces the call, checks the result.
Definition: plugin.hpp:217
sycl::_V1::malloc_device
void * malloc_device(size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:310
sycl::_V1::context::get_platform
platform get_platform() const
Gets platform associated with this SYCL context.
Definition: context.cpp:135
PI_MEM_ALLOC_DEVICE
@ PI_MEM_ALLOC_DEVICE
Definition: pi.h:1699
sycl::_V1::alloc
sycl::usm::alloc alloc
Definition: usm_impl.cpp:33
PI_MEM_TYPE_HOST
@ PI_MEM_TYPE_HOST
Definition: pi.h:1704
PI_MEM_USM_ALLOC_BUFFER_LOCATION
constexpr pi_usm_mem_properties PI_MEM_USM_ALLOC_BUFFER_LOCATION
Definition: pi.h:616
sycl::_V1::queue::get_device
device get_device() const
Definition: queue.cpp:77
sycl::_V1::malloc_shared
void * malloc_shared(size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:406
sycl::_V1::aligned_alloc_device
void * aligned_alloc_device(size_t Alignment, size_t Size, const queue &Q, const property_list &PropList _CODELOCPARAMDEF(&CodeLoc))
Definition: usm_impl.cpp:342
PI_MEM_ALLOC_TYPE
@ PI_MEM_ALLOC_TYPE
Definition: pi.h:1696
sycl::_V1::detail::usm::alignedAllocHost
void * alignedAllocHost(size_t Alignment, size_t Size, const context &Ctxt, alloc Kind, const property_list &PropList, const detail::code_location &CodeLoc)
Definition: usm_impl.cpp:41
sycl::_V1::detail::context_impl
Definition: context_impl.hpp:33
pi_device
_pi_device * pi_device
Definition: pi.h:966
_pi_context
PI context mapping to a CUDA context object.
Definition: pi_cuda.hpp:170
sycl::_V1::detail::getSyclObjImpl
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:300
_pi_device
PI device mapping to a CUdevice.
Definition: pi_cuda.hpp:83
sycl::_V1::context
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:41