DPC++ Runtime
Runtime libraries for oneAPI DPC++
context_impl.cpp
Go to the documentation of this file.
1 //==---------------- context_impl.cpp - SYCL context -----------*- 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 
10 #include <detail/context_info.hpp>
11 #include <detail/event_info.hpp>
12 #include <detail/platform_impl.hpp>
13 #include <detail/queue_impl.hpp>
14 #include <sycl/detail/common.hpp>
15 #include <sycl/detail/ur.hpp>
16 #include <sycl/device.hpp>
17 #include <sycl/exception.hpp>
18 #include <sycl/exception_list.hpp>
19 #include <sycl/info/info_desc.hpp>
20 #include <sycl/platform.hpp>
21 #include <sycl/property_list.hpp>
22 
23 #include <algorithm>
24 
25 namespace sycl {
26 inline namespace _V1 {
27 namespace detail {
28 
29 context_impl::context_impl(const device &Device, async_handler AsyncHandler,
30  const property_list &PropList)
31  : MOwnedByRuntime(true), MAsyncHandler(AsyncHandler), MDevices(1, Device),
32  MContext(nullptr),
33  MPlatform(detail::getSyclObjImpl(Device.get_platform())),
34  MPropList(PropList), MSupportBufferLocationByDevices(NotChecked) {
35  MKernelProgramCache.setContextPtr(this);
36 }
37 
38 context_impl::context_impl(const std::vector<sycl::device> Devices,
39  async_handler AsyncHandler,
40  const property_list &PropList)
41  : MOwnedByRuntime(true), MAsyncHandler(AsyncHandler), MDevices(Devices),
42  MContext(nullptr), MPlatform(), MPropList(PropList),
43  MSupportBufferLocationByDevices(NotChecked) {
44  MPlatform = detail::getSyclObjImpl(MDevices[0].get_platform());
45  std::vector<ur_device_handle_t> DeviceIds;
46  for (const auto &D : MDevices) {
47  if (D.has(aspect::ext_oneapi_is_composite)) {
48  // Component devices are considered to be descendent devices from a
49  // composite device and therefore context created for a composite
50  // device should also work for a component device.
51  // In order to achieve that, we implicitly add all component devices to
52  // the list if a composite device was passed by user to us.
53  std::vector<device> ComponentDevices = D.get_info<
54  ext::oneapi::experimental::info::device::component_devices>();
55  for (const auto &CD : ComponentDevices)
56  DeviceIds.push_back(getSyclObjImpl(CD)->getHandleRef());
57  }
58 
59  DeviceIds.push_back(getSyclObjImpl(D)->getHandleRef());
60  }
61 
62  getPlugin()->call(urContextCreate, DeviceIds.size(), DeviceIds.data(),
63  nullptr, &MContext);
64 
65  MKernelProgramCache.setContextPtr(this);
66 }
67 
68 context_impl::context_impl(ur_context_handle_t UrContext,
69  async_handler AsyncHandler, const PluginPtr &Plugin,
70  const std::vector<sycl::device> &DeviceList,
71  bool OwnedByRuntime)
72  : MOwnedByRuntime(OwnedByRuntime), MAsyncHandler(AsyncHandler),
73  MDevices(DeviceList), MContext(UrContext), MPlatform(),
74  MSupportBufferLocationByDevices(NotChecked) {
75  if (!MDevices.empty()) {
76  MPlatform = detail::getSyclObjImpl(MDevices[0].get_platform());
77  } else {
78  std::vector<ur_device_handle_t> DeviceIds;
79  uint32_t DevicesNum = 0;
80  // TODO catch an exception and put it to list of asynchronous exceptions
81  Plugin->call(urContextGetInfo, MContext, UR_CONTEXT_INFO_NUM_DEVICES,
82  sizeof(DevicesNum), &DevicesNum, nullptr);
83  DeviceIds.resize(DevicesNum);
84  // TODO catch an exception and put it to list of asynchronous exceptions
85  Plugin->call(urContextGetInfo, MContext, UR_CONTEXT_INFO_DEVICES,
86  sizeof(ur_device_handle_t) * DevicesNum, &DeviceIds[0],
87  nullptr);
88 
89  if (DeviceIds.empty())
90  throw exception(
92  "No devices in the provided device list and native context.");
93 
94  std::shared_ptr<detail::platform_impl> Platform =
95  platform_impl::getPlatformFromUrDevice(DeviceIds[0], Plugin);
96  for (ur_device_handle_t Dev : DeviceIds) {
97  MDevices.emplace_back(createSyclObjFromImpl<device>(
98  Platform->getOrMakeDeviceImpl(Dev, Platform)));
99  }
100  MPlatform = Platform;
101  }
102  // TODO catch an exception and put it to list of asynchronous exceptions
103  // getPlugin() will be the same as the Plugin passed. This should be taken
104  // care of when creating device object.
105  //
106  // TODO: Move this backend-specific retain of the context to SYCL-2020 style
107  // make_context<backend::opencl> interop, when that is created.
108  if (getBackend() == sycl::backend::opencl) {
109  getPlugin()->call(urContextRetain, MContext);
110  }
111  MKernelProgramCache.setContextPtr(this);
112 }
113 
114 cl_context context_impl::get() const {
115  // TODO catch an exception and put it to list of asynchronous exceptions
116  getPlugin()->call(urContextRetain, MContext);
117  ur_native_handle_t nativeHandle = 0;
118  getPlugin()->call(urContextGetNativeHandle, MContext, &nativeHandle);
119  return ur::cast<cl_context>(nativeHandle);
120 }
121 
123  try {
124  // Free all events associated with the initialization of device globals.
125  for (auto &DeviceGlobalInitializer : MDeviceGlobalInitializers)
126  DeviceGlobalInitializer.second.ClearEvents(getPlugin());
127  // Free all device_global USM allocations associated with this context.
128  for (const void *DeviceGlobal : MAssociatedDeviceGlobals) {
129  DeviceGlobalMapEntry *DGEntry =
131  DeviceGlobal);
132  DGEntry->removeAssociatedResources(this);
133  }
134  for (auto LibProg : MCachedLibPrograms) {
135  assert(LibProg.second && "Null program must not be kept in the cache");
136  getPlugin()->call(urProgramRelease, LibProg.second);
137  }
138  // TODO catch an exception and put it to list of asynchronous exceptions
139  getPlugin()->call_nocheck(urContextRelease, MContext);
140  } catch (std::exception &e) {
141  __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~context_impl", e);
142  }
143 }
144 
146  return MAsyncHandler;
147 }
148 
149 template <>
150 uint32_t context_impl::get_info<info::context::reference_count>() const {
151  return get_context_info<info::context::reference_count>(this->getHandleRef(),
152  this->getPlugin());
153 }
154 template <> platform context_impl::get_info<info::context::platform>() const {
155  return createSyclObjFromImpl<platform>(MPlatform);
156 }
157 template <>
158 std::vector<sycl::device>
159 context_impl::get_info<info::context::devices>() const {
160  return MDevices;
161 }
162 template <>
163 std::vector<sycl::memory_order>
164 context_impl::get_info<info::context::atomic_memory_order_capabilities>()
165  const {
166  std::vector<sycl::memory_order> CapabilityList{
167  sycl::memory_order::relaxed, sycl::memory_order::acquire,
168  sycl::memory_order::release, sycl::memory_order::acq_rel,
169  sycl::memory_order::seq_cst};
170 
172  sycl::memory_order, info::device::atomic_memory_order_capabilities>(
173  MDevices, CapabilityList);
174 
175  return CapabilityList;
176 }
177 template <>
178 std::vector<sycl::memory_scope>
179 context_impl::get_info<info::context::atomic_memory_scope_capabilities>()
180  const {
181  std::vector<sycl::memory_scope> CapabilityList{
182  sycl::memory_scope::work_item, sycl::memory_scope::sub_group,
183  sycl::memory_scope::work_group, sycl::memory_scope::device,
184  sycl::memory_scope::system};
185 
187  sycl::memory_scope, info::device::atomic_memory_scope_capabilities>(
188  MDevices, CapabilityList);
189 
190  return CapabilityList;
191 }
192 template <>
193 std::vector<sycl::memory_order>
194 context_impl::get_info<info::context::atomic_fence_order_capabilities>() const {
195  std::vector<sycl::memory_order> CapabilityList{
196  sycl::memory_order::relaxed, sycl::memory_order::acquire,
197  sycl::memory_order::release, sycl::memory_order::acq_rel,
198  sycl::memory_order::seq_cst};
199 
201  info::device::atomic_fence_order_capabilities>(
202  MDevices, CapabilityList);
203 
204  return CapabilityList;
205 }
206 template <>
207 std::vector<sycl::memory_scope>
208 context_impl::get_info<info::context::atomic_fence_scope_capabilities>() const {
209  std::vector<sycl::memory_scope> CapabilityList{
210  sycl::memory_scope::work_item, sycl::memory_scope::sub_group,
211  sycl::memory_scope::work_group, sycl::memory_scope::device,
212  sycl::memory_scope::system};
213 
215  info::device::atomic_fence_scope_capabilities>(
216  MDevices, CapabilityList);
217 
218  return CapabilityList;
219 }
220 
221 template <>
222 typename info::platform::version::return_type
223 context_impl::get_backend_info<info::platform::version>() const {
224  if (getBackend() != backend::opencl) {
226  "the info::platform::version info descriptor can "
227  "only be queried with an OpenCL backend");
228  }
229  return MDevices[0].get_platform().get_info<info::platform::version>();
230 }
231 
232 device select_device(DSelectorInvocableType DeviceSelectorInvocable,
233  std::vector<device> &Devices);
234 
235 template <>
236 typename info::device::version::return_type
237 context_impl::get_backend_info<info::device::version>() const {
238  if (getBackend() != backend::opencl) {
240  "the info::device::version info descriptor can only "
241  "be queried with an OpenCL backend");
242  }
243  auto Devices = get_info<info::context::devices>();
244  if (Devices.empty()) {
245  return "No available device";
246  }
247  // Use default selector to pick a device.
248  return select_device(default_selector_v, Devices)
249  .get_info<info::device::version>();
250 }
251 
252 template <>
253 typename info::device::backend_version::return_type
254 context_impl::get_backend_info<info::device::backend_version>() const {
255  if (getBackend() != backend::ext_oneapi_level_zero) {
257  "the info::device::backend_version info descriptor "
258  "can only be queried with a Level Zero backend");
259  }
260  return "";
261  // Currently The Level Zero backend does not define the value of this
262  // information descriptor and implementations are encouraged to return the
263  // empty string as per specification.
264 }
265 
266 ur_context_handle_t &context_impl::getHandleRef() { return MContext; }
267 const ur_context_handle_t &context_impl::getHandleRef() const {
268  return MContext;
269 }
270 
272  return MKernelProgramCache;
273 }
274 
276  std::shared_ptr<detail::device_impl> Device) const {
277  for (auto D : MDevices)
278  if (getSyclObjImpl(D) == Device)
279  return true;
280  return false;
281 }
282 
284 context_impl::findMatchingDeviceImpl(ur_device_handle_t &DeviceUR) const {
285  for (device D : MDevices)
286  if (getSyclObjImpl(D)->getHandleRef() == DeviceUR)
287  return getSyclObjImpl(D);
288 
289  return nullptr;
290 }
291 
292 ur_native_handle_t context_impl::getNative() const {
293  const auto &Plugin = getPlugin();
294  if (getBackend() == backend::opencl)
295  Plugin->call(urContextRetain, getHandleRef());
296  ur_native_handle_t Handle;
297  Plugin->call(urContextGetNativeHandle, getHandleRef(), &Handle);
298  return Handle;
299 }
300 
302  if (MSupportBufferLocationByDevices != NotChecked)
303  return MSupportBufferLocationByDevices == Supported ? true : false;
304  // Check that devices within context have support of buffer location
305  MSupportBufferLocationByDevices = Supported;
306  for (auto &Device : MDevices) {
307  if (!Device.has_extension("cl_intel_mem_alloc_buffer_location")) {
308  MSupportBufferLocationByDevices = NotSupported;
309  break;
310  }
311  }
312  return MSupportBufferLocationByDevices == Supported ? true : false;
313 }
314 
315 void context_impl::addAssociatedDeviceGlobal(const void *DeviceGlobalPtr) {
316  std::lock_guard<std::mutex> Lock{MAssociatedDeviceGlobalsMutex};
317  MAssociatedDeviceGlobals.insert(DeviceGlobalPtr);
318 }
319 
321  ur_program_handle_t Program, const std::vector<device> &Devs,
322  const RTDeviceBinaryImage *BinImage) {
323  std::lock_guard<std::mutex> Lock(MDeviceGlobalInitializersMutex);
324  for (const device &Dev : Devs) {
325  auto Key = std::make_pair(Program, getSyclObjImpl(Dev)->getHandleRef());
326  MDeviceGlobalInitializers.emplace(Key, BinImage);
327  }
328 }
329 
330 std::vector<ur_event_handle_t> context_impl::initializeDeviceGlobals(
331  ur_program_handle_t NativePrg,
332  const std::shared_ptr<queue_impl> &QueueImpl) {
333  const PluginPtr &Plugin = getPlugin();
334  const DeviceImplPtr &DeviceImpl = QueueImpl->getDeviceImplPtr();
335  std::lock_guard<std::mutex> NativeProgramLock(MDeviceGlobalInitializersMutex);
336  auto ImgIt = MDeviceGlobalInitializers.find(
337  std::make_pair(NativePrg, DeviceImpl->getHandleRef()));
338  if (ImgIt == MDeviceGlobalInitializers.end() ||
339  ImgIt->second.MDeviceGlobalsFullyInitialized)
340  return {};
341 
342  DeviceGlobalInitializer &InitRef = ImgIt->second;
343  {
344  std::lock_guard<std::mutex> InitLock(InitRef.MDeviceGlobalInitMutex);
345  std::vector<ur_event_handle_t> &InitEventsRef =
346  InitRef.MDeviceGlobalInitEvents;
347  if (!InitEventsRef.empty()) {
348  // Initialization has begun but we do not know if the events are done.
349  auto NewEnd = std::remove_if(
350  InitEventsRef.begin(), InitEventsRef.end(),
351  [&Plugin](const ur_event_handle_t &Event) {
352  return get_event_info<info::event::command_execution_status>(
353  Event, Plugin) == info::event_command_status::complete;
354  return false;
355  });
356  // Release the removed events.
357  for (auto EventIt = NewEnd; EventIt != InitEventsRef.end(); ++EventIt)
358  Plugin->call(urEventRelease, *EventIt);
359  // Remove them from the collection.
360  InitEventsRef.erase(NewEnd, InitEventsRef.end());
361  // If there are no more events, we can mark it as fully initialized.
362  if (InitEventsRef.empty())
363  InitRef.MDeviceGlobalsFullyInitialized = true;
364  return InitEventsRef;
365  } else if (InitRef.MDeviceGlobalsFullyInitialized) {
366  // MDeviceGlobalsFullyInitialized could have been set while we were
367  // waiting on the lock and since there were no init events we are done.
368  return {};
369  }
370 
371  // There were no events and it was not set as fully initialized, so this is
372  // responsible for intializing the device globals.
373  auto DeviceGlobals = InitRef.MBinImage->getDeviceGlobals();
374  std::vector<std::string> DeviceGlobalIds;
375  DeviceGlobalIds.reserve(DeviceGlobals.size());
376  for (const sycl_device_binary_property &DeviceGlobal : DeviceGlobals)
377  DeviceGlobalIds.push_back(DeviceGlobal->Name);
378  std::vector<DeviceGlobalMapEntry *> DeviceGlobalEntries =
380  DeviceGlobalIds,
381  /*ExcludeDeviceImageScopeDecorated=*/true);
382 
383  // If there were no device globals without device_image_scope the device
384  // globals are trivially fully initialized and we can end early.
385  if (DeviceGlobalEntries.empty()) {
386  InitRef.MDeviceGlobalsFullyInitialized = true;
387  return {};
388  }
389 
390  // We may have reserved too much for DeviceGlobalEntries, but now that we
391  // know number of device globals to initialize, we can use that for the
392  // list.
393  InitEventsRef.reserve(DeviceGlobalEntries.size());
394 
395  // Device global map entry pointers will not die before the end of the
396  // program and the pointers will stay the same, so we do not need
397  // m_DeviceGlobalsMutex here.
398  for (DeviceGlobalMapEntry *DeviceGlobalEntry : DeviceGlobalEntries) {
399  // Get or allocate the USM memory associated with the device global.
400  DeviceGlobalUSMMem &DeviceGlobalUSM =
401  DeviceGlobalEntry->getOrAllocateDeviceGlobalUSM(QueueImpl);
402 
403  // If the device global still has a initialization event it should be
404  // added to the initialization events list. Since initialization events
405  // are cleaned up separately from cleaning up the device global USM memory
406  // this must retain the event.
407  {
408  if (OwnedUrEvent ZIEvent = DeviceGlobalUSM.getInitEvent(Plugin))
409  InitEventsRef.push_back(ZIEvent.TransferOwnership());
410  }
411  // Write the pointer to the device global and store the event in the
412  // initialize events list.
413  ur_event_handle_t InitEvent;
414  void *const &USMPtr = DeviceGlobalUSM.getPtr();
415  Plugin->call(urEnqueueDeviceGlobalVariableWrite,
416  QueueImpl->getHandleRef(), NativePrg,
417  DeviceGlobalEntry->MUniqueId.c_str(), false, sizeof(void *),
418  0, &USMPtr, 0, nullptr, &InitEvent);
419 
420  InitEventsRef.push_back(InitEvent);
421  }
422  return InitEventsRef;
423  }
424 }
425 
426 void context_impl::DeviceGlobalInitializer::ClearEvents(
427  const PluginPtr &Plugin) {
428  for (const ur_event_handle_t &Event : MDeviceGlobalInitEvents)
429  Plugin->call(urEventRelease, Event);
430  MDeviceGlobalInitEvents.clear();
431 }
432 
434  const std::shared_ptr<device_impl> &DeviceImpl, const void *DeviceGlobalPtr,
435  const void *Src, size_t DeviceGlobalTSize, bool IsDeviceImageScoped,
436  size_t NumBytes, size_t Offset) {
437  std::optional<ur_device_handle_t> KeyDevice = std::nullopt;
438  if (IsDeviceImageScoped)
439  KeyDevice = DeviceImpl->getHandleRef();
440  auto Key = std::make_pair(DeviceGlobalPtr, KeyDevice);
441 
442  std::lock_guard<std::mutex> InitLock(MDeviceGlobalUnregisteredDataMutex);
443 
444  auto UnregisteredDataIt = MDeviceGlobalUnregisteredData.find(Key);
445  if (UnregisteredDataIt == MDeviceGlobalUnregisteredData.end()) {
446  std::unique_ptr<std::byte[]> NewData =
447  std::make_unique<std::byte[]>(DeviceGlobalTSize);
448  UnregisteredDataIt =
449  MDeviceGlobalUnregisteredData.insert({Key, std::move(NewData)}).first;
450  }
451  std::byte *ValuePtr = UnregisteredDataIt->second.get();
452  std::memcpy(ValuePtr + Offset, Src, NumBytes);
453 }
454 
456  const std::shared_ptr<device_impl> &DeviceImpl, void *Dest,
457  const void *DeviceGlobalPtr, bool IsDeviceImageScoped, size_t NumBytes,
458  size_t Offset) {
459 
460  std::optional<ur_device_handle_t> KeyDevice = std::nullopt;
461  if (IsDeviceImageScoped)
462  KeyDevice = DeviceImpl->getHandleRef();
463  auto Key = std::make_pair(DeviceGlobalPtr, KeyDevice);
464 
465  std::lock_guard<std::mutex> InitLock(MDeviceGlobalUnregisteredDataMutex);
466 
467  auto UnregisteredDataIt = MDeviceGlobalUnregisteredData.find(Key);
468  if (UnregisteredDataIt == MDeviceGlobalUnregisteredData.end()) {
469  // If there is no entry we do not need to add it as it would just be
470  // zero-initialized.
471  char *FillableDest = reinterpret_cast<char *>(Dest);
472  std::fill(FillableDest, FillableDest + NumBytes, 0);
473  return;
474  }
475  std::byte *ValuePtr = UnregisteredDataIt->second.get();
476  std::memcpy(Dest, ValuePtr + Offset, NumBytes);
477 }
478 
479 std::optional<ur_program_handle_t> context_impl::getProgramForDevImgs(
480  const device &Device, const std::set<std::uintptr_t> &ImgIdentifiers,
481  const std::string &ObjectTypeName) {
482 
484  {
485  auto LockedCache = MKernelProgramCache.acquireCachedPrograms();
486  auto &KeyMap = LockedCache.get().KeyMap;
487  auto &Cache = LockedCache.get().Cache;
488  ur_device_handle_t &DevHandle = getSyclObjImpl(Device)->getHandleRef();
489  for (std::uintptr_t ImageIDs : ImgIdentifiers) {
490  auto OuterKey = std::make_pair(ImageIDs, DevHandle);
491  size_t NProgs = KeyMap.count(OuterKey);
492  if (NProgs == 0)
493  continue;
494  // If the cache has multiple programs for the identifiers or if we have
495  // already found a program in the cache with the device_global or host
496  // pipe we cannot proceed.
497  if (NProgs > 1 || (BuildRes && NProgs == 1))
499  "More than one image exists with the " +
500  ObjectTypeName + ".");
501 
502  auto KeyMappingsIt = KeyMap.find(OuterKey);
503  assert(KeyMappingsIt != KeyMap.end());
504  auto CachedProgIt = Cache.find(KeyMappingsIt->second);
505  assert(CachedProgIt != Cache.end());
506  BuildRes = CachedProgIt->second;
507  }
508  }
509  if (!BuildRes)
510  return std::nullopt;
511  using BuildState = KernelProgramCache::BuildState;
512  BuildState NewState = BuildRes->waitUntilTransition();
513  if (NewState == BuildState::BS_Failed)
514  throw detail::set_ur_error(
515  exception(make_error_code(errc::build), BuildRes->Error.Msg),
516  BuildRes->Error.Code);
517 
518  assert(NewState == BuildState::BS_Done);
519  return BuildRes->Val;
520 }
521 
522 std::optional<ur_program_handle_t> context_impl::getProgramForDeviceGlobal(
523  const device &Device, DeviceGlobalMapEntry *DeviceGlobalEntry) {
524  return getProgramForDevImgs(Device, DeviceGlobalEntry->MImageIdentifiers,
525  "device_global");
526 }
528 std::optional<ur_program_handle_t>
530  HostPipeMapEntry *HostPipeEntry) {
531  // One HostPipe entry belongs to one Img
532  std::set<std::uintptr_t> ImgIdentifiers;
533  ImgIdentifiers.insert(HostPipeEntry->getDevBinImage()->getImageID());
534  return getProgramForDevImgs(Device, ImgIdentifiers, "host_pipe");
535 }
536 
537 } // namespace detail
538 } // namespace _V1
539 } // namespace sycl
std::shared_ptr< ProgramBuildResult > ProgramBuildResultPtr
BuildState
Denotes the state of a build.
void setContextPtr(const ContextPtr &AContext)
static ProgramManager & getInstance()
DeviceGlobalMapEntry * getDeviceGlobalEntry(const void *DeviceGlobalPtr)
std::vector< DeviceGlobalMapEntry * > getDeviceGlobalEntries(const std::vector< std::string > &UniqueIds, bool ExcludeDeviceImageScopeDecorated=false)
bool hasDevice(std::shared_ptr< detail::device_impl > Device) const
Returns true if and only if context contains the given device.
ur_context_handle_t & getHandleRef()
Gets the underlying context object (if any) without reference count modification.
context_impl(const device &Device, async_handler AsyncHandler, const property_list &PropList)
Constructs a context_impl using a single SYCL devices.
std::optional< ur_program_handle_t > getProgramForDevImgs(const device &Device, const std::set< std::uintptr_t > &ImgIdentifiers, const std::string &ObjectTypeName)
Gets a program associated with Dev / Images pairs.
KernelProgramCache & getKernelProgramCache() const
void addDeviceGlobalInitializer(ur_program_handle_t Program, const std::vector< device > &Devs, const RTDeviceBinaryImage *BinImage)
Adds a device global initializer.
void addAssociatedDeviceGlobal(const void *DeviceGlobalPtr)
Adds an associated device global to the tracked associates.
DeviceImplPtr findMatchingDeviceImpl(ur_device_handle_t &DeviceUR) const
Given a UR device, returns the matching shared_ptr<device_impl> within this context.
std::vector< ur_event_handle_t > initializeDeviceGlobals(ur_program_handle_t NativePrg, const std::shared_ptr< queue_impl > &QueueImpl)
Initializes device globals for a program on the associated queue.
void memcpyFromHostOnlyDeviceGlobal(const std::shared_ptr< device_impl > &DeviceImpl, void *Dest, const void *DeviceGlobalPtr, bool IsDeviceImageScoped, size_t NumBytes, size_t Offset)
std::optional< ur_program_handle_t > getProgramForHostPipe(const device &Device, HostPipeMapEntry *HostPipeEntry)
Gets a program associated with a HostPipe Entry from the cache.
void memcpyToHostOnlyDeviceGlobal(const std::shared_ptr< device_impl > &DeviceImpl, const void *DeviceGlobalPtr, const void *Src, size_t DeviceGlobalTSize, bool IsDeviceImageScoped, size_t NumBytes, size_t Offset)
const PluginPtr & getPlugin() const
ur_native_handle_t getNative() const
Gets the native handle of the SYCL context.
cl_context get() const
Gets OpenCL interoperability context handle.
const async_handler & get_async_handler() const
Gets asynchronous exception handler.
std::optional< ur_program_handle_t > getProgramForDeviceGlobal(const device &Device, DeviceGlobalMapEntry *DeviceGlobalEntry)
Gets a program associated with a device global from the cache.
static std::shared_ptr< platform_impl > getPlatformFromUrDevice(ur_device_handle_t UrDevice, const PluginPtr &Plugin)
Queries the cache for the specified platform based on an input device.
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
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:99
Objects of the property_list class are containers for the SYCL properties.
#define __SYCL_REPORT_EXCEPTION_TO_STREAM(str, e)
Definition: common.hpp:367
decltype(Obj::impl) const & getSyclObjImpl(const Obj &SyclObject)
Definition: impl_utils.hpp:31
static const PluginPtr & getPlugin(backend Backend)
Definition: backend.cpp:32
std::function< int(const sycl::device &)> DSelectorInvocableType
device select_device(const DSelectorInvocableType &DeviceSelectorInvocable)
void GetCapabilitiesIntersectionSet(const std::vector< sycl::device > &Devices, std::vector< T > &CapabilityList)
std::shared_ptr< plugin > PluginPtr
Definition: ur.hpp:60
std::shared_ptr< device_impl > DeviceImplPtr
exception set_ur_error(exception &&e, int32_t ur_err)
Definition: exception.hpp:157
void fill(sycl::handler &CGH, T *Ptr, const T &Pattern, size_t Count)
int default_selector_v(const device &dev)
std::function< void(sycl::exception_list)> async_handler
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:65
Definition: access.hpp:18
void removeAssociatedResources(const context_impl *CtxImpl)
OwnedUrEvent getInitEvent(const PluginPtr &Plugin)
C++ utilities for Unified Runtime integration.