DPC++ Runtime
Runtime libraries for oneAPI DPC++
device_info.hpp
Go to the documentation of this file.
1 //==-------- device_info.hpp - SYCL device info methods --------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #pragma once
10 #include <detail/device_impl.hpp>
11 #include <detail/platform_impl.hpp>
12 #include <detail/platform_util.hpp>
13 #include <detail/plugin.hpp>
16 #include <sycl/detail/defines.hpp>
17 #include <sycl/detail/os_util.hpp>
18 #include <sycl/detail/pi.hpp>
19 #include <sycl/device.hpp>
20 #include <sycl/info/info_desc.hpp>
21 #include <sycl/memory_enums.hpp>
22 #include <sycl/platform.hpp>
23 
24 #include <chrono>
25 #include <thread>
26 
27 namespace sycl {
29 namespace detail {
30 
31 inline std::vector<info::fp_config> read_fp_bitfield(pi_device_fp_config bits) {
32  std::vector<info::fp_config> result;
33  if (bits & PI_FP_DENORM)
34  result.push_back(info::fp_config::denorm);
35  if (bits & PI_FP_INF_NAN)
36  result.push_back(info::fp_config::inf_nan);
37  if (bits & PI_FP_ROUND_TO_NEAREST)
38  result.push_back(info::fp_config::round_to_nearest);
39  if (bits & PI_FP_ROUND_TO_ZERO)
40  result.push_back(info::fp_config::round_to_zero);
41  if (bits & PI_FP_ROUND_TO_INF)
42  result.push_back(info::fp_config::round_to_inf);
43  if (bits & PI_FP_FMA)
44  result.push_back(info::fp_config::fma);
45  if (bits & PI_FP_SOFT_FLOAT)
46  result.push_back(info::fp_config::soft_float);
48  result.push_back(info::fp_config::correctly_rounded_divide_sqrt);
49  return result;
50 }
51 
52 inline std::vector<info::partition_affinity_domain>
54  std::vector<info::partition_affinity_domain> result;
56  result.push_back(info::partition_affinity_domain::numa);
58  result.push_back(info::partition_affinity_domain::L4_cache);
60  result.push_back(info::partition_affinity_domain::L3_cache);
62  result.push_back(info::partition_affinity_domain::L2_cache);
64  result.push_back(info::partition_affinity_domain::L1_cache);
66  result.push_back(info::partition_affinity_domain::next_partitionable);
67  return result;
68 }
69 
70 inline std::vector<info::execution_capability>
72  std::vector<info::execution_capability> result;
73  if (bits & PI_EXEC_KERNEL)
74  result.push_back(info::execution_capability::exec_kernel);
75  if (bits & PI_EXEC_NATIVE_KERNEL)
76  result.push_back(info::execution_capability::exec_native_kernel);
77  return result;
78 }
79 
80 inline std::string
82  switch (AffinityDomain) {
83 #define __SYCL_AFFINITY_DOMAIN_STRING_CASE(DOMAIN) \
84  case DOMAIN: \
85  return #DOMAIN;
86 
88  sycl::info::partition_affinity_domain::numa)
90  sycl::info::partition_affinity_domain::L4_cache)
92  sycl::info::partition_affinity_domain::L3_cache)
94  sycl::info::partition_affinity_domain::L2_cache)
96  sycl::info::partition_affinity_domain::L1_cache)
98  sycl::info::partition_affinity_domain::next_partitionable)
99 #undef __SYCL_AFFINITY_DOMAIN_STRING_CASE
100  default:
101  assert(false && "Missing case for affinity domain.");
102  return "unknown";
103  }
104 }
105 
106 // Mapping expected SYCL return types to those returned by PI calls
107 template <typename T> struct sycl_to_pi {
108  using type = T;
109 };
110 template <> struct sycl_to_pi<bool> {
111  using type = pi_bool;
112 };
113 template <> struct sycl_to_pi<device> {
115 };
116 template <> struct sycl_to_pi<platform> {
118 };
119 
120 // Mapping fp_config device info types to the values used to check fp support
121 template <typename Param> struct check_fp_support {};
122 
123 template <> struct check_fp_support<info::device::half_fp_config> {
124  using type = info::device::native_vector_width_half;
125 };
126 
127 template <> struct check_fp_support<info::device::double_fp_config> {
128  using type = info::device::native_vector_width_double;
129 };
130 
131 // Structs for emulating function template partial specialization
132 // Default template for the general case
133 // TODO: get rid of remaining uses of OpenCL directly
134 //
135 template <typename ReturnT, typename Param> struct get_device_info_impl {
136  static ReturnT get(RT::PiDevice dev, const plugin &Plugin) {
137  typename sycl_to_pi<ReturnT>::type result;
139  sizeof(result), &result, nullptr);
140  return ReturnT(result);
141  }
142 };
143 
144 // Specialization for platform
145 template <typename Param> struct get_device_info_impl<platform, Param> {
146  static platform get(RT::PiDevice dev, const plugin &Plugin) {
147  typename sycl_to_pi<platform>::type result;
149  sizeof(result), &result, nullptr);
150  // TODO: Change PiDevice to device_impl.
151  // Use the Plugin from the device_impl class after plugin details
152  // are added to the class.
153  return createSyclObjFromImpl<platform>(
154  platform_impl::getOrMakePlatformImpl(result, Plugin));
155  }
156 };
157 
158 // Helper function to allow using the specialization of get_device_info_impl
159 // for string return type in other specializations.
160 inline std::string get_device_info_string(RT::PiDevice dev,
161  RT::PiDeviceInfo InfoCode,
162  const plugin &Plugin) {
163  size_t resultSize = 0;
164  Plugin.call<PiApiKind::piDeviceGetInfo>(dev, InfoCode, 0, nullptr,
165  &resultSize);
166  if (resultSize == 0) {
167  return std::string();
168  }
169  std::unique_ptr<char[]> result(new char[resultSize]);
170  Plugin.call<PiApiKind::piDeviceGetInfo>(dev, InfoCode, resultSize,
171  result.get(), nullptr);
172 
173  return std::string(result.get());
174 }
175 
176 // Specialization for string return type, variable return size
177 template <typename Param> struct get_device_info_impl<std::string, Param> {
178  static std::string get(RT::PiDevice dev, const plugin &Plugin) {
180  }
181 };
182 
183 // Specialization for parent device
184 template <typename ReturnT>
185 struct get_device_info_impl<ReturnT, info::device::parent_device> {
186  static ReturnT get(RT::PiDevice dev, const plugin &Plugin);
187 };
188 
189 // Specialization for fp_config types, checks the corresponding fp type support
190 template <typename Param>
191 struct get_device_info_impl<std::vector<info::fp_config>, Param> {
192  static std::vector<info::fp_config> get(RT::PiDevice dev,
193  const plugin &Plugin) {
194  // Check if fp type is supported
197  typename check_fp_support<Param>::type>::get(dev, Plugin)) {
198  return {};
199  }
200  cl_device_fp_config result;
202  sizeof(result), &result, nullptr);
203  return read_fp_bitfield(result);
204  }
205 };
206 
207 // Specialization for OpenCL version, splits the string returned by OpenCL
208 template <> struct get_device_info_impl<std::string, info::device::version> {
209  static std::string get(RT::PiDevice dev, const plugin &Plugin) {
210  std::string result = get_device_info_string(
212 
213  // Extract OpenCL version from the returned string.
214  // For example, for the string "OpenCL 2.1 (Build 0)"
215  // return '2.1'.
216  auto dotPos = result.find('.');
217  if (dotPos == std::string::npos)
218  return result;
219 
220  auto leftPos = result.rfind(' ', dotPos);
221  if (leftPos == std::string::npos)
222  leftPos = 0;
223  else
224  leftPos++;
225 
226  auto rightPos = result.find(' ', dotPos);
227  return result.substr(leftPos, rightPos - leftPos);
228  }
229 };
230 
231 // Specialization for single_fp_config, no type support check required
232 template <>
233 struct get_device_info_impl<std::vector<info::fp_config>,
234  info::device::single_fp_config> {
235  static std::vector<info::fp_config> get(RT::PiDevice dev,
236  const plugin &Plugin) {
237  pi_device_fp_config result;
240  &result, nullptr);
241  return read_fp_bitfield(result);
242  }
243 };
244 
245 // Specialization for queue_profiling, OpenCL returns a bitfield
246 template <> struct get_device_info_impl<bool, info::device::queue_profiling> {
247  static bool get(RT::PiDevice dev, const plugin &Plugin) {
248  cl_command_queue_properties result;
251  &result, nullptr);
252  return (result & CL_QUEUE_PROFILING_ENABLE);
253  }
254 };
255 
256 // Specialization for atomic_memory_order_capabilities, PI returns a bitfield
257 template <>
258 struct get_device_info_impl<std::vector<memory_order>,
259  info::device::atomic_memory_order_capabilities> {
260  static std::vector<memory_order> get(RT::PiDevice dev, const plugin &Plugin) {
264  sizeof(pi_memory_order_capabilities), &result, nullptr);
265  return readMemoryOrderBitfield(result);
266  }
267 };
268 
269 // Specialization for atomic_memory_scope_capabilities, PI returns a bitfield
270 template <>
271 struct get_device_info_impl<std::vector<memory_scope>,
272  info::device::atomic_memory_scope_capabilities> {
273  static std::vector<memory_scope> get(RT::PiDevice dev, const plugin &Plugin) {
277  sizeof(pi_memory_scope_capabilities), &result, nullptr);
278  return readMemoryScopeBitfield(result);
279  }
280 };
281 
282 // Specialization for bf16 math functions
283 template <>
285  info::device::ext_oneapi_bfloat16_math_functions> {
286  static bool get(RT::PiDevice dev, const plugin &Plugin) {
287  bool result = false;
288 
290  dev,
292  sizeof(result), &result, nullptr);
293  if (Err != PI_SUCCESS) {
294  return false;
295  }
296  return result;
297  }
298 };
299 
300 // Specialization for exec_capabilities, OpenCL returns a bitfield
301 template <>
302 struct get_device_info_impl<std::vector<info::execution_capability>,
303  info::device::execution_capabilities> {
304  static std::vector<info::execution_capability> get(RT::PiDevice dev,
305  const plugin &Plugin) {
309  sizeof(result), &result, nullptr);
310  return read_execution_bitfield(result);
311  }
312 };
313 
314 // Specialization for built in kernel identifiers
315 template <>
316 struct get_device_info_impl<std::vector<kernel_id>,
317  info::device::built_in_kernel_ids> {
318  static std::vector<kernel_id> get(RT::PiDevice dev, const plugin &Plugin) {
319  std::string result = get_device_info_string(
321  auto names = split_string(result, ';');
322 
323  std::vector<kernel_id> ids;
324  ids.reserve(names.size());
325  for (const auto &name : names) {
326  ids.push_back(ProgramManager::getInstance().getBuiltInKernelID(name));
327  }
328  return ids;
329  }
330 };
331 
332 // Specialization for built in kernels, splits the string returned by OpenCL
333 template <>
334 struct get_device_info_impl<std::vector<std::string>,
335  info::device::built_in_kernels> {
336  static std::vector<std::string> get(RT::PiDevice dev, const plugin &Plugin) {
337  std::string result = get_device_info_string(
339  return split_string(result, ';');
340  }
341 };
342 
343 // Specialization for extensions, splits the string returned by OpenCL
344 template <>
345 struct get_device_info_impl<std::vector<std::string>,
346  info::device::extensions> {
347  static std::vector<std::string> get(RT::PiDevice dev, const plugin &Plugin) {
348  std::string result =
350  dev, Plugin);
351  return split_string(result, ' ');
352  }
353 };
354 
356  switch (PP) {
357  case info::partition_property::no_partition:
358  case info::partition_property::partition_equally:
359  case info::partition_property::partition_by_counts:
360  case info::partition_property::partition_by_affinity_domain:
361  return true;
362  }
363  return false;
364 }
365 
366 // Specialization for partition properties, variable OpenCL return size
367 template <>
368 struct get_device_info_impl<std::vector<info::partition_property>,
369  info::device::partition_properties> {
370  static std::vector<info::partition_property> get(RT::PiDevice dev,
371  const plugin &Plugin) {
373 
374  size_t resultSize;
375  Plugin.call<PiApiKind::piDeviceGetInfo>(dev, info_partition, 0, nullptr,
376  &resultSize);
377 
378  size_t arrayLength = resultSize / sizeof(cl_device_partition_property);
379  if (arrayLength == 0) {
380  return {};
381  }
382  std::unique_ptr<cl_device_partition_property[]> arrayResult(
383  new cl_device_partition_property[arrayLength]);
384  Plugin.call<PiApiKind::piDeviceGetInfo>(dev, info_partition, resultSize,
385  arrayResult.get(), nullptr);
386 
387  std::vector<info::partition_property> result;
388  for (size_t i = 0; i < arrayLength; ++i) {
389  // OpenCL extensions may have partition_properties that
390  // are not yet defined for SYCL (eg. CL_DEVICE_PARTITION_BY_NAMES_INTEL)
392  static_cast<info::partition_property>(arrayResult[i]));
394  result.push_back(pp);
395  }
396  return result;
397  }
398 };
399 
400 // Specialization for partition affinity domains, OpenCL returns a bitfield
401 template <>
402 struct get_device_info_impl<std::vector<info::partition_affinity_domain>,
403  info::device::partition_affinity_domains> {
404  static std::vector<info::partition_affinity_domain>
405  get(RT::PiDevice dev, const plugin &Plugin) {
409  sizeof(result), &result, nullptr);
410  return read_domain_bitfield(result);
411  }
412 };
413 
414 // Specialization for partition type affinity domain, OpenCL can return other
415 // partition properties instead
416 template <>
418  info::device::partition_type_affinity_domain> {
420  const plugin &Plugin) {
421  size_t resultSize;
424  nullptr, &resultSize);
425  if (resultSize != 1) {
426  return info::partition_affinity_domain::not_applicable;
427  }
428  cl_device_partition_property result;
431  sizeof(result), &result, nullptr);
432  if (result == PI_DEVICE_AFFINITY_DOMAIN_NUMA ||
437  return info::partition_affinity_domain(result);
438  }
439 
440  return info::partition_affinity_domain::not_applicable;
441  }
442 };
443 
444 // Specialization for partition type
445 template <>
447  info::device::partition_type_property> {
448  static info::partition_property get(RT::PiDevice dev, const plugin &Plugin) {
449  size_t resultSize;
451  0, nullptr, &resultSize);
452  if (!resultSize)
453  return info::partition_property::no_partition;
454 
455  size_t arrayLength = resultSize / sizeof(cl_device_partition_property);
456 
457  std::unique_ptr<cl_device_partition_property[]> arrayResult(
458  new cl_device_partition_property[arrayLength]);
460  resultSize, arrayResult.get(),
461  nullptr);
462  if (!arrayResult[0])
463  return info::partition_property::no_partition;
464  return info::partition_property(arrayResult[0]);
465  }
466 };
467 // Specialization for supported subgroup sizes
468 template <>
469 struct get_device_info_impl<std::vector<size_t>,
470  info::device::sub_group_sizes> {
471  static std::vector<size_t> get(RT::PiDevice dev, const plugin &Plugin) {
472  size_t resultSize = 0;
475  &resultSize);
476 
477  std::vector<size_t> result(resultSize / sizeof(size_t));
480  result.data(), nullptr);
481  return result;
482  }
483 };
484 
485 // Specialization for kernel to kernel pipes.
486 // Here we step away from OpenCL, since there is no appropriate cl_device_info
487 // enum for global pipes feature.
488 template <>
489 struct get_device_info_impl<bool, info::device::kernel_kernel_pipe_support> {
490  static bool get(RT::PiDevice dev, const plugin &Plugin) {
491  // We claim, that all Intel FPGA devices support kernel to kernel pipe
492  // feature (at least at the scope of SYCL_INTEL_data_flow_pipes extension).
494  dev, Plugin);
495  std::string platform_name = plt.get_info<info::platform::name>();
496  if (platform_name == "Intel(R) FPGA Emulation Platform for OpenCL(TM)" ||
497  platform_name == "Intel(R) FPGA SDK for OpenCL(TM)")
498  return true;
499 
500  // TODO: a better way is to query for supported SPIR-V capabilities when
501  // it's started to be possible. Also, if a device's backend supports
502  // SPIR-V 1.1 (where Pipe Storage feature was defined), than it supports
503  // the feature as well.
504  return false;
505  }
506 };
507 
508 template <int Dimensions> id<Dimensions> construct_id(size_t *values) = delete;
509 // Due to the flipping of work group dimensions before kernel launch, the values
510 // should also be reversed.
511 template <> inline id<1> construct_id<1>(size_t *values) { return {values[0]}; }
512 template <> inline id<2> construct_id<2>(size_t *values) {
513  return {values[1], values[0]};
514 }
515 template <> inline id<3> construct_id<3>(size_t *values) {
516  return {values[2], values[1], values[0]};
517 }
518 
519 // Specialization for max_work_item_sizes.
520 template <int Dimensions>
522  info::device::max_work_item_sizes<Dimensions>> {
523  static id<Dimensions> get(RT::PiDevice dev, const plugin &Plugin) {
524  size_t result[3];
527  sizeof(result), &result, nullptr);
528  return construct_id<Dimensions>(result);
529  }
530 };
531 
532 template <>
534  size_t, ext::oneapi::experimental::info::device::max_global_work_groups> {
535  static size_t get(RT::PiDevice dev, const plugin &Plugin) {
536  (void)dev; // Silence unused warning
537  (void)Plugin;
538  return static_cast<size_t>((std::numeric_limits<int>::max)());
539  }
540 };
541 template <>
543  id<1>, ext::oneapi::experimental::info::device::max_work_groups<1>> {
544  static id<1> get(RT::PiDevice dev, const plugin &Plugin) {
545  size_t result[3];
546  size_t Limit =
547  get_device_info_impl<size_t, ext::oneapi::experimental::info::device::
548  max_global_work_groups>::get(dev,
549  Plugin);
551  dev,
552  PiInfoCode<
554  sizeof(result), &result, nullptr);
555  return id<1>(std::min(Limit, result[0]));
556  }
557 };
558 
559 template <>
561  id<2>, ext::oneapi::experimental::info::device::max_work_groups<2>> {
562  static id<2> get(RT::PiDevice dev, const plugin &Plugin) {
563  size_t result[3];
564  size_t Limit =
565  get_device_info_impl<size_t, ext::oneapi::experimental::info::device::
566  max_global_work_groups>::get(dev,
567  Plugin);
569  dev,
570  PiInfoCode<
572  sizeof(result), &result, nullptr);
573  return id<2>(std::min(Limit, result[1]), std::min(Limit, result[0]));
574  }
575 };
576 
577 template <>
579  id<3>, ext::oneapi::experimental::info::device::max_work_groups<3>> {
580  static id<3> get(RT::PiDevice dev, const plugin &Plugin) {
581  size_t result[3];
582  size_t Limit =
583  get_device_info_impl<size_t, ext::oneapi::experimental::info::device::
584  max_global_work_groups>::get(dev,
585  Plugin);
587  dev,
588  PiInfoCode<
590  sizeof(result), &result, nullptr);
591  return id<3>(std::min(Limit, result[2]), std::min(Limit, result[1]),
592  std::min(Limit, result[0]));
593  }
594 };
595 
596 // TODO:Remove with deprecated feature
597 // device::get_info<info::device::ext_oneapi_max_global_work_groups>
598 template <>
599 struct get_device_info_impl<size_t,
600  info::device::ext_oneapi_max_global_work_groups> {
601  static size_t get(RT::PiDevice dev, const plugin &Plugin) {
602  return get_device_info_impl<size_t,
603  ext::oneapi::experimental::info::device::
604  max_global_work_groups>::get(dev, Plugin);
605  }
606 };
607 
608 // TODO:Remove with deprecated feature
609 // device::get_info<info::device::ext_oneapi_max_work_groups_1d>
610 template <>
612  info::device::ext_oneapi_max_work_groups_1d> {
613  static id<1> get(RT::PiDevice dev, const plugin &Plugin) {
614  return get_device_info_impl<id<1>, ext::oneapi::experimental::info::device::
615  max_work_groups<1>>::get(dev,
616  Plugin);
617  }
618 };
619 
620 // TODO:Remove with deprecated feature
621 // device::get_info<info::device::ext_oneapi_max_work_groups_2d>
622 template <>
624  info::device::ext_oneapi_max_work_groups_2d> {
625  static id<2> get(RT::PiDevice dev, const plugin &Plugin) {
626  return get_device_info_impl<id<2>, ext::oneapi::experimental::info::device::
627  max_work_groups<2>>::get(dev,
628  Plugin);
629  }
630 };
631 
632 // TODO:Remove with deprecated feature
633 // device::get_info<info::device::ext_oneapi_max_work_groups_3d>
634 template <>
636  info::device::ext_oneapi_max_work_groups_3d> {
637  static id<3> get(RT::PiDevice dev, const plugin &Plugin) {
638  return get_device_info_impl<id<3>, ext::oneapi::experimental::info::device::
639  max_work_groups<3>>::get(dev,
640  Plugin);
641  }
642 };
643 
644 // Specialization for parent device
645 template <> struct get_device_info_impl<device, info::device::parent_device> {
646  static device get(RT::PiDevice dev, const plugin &Plugin) {
647  typename sycl_to_pi<device>::type result;
650  &result, nullptr);
651  if (result == nullptr)
652  throw invalid_object_error(
653  "No parent for device because it is not a subdevice",
654  PI_ERROR_INVALID_DEVICE);
655 
656  // Get the platform of this device
657  std::shared_ptr<detail::platform_impl> Platform =
658  platform_impl::getPlatformFromPiDevice(dev, Plugin);
659  return createSyclObjFromImpl<device>(
660  Platform->getOrMakeDeviceImpl(result, Platform));
661  }
662 };
663 
664 // USM
665 
666 // Specialization for device usm query.
667 template <>
668 struct get_device_info_impl<bool, info::device::usm_device_allocations> {
669  static bool get(RT::PiDevice dev, const plugin &Plugin) {
670  pi_usm_capabilities caps;
673  sizeof(pi_usm_capabilities), &caps, nullptr);
674 
675  return (Err != PI_SUCCESS) ? false : (caps & PI_USM_ACCESS);
676  }
677 };
678 
679 // Specialization for host usm query.
680 template <>
681 struct get_device_info_impl<bool, info::device::usm_host_allocations> {
682  static bool get(RT::PiDevice dev, const plugin &Plugin) {
683  pi_usm_capabilities caps;
686  sizeof(pi_usm_capabilities), &caps, nullptr);
687 
688  return (Err != PI_SUCCESS) ? false : (caps & PI_USM_ACCESS);
689  }
690 };
691 
692 // Specialization for shared usm query.
693 template <>
694 struct get_device_info_impl<bool, info::device::usm_shared_allocations> {
695  static bool get(RT::PiDevice dev, const plugin &Plugin) {
696  pi_usm_capabilities caps;
699  sizeof(pi_usm_capabilities), &caps, nullptr);
700  return (Err != PI_SUCCESS) ? false : (caps & PI_USM_ACCESS);
701  }
702 };
703 
704 // Specialization for restricted usm query
705 template <>
707  info::device::usm_restricted_shared_allocations> {
708  static bool get(RT::PiDevice dev, const plugin &Plugin) {
709  pi_usm_capabilities caps;
712  sizeof(pi_usm_capabilities), &caps, nullptr);
713  // Check that we don't support any cross device sharing
714  return (Err != PI_SUCCESS)
715  ? false
716  : !(caps & (PI_USM_ACCESS | PI_USM_CONCURRENT_ACCESS));
717  }
718 };
719 
720 // Specialization for system usm query
721 template <>
722 struct get_device_info_impl<bool, info::device::usm_system_allocations> {
723  static bool get(RT::PiDevice dev, const plugin &Plugin) {
724  pi_usm_capabilities caps;
727  sizeof(pi_usm_capabilities), &caps, nullptr);
728  return (Err != PI_SUCCESS) ? false : (caps & PI_USM_ACCESS);
729  }
730 };
731 
732 // Specialization for memory channel query
733 template <>
734 struct get_device_info_impl<bool, info::device::ext_intel_mem_channel> {
735  static bool get(RT::PiDevice dev, const plugin &Plugin) {
736  pi_mem_properties caps;
739  sizeof(pi_mem_properties), &caps, nullptr);
740  return (Err != PI_SUCCESS) ? false : (caps & PI_MEM_PROPERTIES_CHANNEL);
741  }
742 };
743 
744 template <typename Param>
745 typename Param::return_type get_device_info(RT::PiDevice dev,
746  const plugin &Plugin) {
747  static_assert(is_device_info_desc<Param>::value,
748  "Invalid device information descriptor");
750  Plugin);
751 }
752 
753 // SYCL host device information
754 
755 // Default template is disabled, all possible instantiations are
756 // specified explicitly.
757 template <typename Param>
758 inline typename Param::return_type get_device_info_host() = delete;
759 
760 template <>
761 inline info::device_type get_device_info_host<info::device::device_type>() {
762  return info::device_type::host;
763 }
764 
765 template <> inline uint32_t get_device_info_host<info::device::vendor_id>() {
766  return 0x8086;
767 }
768 
769 template <>
770 inline uint32_t get_device_info_host<info::device::max_compute_units>() {
771  return std::thread::hardware_concurrency();
772 }
773 
774 template <>
775 inline uint32_t get_device_info_host<info::device::max_work_item_dimensions>() {
776  return 3;
777 }
778 
779 template <>
780 inline id<1> get_device_info_host<info::device::max_work_item_sizes<1>>() {
781  // current value is the required minimum
782  return {1};
783 }
784 
785 template <>
786 inline id<2> get_device_info_host<info::device::max_work_item_sizes<2>>() {
787  // current value is the required minimum
788  return {1, 1};
789 }
790 
791 template <>
792 inline id<3> get_device_info_host<info::device::max_work_item_sizes<3>>() {
793  // current value is the required minimum
794  return {1, 1, 1};
795 }
796 
797 template <>
798 inline constexpr size_t get_device_info_host<
799  ext::oneapi::experimental::info::device::max_global_work_groups>() {
800  // See handler.hpp for the maximum value :
801  return static_cast<size_t>((std::numeric_limits<int>::max)());
802 }
803 
804 template <>
807  // See handler.hpp for the maximum value :
808  static constexpr size_t Limit = get_device_info_host<
809  ext::oneapi::experimental::info::device::max_global_work_groups>();
810  return {Limit};
811 }
812 
813 template <>
814 inline id<2> get_device_info_host<
815  ext::oneapi::experimental::info::device::max_work_groups<2>>() {
816  // See handler.hpp for the maximum value :
817  static constexpr size_t Limit = get_device_info_host<
818  ext::oneapi::experimental::info::device::max_global_work_groups>();
819  return {Limit, Limit};
820 }
821 
822 template <>
823 inline id<3> get_device_info_host<
824  ext::oneapi::experimental::info::device::max_work_groups<3>>() {
825  // See handler.hpp for the maximum value :
826  static constexpr size_t Limit = get_device_info_host<
827  ext::oneapi::experimental::info::device::max_global_work_groups>();
828  return {Limit, Limit, Limit};
829 }
830 
831 // TODO:remove with deprecated feature
832 // device::get_info<info::device::ext_oneapi_max_global_work_groups>
833 template <>
834 inline constexpr size_t
835 get_device_info_host<info::device::ext_oneapi_max_global_work_groups>() {
836  return get_device_info_host<
837  ext::oneapi::experimental::info::device::max_global_work_groups>();
838 }
839 
840 // TODO:remove with deprecated feature
841 // device::get_info<info::device::ext_oneapi_max_work_groups_1d>
842 template <>
843 inline id<1>
844 get_device_info_host<info::device::ext_oneapi_max_work_groups_1d>() {
845 
846  return get_device_info_host<
848 }
849 
850 // TODO:remove with deprecated feature
851 // device::get_info<info::device::ext_oneapi_max_work_groups_2d>
852 template <>
853 inline id<2>
854 get_device_info_host<info::device::ext_oneapi_max_work_groups_2d>() {
855  return get_device_info_host<
856  ext::oneapi::experimental::info::device::max_work_groups<2>>();
857 }
858 
859 // TODO:remove with deprecated feature
860 // device::get_info<info::device::ext_oneapi_max_work_groups_3d>
861 template <>
862 inline id<3>
863 get_device_info_host<info::device::ext_oneapi_max_work_groups_3d>() {
864  return get_device_info_host<
865  ext::oneapi::experimental::info::device::max_work_groups<3>>();
866 }
867 
868 template <>
869 inline size_t get_device_info_host<info::device::max_work_group_size>() {
870  // current value is the required minimum
871  return 1;
872 }
873 
874 template <>
875 inline uint32_t
876 get_device_info_host<info::device::preferred_vector_width_char>() {
877  // TODO update when appropriate
878  return 1;
879 }
880 
881 template <>
882 inline uint32_t
883 get_device_info_host<info::device::preferred_vector_width_short>() {
884  // TODO update when appropriate
885  return 1;
886 }
887 
888 template <>
889 inline uint32_t
890 get_device_info_host<info::device::preferred_vector_width_int>() {
891  // TODO update when appropriate
892  return 1;
893 }
894 
895 template <>
896 inline uint32_t
897 get_device_info_host<info::device::preferred_vector_width_long>() {
898  // TODO update when appropriate
899  return 1;
900 }
901 
902 template <>
903 inline uint32_t
904 get_device_info_host<info::device::preferred_vector_width_float>() {
905  // TODO update when appropriate
906  return 1;
907 }
908 
909 template <>
910 inline uint32_t
911 get_device_info_host<info::device::preferred_vector_width_double>() {
912  // TODO update when appropriate
913  return 1;
914 }
915 
916 template <>
917 inline uint32_t
918 get_device_info_host<info::device::preferred_vector_width_half>() {
919  // TODO update when appropriate
920  return 0;
921 }
922 
923 template <>
924 inline uint32_t get_device_info_host<info::device::native_vector_width_char>() {
925  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Char);
926 }
927 
928 template <>
929 inline uint32_t
930 get_device_info_host<info::device::native_vector_width_short>() {
931  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Short);
932 }
933 
934 template <>
935 inline uint32_t get_device_info_host<info::device::native_vector_width_int>() {
936  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Int);
937 }
938 
939 template <>
940 inline uint32_t get_device_info_host<info::device::native_vector_width_long>() {
941  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Long);
942 }
943 
944 template <>
945 inline uint32_t
946 get_device_info_host<info::device::native_vector_width_float>() {
947  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Float);
948 }
949 
950 template <>
951 inline uint32_t
952 get_device_info_host<info::device::native_vector_width_double>() {
953  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Double);
954 }
955 
956 template <>
957 inline uint32_t get_device_info_host<info::device::native_vector_width_half>() {
958  return PlatformUtil::getNativeVectorWidth(PlatformUtil::TypeIndex::Half);
959 }
960 
961 template <>
962 inline uint32_t get_device_info_host<info::device::max_clock_frequency>() {
963  return PlatformUtil::getMaxClockFrequency();
964 }
965 
966 template <> inline uint32_t get_device_info_host<info::device::address_bits>() {
967  return sizeof(void *) * 8;
968 }
969 
970 template <>
971 inline uint64_t get_device_info_host<info::device::global_mem_size>() {
972  return static_cast<uint64_t>(OSUtil::getOSMemSize());
973 }
974 
975 template <>
976 inline uint64_t get_device_info_host<info::device::max_mem_alloc_size>() {
977  // current value is the required minimum
978  const uint64_t a = get_device_info_host<info::device::global_mem_size>() / 4;
979  const uint64_t b = 128ul * 1024 * 1024;
980  return (a > b) ? a : b;
981 }
982 
983 template <> inline bool get_device_info_host<info::device::image_support>() {
984  return true;
985 }
986 
987 template <> inline bool get_device_info_host<info::device::atomic64>() {
988  return false;
989 }
990 
991 template <>
992 inline std::vector<memory_order>
993 get_device_info_host<info::device::atomic_memory_order_capabilities>() {
994  return {memory_order::relaxed, memory_order::acquire, memory_order::release,
995  memory_order::acq_rel, memory_order::seq_cst};
996 }
997 
998 template <>
999 inline std::vector<memory_scope>
1000 get_device_info_host<info::device::atomic_memory_scope_capabilities>() {
1001  return {memory_scope::work_item, memory_scope::sub_group,
1002  memory_scope::work_group, memory_scope::device, memory_scope::system};
1003 }
1004 
1005 template <>
1006 inline bool
1007 get_device_info_host<info::device::ext_oneapi_bfloat16_math_functions>() {
1008  return false;
1009 }
1010 
1011 template <>
1012 inline uint32_t get_device_info_host<info::device::max_read_image_args>() {
1013  // current value is the required minimum
1014  return 128;
1015 }
1016 
1017 template <>
1018 inline uint32_t get_device_info_host<info::device::max_write_image_args>() {
1019  // current value is the required minimum
1020  return 8;
1021 }
1022 
1023 template <>
1024 inline size_t get_device_info_host<info::device::image2d_max_width>() {
1025  // SYCL guarantees at least 8192. Some devices already known to provide more
1026  // than that (i.e. it is 16384 for opencl:gpu), which may create issues during
1027  // image object allocation on host.
1028  // Using any fixed number (i.e. 16384) brings the risk of having similar
1029  // issues on newer devices in future. Thus it does not make sense limiting
1030  // the returned value on host. Practially speaking the returned value on host
1031  // depends only on memory required for the image, which also depends on
1032  // the image channel_type and the image height. Both are not known in this
1033  // query, thus it becomes user's responsibility to choose proper image
1034  // parameters depending on similar query to (non-host device) and amount
1035  // of available/allocatable memory.
1037 }
1038 
1039 template <>
1040 inline size_t get_device_info_host<info::device::image2d_max_height>() {
1041  // SYCL guarantees at least 8192. Some devices already known to provide more
1042  // than that (i.e. it is 16384 for opencl:gpu), which may create issues during
1043  // image object allocation on host.
1044  // Using any fixed number (i.e. 16384) brings the risk of having similar
1045  // issues on newer devices in future. Thus it does not make sense limiting
1046  // the returned value on host. Practially speaking the returned value on host
1047  // depends only on memory required for the image, which also depends on
1048  // the image channel_type and the image width. Both are not known in this
1049  // query, thus it becomes user's responsibility to choose proper image
1050  // parameters depending on similar query to (non-host device) and amount
1051  // of available/allocatable memory.
1053 }
1054 
1055 template <>
1056 inline size_t get_device_info_host<info::device::image3d_max_width>() {
1057  // SYCL guarantees at least 8192. Some devices already known to provide more
1058  // than that (i.e. it is 16384 for opencl:gpu), which may create issues during
1059  // image object allocation on host.
1060  // Using any fixed number (i.e. 16384) brings the risk of having similar
1061  // issues on newer devices in future. Thus it does not make sense limiting
1062  // the returned value on host. Practially speaking the returned value on host
1063  // depends only on memory required for the image, which also depends on
1064  // the image channel_type and the image height/depth. Both are not known
1065  // in this query, thus it becomes user's responsibility to choose proper image
1066  // parameters depending on similar query to (non-host device) and amount
1067  // of available/allocatable memory.
1069 }
1070 
1071 template <>
1072 inline size_t get_device_info_host<info::device::image3d_max_height>() {
1073  // SYCL guarantees at least 8192. Some devices already known to provide more
1074  // than that (i.e. it is 16384 for opencl:gpu), which may create issues during
1075  // image object allocation on host.
1076  // Using any fixed number (i.e. 16384) brings the risk of having similar
1077  // issues on newer devices in future. Thus it does not make sense limiting
1078  // the returned value on host. Practially speaking the returned value on host
1079  // depends only on memory required for the image, which also depends on
1080  // the image channel_type and the image width/depth. Both are not known
1081  // in this query, thus it becomes user's responsibility to choose proper image
1082  // parameters depending on similar query to (non-host device) and amount
1083  // of available/allocatable memory.
1085 }
1086 
1087 template <>
1088 inline size_t get_device_info_host<info::device::image3d_max_depth>() {
1089  // SYCL guarantees at least 8192. Some devices already known to provide more
1090  // than that (i.e. it is 16384 for opencl:gpu), which may create issues during
1091  // image object allocation on host.
1092  // Using any fixed number (i.e. 16384) brings the risk of having similar
1093  // issues on newer devices in future. Thus it does not make sense limiting
1094  // the returned value on host. Practially speaking the returned value on host
1095  // depends only on memory required for the image, which also depends on
1096  // the image channel_type and the image height/width, which are not known
1097  // in this query, thus it becomes user's responsibility to choose proper image
1098  // parameters depending on similar query to (non-host device) and amount
1099  // of available/allocatable memory.
1101 }
1102 
1103 template <>
1104 inline size_t get_device_info_host<info::device::image_max_buffer_size>() {
1105  // Not supported in SYCL
1106  return 0;
1107 }
1108 
1109 template <>
1110 inline size_t get_device_info_host<info::device::image_max_array_size>() {
1111  // current value is the required minimum
1112  return 2048;
1113 }
1114 
1115 template <> inline uint32_t get_device_info_host<info::device::max_samplers>() {
1116  // current value is the required minimum
1117  return 16;
1118 }
1119 
1120 template <>
1121 inline size_t get_device_info_host<info::device::max_parameter_size>() {
1122  // current value is the required minimum
1123  return 1024;
1124 }
1125 
1126 template <>
1127 inline uint32_t get_device_info_host<info::device::mem_base_addr_align>() {
1128  return 1024;
1129 }
1130 
1131 template <>
1132 inline std::vector<info::fp_config>
1133 get_device_info_host<info::device::half_fp_config>() {
1134  // current value is the required minimum
1135  return {};
1136 }
1137 
1138 template <>
1139 inline std::vector<info::fp_config>
1140 get_device_info_host<info::device::single_fp_config>() {
1141  // current value is the required minimum
1142  return {info::fp_config::round_to_nearest, info::fp_config::inf_nan};
1143 }
1144 
1145 template <>
1146 inline std::vector<info::fp_config>
1147 get_device_info_host<info::device::double_fp_config>() {
1148  // current value is the required minimum
1149  return {info::fp_config::fma, info::fp_config::round_to_nearest,
1150  info::fp_config::round_to_zero, info::fp_config::round_to_inf,
1151  info::fp_config::inf_nan, info::fp_config::denorm};
1152 }
1153 
1154 template <>
1156 get_device_info_host<info::device::global_mem_cache_type>() {
1157  return info::global_mem_cache_type::read_write;
1158 }
1159 
1160 template <>
1161 inline uint32_t
1162 get_device_info_host<info::device::global_mem_cache_line_size>() {
1163  return PlatformUtil::getMemCacheLineSize();
1164 }
1165 
1166 template <>
1167 inline uint64_t get_device_info_host<info::device::global_mem_cache_size>() {
1168  return PlatformUtil::getMemCacheSize();
1169 }
1170 
1171 template <>
1172 inline uint64_t get_device_info_host<info::device::max_constant_buffer_size>() {
1173  // current value is the required minimum
1174  return 64 * 1024;
1175 }
1176 
1177 template <>
1178 inline uint32_t get_device_info_host<info::device::max_constant_args>() {
1179  // current value is the required minimum
1180  return 8;
1181 }
1182 
1183 template <>
1185 get_device_info_host<info::device::local_mem_type>() {
1186  return info::local_mem_type::global;
1187 }
1188 
1189 template <>
1190 inline uint64_t get_device_info_host<info::device::local_mem_size>() {
1191  // current value is the required minimum
1192  return 32 * 1024;
1193 }
1194 
1195 template <>
1196 inline bool get_device_info_host<info::device::error_correction_support>() {
1197  return false;
1198 }
1199 
1200 template <>
1201 inline bool get_device_info_host<info::device::host_unified_memory>() {
1202  return true;
1203 }
1204 
1205 template <>
1206 inline size_t get_device_info_host<info::device::profiling_timer_resolution>() {
1207  typedef std::ratio_divide<std::chrono::high_resolution_clock::period,
1208  std::nano>
1209  ns_period;
1210  return ns_period::num / ns_period::den;
1211 }
1212 
1213 template <> inline bool get_device_info_host<info::device::is_endian_little>() {
1214  union {
1215  uint16_t a;
1216  uint8_t b[2];
1217  } u = {0x0100};
1218 
1219  return u.b[1];
1220 }
1221 
1222 template <> inline bool get_device_info_host<info::device::is_available>() {
1223  return true;
1224 }
1225 
1226 template <>
1227 inline bool get_device_info_host<info::device::is_compiler_available>() {
1228  return true;
1229 }
1230 
1231 template <>
1232 inline bool get_device_info_host<info::device::is_linker_available>() {
1233  return true;
1234 }
1235 
1236 template <>
1237 inline std::vector<info::execution_capability>
1238 get_device_info_host<info::device::execution_capabilities>() {
1239  return {info::execution_capability::exec_kernel};
1240 }
1241 
1242 template <> inline bool get_device_info_host<info::device::queue_profiling>() {
1243  return true;
1244 }
1245 
1246 template <>
1247 inline std::vector<kernel_id>
1248 get_device_info_host<info::device::built_in_kernel_ids>() {
1249  return {};
1250 }
1251 
1252 template <>
1253 inline std::vector<std::string>
1254 get_device_info_host<info::device::built_in_kernels>() {
1255  return {};
1256 }
1257 
1258 template <> inline platform get_device_info_host<info::device::platform>() {
1259  return createSyclObjFromImpl<platform>(platform_impl::getHostPlatformImpl());
1260 }
1261 
1262 template <> inline std::string get_device_info_host<info::device::name>() {
1263  return "SYCL host device";
1264 }
1265 
1266 template <> inline std::string get_device_info_host<info::device::vendor>() {
1267  return "";
1268 }
1269 
1270 template <>
1271 inline std::string get_device_info_host<info::device::driver_version>() {
1272  return "1.2";
1273 }
1274 
1275 template <> inline std::string get_device_info_host<info::device::profile>() {
1276  return "FULL PROFILE";
1277 }
1278 
1279 template <> inline std::string get_device_info_host<info::device::version>() {
1280  return "1.2";
1281 }
1282 
1283 template <>
1284 inline std::string get_device_info_host<info::device::opencl_c_version>() {
1285  return "not applicable";
1286 }
1287 
1288 template <>
1289 inline std::vector<std::string>
1290 get_device_info_host<info::device::extensions>() {
1291  // TODO update when appropriate
1292  return {};
1293 }
1294 
1295 template <>
1296 inline size_t get_device_info_host<info::device::printf_buffer_size>() {
1297  // current value is the required minimum
1298  return 1024 * 1024;
1299 }
1300 
1301 template <>
1302 inline bool get_device_info_host<info::device::preferred_interop_user_sync>() {
1303  return false;
1304 }
1305 
1306 template <> inline device get_device_info_host<info::device::parent_device>() {
1307  throw invalid_object_error(
1308  "Partitioning to subdevices of the host device is not implemented",
1309  PI_ERROR_INVALID_DEVICE);
1310 }
1311 
1312 template <>
1313 inline uint32_t
1314 get_device_info_host<info::device::partition_max_sub_devices>() {
1315  // TODO update once subdevice creation is enabled
1316  return 1;
1317 }
1318 
1319 template <>
1320 inline std::vector<info::partition_property>
1321 get_device_info_host<info::device::partition_properties>() {
1322  // TODO update once subdevice creation is enabled
1323  return {};
1324 }
1325 
1326 template <>
1327 inline std::vector<info::partition_affinity_domain>
1328 get_device_info_host<info::device::partition_affinity_domains>() {
1329  // TODO update once subdevice creation is enabled
1330  return {};
1331 }
1332 
1333 template <>
1335 get_device_info_host<info::device::partition_type_property>() {
1336  return info::partition_property::no_partition;
1337 }
1338 
1339 template <>
1341 get_device_info_host<info::device::partition_type_affinity_domain>() {
1342  // TODO update once subdevice creation is enabled
1343  return info::partition_affinity_domain::not_applicable;
1344 }
1345 
1346 template <>
1347 inline uint32_t get_device_info_host<info::device::reference_count>() {
1348  // TODO update once subdevice creation is enabled
1349  return 1;
1350 }
1351 
1352 template <>
1353 inline uint32_t get_device_info_host<info::device::max_num_sub_groups>() {
1354  // TODO update once subgroups are enabled
1355  throw runtime_error("Sub-group feature is not supported on HOST device.",
1356  PI_ERROR_INVALID_DEVICE);
1357 }
1358 
1359 template <>
1360 inline std::vector<size_t>
1361 get_device_info_host<info::device::sub_group_sizes>() {
1362  // TODO update once subgroups are enabled
1363  throw runtime_error("Sub-group feature is not supported on HOST device.",
1364  PI_ERROR_INVALID_DEVICE);
1365 }
1366 
1367 template <>
1368 inline bool
1369 get_device_info_host<info::device::sub_group_independent_forward_progress>() {
1370  // TODO update once subgroups are enabled
1371  throw runtime_error("Sub-group feature is not supported on HOST device.",
1372  PI_ERROR_INVALID_DEVICE);
1373 }
1374 
1375 template <>
1376 inline bool get_device_info_host<info::device::kernel_kernel_pipe_support>() {
1377  return false;
1378 }
1379 
1380 template <>
1381 inline std::string get_device_info_host<info::device::backend_version>() {
1382  throw runtime_error(
1383  "Backend version feature is not supported on HOST device.",
1384  PI_ERROR_INVALID_DEVICE);
1385 }
1386 
1387 template <>
1388 inline bool get_device_info_host<info::device::usm_device_allocations>() {
1389  return true;
1390 }
1391 
1392 template <>
1393 inline bool get_device_info_host<info::device::usm_host_allocations>() {
1394  return true;
1395 }
1396 
1397 template <>
1398 inline bool get_device_info_host<info::device::usm_shared_allocations>() {
1399  return true;
1400 }
1401 
1402 template <>
1403 inline bool
1404 get_device_info_host<info::device::usm_restricted_shared_allocations>() {
1405  return true;
1406 }
1407 
1408 template <>
1409 inline bool get_device_info_host<info::device::usm_system_allocations>() {
1410  return true;
1411 }
1412 
1413 template <>
1414 inline bool get_device_info_host<info::device::ext_intel_mem_channel>() {
1415  return false;
1416 }
1417 
1418 // Specializations for intel extensions for Level Zero low-level
1419 // detail device descriptors (not support on host).
1420 template <>
1421 inline uint32_t
1422 get_device_info_host<ext::intel::info::device::device_id>() {
1423  throw runtime_error(
1424  "Obtaining the device ID is not supported on HOST device",
1425  PI_ERROR_INVALID_DEVICE);
1426 }
1427 template <>
1428 inline std::string
1429 get_device_info_host<ext::intel::info::device::pci_address>() {
1430  throw runtime_error(
1431  "Obtaining the PCI address is not supported on HOST device",
1432  PI_ERROR_INVALID_DEVICE);
1433 }
1434 template <>
1435 inline uint32_t get_device_info_host<ext::intel::info::device::gpu_eu_count>() {
1436  throw runtime_error("Obtaining the EU count is not supported on HOST device",
1437  PI_ERROR_INVALID_DEVICE);
1438 }
1439 template <>
1440 inline uint32_t
1441 get_device_info_host<ext::intel::info::device::gpu_eu_simd_width>() {
1442  throw runtime_error(
1443  "Obtaining the EU SIMD width is not supported on HOST device",
1444  PI_ERROR_INVALID_DEVICE);
1445 }
1446 template <>
1447 inline uint32_t get_device_info_host<ext::intel::info::device::gpu_slices>() {
1448  throw runtime_error(
1449  "Obtaining the number of slices is not supported on HOST device",
1450  PI_ERROR_INVALID_DEVICE);
1451 }
1452 template <>
1453 inline uint32_t
1454 get_device_info_host<ext::intel::info::device::gpu_subslices_per_slice>() {
1455  throw runtime_error("Obtaining the number of subslices per slice is not "
1456  "supported on HOST device",
1457  PI_ERROR_INVALID_DEVICE);
1458 }
1459 template <>
1460 inline uint32_t
1461 get_device_info_host<ext::intel::info::device::gpu_eu_count_per_subslice>() {
1462  throw runtime_error(
1463  "Obtaining the EU count per subslice is not supported on HOST device",
1464  PI_ERROR_INVALID_DEVICE);
1465 }
1466 template <>
1467 inline uint32_t
1468 get_device_info_host<ext::intel::info::device::gpu_hw_threads_per_eu>() {
1469  throw runtime_error(
1470  "Obtaining the HW threads count per EU is not supported on HOST device",
1471  PI_ERROR_INVALID_DEVICE);
1472 }
1473 template <>
1474 inline uint64_t
1475 get_device_info_host<ext::intel::info::device::max_mem_bandwidth>() {
1476  throw runtime_error(
1477  "Obtaining the maximum memory bandwidth is not supported on HOST device",
1478  PI_ERROR_INVALID_DEVICE);
1479 }
1480 template <>
1482 get_device_info_host<ext::intel::info::device::uuid>() {
1483  throw runtime_error(
1484  "Obtaining the device uuid is not supported on HOST device",
1485  PI_ERROR_INVALID_DEVICE);
1486 }
1487 
1488 // TODO: Remove with deprecated feature
1489 // device::get_info<info::device::ext_intel_pci_address>()
1490 template <>
1491 inline std::string get_device_info_host<info::device::ext_intel_pci_address>() {
1492  throw runtime_error(
1493  "Obtaining the PCI address is not supported on HOST device",
1494  PI_ERROR_INVALID_DEVICE);
1495 }
1496 // TODO: Remove with deprecated feature
1497 // device::get_info<info::device::ext_intel_gpu_eu_count>()
1498 template <>
1499 inline uint32_t get_device_info_host<info::device::ext_intel_gpu_eu_count>() {
1500  throw runtime_error("Obtaining the EU count is not supported on HOST device",
1501  PI_ERROR_INVALID_DEVICE);
1502 }
1503 // TODO: Remove with deprecated feature
1504 // device::get_info<info::device::ext_intel_gpu_eu_simd_width>()
1505 template <>
1506 inline uint32_t
1507 get_device_info_host<info::device::ext_intel_gpu_eu_simd_width>() {
1508  throw runtime_error(
1509  "Obtaining the EU SIMD width is not supported on HOST device",
1510  PI_ERROR_INVALID_DEVICE);
1511 }
1512 // TODO: Remove with deprecated feature
1513 // device::get_info<info::device::ext_intel_gpu_slices>()
1514 template <>
1515 inline uint32_t get_device_info_host<info::device::ext_intel_gpu_slices>() {
1516  throw runtime_error(
1517  "Obtaining the number of slices is not supported on HOST device",
1518  PI_ERROR_INVALID_DEVICE);
1519 }
1520 // TODO: Remove with deprecated feature
1521 // device::get_info<info::device::ext_intel_gpu_subslices_per_slice>()
1522 template <>
1523 inline uint32_t
1524 get_device_info_host<info::device::ext_intel_gpu_subslices_per_slice>() {
1525  throw runtime_error("Obtaining the number of subslices per slice is not "
1526  "supported on HOST device",
1527  PI_ERROR_INVALID_DEVICE);
1528 }
1529 // TODO: Remove with deprecated feature
1530 // device::get_info<info::device::ext_intel_gpu_eu_count_per_subslices>()
1531 template <>
1532 inline uint32_t
1533 get_device_info_host<info::device::ext_intel_gpu_eu_count_per_subslice>() {
1534  throw runtime_error(
1535  "Obtaining the EU count per subslice is not supported on HOST device",
1536  PI_ERROR_INVALID_DEVICE);
1537 }
1538 // TODO: Remove with deprecated feature
1539 // device::get_info<info::device::ext_intel_gpu_hw_threads_per_eu>()
1540 template <>
1541 inline uint32_t
1542 get_device_info_host<info::device::ext_intel_gpu_hw_threads_per_eu>() {
1543  throw runtime_error(
1544  "Obtaining the HW threads count per EU is not supported on HOST device",
1545  PI_ERROR_INVALID_DEVICE);
1546 }
1547 // TODO: Remove with deprecated feature
1548 // device::get_info<info::device::ext_intel_max_mem_bandwidth>()
1549 template <>
1550 inline uint64_t
1551 get_device_info_host<info::device::ext_intel_max_mem_bandwidth>() {
1552  throw runtime_error(
1553  "Obtaining the maximum memory bandwidth is not supported on HOST device",
1554  PI_ERROR_INVALID_DEVICE);
1555 }
1556 // TODO:Move to namespace ext::intel::info::device
1557 template <> inline bool get_device_info_host<info::device::ext_oneapi_srgb>() {
1558  return false;
1559 }
1560 
1561 // TODO: Remove with deprecated feature
1562 // device::get_info<info::device::ext_intel_device_info_uuid>()
1563 template <>
1565 get_device_info_host<info::device::ext_intel_device_info_uuid>() {
1566  throw runtime_error(
1567  "Obtaining the device uuid is not supported on HOST device",
1568  PI_ERROR_INVALID_DEVICE);
1569 }
1570 
1571 template <>
1572 inline uint64_t get_device_info_host<ext::intel::info::device::free_memory>() {
1573  throw runtime_error(
1574  "Obtaining the device free memory is not supported on HOST device",
1575  PI_ERROR_INVALID_DEVICE);
1576 }
1577 
1578 template <>
1579 inline uint32_t
1580 get_device_info_host<ext::intel::info::device::memory_clock_rate>() {
1581  throw runtime_error(
1582  "Obtaining the device memory clock rate is not supported on HOST device",
1583  PI_ERROR_INVALID_DEVICE);
1584 }
1585 
1586 template <>
1587 inline uint32_t
1588 get_device_info_host<ext::intel::info::device::memory_bus_width>() {
1589  throw runtime_error(
1590  "Obtaining the device memory bus width is not supported on HOST device",
1591  PI_ERROR_INVALID_DEVICE);
1592 }
1593 
1594 } // namespace detail
1595 } // __SYCL_INLINE_VER_NAMESPACE(_V1)
1596 } // namespace sycl
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
RT::PiResult call_nocheck(ArgsT... Args) const
Calls the PiApi, traces the call, and returns the result.
Definition: plugin.hpp:170
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:47
A unique identifier of an item in an index space.
Definition: id.hpp:32
Encapsulates a SYCL platform on which kernels may be executed.
Definition: platform.hpp:45
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)
#define __SYCL_AFFINITY_DOMAIN_STRING_CASE(DOMAIN)
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_result PiResult
Definition: pi.hpp:108
::pi_device_info PiDeviceInfo
Definition: pi.hpp:112
id< 1 > construct_id< 1 >(size_t *values)
std::vector< memory_scope > readMemoryScopeBitfield(pi_memory_scope_capabilities bits)
std::vector< info::fp_config > read_fp_bitfield(pi_device_fp_config bits)
Definition: device_info.hpp:31
id< 2 > construct_id< 2 >(size_t *values)
std::string affinityDomainToString(info::partition_affinity_domain AffinityDomain)
Definition: device_info.hpp:81
static bool is_sycl_partition_property(info::partition_property PP)
Param::return_type get_device_info_host()=delete
std::vector< std::string > split_string(const std::string &str, char delimeter)
Definition: common.cpp:33
Param::return_type get_device_info(RT::PiDevice dev, const plugin &Plugin)
id< 3 > construct_id< 3 >(size_t *values)
std::string get_device_info_string(RT::PiDevice dev, RT::PiDeviceInfo InfoCode, const plugin &Plugin)
std::vector< info::partition_affinity_domain > read_domain_bitfield(pi_device_affinity_domain bits)
Definition: device_info.hpp:53
id< Dimensions > construct_id(size_t *values)=delete
std::vector< memory_order > readMemoryOrderBitfield(pi_memory_order_capabilities bits)
std::array< unsigned char, 16 > uuid_type
Definition: type_traits.hpp:64
std::vector< info::execution_capability > read_execution_bitfield(pi_device_exec_capabilities bits)
Definition: device_info.hpp:71
detail::enable_if_t< detail::is_genfloat< T >::value, T > fma(T a, T b, T c) __NOEXC
Definition: builtins.hpp:196
class __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:2747
---— Error handling, matching OpenCL plugin semantics.
Definition: access.hpp:14
static constexpr pi_device_fp_config PI_FP_SOFT_FLOAT
Definition: pi.h:652
pi_bitfield pi_device_exec_capabilities
Definition: pi.h:507
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_NEXT_PARTITIONABLE
Definition: pi.h:642
_pi_result
Definition: pi.h:116
pi_uint32 pi_bool
Definition: pi.h:107
_pi_usm_capabilities pi_usm_capabilities
Definition: pi.h:1648
@ PI_DEVICE_INFO_PARTITION_TYPE
Definition: pi.h:261
static constexpr pi_device_fp_config PI_FP_DENORM
Definition: pi.h:646
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_L2_CACHE
Definition: pi.h:637
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_L3_CACHE
Definition: pi.h:635
pi_bitfield pi_mem_properties
Definition: pi.h:560
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_usm_capabilities
Definition: pi.h:1619
@ PI_USM_ACCESS
Definition: pi.h:1620
@ PI_USM_CONCURRENT_ACCESS
Definition: pi.h:1622
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_L4_CACHE
Definition: pi.h:633
static constexpr pi_device_fp_config PI_FP_ROUND_TO_NEAREST
Definition: pi.h:648
static constexpr pi_device_fp_config PI_FP_ROUND_TO_INF
Definition: pi.h:650
static constexpr pi_device_fp_config PI_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT
Definition: pi.h:653
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_L1_CACHE
Definition: pi.h:639
static constexpr pi_device_affinity_domain PI_DEVICE_AFFINITY_DOMAIN_NUMA
Definition: pi.h:631
pi_bitfield pi_memory_scope_capabilities
Definition: pi.h:526
pi_bitfield pi_device_fp_config
Definition: pi.h:645
static constexpr pi_device_exec_capabilities PI_EXEC_NATIVE_KERNEL
Definition: pi.h:659
static constexpr pi_device_fp_config PI_FP_ROUND_TO_ZERO
Definition: pi.h:649
static constexpr pi_device_fp_config PI_FP_FMA
Definition: pi.h:651
static constexpr pi_device_exec_capabilities PI_EXEC_KERNEL
Definition: pi.h:658
static constexpr pi_device_fp_config PI_FP_INF_NAN
Definition: pi.h:647
pi_bitfield pi_device_affinity_domain
Definition: pi.h:630
pi_bitfield pi_memory_order_capabilities
Definition: pi.h:519
constexpr pi_mem_properties PI_MEM_PROPERTIES_CHANNEL
Definition: pi.h:561
C++ wrapper of extern "C" PI interfaces.
simd< _Tp, _Abi > max(const simd< _Tp, _Abi > &, const simd< _Tp, _Abi > &) noexcept
static ReturnT get(RT::PiDevice dev, const plugin &Plugin)
static device get(RT::PiDevice dev, const plugin &Plugin)
static info::partition_property get(RT::PiDevice dev, const plugin &Plugin)
static platform get(RT::PiDevice dev, const plugin &Plugin)
static std::string get(RT::PiDevice dev, const plugin &Plugin)
static std::string get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< info::execution_capability > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< info::fp_config > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< info::fp_config > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< info::partition_affinity_domain > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< info::partition_property > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< kernel_id > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< size_t > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< std::string > get(RT::PiDevice dev, const plugin &Plugin)
static std::vector< std::string > get(RT::PiDevice dev, const plugin &Plugin)
static ReturnT get(RT::PiDevice dev, const plugin &Plugin)