DPC++ Runtime
Runtime libraries for oneAPI DPC++
platform_impl.cpp
Go to the documentation of this file.
1 //==----------- platform_impl.cpp ------------------------------------------==//
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/allowlist.hpp>
10 #include <detail/config.hpp>
11 #include <detail/device_impl.hpp>
13 #include <detail/platform_impl.hpp>
14 #include <detail/platform_info.hpp>
16 #include <sycl/detail/util.hpp>
17 #include <sycl/device.hpp>
18 
19 #include <algorithm>
20 #include <cstring>
21 #include <mutex>
22 #include <string>
23 #include <vector>
24 
25 namespace sycl {
27 namespace detail {
28 
29 using PlatformImplPtr = std::shared_ptr<platform_impl>;
30 
31 PlatformImplPtr platform_impl::getHostPlatformImpl() {
32  static PlatformImplPtr HostImpl = std::make_shared<platform_impl>();
33 
34  return HostImpl;
35 }
36 
37 PlatformImplPtr platform_impl::getOrMakePlatformImpl(RT::PiPlatform PiPlatform,
38  const plugin &Plugin) {
39  PlatformImplPtr Result;
40  {
41  const std::lock_guard<std::mutex> Guard(
42  GlobalHandler::instance().getPlatformMapMutex());
43 
44  std::vector<PlatformImplPtr> &PlatformCache =
45  GlobalHandler::instance().getPlatformCache();
46 
47  // If we've already seen this platform, return the impl
48  for (const auto &PlatImpl : PlatformCache) {
49  if (PlatImpl->getHandleRef() == PiPlatform)
50  return PlatImpl;
51  }
52 
53  // Otherwise make the impl
54  Result = std::make_shared<platform_impl>(PiPlatform, Plugin);
55  PlatformCache.emplace_back(Result);
56  }
57 
58  return Result;
59 }
60 
61 PlatformImplPtr platform_impl::getPlatformFromPiDevice(RT::PiDevice PiDevice,
62  const plugin &Plugin) {
63  RT::PiPlatform Plt = nullptr; // TODO catch an exception and put it to list
64  // of asynchronous exceptions
66  sizeof(Plt), &Plt, nullptr);
67  return getOrMakePlatformImpl(Plt, Plugin);
68 }
69 
70 static bool IsBannedPlatform(platform Platform) {
71  // The NVIDIA OpenCL platform is currently not compatible with DPC++
72  // since it is only 1.2 but gets selected by default in many systems
73  // There is also no support on the PTX backend for OpenCL consumption,
74  // and there have been some internal reports.
75  // To avoid problems on default users and deployment of DPC++ on platforms
76  // where CUDA is available, the OpenCL support is disabled.
77  //
78  auto IsNVIDIAOpenCL = [](platform Platform) {
79  if (getSyclObjImpl(Platform)->is_host())
80  return false;
81 
82  const bool HasCUDA = Platform.get_info<info::platform::name>().find(
83  "NVIDIA CUDA") != std::string::npos;
84  const auto Backend =
85  detail::getSyclObjImpl(Platform)->getPlugin().getBackend();
86  const bool IsCUDAOCL = (HasCUDA && Backend == backend::opencl);
88  std::cout << "SYCL_PI_TRACE[all]: "
89  << "NVIDIA CUDA OpenCL platform found but is not compatible."
90  << std::endl;
91  }
92  return IsCUDAOCL;
93  };
94  return IsNVIDIAOpenCL(Platform);
95 }
96 
97 // This routine has the side effect of registering each platform's last device
98 // id into each plugin, which is used for device counting.
99 std::vector<platform> platform_impl::get_platforms() {
100  std::vector<platform> Platforms;
101  std::vector<plugin> &Plugins = RT::initialize();
102  for (plugin &Plugin : Plugins) {
103  pi_uint32 NumPlatforms = 0;
104  // Move to the next plugin if the plugin fails to initialize.
105  // This way platforms from other plugins get a chance to be discovered.
106  if (Plugin.call_nocheck<PiApiKind::piPlatformsGet>(
107  0, nullptr, &NumPlatforms) != PI_SUCCESS)
108  continue;
109 
110  if (NumPlatforms) {
111  std::vector<RT::PiPlatform> PiPlatforms(NumPlatforms);
112  if (Plugin.call_nocheck<PiApiKind::piPlatformsGet>(
113  NumPlatforms, PiPlatforms.data(), nullptr) != PI_SUCCESS)
114  return Platforms;
115 
116  for (const auto &PiPlatform : PiPlatforms) {
117  platform Platform = detail::createSyclObjFromImpl<platform>(
118  getOrMakePlatformImpl(PiPlatform, Plugin));
119  if (IsBannedPlatform(Platform)) {
120  continue; // bail as early as possible, otherwise banned platforms may
121  // mess up device counting
122  }
123 
124  {
125  std::lock_guard<std::mutex> Guard(*Plugin.getPluginMutex());
126  // insert PiPlatform into the Plugin
127  Plugin.getPlatformId(PiPlatform);
128  }
129  if (!Platform.get_devices(info::device_type::all).empty())
130  Platforms.push_back(Platform);
131  }
132  }
133  }
134 
135  // Register default context release handler after plugins have been loaded and
136  // after the first calls to each plugin. This initializes a function-local
137  // variable that should be destroyed before any global variables in the
138  // plugins are destroyed. This is done after the first call to the backends to
139  // ensure any lazy-loaded dependencies are loaded prior to the handler
140  // variable's initialization. Note: The default context release handler is not
141  // guaranteed to be destroyed before function-local static variables as they
142  // may be initialized after.
143  GlobalHandler::registerDefaultContextReleaseHandler();
144 
145  return Platforms;
146 }
147 
148 // Filter out the devices that are not compatible with SYCL_DEVICE_FILTER or
149 // ONEAPI_DEVICE_SELECTOR This function matches devices in the order of backend,
150 // device_type, and device_num. The device_filter and ods_target structs pun for
151 // each other, as do device_filter_list and ods_target_list.
152 // Since ONEAPI_DEVICE_SELECTOR admits negative filters, we use type traits
153 // to distinguish the case where we are working with ONEAPI_DEVICE_SELECTOR
154 // in the places where the functionality diverges between these two
155 // environment variables.
156 // The return value is a vector that represents the indices of the chosen
157 // devices.
158 template <typename ListT, typename FilterT>
159 static std::vector<int> filterDeviceFilter(std::vector<RT::PiDevice> &PiDevices,
160  RT::PiPlatform Platform, ListT *FilterList) {
161 
162  constexpr bool is_ods_target = std::is_same_v<FilterT, ods_target>;
163  // There are some differences in implementation between SYCL_DEVICE_FILTER
164  // and ONEAPI_DEVICE_SELECTOR so we use if constexpr to select the
165  // appropriate execution path if we are dealing with the latter variable.
166 
167  if constexpr (is_ods_target) {
168 
169  // Since we are working with ods_target filters ,which can be negative,
170  // we sort the filters so that all the negative filters appear before
171  // all the positive filters. This enables us to have the full list of
172  // blacklisted devices by the time we get to the positive filters
173  // so that if a positive filter matches a blacklisted device we do
174  // not add it to the list of available devices.
175  std::sort(FilterList->get().begin(), FilterList->get().end(),
176  [](const ods_target &filter1, const ods_target &filter2) {
177  std::ignore = filter1;
178  if (filter2.IsNegativeTarget)
179  return false;
180  return true;
181  });
182  }
183 
184  // this map keeps track of devices discarded by negative filters, it is only
185  // used in the ONEAPI_DEVICE_SELECTOR implemenation. It cannot be placed
186  // in the if statement above because it will then be out of scope in the rest
187  // of the function
188  std::map<int, bool> Blacklist;
189  // original indices keeps track of the device numbers of the chosen
190  // devices and is whats returned by the function
191  std::vector<int> original_indices;
192 
193  std::vector<plugin> &Plugins = RT::initialize();
194  auto It =
195  std::find_if(Plugins.begin(), Plugins.end(), [Platform](plugin &Plugin) {
196  return Plugin.containsPiPlatform(Platform);
197  });
198  if (It == Plugins.end()) {
199  return original_indices;
200  }
201  plugin &Plugin = *It;
202  backend Backend = Plugin.getBackend();
203  int InsertIDx = 0;
204  // DeviceIds should be given consecutive numbers across platforms in the same
205  // backend
206  std::lock_guard<std::mutex> Guard(*Plugin.getPluginMutex());
207  int DeviceNum = Plugin.getStartingDeviceId(Platform);
208  for (RT::PiDevice Device : PiDevices) {
209  RT::PiDeviceType PiDevType;
211  sizeof(RT::PiDeviceType),
212  &PiDevType, nullptr);
213  // Assumption here is that there is 1-to-1 mapping between PiDevType and
214  // Sycl device type for GPU, CPU, and ACC.
215  info::device_type DeviceType = pi::cast<info::device_type>(PiDevType);
216 
217  for (const FilterT &Filter : FilterList->get()) {
218  backend FilterBackend = Filter.Backend.value_or(backend::all);
219  // First, match the backend entry
220  if (FilterBackend == Backend || FilterBackend == backend::all) {
221  info::device_type FilterDevType =
222  Filter.DeviceType.value_or(info::device_type::all);
223  // Next, match the device_type entry
224  if (FilterDevType == info::device_type::all) {
225  // Last, match the device_num entry
226  if (!Filter.DeviceNum || DeviceNum == Filter.DeviceNum.value()) {
227  if constexpr (is_ods_target) { // dealing with ODS filters
228  if (!Blacklist[DeviceNum]) { // ensure it is not blacklisted
229  if (!Filter.IsNegativeTarget) { // is filter positive?
230  PiDevices[InsertIDx++] = Device;
231  original_indices.push_back(DeviceNum);
232  } else {
233  // Filter is negative and the device matches the filter so
234  // blacklist the device.
235  Blacklist[DeviceNum] = true;
236  }
237  }
238  } else { // dealing with SYCL_DEVICE_FILTER
239  PiDevices[InsertIDx++] = Device;
240  original_indices.push_back(DeviceNum);
241  }
242  break;
243  }
244 
245  } else if (FilterDevType == DeviceType) {
246  if (!Filter.DeviceNum || DeviceNum == Filter.DeviceNum.value()) {
247  if constexpr (is_ods_target) {
248  if (!Blacklist[DeviceNum]) {
249  if (!Filter.IsNegativeTarget) {
250  PiDevices[InsertIDx++] = Device;
251  original_indices.push_back(DeviceNum);
252  } else {
253  // Filter is negative and the device matches the filter so
254  // blacklist the device.
255  Blacklist[DeviceNum] = true;
256  }
257  }
258  } else {
259  PiDevices[InsertIDx++] = Device;
260  original_indices.push_back(DeviceNum);
261  }
262  break;
263  }
264  }
265  }
266  }
267  DeviceNum++;
268  }
269  PiDevices.resize(InsertIDx);
270  // remember the last backend that has gone through this filter function
271  // to assign a unique device id number across platforms that belong to
272  // the same backend. For example, opencl:cpu:0, opencl:acc:1, opencl:gpu:2
273  Plugin.setLastDeviceId(Platform, DeviceNum);
274  return original_indices;
275 }
276 
277 std::shared_ptr<device_impl>
278 platform_impl::getDeviceImpl(RT::PiDevice PiDevice) {
279  const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
280  return getDeviceImplHelper(PiDevice);
281 }
282 
283 std::shared_ptr<device_impl> platform_impl::getOrMakeDeviceImpl(
284  RT::PiDevice PiDevice, const std::shared_ptr<platform_impl> &PlatformImpl) {
285  const std::lock_guard<std::mutex> Guard(MDeviceMapMutex);
286  // If we've already seen this device, return the impl
287  std::shared_ptr<device_impl> Result = getDeviceImplHelper(PiDevice);
288  if (Result)
289  return Result;
290 
291  // Otherwise make the impl
292  Result = std::make_shared<device_impl>(PiDevice, PlatformImpl);
293  MDeviceCache.emplace_back(Result);
294 
295  return Result;
296 }
297 
298 static bool supportsAffinityDomain(const device &dev,
299  info::partition_property partitionProp,
301  if (partitionProp != info::partition_property::partition_by_affinity_domain) {
302  return true;
303  }
304  auto supported = dev.get_info<info::device::partition_affinity_domains>();
305  auto It = std::find(std::begin(supported), std::end(supported), domain);
306  return It != std::end(supported);
307 }
308 
309 static bool supportsPartitionProperty(const device &dev,
310  info::partition_property partitionProp) {
311  auto supported = dev.get_info<info::device::partition_properties>();
312  auto It =
313  std::find(std::begin(supported), std::end(supported), partitionProp);
314  return It != std::end(supported);
315 }
316 
317 static std::vector<device> amendDeviceAndSubDevices(
318  backend PlatformBackend, std::vector<device> &DeviceList,
319  ods_target_list *OdsTargetList, const std::vector<int>& original_indices,
320  PlatformImplPtr PlatformImpl) {
321  constexpr info::partition_property partitionProperty =
322  info::partition_property::partition_by_affinity_domain;
323  constexpr info::partition_affinity_domain affinityDomain =
324  info::partition_affinity_domain::next_partitionable;
325 
326  std::vector<device> FinalResult;
327  // (Only) when amending sub-devices for ONEAPI_DEVICE_SELECTOR, all
328  // sub-devices are treated as root.
329  TempAssignGuard<bool> TAG(PlatformImpl->MAlwaysRootDevice, true);
330 
331  for (unsigned i = 0; i < DeviceList.size(); i++) {
332  // device has already been screened. The question is whether it should be a
333  // top level device and/or is expected to add its sub-devices to the list.
334  device &dev = DeviceList[i];
335  bool deviceAdded = false;
336  for (ods_target target : OdsTargetList->get()) {
337  backend TargetBackend = target.Backend.value_or(backend::all);
338  if (PlatformBackend == TargetBackend || TargetBackend == backend::all) {
339  bool deviceMatch = target.HasDeviceWildCard; // opencl:*
340  if (target.DeviceType) { // opencl:gpu
341  deviceMatch = ((target.DeviceType == info::device_type::all) ||
343  target.DeviceType));
344 
345  } else if (target.DeviceNum) { // opencl:0
346  deviceMatch =
347  (target.DeviceNum.value() == original_indices[i]);
348  }
349 
350  if (deviceMatch) {
351  // Top level matches. Do we add it, or subdevices, or sub-sub-devices?
352  bool wantSubDevice =
353  target.SubDeviceNum || target.HasSubDeviceWildCard;
354  bool supportsSubPartitioning =
355  (supportsPartitionProperty(dev, partitionProperty) &&
356  supportsAffinityDomain(dev, partitionProperty, affinityDomain));
357  bool wantSubSubDevice =
358  target.SubSubDeviceNum || target.HasSubSubDeviceWildCard;
359 
360  // -- Add top level device.
361  if (!wantSubDevice) {
362  if (!deviceAdded) {
363  FinalResult.push_back(dev);
364  deviceAdded = true;
365  }
366  } else {
367  if (!supportsSubPartitioning) {
368  if (target.DeviceNum ||
369  (target.DeviceType &&
370  (target.DeviceType.value() != info::device_type::all))) {
371  // This device was specifically requested and yet is not
372  // partitionable.
373  std::cout << "device is not partitionable: " << target
374  << std::endl;
375  }
376  continue;
377  }
378  // -- Add sub sub device.
379  if (wantSubSubDevice) {
380 
381  auto subDevicesToPartition =
382  dev.create_sub_devices<partitionProperty>(affinityDomain);
383  if (target.SubDeviceNum) {
384  if (subDevicesToPartition.size() >
385  target.SubDeviceNum.value()) {
386  subDevicesToPartition[0] =
387  subDevicesToPartition[target.SubDeviceNum.value()];
388  subDevicesToPartition.resize(1);
389  } else {
390  std::cout << "subdevice index out of bounds: " << target
391  << std::endl;
392  continue;
393  }
394  }
395  for (device subDev : subDevicesToPartition) {
396  bool supportsSubSubPartitioning =
397  (supportsPartitionProperty(subDev, partitionProperty) &&
398  supportsAffinityDomain(subDev, partitionProperty,
399  affinityDomain));
400  if (!supportsSubSubPartitioning) {
401  if (target.SubDeviceNum) {
402  // Parent subdevice was specifically requested, yet is not
403  // partitionable.
404  std::cout << "sub-device is not partitionable: " << target
405  << std::endl;
406  }
407  continue;
408  }
409  // Allright, lets get them sub-sub-devices.
410  auto subSubDevices =
411  subDev.create_sub_devices<partitionProperty>(
412  affinityDomain);
413  if (target.HasSubSubDeviceWildCard) {
414  FinalResult.insert(FinalResult.end(), subSubDevices.begin(),
415  subSubDevices.end());
416  } else {
417  if (subSubDevices.size() > target.SubSubDeviceNum.value()) {
418  FinalResult.push_back(
419  subSubDevices[target.SubSubDeviceNum.value()]);
420  } else {
421  std::cout
422  << "sub-sub-device index out of bounds: " << target
423  << std::endl;
424  }
425  }
426  }
427  } else if (wantSubDevice) {
428  auto subDevices = dev.create_sub_devices<
429  info::partition_property::partition_by_affinity_domain>(
430  affinityDomain);
431  if (target.HasSubDeviceWildCard) {
432  FinalResult.insert(FinalResult.end(), subDevices.begin(),
433  subDevices.end());
434  } else {
435  if (subDevices.size() > target.SubDeviceNum.value()) {
436  FinalResult.push_back(
437  subDevices[target.SubDeviceNum.value()]);
438  } else {
439  std::cout << "subdevice index out of bounds: " << target
440  << std::endl;
441  }
442  }
443  }
444  }
445  } // /if deviceMatch
446  }
447  } // /for
448  } // /for
449  return FinalResult;
450 }
451 
452 std::vector<device>
453 platform_impl::get_devices(info::device_type DeviceType) const {
454  std::vector<device> Res;
455  // Will we be filtering with SYCL_DEVICE_FILTER or ONEAPI_DEVICE_SELECTOR ?
456  // We do NOT attempt to support both simultaneously.
459 
460  if (is_host() && (DeviceType == info::device_type::host ||
461  DeviceType == info::device_type::all)) {
462  Res.push_back(
463  createSyclObjFromImpl<device>(device_impl::getHostDeviceImpl()));
464  }
465 
466  // If any DeviceType other than host was requested for host platform,
467  // an empty vector will be returned.
468  if (is_host() || DeviceType == info::device_type::host)
469  return Res;
470 
471  pi_uint32 NumDevices = 0;
472  const detail::plugin &Plugin = getPlugin();
474  MPlatform, pi::cast<RT::PiDeviceType>(DeviceType),
475  0, // CP info::device_type::all
476  pi::cast<RT::PiDevice *>(nullptr), &NumDevices);
477  const backend Backend = Plugin.getBackend();
478 
479  if (NumDevices == 0) {
480  // If platform doesn't have devices (even without filter)
481  // LastDeviceIds[PlatformId] stay 0 that affects next platform devices num
482  // analysis. Doing adjustment by simple copy of last device num from
483  // previous platform.
484  // Needs non const plugin reference.
485  std::vector<plugin> &Plugins = RT::initialize();
486  auto It = std::find_if(Plugins.begin(), Plugins.end(),
487  [&Platform = MPlatform](plugin &Plugin) {
488  return Plugin.containsPiPlatform(Platform);
489  });
490  if (It != Plugins.end()) {
491  std::lock_guard<std::mutex> Guard(*(It->getPluginMutex()));
492  (*It).adjustLastDeviceId(MPlatform);
493  }
494  return Res;
495  }
496 
497  std::vector<RT::PiDevice> PiDevices(NumDevices);
498  // TODO catch an exception and put it to list of asynchronous exceptions
500  MPlatform,
501  pi::cast<RT::PiDeviceType>(DeviceType), // CP info::device_type::all
502  NumDevices, PiDevices.data(), nullptr);
503 
504  // Filter out devices that are not present in the SYCL_DEVICE_ALLOWLIST
506  applyAllowList(PiDevices, MPlatform, Plugin);
507 
508  // The first step is to filter out devices that are not compatible with
509  // SYCL_DEVICE_FILTER or ONEAPI_DEVICE_SELECTOR. This is also the mechanism by
510  // which top level device ids are assigned.
511  std::vector<int> PlatformDeviceIndices;
512  if (OdsTargetList) {
513  if (FilterList) {
514  throw sycl::exception(sycl::make_error_code(errc::invalid),
515  "ONEAPI_DEVICE_SELECTOR cannot be used in "
516  "conjunction with SYCL_DEVICE_FILTER");
517  }
518  PlatformDeviceIndices = filterDeviceFilter<ods_target_list, ods_target>(
519  PiDevices, MPlatform, OdsTargetList);
520  } else if (FilterList) {
521  PlatformDeviceIndices = filterDeviceFilter<device_filter_list, device_filter>(
522  PiDevices, MPlatform, FilterList);
523  }
524 
525  // The next step is to inflate the filtered PIDevices into SYCL Device
526  // objects.
527  PlatformImplPtr PlatformImpl = getOrMakePlatformImpl(MPlatform, Plugin);
528  std::transform(
529  PiDevices.begin(), PiDevices.end(), std::back_inserter(Res),
530  [PlatformImpl](const RT::PiDevice &PiDevice) -> device {
531  return detail::createSyclObjFromImpl<device>(
532  PlatformImpl->getOrMakeDeviceImpl(PiDevice, PlatformImpl));
533  });
534 
535  // If we aren't using ONEAPI_DEVICE_SELECTOR, then we are done.
536  // and if there are no devices so far, there won't be any need to replace them
537  // with subdevices.
538  if (!OdsTargetList || Res.size() == 0)
539  return Res;
540 
541  // Otherwise, our last step is to revisit the devices, possibly replacing
542  // them with subdevices (which have been ignored until now)
543  return amendDeviceAndSubDevices(Backend, Res, OdsTargetList,
544  PlatformDeviceIndices, PlatformImpl);
545 }
546 
547 bool platform_impl::has_extension(const std::string &ExtensionName) const {
548  if (is_host())
549  return false;
550 
551  std::string AllExtensionNames = get_platform_info_string_impl(
552  MPlatform, getPlugin(),
554  return (AllExtensionNames.find(ExtensionName) != std::string::npos);
555 }
556 
557 pi_native_handle platform_impl::getNative() const {
558  const auto &Plugin = getPlugin();
559  pi_native_handle Handle;
560  Plugin.call<PiApiKind::piextPlatformGetNativeHandle>(getHandleRef(), &Handle);
561  return Handle;
562 }
563 
564 template <typename Param>
565 typename Param::return_type platform_impl::get_info() const {
566  if (is_host())
567  return get_platform_info_host<Param>();
568 
569  return get_platform_info<Param>(this->getHandleRef(), getPlugin());
570 }
571 
572 // All devices on the platform must have the given aspect.
573 bool platform_impl::has(aspect Aspect) const {
574  for (const auto &dev : get_devices()) {
575  if (dev.has(Aspect) == false) {
576  return false;
577  }
578  }
579  return true;
580 }
581 
582 std::shared_ptr<device_impl>
583 platform_impl::getDeviceImplHelper(RT::PiDevice PiDevice) {
584  for (const std::weak_ptr<device_impl> &DeviceWP : MDeviceCache) {
585  if (std::shared_ptr<device_impl> Device = DeviceWP.lock()) {
586  if (Device->getHandleRef() == PiDevice)
587  return Device;
588  }
589  }
590  return nullptr;
591 }
592 
593 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
594  template ReturnT platform_impl::get_info<info::platform::Desc>() const;
595 
596 #include <sycl/info/platform_traits.def>
597 #undef __SYCL_PARAM_TRAITS_SPEC
598 
599 } // namespace detail
600 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
601 } // namespace sycl
std::vector< ods_target > & get()
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
void call(ArgsT... Args) const
Calls the API, traces the call, checks the result.
Definition: plugin.hpp:217
int getStartingDeviceId(RT::PiPlatform Platform)
Definition: plugin.hpp:252
void setLastDeviceId(RT::PiPlatform Platform, int Id)
Definition: plugin.hpp:261
backend getBackend(void) const
Definition: plugin.hpp:229
std::shared_ptr< std::mutex > getPluginMutex()
Definition: plugin.hpp:281
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:47
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:126
std::vector< device > create_sub_devices(size_t ComputeUnits) const
Partition device into sub devices.
Definition: device.cpp:92
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:45
std::vector< device > get_devices(info::device_type DeviceType=info::device_type::all) const
Returns all SYCL devices associated with this platform.
Definition: platform.cpp:49
detail::is_platform_info_desc< Param >::return_type get_info() const
Queries this SYCL platform for info.
Definition: platform.cpp:61
#define __SYCL_INLINE_VER_NAMESPACE(X)
__SYCL_EXTERN_STREAM_ATTRS ostream cout
Linked to standard output.
constexpr tuple_element< I, tuple< Types... > >::type & get(sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
::pi_device PiDevice
Definition: pi.hpp:110
::pi_platform PiPlatform
Definition: pi.hpp:109
::pi_device_type PiDeviceType
Definition: pi.hpp:111
bool trace(TraceLevel level)
Definition: pi.cpp:394
const plugin & getPlugin()
Definition: pi.cpp:509
std::vector< plugin > & initialize()
Definition: pi.cpp:400
void applyAllowList(std::vector< RT::PiDevice > &PiDevices, RT::PiPlatform PiPlatform, const plugin &Plugin)
Definition: allowlist.cpp:336
static std::vector< device > amendDeviceAndSubDevices(backend PlatformBackend, std::vector< device > &DeviceList, ods_target_list *OdsTargetList, const std::vector< int > &original_indices, PlatformImplPtr PlatformImpl)
static bool supportsPartitionProperty(const device &dev, info::partition_property partitionProp)
static std::vector< int > filterDeviceFilter(std::vector< RT::PiDevice > &PiDevices, RT::PiPlatform Platform, ListT *FilterList)
decltype(Obj::impl) getSyclObjImpl(const Obj &SyclObject)
Definition: common.hpp:240
std::string get_platform_info_string_impl(RT::PiPlatform Plt, const plugin &Plugin, pi_platform_info PiCode)
std::shared_ptr< detail::platform_impl > PlatformImplPtr
static bool supportsAffinityDomain(const device &dev, info::partition_property partitionProp, info::partition_affinity_domain domain)
static bool IsBannedPlatform(platform Platform)
bool has_extension(const sycl::platform &SyclPlatform, const std::string &Extension)
Definition: opencl.cpp:54
detail::enable_if_t< detail::is_sigeninteger< T >::value, detail::anyall_ret_t > all(T x) __NOEXC
Definition: builtins.hpp:1243
std::error_code make_error_code(sycl::errc E) noexcept
Constructs an error code using e and sycl_category()
Definition: exception.cpp:91
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
uintptr_t pi_native_handle
Definition: pi.h:107
@ PI_DEVICE_INFO_PLATFORM
Definition: pi.h:243
@ PI_DEVICE_INFO_TYPE
Definition: pi.h:184
pi_result piextPlatformGetNativeHandle(pi_platform platform, pi_native_handle *nativeHandle)
Gets the native handle of a PI platform object.
pi_result piDeviceGetInfo(pi_device device, pi_device_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret)
Returns requested info for provided native device Return PI_DEVICE_INFO_EXTENSION_DEVICELIB_ASSERT fo...
pi_result piPlatformsGet(pi_uint32 num_entries, pi_platform *platforms, pi_uint32 *num_platforms)
pi_result piDevicesGet(pi_platform platform, pi_device_type device_type, pi_uint32 num_entries, pi_device *devices, pi_uint32 *num_devices)
uint32_t pi_uint32
Definition: pi.h:103
@ Device