17 inline namespace _V1 {
21 : MIsHostDevice(true), MPlatform(
platform_impl::getHostPlatformImpl()),
23 MIsAssertFailSupported(true) {}
27 :
device_impl(InteropDeviceHandle, nullptr, nullptr, Plugin) {}
42 : MDevice(Device), MIsHostDevice(false),
43 MDeviceHostBaseTime(
std::make_pair(0, 0)) {
45 bool InteroperabilityConstructor =
false;
46 if (Device ==
nullptr) {
47 assert(InteropDeviceHandle);
52 InteropDeviceHandle,
nullptr, &MDevice);
53 InteroperabilityConstructor =
true;
62 if ((Platform ==
nullptr) || !Platform->MAlwaysRootDevice) {
69 if (!InteroperabilityConstructor) {
82 MIsAssertFailSupported =
98 auto SupportedDomains = get_info<info::device::partition_affinity_domains>();
99 return std::find(SupportedDomains.begin(), SupportedDomains.end(),
100 AffinityDomain) != SupportedDomains.end();
105 throw invalid_object_error(
106 "This instance of device doesn't support OpenCL interoperability.",
107 PI_ERROR_INVALID_DEVICE);
111 return pi::cast<cl_device_id>(
getNative());
115 return createSyclObjFromImpl<platform>(MPlatform);
118 template <
typename Param>
121 return get_device_info_host<Param>();
123 return get_device_info<Param>(
124 MPlatform->getOrMakeDeviceImpl(MDevice, MPlatform));
127 #define __SYCL_PARAM_TRAITS_SPEC(DescType, Desc, ReturnT, PiCode) \
128 template ReturnT device_impl::get_info<info::device::Desc>() const;
130 #define __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED(DescType, Desc, ReturnT, PiCode) \
131 template ReturnT device_impl::get_info<info::device::Desc>() const;
133 #include <sycl/info/device_traits.def>
134 #undef __SYCL_PARAM_TRAITS_SPEC_SPECIALIZED
135 #undef __SYCL_PARAM_TRAITS_SPEC
137 #define __SYCL_PARAM_TRAITS_SPEC(Namespace, DescType, Desc, ReturnT, PiCode) \
138 template __SYCL_EXPORT ReturnT \
139 device_impl::get_info<Namespace::info::DescType::Desc>() const;
141 #include <sycl/info/ext_codeplay_device_traits.def>
142 #include <sycl/info/ext_intel_device_traits.def>
143 #include <sycl/info/ext_oneapi_device_traits.def>
144 #undef __SYCL_PARAM_TRAITS_SPEC
147 typename info::platform::version::return_type
148 device_impl::get_backend_info<info::platform::version>()
const {
151 "the info::platform::version info descriptor can "
152 "only be queried with an OpenCL backend");
154 return get_platform().get_info<info::platform::version>();
158 typename info::device::version::return_type
159 device_impl::get_backend_info<info::device::version>()
const {
162 "the info::device::version info descriptor can only "
163 "be queried with an OpenCL backend");
165 return get_info<info::device::version>();
169 typename info::device::backend_version::return_type
170 device_impl::get_backend_info<info::device::backend_version>()
const {
173 "the info::device::backend_version info descriptor "
174 "can only be queried with a Level Zero backend");
186 std::string AllExtensionNames =
188 return (AllExtensionNames.find(ExtensionName) != std::string::npos);
192 auto SupportedProperties = get_info<info::device::partition_properties>();
193 return std::find(SupportedProperties.begin(), SupportedProperties.end(),
194 Prop) != SupportedProperties.end();
199 size_t SubDevicesCount)
const {
201 std::vector<sycl::detail::pi::PiDevice> SubDevices(SubDevicesCount);
205 MDevice, Properties, SubDevicesCount, SubDevices.data(),
206 &ReturnedSubDevices);
207 if (ReturnedSubDevices != SubDevicesCount) {
210 "Could not partition to the specified number of sub-devices");
216 std::vector<device> res;
219 device sycl_device = detail::createSyclObjFromImpl<device>(
220 MPlatform->getOrMakeDeviceImpl(a_pi_device, MPlatform));
221 res.push_back(sycl_device);
227 assert(!MIsHostDevice &&
"Partitioning is not supported on host.");
230 throw sycl::feature_not_supported(
231 "Device does not support "
232 "sycl::info::partition_property::partition_equally.",
233 PI_ERROR_INVALID_OPERATION);
237 auto MaxComputeUnits = get_info<info::device::max_compute_units>();
238 if (ComputeUnits > MaxComputeUnits)
240 "Total counts exceed max compute units");
242 size_t SubDevicesCount = MaxComputeUnits / ComputeUnits;
251 assert(!MIsHostDevice &&
"Partitioning is not supported on host.");
254 throw sycl::feature_not_supported(
255 "Device does not support "
256 "sycl::info::partition_property::partition_by_counts.",
257 PI_ERROR_INVALID_OPERATION);
261 std::vector<pi_device_partition_property> Properties(P, P + 3);
264 auto It = Properties.begin() + 1;
265 size_t TotalCounts = 0;
266 size_t NonZeroCounts = 0;
267 for (
auto Count : Counts) {
268 TotalCounts += Count;
269 NonZeroCounts += (Count != 0) ? 1 : 0;
270 It = Properties.insert(It, Count);
277 if (NonZeroCounts > get_info<info::device::partition_max_sub_devices>())
279 "Total non-zero counts exceed max sub-devices");
285 if (TotalCounts > get_info<info::device::max_compute_units>())
287 "Total counts exceed max compute units");
294 assert(!MIsHostDevice &&
"Partitioning is not supported on host.");
298 throw sycl::feature_not_supported(
299 "Device does not support "
300 "sycl::info::partition_property::partition_by_affinity_domain.",
301 PI_ERROR_INVALID_OPERATION);
304 throw sycl::feature_not_supported(
307 PI_ERROR_INVALID_VALUE);
316 MDevice, Properties, 0,
nullptr, &SubDevicesCount);
322 assert(!MIsHostDevice &&
"Partitioning is not supported on host.");
326 throw sycl::feature_not_supported(
327 "Device does not support "
328 "sycl::info::partition_property::ext_intel_partition_by_cslice.",
329 PI_ERROR_INVALID_OPERATION);
338 MDevice, Properties, 0,
nullptr, &SubDevicesCount);
353 size_t return_size = 0;
362 case aspect::accelerator:
367 case aspect::emulated:
369 case aspect::host_debuggable:
375 case aspect::ext_oneapi_bfloat16_math_functions:
376 return get_info<info::device::ext_oneapi_bfloat16_math_functions>();
377 case aspect::int64_base_atomics:
379 case aspect::int64_extended_atomics:
381 case aspect::atomic64:
382 return get_info<info::device::atomic64>();
384 return get_info<info::device::image_support>();
385 case aspect::online_compiler:
386 return get_info<info::device::is_compiler_available>();
387 case aspect::online_linker:
388 return get_info<info::device::is_linker_available>();
389 case aspect::queue_profiling:
390 return get_info<info::device::queue_profiling>();
391 case aspect::usm_device_allocations:
392 return get_info<info::device::usm_device_allocations>();
393 case aspect::usm_host_allocations:
394 return get_info<info::device::usm_host_allocations>();
395 case aspect::ext_intel_mem_channel:
396 return get_info<info::device::ext_intel_mem_channel>();
397 case aspect::usm_atomic_host_allocations:
400 info::device::usm_host_allocations>
::
401 get(MPlatform->getDeviceImpl(MDevice)) &
403 case aspect::usm_shared_allocations:
404 return get_info<info::device::usm_shared_allocations>();
405 case aspect::usm_atomic_shared_allocations:
408 info::device::usm_shared_allocations>
::
409 get(MPlatform->getDeviceImpl(MDevice)) &
411 case aspect::usm_restricted_shared_allocations:
412 return get_info<info::device::usm_restricted_shared_allocations>();
413 case aspect::usm_system_allocations:
414 return get_info<info::device::usm_system_allocations>();
415 case aspect::ext_intel_device_id:
419 case aspect::ext_intel_pci_address:
423 case aspect::ext_intel_gpu_eu_count:
426 &return_size) == PI_SUCCESS;
427 case aspect::ext_intel_gpu_eu_simd_width:
430 &return_size) == PI_SUCCESS;
431 case aspect::ext_intel_gpu_slices:
435 case aspect::ext_intel_gpu_subslices_per_slice:
438 &return_size) == PI_SUCCESS;
439 case aspect::ext_intel_gpu_eu_count_per_subslice:
442 &return_size) == PI_SUCCESS;
443 case aspect::ext_intel_gpu_hw_threads_per_eu:
446 &return_size) == PI_SUCCESS;
447 case aspect::ext_intel_free_memory:
450 &return_size) == PI_SUCCESS;
451 case aspect::ext_intel_memory_clock_rate:
454 &return_size) == PI_SUCCESS;
455 case aspect::ext_intel_memory_bus_width:
458 &return_size) == PI_SUCCESS;
459 case aspect::ext_intel_device_info_uuid: {
462 if (Result != PI_SUCCESS) {
466 assert(return_size <= 16);
467 unsigned char UUID[16];
471 nullptr) == PI_SUCCESS;
473 case aspect::ext_intel_max_mem_bandwidth:
476 case aspect::ext_oneapi_srgb:
477 return get_info<info::device::ext_oneapi_srgb>();
478 case aspect::ext_oneapi_native_assert:
480 case aspect::ext_oneapi_cuda_async_barrier: {
481 int async_barrier_supported;
482 bool call_successful =
485 &async_barrier_supported,
nullptr) == PI_SUCCESS;
486 return call_successful && async_barrier_supported;
488 case aspect::ext_intel_legacy_image: {
490 bool call_successful =
493 &legacy_image_support,
nullptr) == PI_SUCCESS;
494 return call_successful && legacy_image_support;
496 case aspect::ext_oneapi_bindless_images: {
498 bool call_successful =
501 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
502 return call_successful && support;
504 case aspect::ext_oneapi_bindless_images_shared_usm: {
506 bool call_successful =
510 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
511 return call_successful && support;
513 case aspect::ext_oneapi_bindless_images_1d_usm: {
515 bool call_successful =
518 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
519 return call_successful && support;
521 case aspect::ext_oneapi_bindless_images_2d_usm: {
523 bool call_successful =
526 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
527 return call_successful && support;
529 case aspect::ext_oneapi_interop_memory_import: {
531 bool call_successful =
534 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
535 return call_successful && support;
537 case aspect::ext_oneapi_interop_memory_export: {
539 bool call_successful =
542 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
543 return call_successful && support;
545 case aspect::ext_oneapi_interop_semaphore_import: {
547 bool call_successful =
550 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
551 return call_successful && support;
553 case aspect::ext_oneapi_interop_semaphore_export: {
555 bool call_successful =
558 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
559 return call_successful && support;
561 case aspect::ext_oneapi_mipmap: {
563 bool call_successful =
566 &support,
nullptr) == PI_SUCCESS;
567 return call_successful && support;
569 case aspect::ext_oneapi_mipmap_anisotropy: {
571 bool call_successful =
574 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
575 return call_successful && support;
577 case aspect::ext_oneapi_mipmap_level_reference: {
579 bool call_successful =
582 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
583 return call_successful && support;
585 case aspect::ext_oneapi_cubemap: {
587 bool call_successful =
590 &support,
nullptr) == PI_SUCCESS;
591 return call_successful && support;
593 case aspect::ext_oneapi_cubemap_seamless_filtering: {
595 bool call_successful =
599 sizeof(
pi_bool), &support,
nullptr) == PI_SUCCESS;
600 return call_successful && support;
602 case aspect::ext_intel_esimd: {
604 bool call_successful =
607 &support,
nullptr) == PI_SUCCESS;
608 return call_successful && support;
610 case aspect::ext_oneapi_ballot_group:
611 case aspect::ext_oneapi_fixed_size_group:
612 case aspect::ext_oneapi_opportunistic_group: {
617 case aspect::ext_oneapi_tangle_group: {
623 case aspect::ext_intel_matrix: {
625 const std::vector<arch> supported_archs = {
626 arch::intel_cpu_spr, arch::intel_gpu_pvc, arch::intel_gpu_dg2_g10,
627 arch::intel_gpu_dg2_g11, arch::intel_gpu_dg2_g12};
630 supported_archs.begin(), supported_archs.end(),
631 [=](
const arch
a) { return this->extOneapiArchitectureIs(a); });
638 case aspect::ext_oneapi_is_composite: {
640 sycl::ext::oneapi::experimental::info::device::component_devices>();
643 return components.size() >= 2;
645 case aspect::ext_oneapi_is_component: {
653 ext::oneapi::experimental::info::device::composite_device>::value,
654 sizeof(Result), &Result,
nullptr);
656 return Result !=
nullptr;
658 case aspect::ext_oneapi_graph: {
659 pi_bool SupportsCommandBufferUpdate =
false;
660 bool CallSuccessful =
663 sizeof(SupportsCommandBufferUpdate), &SupportsCommandBufferUpdate,
664 nullptr) == PI_SUCCESS;
665 if (!CallSuccessful) {
669 return has(aspect::ext_oneapi_limited_graph) && SupportsCommandBufferUpdate;
671 case aspect::ext_oneapi_limited_graph: {
672 pi_bool SupportsCommandBuffers =
false;
673 bool CallSuccessful =
676 sizeof(SupportsCommandBuffers), &SupportsCommandBuffers,
677 nullptr) == PI_SUCCESS;
678 if (!CallSuccessful) {
682 return SupportsCommandBuffers;
684 case aspect::ext_intel_fpga_task_sequence: {
687 case aspect::ext_oneapi_private_alloca: {
690 return be == sycl::backend::ext_oneapi_level_zero ||
691 be == sycl::backend::opencl;
694 throw runtime_error(
"This device aspect has not been implemented yet.",
695 PI_ERROR_INVALID_DEVICE);
699 static std::shared_ptr<device_impl> HostImpl =
700 std::make_shared<device_impl>();
706 return MIsAssertFailSupported;
710 std::call_once(MDeviceNameFlag,
711 [
this]() { MDeviceName = get_info<info::device::name>(); });
717 std::call_once(MDeviceArchFlag, [
this]() {
719 get_info<ext::oneapi::experimental::info::device::architecture>();
737 using namespace std::chrono;
739 duration_cast<nanoseconds>(steady_clock::now().time_since_epoch())
747 constexpr uint64_t TimeTillRefresh = 200e9;
748 assert(HostTime >= MDeviceHostBaseTime.second);
749 uint64_t Diff = HostTime - MDeviceHostBaseTime.second;
752 if (!MDeviceHostBaseTime.second || Diff > TimeTillRefresh) {
756 MDevice, &MDeviceHostBaseTime.first, &MDeviceHostBaseTime.second);
768 duration_cast<nanoseconds>(steady_clock::now().time_since_epoch())
770 if (Result == PI_ERROR_INVALID_OPERATION) {
773 std::string errorMsg(p ? p :
"");
774 throw sycl::feature_not_supported(
775 "Device and/or backend does not support querying timestamp: " +
779 Plugin->checkPiResult(Result);
783 MDeviceHostBaseTime.second = HostTime;
786 return MDeviceHostBaseTime.first + Diff;
791 uint64_t DeviceTime = 0, HostTime = 0;
794 MDevice, &DeviceTime, &HostTime);
795 return Result != PI_ERROR_INVALID_OPERATION;
std::vector< device > create_sub_devices() const
Partition device into sub devices.
bool has(aspect Aspect) const
Indicates if the SYCL device has the given feature.
bool is_host() const
Check if SYCL device is a host device.
Param::return_type get_info() const
Queries this SYCL device for information requested by the template parameter param.
platform get_platform() const
Get associated SYCL platform.
bool isGetDeviceAndHostTimerSupported()
Check clGetDeviceAndHostTimer is available for fallback profiling.
std::string get_device_info_string(sycl::detail::pi::PiDeviceInfo InfoCode) const
Get device info string.
device_impl()
Constructs a SYCL device instance as a host device.
bool is_cpu() const
Check if device is a CPU device.
backend getBackend() const
Get the backend of this device.
const PluginPtr & getPlugin() const
pi_native_handle getNative() const
Gets the native handle of the SYCL device.
bool is_gpu() const
Check if device is a GPU device.
uint64_t getCurrentDeviceTime()
Gets the current device timestamp.
std::string getDeviceName() const
sycl::detail::pi::PiDevice & getHandleRef()
Get reference to PI device.
bool has_extension(const std::string &ExtensionName) const
Check SYCL extension support by device.
bool is_affinity_supported(info::partition_affinity_domain AffinityDomain) const
Check if affinity partitioning by specified domain is supported by device.
bool isAssertFailSupported() const
cl_device_id get() const
Get instance of OpenCL device.
ext::oneapi::experimental::architecture getDeviceArch() const
Get device architecture.
bool extOneapiCanCompile(ext::oneapi::experimental::source_language Language)
bool is_partition_supported(info::partition_property Prop) const
Check if desired partition property supported by device.
static std::shared_ptr< device_impl > getHostDeviceImpl()
Gets the single instance of the Host Device.
bool is_accelerator() const
Check if device is an accelerator device.
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
#define __SYCL_CHECK_OCL_CODE_NO_EXC(X)
::pi_device_type PiDeviceType
std::string affinityDomainToString(info::partition_affinity_domain AffinityDomain)
static const PluginPtr & getPlugin(backend Backend)
std::shared_ptr< plugin > PluginPtr
std::shared_ptr< detail::platform_impl > PlatformImplPtr
Function for_each(Group g, Ptr first, Ptr last, Function f)
bool is_source_kernel_bundle_supported(backend BE, source_language Language)
partition_affinity_domain
@ partition_by_affinity_domain
@ ext_intel_partition_by_cslice
#define PI_DEVICE_INFO_EXTENSION_DEVICELIB_ASSERT
Extension to denote native support of assert feature by an arbitrary device piDeviceGetInfo call shou...
uintptr_t pi_native_handle
pi_result piextDeviceGetNativeHandle(pi_device device, pi_native_handle *nativeHandle)
Gets the native handle of a PI device object.
static constexpr pi_device_partition_property PI_EXT_INTEL_DEVICE_PARTITION_BY_CSLICE
_pi_usm_capabilities pi_usm_capabilities
@ PI_DEVICE_INFO_GPU_SLICES
@ PI_EXT_ONEAPI_DEVICE_INFO_INTEROP_MEMORY_IMPORT_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_CUBEMAP_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_COMMAND_BUFFER_UPDATE_SUPPORT
@ PI_EXT_INTEL_DEVICE_INFO_ESIMD_SUPPORT
@ PI_DEVICE_INFO_GPU_EU_COUNT
@ PI_DEVICE_INFO_IMAGE_SUPPORT
@ PI_EXT_INTEL_DEVICE_INFO_FREE_MEMORY
@ PI_EXT_ONEAPI_DEVICE_INFO_INTEROP_MEMORY_EXPORT_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_MIPMAP_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_MIPMAP_ANISOTROPY_SUPPORT
@ PI_DEVICE_INFO_PARENT_DEVICE
@ PI_DEVICE_INFO_GPU_EU_SIMD_WIDTH
@ PI_EXT_ONEAPI_DEVICE_INFO_BINDLESS_IMAGES_SUPPORT
@ PI_DEVICE_INFO_GPU_HW_THREADS_PER_EU
@ PI_EXT_ONEAPI_DEVICE_INFO_CUBEMAP_SEAMLESS_FILTERING_SUPPORT
@ PI_DEVICE_INFO_DEVICE_ID
@ PI_EXT_ONEAPI_DEVICE_INFO_INTEROP_SEMAPHORE_EXPORT_SUPPORT
@ PI_DEVICE_INFO_PCI_ADDRESS
@ PI_EXT_ONEAPI_DEVICE_INFO_CUDA_ASYNC_BARRIER
@ PI_DEVICE_INFO_GPU_EU_COUNT_PER_SUBSLICE
@ PI_EXT_ONEAPI_DEVICE_INFO_MIPMAP_LEVEL_REFERENCE_SUPPORT
@ PI_EXT_INTEL_DEVICE_INFO_MEMORY_CLOCK_RATE
@ PI_EXT_ONEAPI_DEVICE_INFO_INTEROP_SEMAPHORE_IMPORT_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_BINDLESS_IMAGES_SHARED_USM_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_BINDLESS_IMAGES_1D_USM_SUPPORT
@ PI_EXT_INTEL_DEVICE_INFO_MEMORY_BUS_WIDTH
@ PI_EXT_ONEAPI_DEVICE_INFO_BINDLESS_IMAGES_2D_USM_SUPPORT
@ PI_EXT_ONEAPI_DEVICE_INFO_COMMAND_BUFFER_SUPPORT
@ PI_DEVICE_INFO_GPU_SUBSLICES_PER_SLICE
static constexpr pi_device_partition_property PI_DEVICE_PARTITION_BY_COUNTS
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_CONCURRENT_ATOMIC_ACCESS
static constexpr pi_device_partition_property PI_DEVICE_PARTITION_BY_COUNTS_LIST_END
static constexpr pi_device_partition_property PI_DEVICE_PARTITION_EQUALLY
static constexpr pi_device_partition_property PI_DEVICE_PARTITION_BY_AFFINITY_DOMAIN
pi_result piPluginGetLastError(char **message)
API to get Plugin specific warning and error messages.
pi_result piextDeviceCreateWithNativeHandle(pi_native_handle nativeHandle, pi_platform platform, pi_device *device)
Creates PI device object from a native handle.
pi_result piDeviceRetain(pi_device device)
pi_result piDeviceRelease(pi_device device)
pi_result piGetDeviceAndHostTimer(pi_device Device, uint64_t *DeviceTime, uint64_t *HostTime)
Queries device for it's global timestamp in nanoseconds, and updates HostTime with the value of the h...
intptr_t pi_device_partition_property
pi_result piDevicePartition(pi_device device, const pi_device_partition_property *properties, pi_uint32 num_devices, pi_device *out_devices, pi_uint32 *out_num_devices)
bool any_of(const simd_mask< _Tp, _Abi > &) noexcept