diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b3d0c90d1..9407102e25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [dev] - XXX. XX, XXXX ### Added +* Added `dpctl.SyclDevice` aspect queries `has_aspect_ext_oneapi_is_integrated_gpu`, `has_aspect_ext_oneapi_clock_sub_group`, `has_aspect_ext_oneapi_clock_work_group`, `has_aspect_ext_oneapi_clock_device`, `has_aspect_ext_oneapi_native_assert` and `has_aspect_ext_oneapi_register_host_memory`, along with the matching `DPCTLSyclAspectType` values; `has_aspect_ext_oneapi_register_host_memory` is always `False` when dpctl is built with a DPC++ compiler older than 2026.2 [gh-2416](https://github.com/IntelPython/dpctl/pull/2416) ### Changed diff --git a/dpctl/_backend.pxd b/dpctl/_backend.pxd index 3708ea9130..27f1a9ceb2 100644 --- a/dpctl/_backend.pxd +++ b/dpctl/_backend.pxd @@ -103,6 +103,12 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": _is_component "is_component", _is_composite "is_composite", _ext_oneapi_ipc_memory "ext_oneapi_ipc_memory", + _ext_oneapi_is_integrated_gpu "ext_oneapi_is_integrated_gpu", + _ext_oneapi_clock_sub_group "ext_oneapi_clock_sub_group", + _ext_oneapi_clock_work_group "ext_oneapi_clock_work_group", + _ext_oneapi_clock_device "ext_oneapi_clock_device", + _ext_oneapi_native_assert "ext_oneapi_native_assert", + _ext_oneapi_register_host_memory "ext_oneapi_register_host_memory", ctypedef enum _partition_affinity_domain_type \ "DPCTLPartitionAffinityDomainType": diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 624575a5d8..e39af0e0fd 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -960,6 +960,86 @@ cdef class SyclDevice(_SyclDevice): cdef _aspect_type AT = _aspect_type._ext_oneapi_ipc_memory return DPCTLDevice_HasAspect(self._device_ref, AT) + @property + def has_aspect_ext_oneapi_is_integrated_gpu(self): + """ Returns ``True`` if this device is a GPU integrated with + the host processor, sharing its memory, ``False`` otherwise. + + Returns: + bool: + Indicates if device is an integrated GPU. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_is_integrated_gpu + return DPCTLDevice_HasAspect(self._device_ref, AT) + + @property + def has_aspect_ext_oneapi_clock_sub_group(self): + """ Returns ``True`` if this device supports reading a clock + counter of ``sub_group`` scope in kernels + (``sycl_ext_oneapi_clock``), ``False`` otherwise. + + Returns: + bool: + Indicates if device supports a sub-group scope clock. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_clock_sub_group + return DPCTLDevice_HasAspect(self._device_ref, AT) + + @property + def has_aspect_ext_oneapi_clock_work_group(self): + """ Returns ``True`` if this device supports reading a clock + counter of ``work_group`` scope in kernels + (``sycl_ext_oneapi_clock``), ``False`` otherwise. + + Returns: + bool: + Indicates if device supports a work-group scope clock. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_clock_work_group + return DPCTLDevice_HasAspect(self._device_ref, AT) + + @property + def has_aspect_ext_oneapi_clock_device(self): + """ Returns ``True`` if this device supports reading a clock + counter of ``device`` scope in kernels + (``sycl_ext_oneapi_clock``), ``False`` otherwise. + + Returns: + bool: + Indicates if device supports a device scope clock. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_clock_device + return DPCTLDevice_HasAspect(self._device_ref, AT) + + @property + def has_aspect_ext_oneapi_native_assert(self): + """ Returns ``True`` if this device supports ``assert`` in + kernels natively, ``False`` otherwise. On devices without this + aspect, ``assert`` statements in kernels are ignored. + + Returns: + bool: + Indicates if device supports native ``assert`` in kernels. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_native_assert + return DPCTLDevice_HasAspect(self._device_ref, AT) + + @property + def has_aspect_ext_oneapi_register_host_memory(self): + """ Returns ``True`` if host memory allocated outside of SYCL + can be registered for faster transfers to this device + (``sycl_ext_oneapi_register_host_memory``), ``False`` otherwise. + + Always ``False`` if dpctl was built with a DPC++ compiler that + does not support this extension (older than 2026.2). + + Returns: + bool: + Indicates if device supports registering host memory. + """ + cdef _aspect_type AT = _aspect_type._ext_oneapi_register_host_memory + return DPCTLDevice_HasAspect(self._device_ref, AT) + @property def image_2d_max_width(self): """ Returns the maximum width of a 2D image or 1D image in pixels. diff --git a/dpctl/tests/_device_attributes_checks.py b/dpctl/tests/_device_attributes_checks.py index 7e00831fae..fa55b2729f 100644 --- a/dpctl/tests/_device_attributes_checks.py +++ b/dpctl/tests/_device_attributes_checks.py @@ -252,6 +252,48 @@ def check_has_aspect_emulated(device): pytest.fail("has_aspect_emulated call failed") +def check_has_aspect_ext_oneapi_is_integrated_gpu(device): + try: + device.has_aspect_ext_oneapi_is_integrated_gpu + except Exception: + pytest.fail("has_aspect_ext_oneapi_is_integrated_gpu call failed") + + +def check_has_aspect_ext_oneapi_clock_sub_group(device): + try: + device.has_aspect_ext_oneapi_clock_sub_group + except Exception: + pytest.fail("has_aspect_ext_oneapi_clock_sub_group call failed") + + +def check_has_aspect_ext_oneapi_clock_work_group(device): + try: + device.has_aspect_ext_oneapi_clock_work_group + except Exception: + pytest.fail("has_aspect_ext_oneapi_clock_work_group call failed") + + +def check_has_aspect_ext_oneapi_clock_device(device): + try: + device.has_aspect_ext_oneapi_clock_device + except Exception: + pytest.fail("has_aspect_ext_oneapi_clock_device call failed") + + +def check_has_aspect_ext_oneapi_native_assert(device): + try: + device.has_aspect_ext_oneapi_native_assert + except Exception: + pytest.fail("has_aspect_ext_oneapi_native_assert call failed") + + +def check_has_aspect_ext_oneapi_register_host_memory(device): + try: + device.has_aspect_ext_oneapi_register_host_memory + except Exception: + pytest.fail("has_aspect_ext_oneapi_register_host_memory call failed") + + def check_is_accelerator(device): try: device.is_accelerator @@ -838,6 +880,12 @@ def check_partition_affinity_domains(device): check_has_aspect_usm_atomic_shared_allocations, check_has_aspect_host_debuggable, check_has_aspect_emulated, + check_has_aspect_ext_oneapi_is_integrated_gpu, + check_has_aspect_ext_oneapi_clock_sub_group, + check_has_aspect_ext_oneapi_clock_work_group, + check_has_aspect_ext_oneapi_clock_device, + check_has_aspect_ext_oneapi_native_assert, + check_has_aspect_ext_oneapi_register_host_memory, check_max_read_image_args, check_max_write_image_args, check_image_2d_max_width, diff --git a/dpctl/tests/test_sycl_device.py b/dpctl/tests/test_sycl_device.py index dd1a579272..3650b37dad 100644 --- a/dpctl/tests/test_sycl_device.py +++ b/dpctl/tests/test_sycl_device.py @@ -164,6 +164,13 @@ def test_equal(): "emulated", "is_component", "is_composite", + "ext_oneapi_ipc_memory", + "ext_oneapi_is_integrated_gpu", + "ext_oneapi_clock_sub_group", + "ext_oneapi_clock_work_group", + "ext_oneapi_clock_device", + "ext_oneapi_native_assert", + "ext_oneapi_register_host_memory", ] # SYCL 2020 spec aspects not presently diff --git a/libsyclinterface/helper/source/dpctl_utils_helper.cpp b/libsyclinterface/helper/source/dpctl_utils_helper.cpp index c03887a2b1..7ecfa9b8c5 100644 --- a/libsyclinterface/helper/source/dpctl_utils_helper.cpp +++ b/libsyclinterface/helper/source/dpctl_utils_helper.cpp @@ -229,6 +229,26 @@ std::string DPCTL_AspectToStr(aspect aspectTy) case aspect::ext_oneapi_ipc_memory: ss << "ext_oneapi_ipc_memory"; break; +#endif + case aspect::ext_oneapi_is_integrated_gpu: + ss << "ext_oneapi_is_integrated_gpu"; + break; + case aspect::ext_oneapi_clock_sub_group: + ss << "ext_oneapi_clock_sub_group"; + break; + case aspect::ext_oneapi_clock_work_group: + ss << "ext_oneapi_clock_work_group"; + break; + case aspect::ext_oneapi_clock_device: + ss << "ext_oneapi_clock_device"; + break; + case aspect::ext_oneapi_native_assert: + ss << "ext_oneapi_native_assert"; + break; +#ifdef SYCL_EXT_ONEAPI_REGISTER_HOST_MEMORY + case aspect::ext_oneapi_register_host_memory: + ss << "ext_oneapi_register_host_memory"; + break; #endif default: throw std::runtime_error("Unsupported aspect type"); @@ -309,6 +329,26 @@ aspect DPCTL_StrToAspectType(const std::string &aspectTyStr) else if (aspectTyStr == "ext_oneapi_ipc_memory") { aspectTy = aspect::ext_oneapi_ipc_memory; } +#endif + else if (aspectTyStr == "ext_oneapi_is_integrated_gpu") { + aspectTy = aspect::ext_oneapi_is_integrated_gpu; + } + else if (aspectTyStr == "ext_oneapi_clock_sub_group") { + aspectTy = aspect::ext_oneapi_clock_sub_group; + } + else if (aspectTyStr == "ext_oneapi_clock_work_group") { + aspectTy = aspect::ext_oneapi_clock_work_group; + } + else if (aspectTyStr == "ext_oneapi_clock_device") { + aspectTy = aspect::ext_oneapi_clock_device; + } + else if (aspectTyStr == "ext_oneapi_native_assert") { + aspectTy = aspect::ext_oneapi_native_assert; + } +#ifdef SYCL_EXT_ONEAPI_REGISTER_HOST_MEMORY + else if (aspectTyStr == "ext_oneapi_register_host_memory") { + aspectTy = aspect::ext_oneapi_register_host_memory; + } #endif else { // \todo handle the error @@ -365,6 +405,20 @@ aspect DPCTL_DPCTLAspectTypeToSyclAspect(DPCTLSyclAspectType AspectTy) #ifdef SYCL_EXT_ONEAPI_INTER_PROCESS_COMMUNICATION case DPCTLSyclAspectType::ext_oneapi_ipc_memory: return aspect::ext_oneapi_ipc_memory; +#endif + case DPCTLSyclAspectType::ext_oneapi_is_integrated_gpu: + return aspect::ext_oneapi_is_integrated_gpu; + case DPCTLSyclAspectType::ext_oneapi_clock_sub_group: + return aspect::ext_oneapi_clock_sub_group; + case DPCTLSyclAspectType::ext_oneapi_clock_work_group: + return aspect::ext_oneapi_clock_work_group; + case DPCTLSyclAspectType::ext_oneapi_clock_device: + return aspect::ext_oneapi_clock_device; + case DPCTLSyclAspectType::ext_oneapi_native_assert: + return aspect::ext_oneapi_native_assert; +#ifdef SYCL_EXT_ONEAPI_REGISTER_HOST_MEMORY + case DPCTLSyclAspectType::ext_oneapi_register_host_memory: + return aspect::ext_oneapi_register_host_memory; #endif default: throw std::runtime_error("Unsupported aspect type"); @@ -419,6 +473,20 @@ DPCTLSyclAspectType DPCTL_SyclAspectToDPCTLAspectType(aspect Aspect) #ifdef SYCL_EXT_ONEAPI_INTER_PROCESS_COMMUNICATION case aspect::ext_oneapi_ipc_memory: return DPCTLSyclAspectType::ext_oneapi_ipc_memory; +#endif + case aspect::ext_oneapi_is_integrated_gpu: + return DPCTLSyclAspectType::ext_oneapi_is_integrated_gpu; + case aspect::ext_oneapi_clock_sub_group: + return DPCTLSyclAspectType::ext_oneapi_clock_sub_group; + case aspect::ext_oneapi_clock_work_group: + return DPCTLSyclAspectType::ext_oneapi_clock_work_group; + case aspect::ext_oneapi_clock_device: + return DPCTLSyclAspectType::ext_oneapi_clock_device; + case aspect::ext_oneapi_native_assert: + return DPCTLSyclAspectType::ext_oneapi_native_assert; +#ifdef SYCL_EXT_ONEAPI_REGISTER_HOST_MEMORY + case aspect::ext_oneapi_register_host_memory: + return DPCTLSyclAspectType::ext_oneapi_register_host_memory; #endif default: throw std::runtime_error("Unsupported aspect type"); diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h index c66b8330f9..372d440a25 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h @@ -134,7 +134,13 @@ typedef enum emulated, is_component, is_composite, - ext_oneapi_ipc_memory + ext_oneapi_ipc_memory, + ext_oneapi_is_integrated_gpu, + ext_oneapi_clock_sub_group, + ext_oneapi_clock_work_group, + ext_oneapi_clock_device, + ext_oneapi_native_assert, + ext_oneapi_register_host_memory } DPCTLSyclAspectType; /*! diff --git a/libsyclinterface/tests/test_sycl_device_aspects.cpp b/libsyclinterface/tests/test_sycl_device_aspects.cpp index 352e60f8cc..eb91103031 100644 --- a/libsyclinterface/tests/test_sycl_device_aspects.cpp +++ b/libsyclinterface/tests/test_sycl_device_aspects.cpp @@ -131,7 +131,23 @@ auto build_params() std::make_pair("is_component", sycl::aspect::ext_oneapi_is_component), std::make_pair("is_composite", - sycl::aspect::ext_oneapi_is_composite)); + sycl::aspect::ext_oneapi_is_composite), + std::make_pair("ext_oneapi_is_integrated_gpu", + sycl::aspect::ext_oneapi_is_integrated_gpu), + std::make_pair("ext_oneapi_clock_sub_group", + sycl::aspect::ext_oneapi_clock_sub_group), + std::make_pair("ext_oneapi_clock_work_group", + sycl::aspect::ext_oneapi_clock_work_group), + std::make_pair("ext_oneapi_clock_device", + sycl::aspect::ext_oneapi_clock_device), + std::make_pair("ext_oneapi_native_assert", + sycl::aspect::ext_oneapi_native_assert) +#ifdef SYCL_EXT_ONEAPI_REGISTER_HOST_MEMORY + , + std::make_pair("ext_oneapi_register_host_memory", + sycl::aspect::ext_oneapi_register_host_memory) +#endif + ); auto pairs = build_param_pairs,