From 2cdd2eda7d0adfbeebcac35894ee124141574d52 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Thu, 11 Jun 2026 17:29:36 -0700 Subject: [PATCH 01/13] add missing device info queries --- dpctl/__init__.py | 10 + dpctl/_backend.pxd | 76 +++ dpctl/_sycl_device.pyx | 476 +++++++++++++++++- dpctl/enum_types.py | 154 +++++- dpctl/tests/_device_attributes_checks.py | 162 ++++++ .../dpctl_sycl_device_interface.h | 267 ++++++++++ .../syclinterface/dpctl_sycl_enum_types.h | 45 ++ .../include/syclinterface/dpctl_utils.h | 8 + .../source/dpctl_sycl_device_interface.cpp | 414 +++++++++++++++ libsyclinterface/source/dpctl_utils.cpp | 2 + .../tests/test_sycl_device_interface.cpp | 130 +++++ 11 files changed, 1742 insertions(+), 2 deletions(-) diff --git a/dpctl/__init__.py b/dpctl/__init__.py index 5f57cdf90e..42d61207de 100644 --- a/dpctl/__init__.py +++ b/dpctl/__init__.py @@ -65,7 +65,12 @@ backend_type, device_type, event_status_type, + fp_config, global_mem_cache_type, + local_mem_type, + memory_order, + memory_scope, + partition_property, ) __all__ = [ @@ -118,6 +123,11 @@ "backend_type", "event_status_type", "global_mem_cache_type", + "local_mem_type", + "partition_property", + "fp_config", + "memory_order", + "memory_scope", ] __all__ += [ "get_include", diff --git a/dpctl/_backend.pxd b/dpctl/_backend.pxd index 452ff8f255..9165292ca0 100644 --- a/dpctl/_backend.pxd +++ b/dpctl/_backend.pxd @@ -31,6 +31,7 @@ cdef extern from "syclinterface/dpctl_error_handler_type.h": cdef extern from "syclinterface/dpctl_utils.h": cdef void DPCTLCString_Delete(const char *str) cdef void DPCTLSize_t_Array_Delete(size_t *arr) + cdef void DPCTLInt_Array_Delete(int *arr) cdef extern from "syclinterface/dpctl_sycl_enum_types.h": @@ -129,6 +130,41 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": _MEM_CACHE_TYPE_READ_ONLY "DPCTL_MEM_CACHE_TYPE_READ_ONLY" _MEM_CACHE_TYPE_READ_WRITE "DPCTL_MEM_CACHE_TYPE_READ_WRITE" + ctypedef enum _local_mem_type "DPCTLLocalMemType": + _LOCAL_MEM_TYPE_NONE "DPCTL_LOCAL_MEM_TYPE_NONE" + _LOCAL_MEM_TYPE_LOCAL "DPCTL_LOCAL_MEM_TYPE_LOCAL" + _LOCAL_MEM_TYPE_GLOBAL "DPCTL_LOCAL_MEM_TYPE_GLOBAL" + + ctypedef enum _partition_property_type "DPCTLPartitionPropertyType": + _PARTITION_NO_PARTITION "DPCTL_PARTITION_NO_PARTITION" + _PARTITION_EQUALLY "DPCTL_PARTITION_EQUALLY" + _PARTITION_BY_COUNTS "DPCTL_PARTITION_BY_COUNTS" + _PARTITION_BY_AFFINITY_DOMAIN "DPCTL_PARTITION_BY_AFFINITY_DOMAIN" + + ctypedef enum _fp_config_type "DPCTLFPConfigType": + _FP_DENORM "DPCTL_FP_DENORM" + _FP_INF_NAN "DPCTL_FP_INF_NAN" + _FP_ROUND_TO_NEAREST "DPCTL_FP_ROUND_TO_NEAREST" + _FP_ROUND_TO_ZERO "DPCTL_FP_ROUND_TO_ZERO" + _FP_ROUND_TO_INF "DPCTL_FP_ROUND_TO_INF" + _FP_FMA "DPCTL_FP_FMA" + _FP_CORRECT_ROUND_DIV_SQRT "DPCTL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT" + _FP_SOFT_FLOAT "DPCTL_FP_SOFT_FLOAT" + + ctypedef enum _memory_order_type "DPCTLMemoryOrderType": + _MEMORY_ORDER_RELAXED "DPCTL_MEMORY_ORDER_RELAXED" + _MEMORY_ORDER_ACQUIRE "DPCTL_MEMORY_ORDER_ACQUIRE" + _MEMORY_ORDER_RELEASE "DPCTL_MEMORY_ORDER_RELEASE" + _MEMORY_ORDER_ACQ_REL "DPCTL_MEMORY_ORDER_ACQ_REL" + _MEMORY_ORDER_SEQ_CST "DPCTL_MEMORY_ORDER_SEQ_CST" + + ctypedef enum _memory_scope_type "DPCTLMemoryScopeType": + _MEMORY_SCOPE_WORK_ITEM "DPCTL_MEMORY_SCOPE_WORK_ITEM" + _MEMORY_SCOPE_SUB_GROUP "DPCTL_MEMORY_SCOPE_SUB_GROUP" + _MEMORY_SCOPE_WORK_GROUP "DPCTL_MEMORY_SCOPE_WORK_GROUP" + _MEMORY_SCOPE_DEVICE "DPCTL_MEMORY_SCOPE_DEVICE" + _MEMORY_SCOPE_SYSTEM "DPCTL_MEMORY_SCOPE_SYSTEM" + cdef extern from "syclinterface/dpctl_sycl_types.h": cdef struct DPCTLOpaqueSyclContext @@ -291,6 +327,46 @@ cdef extern from "syclinterface/dpctl_sycl_device_interface.h": cdef void DPCTLDevice_DisablePeerAccess(const DPCTLSyclDeviceRef DRef, const DPCTLSyclDeviceRef PDRef) + cdef uint32_t DPCTLDevice_GetVendorId(const DPCTLSyclDeviceRef DRef) + cdef uint32_t DPCTLDevice_GetAddressBits(const DPCTLSyclDeviceRef DRef) + cdef size_t DPCTLDevice_GetImageMaxBufferSize( + const DPCTLSyclDeviceRef DRef) + cdef uint32_t DPCTLDevice_GetMaxSamplers(const DPCTLSyclDeviceRef DRef) + cdef size_t DPCTLDevice_GetMaxParameterSize( + const DPCTLSyclDeviceRef DRef) + cdef uint32_t DPCTLDevice_GetMemBaseAddrAlign( + const DPCTLSyclDeviceRef DRef) + cdef bool DPCTLDevice_GetErrorCorrectionSupport( + const DPCTLSyclDeviceRef DRef) + cdef bool DPCTLDevice_IsAvailable(const DPCTLSyclDeviceRef DRef) + cdef const char *DPCTLDevice_GetVersion(const DPCTLSyclDeviceRef DRef) + cdef const char *DPCTLDevice_GetBackendVersion( + const DPCTLSyclDeviceRef DRef) + cdef _local_mem_type DPCTLDevice_GetLocalMemType( + const DPCTLSyclDeviceRef DRef) + cdef _partition_property_type DPCTLDevice_GetPartitionTypeProperty( + const DPCTLSyclDeviceRef DRef) + cdef _partition_affinity_domain_type \ + DPCTLDevice_GetPartitionTypeAffinityDomain( + const DPCTLSyclDeviceRef DRef) + cdef int *DPCTLDevice_GetHalfFPConfig( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetSingleFPConfig( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetDoubleFPConfig( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetAtomicFenceOrderCapabilities( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetAtomicFenceScopeCapabilities( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetPartitionProperties( + const DPCTLSyclDeviceRef DRef, size_t *res_len) + cdef int *DPCTLDevice_GetPartitionAffinityDomains( + const DPCTLSyclDeviceRef DRef, size_t *res_len) cdef extern from "syclinterface/dpctl_sycl_device_manager.h": cdef DPCTLDeviceVectorRef DPCTLDeviceVector_CreateFromArray( diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 506664ab18..aa506751f3 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -35,32 +35,46 @@ from ._backend cimport ( # noqa: E211 DPCTLDevice_Delete, DPCTLDevice_DisablePeerAccess, DPCTLDevice_EnablePeerAccess, + DPCTLDevice_GetAddressBits, + DPCTLDevice_GetAtomicFenceOrderCapabilities, + DPCTLDevice_GetAtomicFenceScopeCapabilities, + DPCTLDevice_GetAtomicMemoryOrderCapabilities, + DPCTLDevice_GetAtomicMemoryScopeCapabilities, DPCTLDevice_GetBackend, + DPCTLDevice_GetBackendVersion, DPCTLDevice_GetComponentDevices, DPCTLDevice_GetCompositeDevice, DPCTLDevice_GetDeviceType, + DPCTLDevice_GetDoubleFPConfig, DPCTLDevice_GetDriverVersion, + DPCTLDevice_GetErrorCorrectionSupport, DPCTLDevice_GetGlobalMemCacheLineSize, DPCTLDevice_GetGlobalMemCacheSize, DPCTLDevice_GetGlobalMemCacheType, DPCTLDevice_GetGlobalMemSize, + DPCTLDevice_GetHalfFPConfig, DPCTLDevice_GetImage2dMaxHeight, DPCTLDevice_GetImage2dMaxWidth, DPCTLDevice_GetImage3dMaxDepth, DPCTLDevice_GetImage3dMaxHeight, DPCTLDevice_GetImage3dMaxWidth, + DPCTLDevice_GetImageMaxBufferSize, DPCTLDevice_GetLocalMemSize, + DPCTLDevice_GetLocalMemType, DPCTLDevice_GetMaxClockFrequency, DPCTLDevice_GetMaxComputeUnits, DPCTLDevice_GetMaxMemAllocSize, DPCTLDevice_GetMaxNumSubGroups, + DPCTLDevice_GetMaxParameterSize, DPCTLDevice_GetMaxReadImageArgs, + DPCTLDevice_GetMaxSamplers, DPCTLDevice_GetMaxWorkGroupSize, DPCTLDevice_GetMaxWorkItemDims, DPCTLDevice_GetMaxWorkItemSizes1d, DPCTLDevice_GetMaxWorkItemSizes2d, DPCTLDevice_GetMaxWorkItemSizes3d, DPCTLDevice_GetMaxWriteImageArgs, + DPCTLDevice_GetMemBaseAddrAlign, DPCTLDevice_GetName, DPCTLDevice_GetNativeVectorWidthChar, DPCTLDevice_GetNativeVectorWidthDouble, @@ -70,7 +84,11 @@ from ._backend cimport ( # noqa: E211 DPCTLDevice_GetNativeVectorWidthLong, DPCTLDevice_GetNativeVectorWidthShort, DPCTLDevice_GetParentDevice, + DPCTLDevice_GetPartitionAffinityDomains, DPCTLDevice_GetPartitionMaxSubDevices, + DPCTLDevice_GetPartitionProperties, + DPCTLDevice_GetPartitionTypeAffinityDomain, + DPCTLDevice_GetPartitionTypeProperty, DPCTLDevice_GetPlatform, DPCTLDevice_GetPreferredVectorWidthChar, DPCTLDevice_GetPreferredVectorWidthDouble, @@ -80,12 +98,16 @@ from ._backend cimport ( # noqa: E211 DPCTLDevice_GetPreferredVectorWidthLong, DPCTLDevice_GetPreferredVectorWidthShort, DPCTLDevice_GetProfilingTimerResolution, + DPCTLDevice_GetSingleFPConfig, DPCTLDevice_GetSubGroupIndependentForwardProgress, DPCTLDevice_GetSubGroupSizes, DPCTLDevice_GetVendor, + DPCTLDevice_GetVendorId, + DPCTLDevice_GetVersion, DPCTLDevice_HasAspect, DPCTLDevice_Hash, DPCTLDevice_IsAccelerator, + DPCTLDevice_IsAvailable, DPCTLDevice_IsCPU, DPCTLDevice_IsGPU, DPCTLDeviceMgr_GetDeviceInfoStr, @@ -98,6 +120,7 @@ from ._backend cimport ( # noqa: E211 DPCTLDeviceVector_Size, DPCTLDeviceVectorRef, DPCTLFilterSelector_Create, + DPCTLInt_Array_Delete, DPCTLSize_t_Array_Delete, DPCTLSyclDeviceRef, DPCTLSyclDeviceSelectorRef, @@ -106,11 +129,22 @@ from ._backend cimport ( # noqa: E211 _backend_type, _device_type, _global_mem_cache_type, + _local_mem_type, _partition_affinity_domain_type, + _partition_property_type, _peer_access, ) -from .enum_types import backend_type, device_type, global_mem_cache_type +from .enum_types import ( + backend_type, + device_type, + fp_config, + global_mem_cache_type, + local_mem_type, + memory_order, + memory_scope, + partition_property, +) from libc.stdint cimport int64_t, uint32_t, uint64_t from libc.stdlib cimport free, malloc @@ -2123,6 +2157,446 @@ cdef class SyclDevice(_SyclDevice): ) return max_part + @property + def vendor_id(self): + """ Returns the vendor identifier of the device. + + Returns: + int: + The vendor ID as an unsigned 32-bit integer. + """ + return DPCTLDevice_GetVendorId(self._device_ref) + + @property + def address_bits(self): + """ Returns the address space size of the device. + + Returns: + int: + The default compute device address space size specified as + an unsigned integer value in bits. + The result should always be 32 or 64. + """ + return DPCTLDevice_GetAddressBits(self._device_ref) + + @property + def image_max_buffer_size(self): + """ Returns the max number of pixels for a 1D image created from a + buffer. + + Returns: + int: + The maximum number of pixels in a 1D image from buffer. + """ + return DPCTLDevice_GetImageMaxBufferSize(self._device_ref) + + @property + def max_samplers(self): + """ Returns the maximum number of samplers that can be used in a + kernel. + + Returns: + int: + Maximum number of samplers. + """ + return DPCTLDevice_GetMaxSamplers(self._device_ref) + + @property + def max_parameter_size(self): + """ Returns the maximum size in bytes of all arguments that can be + passed to a kernel. + + Returns: + int: + Maximum kernel parameter size in bytes. + """ + return DPCTLDevice_GetMaxParameterSize(self._device_ref) + + @property + def mem_base_addr_align(self): + """ Returns the minimum value to which memory allocations on this + device are aligned in bits. + + Returns: + int: + Minimum alignment in bits for memory allocations. + """ + return DPCTLDevice_GetMemBaseAddrAlign(self._device_ref) + + @property + def error_correction_support(self): + """ Returns ``True`` if the device implements error correction for + all accesses to compute device memories (global, local, etc.). + + Returns: + bool: + Whether ECC memory is supported. + """ + return DPCTLDevice_GetErrorCorrectionSupport(self._device_ref) + + @property + def is_available(self): + """ Returns ``True`` if the device is available. + + Returns: + bool: + Whether the device is currently available. + """ + return DPCTLDevice_IsAvailable(self._device_ref) + + @property + def version(self): + """ Returns a backend-defined device version string. + + Returns: + str: + The device version string. + """ + cdef const char *ver = DPCTLDevice_GetVersion(self._device_ref) + if ver is NULL: + raise RuntimeError("Descriptor 'version' not available") + cdef str ver_str = ver.decode() + DPCTLCString_Delete(ver) + return ver_str + + @property + def backend_version(self): + """ Returns a backend-defined driver version string. + + Returns: + str: + The backend version string. + """ + cdef const char *ver = DPCTLDevice_GetBackendVersion(self._device_ref) + if ver is NULL: + raise RuntimeError("Descriptor 'backend_version' not available") + cdef str ver_str = ver.decode() + DPCTLCString_Delete(ver) + return ver_str + + @property + def local_mem_type(self): + """ Returns the type of local memory supported by the device. + + Returns: + :class:`dpctl.local_mem_type`: + The type of local memory (none, local, or global). + + Raises: + RuntimeError: + If an unrecognized memory type is reported by runtime. + """ + cdef _local_mem_type lmTy = ( + DPCTLDevice_GetLocalMemType(self._device_ref) + ) + if lmTy == _local_mem_type._LOCAL_MEM_TYPE_LOCAL: + return local_mem_type.local + elif lmTy == _local_mem_type._LOCAL_MEM_TYPE_GLOBAL: + return local_mem_type.global_mem + elif lmTy == _local_mem_type._LOCAL_MEM_TYPE_NONE: + return local_mem_type.none + raise RuntimeError("Unrecognized local memory type reported") + + @property + def partition_type_property(self): + """ Returns the partition property of this device if it is a + sub-device, or ``partition_property.no_partition`` if it is not a + sub-device. + + Returns: + :class:`dpctl.partition_property`: + The partition property that was used to create this device. + """ + cdef _partition_property_type ppTy = ( + DPCTLDevice_GetPartitionTypeProperty(self._device_ref) + ) + if ppTy == _partition_property_type._PARTITION_NO_PARTITION: + return partition_property.no_partition + elif ppTy == _partition_property_type._PARTITION_EQUALLY: + return partition_property.partition_equally + elif ppTy == _partition_property_type._PARTITION_BY_COUNTS: + return partition_property.partition_by_counts + elif ppTy == _partition_property_type._PARTITION_BY_AFFINITY_DOMAIN: + return partition_property.partition_by_affinity_domain + return partition_property.no_partition + + @property + def partition_type_affinity_domain(self): + """ Returns the partition affinity domain used to partition the parent + device if this is a sub-device partitioned by affinity domain, or + ``"not_applicable"`` otherwise. + + Returns: + str: + The affinity domain string. + """ + cdef _partition_affinity_domain_type padTy = ( + DPCTLDevice_GetPartitionTypeAffinityDomain(self._device_ref) + ) + if padTy == _partition_affinity_domain_type._not_applicable: + return "not_applicable" + elif padTy == _partition_affinity_domain_type._numa: + return "numa" + elif padTy == _partition_affinity_domain_type._L4_cache: + return "L4_cache" + elif padTy == _partition_affinity_domain_type._L3_cache: + return "L3_cache" + elif padTy == _partition_affinity_domain_type._L2_cache: + return "L2_cache" + elif padTy == _partition_affinity_domain_type._L1_cache: + return "L1_cache" + elif padTy == _partition_affinity_domain_type._next_partitionable: + return "next_partitionable" + return "not_applicable" + + @property + def half_fp_config(self): + """ Returns a tuple of :class:`dpctl.fp_config` enum members + describing half-precision floating-point capabilities of the device. + + Returns: + Tuple[:class:`dpctl.fp_config`]: + Tuple of floating-point configuration flags. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetHalfFPConfig(self._device_ref, &arr_len) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(fp_config(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def single_fp_config(self): + """ Returns a tuple of :class:`dpctl.fp_config` enum members + describing single-precision floating-point capabilities of the device. + + Returns: + Tuple[:class:`dpctl.fp_config`]: + Tuple of floating-point configuration flags. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetSingleFPConfig(self._device_ref, &arr_len) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(fp_config(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def double_fp_config(self): + """ Returns a tuple of :class:`dpctl.fp_config` enum members + describing double-precision floating-point capabilities of the device. + + Returns: + Tuple[:class:`dpctl.fp_config`]: + Tuple of floating-point configuration flags. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetDoubleFPConfig(self._device_ref, &arr_len) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(fp_config(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def atomic_memory_order_capabilities(self): + """ Returns a tuple of :class:`dpctl.memory_order` enum members + describing atomic memory order capabilities of the device. + + Returns: + Tuple[:class:`dpctl.memory_order`]: + Tuple of supported memory orders. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(memory_order(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def atomic_fence_order_capabilities(self): + """ Returns a tuple of :class:`dpctl.memory_order` enum members + describing atomic fence order capabilities of the device. + + Returns: + Tuple[:class:`dpctl.memory_order`]: + Tuple of supported fence orders. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetAtomicFenceOrderCapabilities( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(memory_order(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def atomic_memory_scope_capabilities(self): + """ Returns a tuple of :class:`dpctl.memory_scope` enum members + describing atomic memory scope capabilities of the device. + + Returns: + Tuple[:class:`dpctl.memory_scope`]: + Tuple of supported memory scopes. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(memory_scope(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def atomic_fence_scope_capabilities(self): + """ Returns a tuple of :class:`dpctl.memory_scope` enum members + describing atomic fence scope capabilities of the device. + + Returns: + Tuple[:class:`dpctl.memory_scope`]: + Tuple of supported fence scopes. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetAtomicFenceScopeCapabilities( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(memory_scope(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def partition_properties(self): + """ Returns a tuple of :class:`dpctl.partition_property` enum members + describing supported partition properties of the device. + + Returns: + Tuple[:class:`dpctl.partition_property`]: + Tuple of supported partition properties. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + + arr = DPCTLDevice_GetPartitionProperties( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(partition_property(arr[i] + 1)) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + + @property + def partition_affinity_domains(self): + """ Returns a tuple of strings describing supported partition + affinity domains of the device. + + Returns: + Tuple[str]: + Tuple of supported affinity domain names. + """ + cdef int *arr = NULL + cdef size_t arr_len = 0 + cdef size_t i + cdef list res + cdef dict _pad_map = { + _partition_affinity_domain_type._not_applicable: + "not_applicable", + _partition_affinity_domain_type._numa: "numa", + _partition_affinity_domain_type._L4_cache: "L4_cache", + _partition_affinity_domain_type._L3_cache: "L3_cache", + _partition_affinity_domain_type._L2_cache: "L2_cache", + _partition_affinity_domain_type._L1_cache: "L1_cache", + _partition_affinity_domain_type._next_partitionable: + "next_partitionable", + } + + arr = DPCTLDevice_GetPartitionAffinityDomains( + self._device_ref, &arr_len + ) + if arr is not NULL and arr_len > 0: + res = [] + for i in range(arr_len): + res.append(_pad_map.get(arr[i], "not_applicable")) + DPCTLInt_Array_Delete(arr) + return tuple(res) + if arr is not NULL: + DPCTLInt_Array_Delete(arr) + return () + cdef cpp_bool equals(self, SyclDevice other): """ Returns ``True`` if the :class:`dpctl.SyclDevice` argument has the same _device_ref as this SyclDevice. diff --git a/dpctl/enum_types.py b/dpctl/enum_types.py index 6872afa42e..f445ebb7f6 100644 --- a/dpctl/enum_types.py +++ b/dpctl/enum_types.py @@ -23,7 +23,17 @@ from enum import Enum, auto -__all__ = ["device_type", "backend_type", "event_status_type"] +__all__ = [ + "device_type", + "backend_type", + "event_status_type", + "global_mem_cache_type", + "local_mem_type", + "partition_property", + "fp_config", + "memory_order", + "memory_scope", +] class device_type(Enum): @@ -134,3 +144,145 @@ class global_mem_cache_type(Enum): none = auto() read_only = auto() read_write = auto() + + +class local_mem_type(Enum): + """ + An :class:`enum.Enum` of local memory types for a device. + + | ``none`` + | ``local`` + | ``global_mem`` + + :Example: + .. code-block:: python + + import dpctl + dev = dpctl.SyclDevice() + dev.local_mem_type + # Possible output: + """ + + none = auto() + local = auto() + global_mem = auto() + + +class partition_property(Enum): + """ + An :class:`enum.Enum` of partition property types. + + | ``no_partition`` + | ``partition_equally`` + | ``partition_by_counts`` + | ``partition_by_affinity_domain`` + + :Example: + .. code-block:: python + + import dpctl + dev = dpctl.SyclDevice() + dev.partition_type_property + # Possible output: + """ + + no_partition = auto() + partition_equally = auto() + partition_by_counts = auto() + partition_by_affinity_domain = auto() + + +class fp_config(Enum): + """ + An :class:`enum.Enum` of floating-point capability flags. + + | ``denorm`` + | ``inf_nan`` + | ``round_to_nearest`` + | ``round_to_zero`` + | ``round_to_inf`` + | ``fma`` + | ``correctly_rounded_divide_sqrt`` + | ``soft_float`` + + :Example: + .. code-block:: python + + import dpctl + dev = dpctl.SyclDevice() + dev.single_fp_config + # Possible output: ( + # , + # , + # ... + # ) + """ + + denorm = auto() + inf_nan = auto() + round_to_nearest = auto() + round_to_zero = auto() + round_to_inf = auto() + fma = auto() + correctly_rounded_divide_sqrt = auto() + soft_float = auto() + + +class memory_order(Enum): + """ + An :class:`enum.Enum` of memory ordering capabilities. + + | ``relaxed`` + | ``acquire`` + | ``release`` + | ``acq_rel`` + | ``seq_cst`` + + :Example: + .. code-block:: python + + import dpctl + dev = dpctl.SyclDevice() + dev.atomic_memory_order_capabilities + # Possible output: ( + # , + # , + # ... + # ) + """ + + relaxed = auto() + acquire = auto() + release = auto() + acq_rel = auto() + seq_cst = auto() + + +class memory_scope(Enum): + """ + An :class:`enum.Enum` of memory scope capabilities. + + | ``work_item`` + | ``sub_group`` + | ``work_group`` + | ``device`` + | ``system`` + + :Example: + .. code-block:: python + + import dpctl + dev = dpctl.SyclDevice() + dev.atomic_memory_scope_capabilities + # Possible output: ( + # , + # , + # ... + # ) + """ + + work_item = auto() + sub_group = auto() + work_group = auto() + device = auto() + system = auto() diff --git a/dpctl/tests/_device_attributes_checks.py b/dpctl/tests/_device_attributes_checks.py index 003eefa721..2639c78035 100644 --- a/dpctl/tests/_device_attributes_checks.py +++ b/dpctl/tests/_device_attributes_checks.py @@ -659,6 +659,146 @@ def check_global_mem_cache_line_size(device): assert gmc_sz +def check_vendor_id(device): + vid = device.vendor_id + assert isinstance(vid, int) + assert vid > 0 + + +def check_address_bits(device): + ab = device.address_bits + assert isinstance(ab, int) + assert ab in (32, 64) + + +def check_image_max_buffer_size(device): + sz = device.image_max_buffer_size + assert isinstance(sz, int) + assert sz >= 0 + + +def check_max_samplers(device): + ms = device.max_samplers + assert isinstance(ms, int) + assert ms >= 0 + + +def check_max_parameter_size(device): + mps = device.max_parameter_size + assert isinstance(mps, int) + assert mps > 0 + + +def check_mem_base_addr_align(device): + align = device.mem_base_addr_align + assert isinstance(align, int) + assert align > 0 + + +def check_error_correction_support(device): + ecs = device.error_correction_support + assert isinstance(ecs, bool) + + +def check_is_available(device): + avail = device.is_available + assert isinstance(avail, bool) + assert avail + + +def check_version(device): + ver = device.version + assert isinstance(ver, str) + assert len(ver) > 0 + + +def check_backend_version(device): + ver = device.backend_version + assert isinstance(ver, str) + + +def check_local_mem_type(device): + lmt = device.local_mem_type + assert type(lmt) is dpctl.local_mem_type + + +def check_partition_type_property(device): + ptp = device.partition_type_property + assert type(ptp) is dpctl.partition_property + + +def check_partition_type_affinity_domain(device): + ptad = device.partition_type_affinity_domain + assert isinstance(ptad, str) + + +def check_half_fp_config(device): + cfg = device.half_fp_config + assert isinstance(cfg, tuple) + for v in cfg: + assert type(v) is dpctl.fp_config + + +def check_single_fp_config(device): + cfg = device.single_fp_config + assert isinstance(cfg, tuple) + for v in cfg: + assert type(v) is dpctl.fp_config + + +def check_double_fp_config(device): + cfg = device.double_fp_config + assert isinstance(cfg, tuple) + for v in cfg: + assert type(v) is dpctl.fp_config + + +def check_atomic_memory_order_capabilities(device): + caps = device.atomic_memory_order_capabilities + assert isinstance(caps, tuple) + assert len(caps) > 0 + for v in caps: + assert type(v) is dpctl.memory_order + + +def check_atomic_fence_order_capabilities(device): + caps = device.atomic_fence_order_capabilities + assert isinstance(caps, tuple) + assert len(caps) > 0 + for v in caps: + assert type(v) is dpctl.memory_order + + +def check_atomic_memory_scope_capabilities(device): + caps = device.atomic_memory_scope_capabilities + assert isinstance(caps, tuple) + assert len(caps) > 0 + for v in caps: + assert type(v) is dpctl.memory_scope + + +def check_atomic_fence_scope_capabilities(device): + caps = device.atomic_fence_scope_capabilities + assert isinstance(caps, tuple) + assert len(caps) > 0 + for v in caps: + assert type(v) is dpctl.memory_scope + + +def check_partition_properties(device): + props = device.partition_properties + assert isinstance(props, tuple) + for v in props: + assert type(v) is dpctl.partition_property + + +def check_partition_affinity_domains(device): + domains = device.partition_affinity_domains + assert isinstance(domains, tuple) + for v in domains: + assert isinstance(v, str) + + list_of_checks = [ check_max_compute_units, check_max_work_item_dims, @@ -742,6 +882,28 @@ def check_global_mem_cache_line_size(device): check_global_mem_cache_line_size, check_max_clock_frequency, check_max_mem_alloc_size, + check_vendor_id, + check_address_bits, + check_image_max_buffer_size, + check_max_samplers, + check_max_parameter_size, + check_mem_base_addr_align, + check_error_correction_support, + check_is_available, + check_version, + check_backend_version, + check_local_mem_type, + check_partition_type_property, + check_partition_type_affinity_domain, + check_half_fp_config, + check_single_fp_config, + check_double_fp_config, + check_atomic_memory_order_capabilities, + check_atomic_fence_order_capabilities, + check_atomic_memory_scope_capabilities, + check_atomic_fence_scope_capabilities, + check_partition_properties, + check_partition_affinity_domains, ] diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h index c07a0f8f46..bfcf956957 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h @@ -828,4 +828,271 @@ DPCTL_API void DPCTLDevice_DisablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef, __dpctl_keep const DPCTLSyclDeviceRef PDRef); +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the vendor id of the device. + * @ingroup DeviceInterface + */ +DPCTL_API +uint32_t DPCTLDevice_GetVendorId(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the address space size (32 or 64 bits). + * @ingroup DeviceInterface + */ +DPCTL_API +uint32_t DPCTLDevice_GetAddressBits(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the max number of pixels for a 1D image from buffer. + * @ingroup DeviceInterface + */ +DPCTL_API +size_t +DPCTLDevice_GetImageMaxBufferSize(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the maximum number of samplers that can be used in a + * kernel. + * @ingroup DeviceInterface + */ +DPCTL_API +uint32_t DPCTLDevice_GetMaxSamplers(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the max size in bytes of all arguments passed to a kernel. + * @ingroup DeviceInterface + */ +DPCTL_API +size_t +DPCTLDevice_GetMaxParameterSize(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the minimum alignment in bits for memory allocations. + * @ingroup DeviceInterface + */ +DPCTL_API +uint32_t +DPCTLDevice_GetMemBaseAddrAlign(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns true if the device supports ECC memory. + * @ingroup DeviceInterface + */ +DPCTL_API +bool DPCTLDevice_GetErrorCorrectionSupport( + __dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns true if the device is available. + * @ingroup DeviceInterface + */ +DPCTL_API +bool DPCTLDevice_IsAvailable(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns a C string with the device version. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_give const char * +DPCTLDevice_GetVersion(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns a C string with the backend version. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_give const char * +DPCTLDevice_GetBackendVersion(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the type of local memory supported. + * @ingroup DeviceInterface + */ +DPCTL_API +DPCTLLocalMemType +DPCTLDevice_GetLocalMemType(__dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the partition property used to create this device. + * @ingroup DeviceInterface + */ +DPCTL_API +DPCTLPartitionPropertyType DPCTLDevice_GetPartitionTypeProperty( + __dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @return Returns the affinity domain used to partition the parent device. + * @ingroup DeviceInterface + */ +DPCTL_API +DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( + __dpctl_keep const DPCTLSyclDeviceRef DRef); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLFPConfigType values. Caller must free + * with DPCTLSize_t_Array_Delete. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int * +DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLFPConfigType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int * +DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLFPConfigType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int * +DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLMemoryOrderType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLMemoryOrderType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLMemoryScopeType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLMemoryScopeType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLPartitionPropertyType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int * +DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + +/*! + * @brief Wrapper over + * device.get_info(). + * + * @param DRef Opaque pointer to a ``sycl::device`` + * @param res_len Populated with size of the returned array + * @return Returns an array of DPCTLPartitionAffinityDomainType values. + * @ingroup DeviceInterface + */ +DPCTL_API +__dpctl_keep int *DPCTLDevice_GetPartitionAffinityDomains( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len); + DPCTL_C_EXTERN_C_END diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h index e6ee311980..899c093b44 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h @@ -192,4 +192,49 @@ typedef enum DPCTL_MEM_CACHE_TYPE_READ_WRITE } DPCTLGlobalMemCacheType; +typedef enum +{ + DPCTL_LOCAL_MEM_TYPE_NONE, + DPCTL_LOCAL_MEM_TYPE_LOCAL, + DPCTL_LOCAL_MEM_TYPE_GLOBAL +} DPCTLLocalMemType; + +typedef enum +{ + DPCTL_PARTITION_NO_PARTITION, + DPCTL_PARTITION_EQUALLY, + DPCTL_PARTITION_BY_COUNTS, + DPCTL_PARTITION_BY_AFFINITY_DOMAIN +} DPCTLPartitionPropertyType; + +typedef enum +{ + DPCTL_FP_DENORM, + DPCTL_FP_INF_NAN, + DPCTL_FP_ROUND_TO_NEAREST, + DPCTL_FP_ROUND_TO_ZERO, + DPCTL_FP_ROUND_TO_INF, + DPCTL_FP_FMA, + DPCTL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT, + DPCTL_FP_SOFT_FLOAT +} DPCTLFPConfigType; + +typedef enum +{ + DPCTL_MEMORY_ORDER_RELAXED, + DPCTL_MEMORY_ORDER_ACQUIRE, + DPCTL_MEMORY_ORDER_RELEASE, + DPCTL_MEMORY_ORDER_ACQ_REL, + DPCTL_MEMORY_ORDER_SEQ_CST +} DPCTLMemoryOrderType; + +typedef enum +{ + DPCTL_MEMORY_SCOPE_WORK_ITEM, + DPCTL_MEMORY_SCOPE_SUB_GROUP, + DPCTL_MEMORY_SCOPE_WORK_GROUP, + DPCTL_MEMORY_SCOPE_DEVICE, + DPCTL_MEMORY_SCOPE_SYSTEM +} DPCTLMemoryScopeType; + DPCTL_C_EXTERN_C_END diff --git a/libsyclinterface/include/syclinterface/dpctl_utils.h b/libsyclinterface/include/syclinterface/dpctl_utils.h index d124869062..bdf5709784 100644 --- a/libsyclinterface/include/syclinterface/dpctl_utils.h +++ b/libsyclinterface/include/syclinterface/dpctl_utils.h @@ -47,4 +47,12 @@ void DPCTLCString_Delete(__dpctl_take const char *str); DPCTL_API void DPCTLSize_t_Array_Delete(__dpctl_take size_t *arr); +/*! + * @brief Deletes an array of int elements. + * + * @param arr Array to be deleted. + */ +DPCTL_API +void DPCTLInt_Array_Delete(__dpctl_take int *arr); + DPCTL_C_EXTERN_C_END diff --git a/libsyclinterface/source/dpctl_sycl_device_interface.cpp b/libsyclinterface/source/dpctl_sycl_device_interface.cpp index 65be01a0bb..12ec15e747 100644 --- a/libsyclinterface/source/dpctl_sycl_device_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_device_interface.cpp @@ -982,3 +982,417 @@ void DPCTLDevice_DisablePeerAccess(__dpctl_keep const DPCTLSyclDeviceRef DRef, } return; } + +uint32_t DPCTLDevice_GetVendorId(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + uint32_t vendorId = 0; + auto D = unwrap(DRef); + if (D) { + try { + vendorId = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return vendorId; +} + +uint32_t DPCTLDevice_GetAddressBits(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + uint32_t addressBits = 0; + auto D = unwrap(DRef); + if (D) { + try { + addressBits = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return addressBits; +} + +size_t +DPCTLDevice_GetImageMaxBufferSize(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + size_t result = 0; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +uint32_t DPCTLDevice_GetMaxSamplers(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + uint32_t result = 0; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +size_t +DPCTLDevice_GetMaxParameterSize(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + size_t result = 0; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +uint32_t +DPCTLDevice_GetMemBaseAddrAlign(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + uint32_t result = 0; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +bool DPCTLDevice_GetErrorCorrectionSupport( + __dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + bool result = false; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +bool DPCTLDevice_IsAvailable(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + bool result = false; + auto D = unwrap(DRef); + if (D) { + try { + result = D->get_info(); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return result; +} + +__dpctl_give const char * +DPCTLDevice_GetVersion(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + const char *cstr_version = nullptr; + auto D = unwrap(DRef); + if (D) { + try { + auto version = D->get_info(); + cstr_version = dpctl::helper::cstring_from_string(version); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return cstr_version; +} + +__dpctl_give const char * +DPCTLDevice_GetBackendVersion(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + const char *cstr_version = nullptr; + auto D = unwrap(DRef); + if (D) { + try { + auto version = D->get_info(); + cstr_version = dpctl::helper::cstring_from_string(version); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return cstr_version; +} + +DPCTLLocalMemType +DPCTLDevice_GetLocalMemType(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + if (DRef) { + auto D = unwrap(DRef); + try { + auto mem_type = D->get_info(); + switch (mem_type) { + case info::local_mem_type::none: + return DPCTL_LOCAL_MEM_TYPE_NONE; + case info::local_mem_type::local: + return DPCTL_LOCAL_MEM_TYPE_LOCAL; + case info::local_mem_type::global: + return DPCTL_LOCAL_MEM_TYPE_GLOBAL; + } + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return DPCTL_LOCAL_MEM_TYPE_NONE; +} + +DPCTLPartitionPropertyType +DPCTLDevice_GetPartitionTypeProperty(__dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + if (DRef) { + auto D = unwrap(DRef); + try { + auto pp = D->get_info(); + switch (pp) { + case info::partition_property::no_partition: + return DPCTL_PARTITION_NO_PARTITION; + case info::partition_property::partition_equally: + return DPCTL_PARTITION_EQUALLY; + case info::partition_property::partition_by_counts: + return DPCTL_PARTITION_BY_COUNTS; + case info::partition_property::partition_by_affinity_domain: + return DPCTL_PARTITION_BY_AFFINITY_DOMAIN; + default: + // TODO: investigate ext_intel_partition_by_cslice extension + break; + } + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return DPCTL_PARTITION_NO_PARTITION; +} + +DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( + __dpctl_keep const DPCTLSyclDeviceRef DRef) +{ + if (DRef) { + auto D = unwrap(DRef); + try { + auto domain = + D->get_info(); + return DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain); + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + } + } + return DPCTLPartitionAffinityDomainType::not_applicable; +} + +namespace +{ + +int dpctl_fp_config_to_int(info::fp_config fc) +{ + switch (fc) { + case info::fp_config::denorm: + return DPCTL_FP_DENORM; + case info::fp_config::inf_nan: + return DPCTL_FP_INF_NAN; + case info::fp_config::round_to_nearest: + return DPCTL_FP_ROUND_TO_NEAREST; + case info::fp_config::round_to_zero: + return DPCTL_FP_ROUND_TO_ZERO; + case info::fp_config::round_to_inf: + return DPCTL_FP_ROUND_TO_INF; + case info::fp_config::fma: + return DPCTL_FP_FMA; + case info::fp_config::correctly_rounded_divide_sqrt: + return DPCTL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT; + case info::fp_config::soft_float: + return DPCTL_FP_SOFT_FLOAT; + } + return -1; +} + +int dpctl_memory_order_to_int(sycl::memory_order mo) +{ + switch (mo) { + case sycl::memory_order::relaxed: + return DPCTL_MEMORY_ORDER_RELAXED; + case sycl::memory_order::acquire: + return DPCTL_MEMORY_ORDER_ACQUIRE; + case sycl::memory_order::release: + return DPCTL_MEMORY_ORDER_RELEASE; + case sycl::memory_order::acq_rel: + return DPCTL_MEMORY_ORDER_ACQ_REL; + case sycl::memory_order::seq_cst: + return DPCTL_MEMORY_ORDER_SEQ_CST; + default: + return -1; + } +} + +int dpctl_memory_scope_to_int(sycl::memory_scope ms) +{ + switch (ms) { + case sycl::memory_scope::work_item: + return DPCTL_MEMORY_SCOPE_WORK_ITEM; + case sycl::memory_scope::sub_group: + return DPCTL_MEMORY_SCOPE_SUB_GROUP; + case sycl::memory_scope::work_group: + return DPCTL_MEMORY_SCOPE_WORK_GROUP; + case sycl::memory_scope::device: + return DPCTL_MEMORY_SCOPE_DEVICE; + case sycl::memory_scope::system: + return DPCTL_MEMORY_SCOPE_SYSTEM; + } + return -1; +} + +int dpctl_partition_property_to_int(info::partition_property pp) +{ + switch (pp) { + case info::partition_property::no_partition: + return DPCTL_PARTITION_NO_PARTITION; + case info::partition_property::partition_equally: + return DPCTL_PARTITION_EQUALLY; + case info::partition_property::partition_by_counts: + return DPCTL_PARTITION_BY_COUNTS; + case info::partition_property::partition_by_affinity_domain: + return DPCTL_PARTITION_BY_AFFINITY_DOMAIN; + default: + // TODO: investigate ext_intel_partition_by_cslice extension + return -1; + } +} + +int dpctl_partition_affinity_domain_to_int(info::partition_affinity_domain pad) +{ + switch (pad) { + case info::partition_affinity_domain::not_applicable: + return DPCTLPartitionAffinityDomainType::not_applicable; + case info::partition_affinity_domain::numa: + return DPCTLPartitionAffinityDomainType::numa; + case info::partition_affinity_domain::L4_cache: + return DPCTLPartitionAffinityDomainType::L4_cache; + case info::partition_affinity_domain::L3_cache: + return DPCTLPartitionAffinityDomainType::L3_cache; + case info::partition_affinity_domain::L2_cache: + return DPCTLPartitionAffinityDomainType::L2_cache; + case info::partition_affinity_domain::L1_cache: + return DPCTLPartitionAffinityDomainType::L1_cache; + case info::partition_affinity_domain::next_partitionable: + return DPCTLPartitionAffinityDomainType::next_partitionable; + } + return DPCTLPartitionAffinityDomainType::not_applicable; +} + +template +int *get_info_enum_array(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len, + ConvertFn convert) +{ + int *arr = nullptr; + *res_len = 0; + auto D = unwrap(DRef); + if (D) { + try { + auto values = D->get_info(); + *res_len = values.size(); + if (*res_len > 0) { + arr = new int[*res_len]; + for (size_t i = 0; i < *res_len; ++i) { + arr[i] = convert(values[i]); + } + } + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); + delete[] arr; + arr = nullptr; + *res_len = 0; + } + } + return arr; +} + +} // end of anonymous namespace + +__dpctl_keep int * +DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_fp_config_to_int); +} + +__dpctl_keep int * +DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_fp_config_to_int); +} + +__dpctl_keep int * +DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_fp_config_to_int); +} + +__dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_memory_order_to_int); +} + +__dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_memory_order_to_int); +} + +__dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_memory_scope_to_int); +} + +__dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_memory_scope_to_int); +} + +__dpctl_keep int * +DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_partition_property_to_int); +} + +__dpctl_keep int *DPCTLDevice_GetPartitionAffinityDomains( + __dpctl_keep const DPCTLSyclDeviceRef DRef, + size_t *res_len) +{ + return get_info_enum_array( + DRef, res_len, dpctl_partition_affinity_domain_to_int); +} diff --git a/libsyclinterface/source/dpctl_utils.cpp b/libsyclinterface/source/dpctl_utils.cpp index 16c79fc8b0..0d4eb8840b 100644 --- a/libsyclinterface/source/dpctl_utils.cpp +++ b/libsyclinterface/source/dpctl_utils.cpp @@ -29,3 +29,5 @@ void DPCTLCString_Delete(__dpctl_take const char *str) { delete[] str; } void DPCTLSize_t_Array_Delete(__dpctl_take size_t *arr) { delete[] arr; } + +void DPCTLInt_Array_Delete(__dpctl_take int *arr) { delete[] arr; } diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index 3aa89b53be..dd7b8ac11c 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -551,6 +551,136 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetCompositeDevice) } } +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetVendorId) +{ + uint32_t vid = 0; + EXPECT_NO_FATAL_FAILURE(vid = DPCTLDevice_GetVendorId(DRef)); + EXPECT_TRUE(vid > 0); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAddressBits) +{ + uint32_t ab = 0; + EXPECT_NO_FATAL_FAILURE(ab = DPCTLDevice_GetAddressBits(DRef)); + EXPECT_TRUE(ab == 32 || ab == 64); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxSamplers) +{ + uint32_t ms = 0; + EXPECT_NO_FATAL_FAILURE(ms = DPCTLDevice_GetMaxSamplers(DRef)); + EXPECT_TRUE(ms >= 0); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxParameterSize) +{ + size_t mps = 0; + EXPECT_NO_FATAL_FAILURE(mps = DPCTLDevice_GetMaxParameterSize(DRef)); + EXPECT_TRUE(mps > 0); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMemBaseAddrAlign) +{ + uint32_t align = 0; + EXPECT_NO_FATAL_FAILURE(align = DPCTLDevice_GetMemBaseAddrAlign(DRef)); + EXPECT_TRUE(align > 0); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetErrorCorrectionSupport) +{ + bool ecs = false; + EXPECT_NO_FATAL_FAILURE(ecs = DPCTLDevice_GetErrorCorrectionSupport(DRef)); + (void)ecs; +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkIsAvailable) +{ + bool avail = false; + EXPECT_NO_FATAL_FAILURE(avail = DPCTLDevice_IsAvailable(DRef)); + EXPECT_TRUE(avail); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetVersion) +{ + const char *ver = nullptr; + EXPECT_NO_FATAL_FAILURE(ver = DPCTLDevice_GetVersion(DRef)); + EXPECT_TRUE(ver != nullptr); + EXPECT_NO_FATAL_FAILURE(DPCTLCString_Delete(ver)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetBackendVersion) +{ + const char *ver = nullptr; + EXPECT_NO_FATAL_FAILURE(ver = DPCTLDevice_GetBackendVersion(DRef)); + EXPECT_TRUE(ver != nullptr); + EXPECT_NO_FATAL_FAILURE(DPCTLCString_Delete(ver)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetLocalMemType) +{ + DPCTLLocalMemType lmt; + EXPECT_NO_FATAL_FAILURE(lmt = DPCTLDevice_GetLocalMemType(DRef)); + EXPECT_TRUE(lmt == DPCTL_LOCAL_MEM_TYPE_NONE || + lmt == DPCTL_LOCAL_MEM_TYPE_LOCAL || + lmt == DPCTL_LOCAL_MEM_TYPE_GLOBAL); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionTypeProperty) +{ + DPCTLPartitionPropertyType ptp; + EXPECT_NO_FATAL_FAILURE(ptp = DPCTLDevice_GetPartitionTypeProperty(DRef)); + EXPECT_TRUE(ptp == DPCTL_PARTITION_NO_PARTITION || + ptp == DPCTL_PARTITION_EQUALLY || + ptp == DPCTL_PARTITION_BY_COUNTS || + ptp == DPCTL_PARTITION_BY_AFFINITY_DOMAIN); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetSingleFPConfig) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetSingleFPConfig(DRef, &len)); + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + if (arr) + delete[] arr; +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryOrderCapabilities) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities(DRef, &len)); + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + if (arr) + delete[] arr; +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryScopeCapabilities) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities(DRef, &len)); + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + if (arr) + delete[] arr; +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionProperties) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE(arr = + DPCTLDevice_GetPartitionProperties(DRef, &len)); + // may be empty if device doesn't support partitioning + if (arr) + delete[] arr; +} + INSTANTIATE_TEST_SUITE_P(DPCTLDeviceFns, TestDPCTLSyclDeviceInterface, ::testing::Values("opencl", From 0ca163fe8ceca18bf481a77654a64b9443fe08eb Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Mon, 3 Aug 2026 12:58:48 -0700 Subject: [PATCH 02/13] add missing enums to docs --- docs/doc_sources/api_reference/dpctl/constants.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/doc_sources/api_reference/dpctl/constants.rst b/docs/doc_sources/api_reference/dpctl/constants.rst index a7a44a69d1..b1b5b70f13 100644 --- a/docs/doc_sources/api_reference/dpctl/constants.rst +++ b/docs/doc_sources/api_reference/dpctl/constants.rst @@ -14,3 +14,13 @@ The following constants are defined in :py:mod:`dpctl`: .. autodata:: event_status_type .. autodata:: global_mem_cache_type + +.. autodata:: local_mem_type + +.. autodata:: partition_property + +.. autodata:: fp_config + +.. autodata:: memory_order + +.. autodata:: memory_scope From 4d65de0c27eb018f48c2b8e85546bc6140662457 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Mon, 3 Aug 2026 13:21:42 -0700 Subject: [PATCH 03/13] Fix missing validation of returned enums --- dpctl/_sycl_device.pyx | 161 +++++++++++++++++++---------------------- 1 file changed, 73 insertions(+), 88 deletions(-) diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index aa506751f3..e3e02d9fda 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -209,6 +209,28 @@ cdef tuple _get_devices(DPCTLDeviceVectorRef DVRef): return tuple(devices) +cdef tuple _to_enum_tuple( + int *arr, size_t arr_len, object enum_type, str descr +): + """ + Converts an array of DPCTL enum values into a tuple of ``enum_type``s + """ + cdef list res = [] + cdef size_t i + + if arr is NULL: + return () + try: + for i in range(arr_len): + if arr[i] < 0: + raise RuntimeError(f"Unrecognized {descr} reported") + res.append(enum_type(arr[i] + 1)) + finally: + DPCTLInt_Array_Delete(arr) + + return tuple(res) + + cdef str _backend_type_to_filter_string_part(_backend_type BTy): if BTy == _backend_type._CUDA: return "cuda" @@ -2357,22 +2379,19 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.fp_config`]: Tuple of floating-point configuration flags. + + Raises: + RuntimeError: + If an unrecognized floating-point configuration flag is + reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetHalfFPConfig(self._device_ref, &arr_len) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(fp_config(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple( + arr, arr_len, fp_config, "floating-point configuration flag" + ) @property def single_fp_config(self): @@ -2382,22 +2401,19 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.fp_config`]: Tuple of floating-point configuration flags. + + Raises: + RuntimeError: + If an unrecognized floating-point configuration flag is + reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetSingleFPConfig(self._device_ref, &arr_len) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(fp_config(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple( + arr, arr_len, fp_config, "floating-point configuration flag" + ) @property def double_fp_config(self): @@ -2407,22 +2423,19 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.fp_config`]: Tuple of floating-point configuration flags. + + Raises: + RuntimeError: + If an unrecognized floating-point configuration flag is + reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetDoubleFPConfig(self._device_ref, &arr_len) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(fp_config(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple( + arr, arr_len, fp_config, "floating-point configuration flag" + ) @property def atomic_memory_order_capabilities(self): @@ -2432,24 +2445,18 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.memory_order`]: Tuple of supported memory orders. + + Raises: + RuntimeError: + If an unrecognized memory order is reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(memory_order(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple(arr, arr_len, memory_order, "memory order") @property def atomic_fence_order_capabilities(self): @@ -2459,24 +2466,18 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.memory_order`]: Tuple of supported fence orders. + + Raises: + RuntimeError: + If an unrecognized memory order is reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetAtomicFenceOrderCapabilities( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(memory_order(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple(arr, arr_len, memory_order, "memory order") @property def atomic_memory_scope_capabilities(self): @@ -2486,24 +2487,18 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.memory_scope`]: Tuple of supported memory scopes. + + Raises: + RuntimeError: + If an unrecognized memory scope is reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(memory_scope(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple(arr, arr_len, memory_scope, "memory scope") @property def atomic_fence_scope_capabilities(self): @@ -2513,24 +2508,18 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.memory_scope`]: Tuple of supported fence scopes. + + Raises: + RuntimeError: + If an unrecognized memory scope is reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetAtomicFenceScopeCapabilities( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(memory_scope(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple(arr, arr_len, memory_scope, "memory scope") @property def partition_properties(self): @@ -2540,24 +2529,20 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[:class:`dpctl.partition_property`]: Tuple of supported partition properties. + + Raises: + RuntimeError: + If an unrecognized partition property is reported by runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 - cdef size_t i - cdef list res arr = DPCTLDevice_GetPartitionProperties( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: - res = [] - for i in range(arr_len): - res.append(partition_property(arr[i] + 1)) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: - DPCTLInt_Array_Delete(arr) - return () + return _to_enum_tuple( + arr, arr_len, partition_property, "partition property" + ) @property def partition_affinity_domains(self): From 9f7a28f5bdc154998769a59914b71ab7908e9c50 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Mon, 3 Aug 2026 13:23:14 -0700 Subject: [PATCH 04/13] use array deletion utilities in new C++ tests --- .../tests/test_sycl_device_interface.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index dd7b8ac11c..c24f507c7b 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -642,8 +642,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetSingleFPConfig) EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetSingleFPConfig(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); - if (arr) - delete[] arr; + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryOrderCapabilities) @@ -654,8 +653,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryOrderCapabilities) arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); - if (arr) - delete[] arr; + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryScopeCapabilities) @@ -666,8 +664,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryScopeCapabilities) arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); - if (arr) - delete[] arr; + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionProperties) @@ -677,8 +674,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionProperties) EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetPartitionProperties(DRef, &len)); // may be empty if device doesn't support partitioning - if (arr) - delete[] arr; + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } INSTANTIATE_TEST_SUITE_P(DPCTLDeviceFns, From 7e100978a2d6a31824bf830421492b2898270e69 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Mon, 3 Aug 2026 13:25:00 -0700 Subject: [PATCH 05/13] remove deletion instruction from docstring --- .../include/syclinterface/dpctl_sycl_device_interface.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h index bfcf956957..27477caefb 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h @@ -976,8 +976,7 @@ DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( * * @param DRef Opaque pointer to a ``sycl::device`` * @param res_len Populated with size of the returned array - * @return Returns an array of DPCTLFPConfigType values. Caller must free - * with DPCTLSize_t_Array_Delete. + * @return Returns an array of DPCTLFPConfigType values. * @ingroup DeviceInterface */ DPCTL_API From 38b62bf95c03f7aaaba523360b7d310bde02311c Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Mon, 3 Aug 2026 15:33:37 -0700 Subject: [PATCH 06/13] add null tests for new APIs --- .../tests/test_sycl_device_interface.cpp | 304 ++++++++++++++++++ 1 file changed, 304 insertions(+) diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index c24f507c7b..604f9db2f3 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -472,6 +472,16 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetImage3dMaxDepth) EXPECT_TRUE(image_3d_max_depth >= min_val); } +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetImageMaxBufferSize) +{ + size_t image_max_buffer_size = 0; + EXPECT_NO_FATAL_FAILURE(image_max_buffer_size = + DPCTLDevice_GetImageMaxBufferSize(DRef)); + if (DPCTLDevice_HasAspect(DRef, DPCTL_SyclAspectToDPCTLAspectType( + DPCTL_StrToAspectType("image")))) + EXPECT_TRUE(image_max_buffer_size > 0); +} + TEST_P(TestDPCTLSyclDeviceInterface, ChkGetParentDevice) { DPCTLSyclDeviceRef pDRef = nullptr; @@ -635,6 +645,24 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionTypeProperty) ptp == DPCTL_PARTITION_BY_AFFINITY_DOMAIN); } +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetHalfFPConfig) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetHalfFPConfig(DRef, &len)); + // half_fp_config is empty for devices without aspect::fp16 + if (DPCTLDevice_HasAspect(DRef, DPCTL_SyclAspectToDPCTLAspectType( + DPCTL_StrToAspectType("fp16")))) + { + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + } + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_FP_DENORM && arr[i] <= DPCTL_FP_SOFT_FLOAT); + } + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); +} + TEST_P(TestDPCTLSyclDeviceInterface, ChkGetSingleFPConfig) { int *arr = nullptr; @@ -642,6 +670,27 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetSingleFPConfig) EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetSingleFPConfig(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_FP_DENORM && arr[i] <= DPCTL_FP_SOFT_FLOAT); + } + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetDoubleFPConfig) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetDoubleFPConfig(DRef, &len)); + // double_fp_config is empty for devices without aspect::fp64 + if (DPCTLDevice_HasAspect(DRef, DPCTL_SyclAspectToDPCTLAspectType( + DPCTL_StrToAspectType("fp64")))) + { + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + } + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_FP_DENORM && arr[i] <= DPCTL_FP_SOFT_FLOAT); + } EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } @@ -653,6 +702,25 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryOrderCapabilities) arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_MEMORY_ORDER_RELAXED && + arr[i] <= DPCTL_MEMORY_ORDER_SEQ_CST); + } + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicFenceOrderCapabilities) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicFenceOrderCapabilities(DRef, &len)); + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_MEMORY_ORDER_RELAXED && + arr[i] <= DPCTL_MEMORY_ORDER_SEQ_CST); + } EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } @@ -664,6 +732,25 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicMemoryScopeCapabilities) arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities(DRef, &len)); EXPECT_TRUE(len > 0); EXPECT_TRUE(arr != nullptr); + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_MEMORY_SCOPE_WORK_ITEM && + arr[i] <= DPCTL_MEMORY_SCOPE_SYSTEM); + } + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAtomicFenceScopeCapabilities) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicFenceScopeCapabilities(DRef, &len)); + EXPECT_TRUE(len > 0); + EXPECT_TRUE(arr != nullptr); + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_MEMORY_SCOPE_WORK_ITEM && + arr[i] <= DPCTL_MEMORY_SCOPE_SYSTEM); + } EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } @@ -674,9 +761,42 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionProperties) EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetPartitionProperties(DRef, &len)); // may be empty if device doesn't support partitioning + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE(arr[i] >= DPCTL_PARTITION_NO_PARTITION && + arr[i] <= DPCTL_PARTITION_BY_AFFINITY_DOMAIN); + } EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionAffinityDomains) +{ + int *arr = nullptr; + size_t len = 0; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetPartitionAffinityDomains(DRef, &len)); + // may be empty if device doesn't support partitioning by affinity + for (size_t i = 0; i < len; ++i) { + EXPECT_TRUE( + arr[i] >= DPCTLPartitionAffinityDomainType::not_applicable && + arr[i] <= DPCTLPartitionAffinityDomainType::next_partitionable); + } + EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); +} + +TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionTypeAffinityDomain) +{ + DPCTLPartitionAffinityDomainType ptad; + EXPECT_NO_FATAL_FAILURE( + ptad = DPCTLDevice_GetPartitionTypeAffinityDomain(DRef)); + EXPECT_TRUE(ptad == DPCTLPartitionAffinityDomainType::not_applicable || + ptad == DPCTLPartitionAffinityDomainType::numa || + ptad == DPCTLPartitionAffinityDomainType::L4_cache || + ptad == DPCTLPartitionAffinityDomainType::L3_cache || + ptad == DPCTLPartitionAffinityDomainType::L2_cache || + ptad == DPCTLPartitionAffinityDomainType::L1_cache || + ptad == DPCTLPartitionAffinityDomainType::next_partitionable); +} + INSTANTIATE_TEST_SUITE_P(DPCTLDeviceFns, TestDPCTLSyclDeviceInterface, ::testing::Values("opencl", @@ -1051,3 +1171,187 @@ TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetCompositeDevice) EXPECT_NO_FATAL_FAILURE(CDRef = DPCTLDevice_GetCompositeDevice(Null_DRef)); EXPECT_TRUE(CDRef == nullptr); } + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetImageMaxBufferSize) +{ + size_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetImageMaxBufferSize(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetHalfFPConfig) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE(arr = DPCTLDevice_GetHalfFPConfig(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetDoubleFPConfig) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE(arr = + DPCTLDevice_GetDoubleFPConfig(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetAtomicFenceOrderCapabilities) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicFenceOrderCapabilities(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetAtomicFenceScopeCapabilities) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicFenceScopeCapabilities(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionAffinityDomains) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetPartitionAffinityDomains(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionTypeAffinityDomain) +{ + DPCTLPartitionAffinityDomainType res = + DPCTLPartitionAffinityDomainType::numa; + EXPECT_NO_FATAL_FAILURE( + res = DPCTLDevice_GetPartitionTypeAffinityDomain(Null_DRef)); + ASSERT_TRUE(res == DPCTLPartitionAffinityDomainType::not_applicable); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetVendorId) +{ + uint32_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetVendorId(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetAddressBits) +{ + uint32_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetAddressBits(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetMaxSamplers) +{ + uint32_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetMaxSamplers(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetMaxParameterSize) +{ + size_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetMaxParameterSize(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetMemBaseAddrAlign) +{ + uint32_t res = 1; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetMemBaseAddrAlign(Null_DRef)); + ASSERT_TRUE(res == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetErrorCorrectionSupport) +{ + bool res = true; + EXPECT_NO_FATAL_FAILURE( + res = DPCTLDevice_GetErrorCorrectionSupport(Null_DRef)); + ASSERT_FALSE(res); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkIsAvailable) +{ + bool res = true; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_IsAvailable(Null_DRef)); + ASSERT_FALSE(res); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetVersion) +{ + const char *version = nullptr; + EXPECT_NO_FATAL_FAILURE(version = DPCTLDevice_GetVersion(Null_DRef)); + ASSERT_TRUE(version == nullptr); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetBackendVersion) +{ + const char *version = nullptr; + EXPECT_NO_FATAL_FAILURE(version = DPCTLDevice_GetBackendVersion(Null_DRef)); + ASSERT_TRUE(version == nullptr); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetLocalMemType) +{ + DPCTLLocalMemType res = DPCTL_LOCAL_MEM_TYPE_LOCAL; + EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetLocalMemType(Null_DRef)); + ASSERT_TRUE(res == DPCTL_LOCAL_MEM_TYPE_NONE); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionTypeProperty) +{ + DPCTLPartitionPropertyType res = DPCTL_PARTITION_EQUALLY; + EXPECT_NO_FATAL_FAILURE( + res = DPCTLDevice_GetPartitionTypeProperty(Null_DRef)); + ASSERT_TRUE(res == DPCTL_PARTITION_NO_PARTITION); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetSingleFPConfig) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE(arr = + DPCTLDevice_GetSingleFPConfig(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetAtomicMemoryOrderCapabilities) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicMemoryOrderCapabilities(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetAtomicMemoryScopeCapabilities) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetAtomicMemoryScopeCapabilities(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} + +TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionProperties) +{ + int *arr = nullptr; + size_t len = 1; + EXPECT_NO_FATAL_FAILURE( + arr = DPCTLDevice_GetPartitionProperties(Null_DRef, &len)); + ASSERT_TRUE(arr == nullptr); + ASSERT_TRUE(len == 0); +} From 559c9e57169e41638e503b57519d828e438e1fe5 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 10:47:12 -0700 Subject: [PATCH 07/13] fix __dpctl_keep to __dpctl_give where appropriate --- .../dpctl_sycl_device_interface.h | 18 +++++++++--------- .../source/dpctl_sycl_device_interface.cpp | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h index 27477caefb..9f1e1eece1 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h @@ -980,7 +980,7 @@ DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -993,7 +993,7 @@ DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1006,7 +1006,7 @@ DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1020,7 +1020,7 @@ DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1034,7 +1034,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicFenceOrderCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1048,7 +1048,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1062,7 +1062,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicFenceScopeCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1076,7 +1076,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); @@ -1090,7 +1090,7 @@ DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep int *DPCTLDevice_GetPartitionAffinityDomains( +__dpctl_give int *DPCTLDevice_GetPartitionAffinityDomains( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); diff --git a/libsyclinterface/source/dpctl_sycl_device_interface.cpp b/libsyclinterface/source/dpctl_sycl_device_interface.cpp index 12ec15e747..535876a3b7 100644 --- a/libsyclinterface/source/dpctl_sycl_device_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_device_interface.cpp @@ -1325,7 +1325,7 @@ int *get_info_enum_array(__dpctl_keep const DPCTLSyclDeviceRef DRef, } // end of anonymous namespace -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1333,7 +1333,7 @@ DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, DRef, res_len, dpctl_fp_config_to_int); } -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1341,7 +1341,7 @@ DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, DRef, res_len, dpctl_fp_config_to_int); } -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1349,7 +1349,7 @@ DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, DRef, res_len, dpctl_fp_config_to_int); } -__dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1357,7 +1357,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( DRef, res_len, dpctl_memory_order_to_int); } -__dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicFenceOrderCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1365,7 +1365,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicFenceOrderCapabilities( DRef, res_len, dpctl_memory_order_to_int); } -__dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1373,7 +1373,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( DRef, res_len, dpctl_memory_scope_to_int); } -__dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( +__dpctl_give int *DPCTLDevice_GetAtomicFenceScopeCapabilities( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1381,7 +1381,7 @@ __dpctl_keep int *DPCTLDevice_GetAtomicFenceScopeCapabilities( DRef, res_len, dpctl_memory_scope_to_int); } -__dpctl_keep int * +__dpctl_give int * DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { @@ -1389,7 +1389,7 @@ DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, DRef, res_len, dpctl_partition_property_to_int); } -__dpctl_keep int *DPCTLDevice_GetPartitionAffinityDomains( +__dpctl_give int *DPCTLDevice_GetPartitionAffinityDomains( __dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { From 4995e8471ba266a2f672679b0b52fb728d01da3b Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 10:50:22 -0700 Subject: [PATCH 08/13] fixed functions mislabeled with __dpctl_keep --- .../syclinterface/dpctl_sycl_device_interface.h | 8 ++++---- .../source/dpctl_sycl_device_interface.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h index 9f1e1eece1..2d8bfad0c6 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_device_interface.h @@ -208,7 +208,7 @@ DPCTLDevice_GetMaxWorkItemDims(__dpctl_keep const DPCTLSyclDeviceRef DRef); * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes1d(__dpctl_keep const DPCTLSyclDeviceRef DRef); /*! @@ -219,7 +219,7 @@ DPCTLDevice_GetMaxWorkItemSizes1d(__dpctl_keep const DPCTLSyclDeviceRef DRef); * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes2d(__dpctl_keep const DPCTLSyclDeviceRef DRef); /*! @@ -230,7 +230,7 @@ DPCTLDevice_GetMaxWorkItemSizes2d(__dpctl_keep const DPCTLSyclDeviceRef DRef); * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes3d(__dpctl_keep const DPCTLSyclDeviceRef DRef); /*! @@ -762,7 +762,7 @@ DPCTLDevice_GetGlobalMemCacheType(__dpctl_keep const DPCTLSyclDeviceRef DRef); * @ingroup DeviceInterface */ DPCTL_API -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetSubGroupSizes(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len); diff --git a/libsyclinterface/source/dpctl_sycl_device_interface.cpp b/libsyclinterface/source/dpctl_sycl_device_interface.cpp index 535876a3b7..de381c6c54 100644 --- a/libsyclinterface/source/dpctl_sycl_device_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_device_interface.cpp @@ -55,7 +55,7 @@ device *new_device_from_selector(const dpctl_device_selector *sel) } template -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice__GetMaxWorkItemSizes(__dpctl_keep const DPCTLSyclDeviceRef DRef) { size_t *sizes = nullptr; @@ -248,19 +248,19 @@ DPCTLDevice_GetMaxWorkItemDims(__dpctl_keep const DPCTLSyclDeviceRef DRef) return maxWorkItemDims; } -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes1d(__dpctl_keep const DPCTLSyclDeviceRef DRef) { return DPCTLDevice__GetMaxWorkItemSizes<1>(DRef); } -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes2d(__dpctl_keep const DPCTLSyclDeviceRef DRef) { return DPCTLDevice__GetMaxWorkItemSizes<2>(DRef); } -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetMaxWorkItemSizes3d(__dpctl_keep const DPCTLSyclDeviceRef DRef) { return DPCTLDevice__GetMaxWorkItemSizes<3>(DRef); @@ -821,7 +821,7 @@ DPCTLDevice_GetGlobalMemCacheType(__dpctl_keep const DPCTLSyclDeviceRef DRef) } } -__dpctl_keep size_t * +__dpctl_give size_t * DPCTLDevice_GetSubGroupSizes(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { From a42d4d85ca26697f19af53ac007dcc8ffbb1caf0 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 11:02:41 -0700 Subject: [PATCH 09/13] clean up condition for indeterminate global mem cache type --- .../source/dpctl_sycl_device_interface.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libsyclinterface/source/dpctl_sycl_device_interface.cpp b/libsyclinterface/source/dpctl_sycl_device_interface.cpp index de381c6c54..5f9a9b64dc 100644 --- a/libsyclinterface/source/dpctl_sycl_device_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_device_interface.cpp @@ -801,24 +801,24 @@ DPCTLDevice_GetGlobalMemCacheType(__dpctl_keep const DPCTLSyclDeviceRef DRef) { if (DRef) { auto D = unwrap(DRef); - auto mem_type = D->get_info(); - switch (mem_type) { - case info::global_mem_cache_type::none: - return DPCTL_MEM_CACHE_TYPE_NONE; - case info::global_mem_cache_type::read_only: - return DPCTL_MEM_CACHE_TYPE_READ_ONLY; - case info::global_mem_cache_type::read_write: - return DPCTL_MEM_CACHE_TYPE_READ_WRITE; + try { + auto mem_type = D->get_info(); + switch (mem_type) { + case info::global_mem_cache_type::none: + return DPCTL_MEM_CACHE_TYPE_NONE; + case info::global_mem_cache_type::read_only: + return DPCTL_MEM_CACHE_TYPE_READ_ONLY; + case info::global_mem_cache_type::read_write: + return DPCTL_MEM_CACHE_TYPE_READ_WRITE; + } + // If execution reaches here unrecognized mem_type was returned. + // Check values in the enumeration `info::global_mem_cache_type` in + // SYCL specs + } catch (std::exception const &e) { + error_handler(e, __FILE__, __func__, __LINE__); } - // If execution reaches here unrecognized mem_type was returned. Check - // values in the enumeration `info::global_mem_cache_type` in SYCL specs - assert(false); - return DPCTL_MEM_CACHE_TYPE_INDETERMINATE; - } - else { - error_handler("Argument DRef is null", __FILE__, __func__, __LINE__); - return DPCTL_MEM_CACHE_TYPE_INDETERMINATE; } + return DPCTL_MEM_CACHE_TYPE_INDETERMINATE; } __dpctl_give size_t * From 9f9729439f5e22db8d8cf86db4bc5a13c1a39f7c Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 11:06:44 -0700 Subject: [PATCH 10/13] fix tautology in get max samplers test --- libsyclinterface/tests/test_sycl_device_interface.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index 604f9db2f3..be83fc75e2 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -577,9 +577,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetAddressBits) TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxSamplers) { - uint32_t ms = 0; - EXPECT_NO_FATAL_FAILURE(ms = DPCTLDevice_GetMaxSamplers(DRef)); - EXPECT_TRUE(ms >= 0); + EXPECT_NO_FATAL_FAILURE(DPCTLDevice_GetMaxSamplers(DRef)); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxParameterSize) From 587a16916ea25064c375bd3dd7debb531e346c6a Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 11:26:57 -0700 Subject: [PATCH 11/13] fix remaining tautologies in tests --- .../tests/test_sycl_device_interface.cpp | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index be83fc75e2..277f112767 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -181,9 +181,8 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxWorkGroupSize) { size_t n = 0; EXPECT_NO_FATAL_FAILURE(n = DPCTLDevice_GetMaxWorkGroupSize(DRef)); - if (DPCTLDevice_IsAccelerator(DRef)) - EXPECT_TRUE(n >= 0); - else + // accelerators may report 0, all other devices must report a positive value + if (!DPCTLDevice_IsAccelerator(DRef)) EXPECT_TRUE(n > 0); } @@ -191,9 +190,8 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetMaxNumSubGroups) { size_t n = 0; EXPECT_NO_FATAL_FAILURE(n = DPCTLDevice_GetMaxNumSubGroups(DRef)); - if (DPCTLDevice_IsAccelerator(DRef)) - EXPECT_TRUE(n >= 0); - else + // accelerators may report 0, all other devices must report a positive value + if (!DPCTLDevice_IsAccelerator(DRef)) EXPECT_TRUE(n > 0); } @@ -203,9 +201,8 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetSubGroupSizes) size_t *sg_sizes = nullptr; EXPECT_NO_FATAL_FAILURE( sg_sizes = DPCTLDevice_GetSubGroupSizes(DRef, &sg_sizes_len)); - if (DPCTLDevice_IsAccelerator(DRef)) - EXPECT_TRUE(sg_sizes_len >= 0); - else + // accelerators may report 0, all other devices must report a positive value + if (!DPCTLDevice_IsAccelerator(DRef)) EXPECT_TRUE(sg_sizes_len > 0); for (size_t i = 0; i < sg_sizes_len; ++i) { EXPECT_TRUE(sg_sizes[i] > 0); @@ -495,7 +492,6 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionMaxSubDevices) size_t max_cu = 0; EXPECT_NO_FATAL_FAILURE(max_part = DPCTLDevice_GetPartitionMaxSubDevices(DRef)); - EXPECT_TRUE(max_part >= 0); EXPECT_NO_FATAL_FAILURE(max_cu = DPCTLDevice_GetMaxComputeUnits(DRef)); EXPECT_TRUE(max_part <= max_cu); } @@ -533,10 +529,10 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetGetMaxClockFrequency) { uint32_t res = 0; EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetMaxClockFrequency(DRef)); - // FIXME: uncomment once coverage build transitions away - // FIXME: from using DPC++ 2023.2 EXPECT_TRUE(res >= 0); - // EXPECT_TRUE(res != 0); + // FIXME: DPC++ may return 0 for some CPUs + // unknown whether bug or expected behavior + // EXPECT_TRUE(res > 0); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetGlobalMemCacheType) From 75030b54b733af1e19f19759df0f882a9e496c75 Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Tue, 4 Aug 2026 11:27:02 -0700 Subject: [PATCH 12/13] docstring fixes --- dpctl/_sycl_device.pyx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index e3e02d9fda..1ab0a6abea 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -2273,6 +2273,10 @@ cdef class SyclDevice(_SyclDevice): Returns: str: The device version string. + + Raises: + RuntimeError: + If the ``version`` descriptor is not available. """ cdef const char *ver = DPCTLDevice_GetVersion(self._device_ref) if ver is NULL: @@ -2283,11 +2287,15 @@ cdef class SyclDevice(_SyclDevice): @property def backend_version(self): - """ Returns a backend-defined driver version string. + """ Returns a backend version string. Returns: str: The backend version string. + + Raises: + RuntimeError: + If the ``backend_version`` descriptor is not available. """ cdef const char *ver = DPCTLDevice_GetBackendVersion(self._device_ref) if ver is NULL: From e06af592f78bd2c2aac31647a759e8d5fb47544d Mon Sep 17 00:00:00 2001 From: Nikita Grigorian Date: Wed, 5 Aug 2026 10:09:33 -0700 Subject: [PATCH 13/13] add sentinel values for enums and remove duplication --- dpctl/_backend.pxd | 7 + dpctl/_sycl_device.pyx | 46 ++++-- .../helper/include/dpctl_utils_helper.h | 73 ++++++++- .../helper/source/dpctl_utils_helper.cpp | 97 +++++++++++- .../syclinterface/dpctl_sycl_enum_types.h | 6 + .../source/dpctl_sycl_device_interface.cpp | 144 ++---------------- .../tests/test_sycl_device_interface.cpp | 18 ++- .../tests/test_sycl_device_subdevices.cpp | 25 ++- 8 files changed, 258 insertions(+), 158 deletions(-) diff --git a/dpctl/_backend.pxd b/dpctl/_backend.pxd index 9165292ca0..a85565b729 100644 --- a/dpctl/_backend.pxd +++ b/dpctl/_backend.pxd @@ -106,6 +106,8 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": ctypedef enum _partition_affinity_domain_type \ "DPCTLPartitionAffinityDomainType": + _PARTITION_AFFINITY_DOMAIN_UNKNOWN \ + "DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN", _not_applicable "not_applicable", _numa "numa", _L4_cache "L4_cache", @@ -131,17 +133,20 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": _MEM_CACHE_TYPE_READ_WRITE "DPCTL_MEM_CACHE_TYPE_READ_WRITE" ctypedef enum _local_mem_type "DPCTLLocalMemType": + _LOCAL_MEM_TYPE_UNKNOWN "DPCTL_LOCAL_MEM_TYPE_UNKNOWN" _LOCAL_MEM_TYPE_NONE "DPCTL_LOCAL_MEM_TYPE_NONE" _LOCAL_MEM_TYPE_LOCAL "DPCTL_LOCAL_MEM_TYPE_LOCAL" _LOCAL_MEM_TYPE_GLOBAL "DPCTL_LOCAL_MEM_TYPE_GLOBAL" ctypedef enum _partition_property_type "DPCTLPartitionPropertyType": + _PARTITION_UNKNOWN "DPCTL_PARTITION_UNKNOWN" _PARTITION_NO_PARTITION "DPCTL_PARTITION_NO_PARTITION" _PARTITION_EQUALLY "DPCTL_PARTITION_EQUALLY" _PARTITION_BY_COUNTS "DPCTL_PARTITION_BY_COUNTS" _PARTITION_BY_AFFINITY_DOMAIN "DPCTL_PARTITION_BY_AFFINITY_DOMAIN" ctypedef enum _fp_config_type "DPCTLFPConfigType": + _FP_UNKNOWN "DPCTL_FP_UNKNOWN" _FP_DENORM "DPCTL_FP_DENORM" _FP_INF_NAN "DPCTL_FP_INF_NAN" _FP_ROUND_TO_NEAREST "DPCTL_FP_ROUND_TO_NEAREST" @@ -152,6 +157,7 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": _FP_SOFT_FLOAT "DPCTL_FP_SOFT_FLOAT" ctypedef enum _memory_order_type "DPCTLMemoryOrderType": + _MEMORY_ORDER_UNKNOWN "DPCTL_MEMORY_ORDER_UNKNOWN" _MEMORY_ORDER_RELAXED "DPCTL_MEMORY_ORDER_RELAXED" _MEMORY_ORDER_ACQUIRE "DPCTL_MEMORY_ORDER_ACQUIRE" _MEMORY_ORDER_RELEASE "DPCTL_MEMORY_ORDER_RELEASE" @@ -159,6 +165,7 @@ cdef extern from "syclinterface/dpctl_sycl_enum_types.h": _MEMORY_ORDER_SEQ_CST "DPCTL_MEMORY_ORDER_SEQ_CST" ctypedef enum _memory_scope_type "DPCTLMemoryScopeType": + _MEMORY_SCOPE_UNKNOWN "DPCTL_MEMORY_SCOPE_UNKNOWN" _MEMORY_SCOPE_WORK_ITEM "DPCTL_MEMORY_SCOPE_WORK_ITEM" _MEMORY_SCOPE_SUB_GROUP "DPCTL_MEMORY_SCOPE_SUB_GROUP" _MEMORY_SCOPE_WORK_GROUP "DPCTL_MEMORY_SCOPE_WORK_GROUP" diff --git a/dpctl/_sycl_device.pyx b/dpctl/_sycl_device.pyx index 1ab0a6abea..1bc00fdd2a 100644 --- a/dpctl/_sycl_device.pyx +++ b/dpctl/_sycl_device.pyx @@ -214,6 +214,10 @@ cdef tuple _to_enum_tuple( ): """ Converts an array of DPCTL enum values into a tuple of ``enum_type``s + + The DPCTL enums reserve value 0 for an unrecognized value, so a DPCTL + value of ``n`` corresponds to the ``n``-th member of ``enum_type``, whose + members are numbered from 1 by ``enum.auto()``. """ cdef list res = [] cdef size_t i @@ -222,9 +226,10 @@ cdef tuple _to_enum_tuple( return () try: for i in range(arr_len): - if arr[i] < 0: + try: + res.append(enum_type(arr[i])) + except ValueError: raise RuntimeError(f"Unrecognized {descr} reported") - res.append(enum_type(arr[i] + 1)) finally: DPCTLInt_Array_Delete(arr) @@ -2336,6 +2341,10 @@ cdef class SyclDevice(_SyclDevice): Returns: :class:`dpctl.partition_property`: The partition property that was used to create this device. + + Raises: + RuntimeError: + If an unrecognized partition property is reported by runtime. """ cdef _partition_property_type ppTy = ( DPCTLDevice_GetPartitionTypeProperty(self._device_ref) @@ -2348,7 +2357,7 @@ cdef class SyclDevice(_SyclDevice): return partition_property.partition_by_counts elif ppTy == _partition_property_type._PARTITION_BY_AFFINITY_DOMAIN: return partition_property.partition_by_affinity_domain - return partition_property.no_partition + raise RuntimeError("Unrecognized partition property reported") @property def partition_type_affinity_domain(self): @@ -2359,6 +2368,11 @@ cdef class SyclDevice(_SyclDevice): Returns: str: The affinity domain string. + + Raises: + RuntimeError: + If an unrecognized partition affinity domain is reported by + runtime. """ cdef _partition_affinity_domain_type padTy = ( DPCTLDevice_GetPartitionTypeAffinityDomain(self._device_ref) @@ -2377,7 +2391,9 @@ cdef class SyclDevice(_SyclDevice): return "L1_cache" elif padTy == _partition_affinity_domain_type._next_partitionable: return "next_partitionable" - return "not_applicable" + raise RuntimeError( + "Unrecognized partition affinity domain reported" + ) @property def half_fp_config(self): @@ -2560,6 +2576,11 @@ cdef class SyclDevice(_SyclDevice): Returns: Tuple[str]: Tuple of supported affinity domain names. + + Raises: + RuntimeError: + If an unrecognized partition affinity domain is reported by + runtime. """ cdef int *arr = NULL cdef size_t arr_len = 0 @@ -2580,15 +2601,20 @@ cdef class SyclDevice(_SyclDevice): arr = DPCTLDevice_GetPartitionAffinityDomains( self._device_ref, &arr_len ) - if arr is not NULL and arr_len > 0: + if arr is NULL: + return () + try: res = [] for i in range(arr_len): - res.append(_pad_map.get(arr[i], "not_applicable")) - DPCTLInt_Array_Delete(arr) - return tuple(res) - if arr is not NULL: + if arr[i] not in _pad_map: + raise RuntimeError( + "Unrecognized partition affinity domain reported" + ) + res.append(_pad_map[arr[i]]) + finally: DPCTLInt_Array_Delete(arr) - return () + + return tuple(res) cdef cpp_bool equals(self, SyclDevice other): """ Returns ``True`` if the :class:`dpctl.SyclDevice` argument has the diff --git a/libsyclinterface/helper/include/dpctl_utils_helper.h b/libsyclinterface/helper/include/dpctl_utils_helper.h index d999088d3b..c441a40aec 100644 --- a/libsyclinterface/helper/include/dpctl_utils_helper.h +++ b/libsyclinterface/helper/include/dpctl_utils_helper.h @@ -172,13 +172,82 @@ DPCTL_DPCTLPartitionAffinityDomainTypeToSycl( * @param PartitionAffinityDomain sycl::info::partition_affinity_domain to be * converted to DPCTLPartitionAffinityDomainType enum. * @return A DPCTLPartitionAffinityDomainType enum value for the input - * sycl::info::partition_affinity_domain enum value. - * @throws runtime_error + * sycl::info::partition_affinity_domain enum value, or + * DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN if the value is not recognized. */ DPCTL_API DPCTLPartitionAffinityDomainType DPCTL_SyclPartitionAffinityDomainToDPCTLType( sycl::info::partition_affinity_domain PartitionAffinityDomain); +/*! + * @brief Converts a sycl::info::fp_config enum value to corresponding + * DPCTLFPConfigType enum value. + * + * @param FPConfig sycl::info::fp_config to be converted to + * DPCTLFPConfigType enum. + * @return A DPCTLFPConfigType enum value for the input + * sycl::info::fp_config enum value, or DPCTL_FP_UNKNOWN if the value is + * not recognized. + */ +DPCTL_API +DPCTLFPConfigType DPCTL_SyclFPConfigToDPCTLType(sycl::info::fp_config FPConfig); + +/*! + * @brief Converts a sycl::info::local_mem_type enum value to corresponding + * DPCTLLocalMemType enum value. + * + * @param LocalMemType sycl::info::local_mem_type to be converted to + * DPCTLLocalMemType enum. + * @return A DPCTLLocalMemType enum value for the input + * sycl::info::local_mem_type enum value, or DPCTL_LOCAL_MEM_TYPE_UNKNOWN if + * the value is not recognized. + */ +DPCTL_API +DPCTLLocalMemType +DPCTL_SyclLocalMemTypeToDPCTLType(sycl::info::local_mem_type LocalMemType); + +/*! + * @brief Converts a sycl::memory_order enum value to corresponding + * DPCTLMemoryOrderType enum value. + * + * @param MemoryOrder sycl::memory_order to be converted to + * DPCTLMemoryOrderType enum. + * @return A DPCTLMemoryOrderType enum value for the input + * sycl::memory_order enum value, or DPCTL_MEMORY_ORDER_UNKNOWN if the value + * is not recognized. + */ +DPCTL_API +DPCTLMemoryOrderType +DPCTL_SyclMemoryOrderToDPCTLType(sycl::memory_order MemoryOrder); + +/*! + * @brief Converts a sycl::memory_scope enum value to corresponding + * DPCTLMemoryScopeType enum value. + * + * @param MemoryScope sycl::memory_scope to be converted to + * DPCTLMemoryScopeType enum. + * @return A DPCTLMemoryScopeType enum value for the input + * sycl::memory_scope enum value, or DPCTL_MEMORY_SCOPE_UNKNOWN if the value + * is not recognized. + */ +DPCTL_API +DPCTLMemoryScopeType +DPCTL_SyclMemoryScopeToDPCTLType(sycl::memory_scope MemoryScope); + +/*! + * @brief Converts a sycl::info::partition_property enum value to corresponding + * DPCTLPartitionPropertyType enum value. + * + * @param PartitionProperty sycl::info::partition_property to be converted + * to DPCTLPartitionPropertyType enum. + * @return A DPCTLPartitionPropertyType enum value for the input + * sycl::info::partition_property enum value, or DPCTL_PARTITION_UNKNOWN if + * the value is not recognized. + */ +DPCTL_API +DPCTLPartitionPropertyType DPCTL_SyclPartitionPropertyToDPCTLType( + sycl::info::partition_property PartitionProperty); + /*! * @brief Converts a DPCTLPeerAccessType enum value to its corresponding * sycl::ext::oneapi::peer_access enum value. diff --git a/libsyclinterface/helper/source/dpctl_utils_helper.cpp b/libsyclinterface/helper/source/dpctl_utils_helper.cpp index 347d036458..c03887a2b1 100644 --- a/libsyclinterface/helper/source/dpctl_utils_helper.cpp +++ b/libsyclinterface/helper/source/dpctl_utils_helper.cpp @@ -26,6 +26,7 @@ #include "dpctl_utils_helper.h" #include "Config/dpctl_config.h" #include +#include #include using namespace sycl; @@ -466,7 +467,101 @@ DPCTLPartitionAffinityDomainType DPCTL_SyclPartitionAffinityDomainToDPCTLType( case info::partition_affinity_domain::next_partitionable: return DPCTLPartitionAffinityDomainType::next_partitionable; default: - throw std::runtime_error("Unsupported partition_affinity_domain type"); + return DPCTLPartitionAffinityDomainType:: + DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN; + } +} + +DPCTLFPConfigType DPCTL_SyclFPConfigToDPCTLType(info::fp_config FPConfig) +{ + switch (FPConfig) { + case info::fp_config::denorm: + return DPCTLFPConfigType::DPCTL_FP_DENORM; + case info::fp_config::inf_nan: + return DPCTLFPConfigType::DPCTL_FP_INF_NAN; + case info::fp_config::round_to_nearest: + return DPCTLFPConfigType::DPCTL_FP_ROUND_TO_NEAREST; + case info::fp_config::round_to_zero: + return DPCTLFPConfigType::DPCTL_FP_ROUND_TO_ZERO; + case info::fp_config::round_to_inf: + return DPCTLFPConfigType::DPCTL_FP_ROUND_TO_INF; + case info::fp_config::fma: + return DPCTLFPConfigType::DPCTL_FP_FMA; + case info::fp_config::correctly_rounded_divide_sqrt: + return DPCTLFPConfigType::DPCTL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT; + case info::fp_config::soft_float: + return DPCTLFPConfigType::DPCTL_FP_SOFT_FLOAT; + default: + return DPCTLFPConfigType::DPCTL_FP_UNKNOWN; + } +} + +DPCTLLocalMemType +DPCTL_SyclLocalMemTypeToDPCTLType(info::local_mem_type LocalMemType) +{ + switch (LocalMemType) { + case info::local_mem_type::none: + return DPCTLLocalMemType::DPCTL_LOCAL_MEM_TYPE_NONE; + case info::local_mem_type::local: + return DPCTLLocalMemType::DPCTL_LOCAL_MEM_TYPE_LOCAL; + case info::local_mem_type::global: + return DPCTLLocalMemType::DPCTL_LOCAL_MEM_TYPE_GLOBAL; + default: + return DPCTLLocalMemType::DPCTL_LOCAL_MEM_TYPE_UNKNOWN; + } +} + +DPCTLMemoryOrderType DPCTL_SyclMemoryOrderToDPCTLType(memory_order MemoryOrder) +{ + switch (MemoryOrder) { + case memory_order::relaxed: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_RELAXED; + case memory_order::acquire: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_ACQUIRE; + case memory_order::release: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_RELEASE; + case memory_order::acq_rel: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_ACQ_REL; + case memory_order::seq_cst: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_SEQ_CST; + default: + return DPCTLMemoryOrderType::DPCTL_MEMORY_ORDER_UNKNOWN; + } +} + +DPCTLMemoryScopeType DPCTL_SyclMemoryScopeToDPCTLType(memory_scope MemoryScope) +{ + switch (MemoryScope) { + case memory_scope::work_item: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_WORK_ITEM; + case memory_scope::sub_group: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_SUB_GROUP; + case memory_scope::work_group: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_WORK_GROUP; + case memory_scope::device: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_DEVICE; + case memory_scope::system: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_SYSTEM; + default: + return DPCTLMemoryScopeType::DPCTL_MEMORY_SCOPE_UNKNOWN; + } +} + +DPCTLPartitionPropertyType DPCTL_SyclPartitionPropertyToDPCTLType( + info::partition_property PartitionProperty) +{ + switch (PartitionProperty) { + case info::partition_property::no_partition: + return DPCTLPartitionPropertyType::DPCTL_PARTITION_NO_PARTITION; + case info::partition_property::partition_equally: + return DPCTLPartitionPropertyType::DPCTL_PARTITION_EQUALLY; + case info::partition_property::partition_by_counts: + return DPCTLPartitionPropertyType::DPCTL_PARTITION_BY_COUNTS; + case info::partition_property::partition_by_affinity_domain: + return DPCTLPartitionPropertyType::DPCTL_PARTITION_BY_AFFINITY_DOMAIN; + default: + // TODO: investigate ext_intel_partition_by_cslice extension + return DPCTLPartitionPropertyType::DPCTL_PARTITION_UNKNOWN; } } diff --git a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h index 899c093b44..c66b8330f9 100644 --- a/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h +++ b/libsyclinterface/include/syclinterface/dpctl_sycl_enum_types.h @@ -143,6 +143,7 @@ typedef enum */ typedef enum { + DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN = 0, not_applicable, numa, L4_cache, @@ -194,6 +195,7 @@ typedef enum typedef enum { + DPCTL_LOCAL_MEM_TYPE_UNKNOWN = 0, DPCTL_LOCAL_MEM_TYPE_NONE, DPCTL_LOCAL_MEM_TYPE_LOCAL, DPCTL_LOCAL_MEM_TYPE_GLOBAL @@ -201,6 +203,7 @@ typedef enum typedef enum { + DPCTL_PARTITION_UNKNOWN = 0, DPCTL_PARTITION_NO_PARTITION, DPCTL_PARTITION_EQUALLY, DPCTL_PARTITION_BY_COUNTS, @@ -209,6 +212,7 @@ typedef enum typedef enum { + DPCTL_FP_UNKNOWN = 0, DPCTL_FP_DENORM, DPCTL_FP_INF_NAN, DPCTL_FP_ROUND_TO_NEAREST, @@ -221,6 +225,7 @@ typedef enum typedef enum { + DPCTL_MEMORY_ORDER_UNKNOWN = 0, DPCTL_MEMORY_ORDER_RELAXED, DPCTL_MEMORY_ORDER_ACQUIRE, DPCTL_MEMORY_ORDER_RELEASE, @@ -230,6 +235,7 @@ typedef enum typedef enum { + DPCTL_MEMORY_SCOPE_UNKNOWN = 0, DPCTL_MEMORY_SCOPE_WORK_ITEM, DPCTL_MEMORY_SCOPE_SUB_GROUP, DPCTL_MEMORY_SCOPE_WORK_GROUP, diff --git a/libsyclinterface/source/dpctl_sycl_device_interface.cpp b/libsyclinterface/source/dpctl_sycl_device_interface.cpp index 5f9a9b64dc..d7e1b092ef 100644 --- a/libsyclinterface/source/dpctl_sycl_device_interface.cpp +++ b/libsyclinterface/source/dpctl_sycl_device_interface.cpp @@ -1138,19 +1138,12 @@ DPCTLDevice_GetLocalMemType(__dpctl_keep const DPCTLSyclDeviceRef DRef) auto D = unwrap(DRef); try { auto mem_type = D->get_info(); - switch (mem_type) { - case info::local_mem_type::none: - return DPCTL_LOCAL_MEM_TYPE_NONE; - case info::local_mem_type::local: - return DPCTL_LOCAL_MEM_TYPE_LOCAL; - case info::local_mem_type::global: - return DPCTL_LOCAL_MEM_TYPE_GLOBAL; - } + return DPCTL_SyclLocalMemTypeToDPCTLType(mem_type); } catch (std::exception const &e) { error_handler(e, __FILE__, __func__, __LINE__); } } - return DPCTL_LOCAL_MEM_TYPE_NONE; + return DPCTL_LOCAL_MEM_TYPE_UNKNOWN; } DPCTLPartitionPropertyType @@ -1160,24 +1153,12 @@ DPCTLDevice_GetPartitionTypeProperty(__dpctl_keep const DPCTLSyclDeviceRef DRef) auto D = unwrap(DRef); try { auto pp = D->get_info(); - switch (pp) { - case info::partition_property::no_partition: - return DPCTL_PARTITION_NO_PARTITION; - case info::partition_property::partition_equally: - return DPCTL_PARTITION_EQUALLY; - case info::partition_property::partition_by_counts: - return DPCTL_PARTITION_BY_COUNTS; - case info::partition_property::partition_by_affinity_domain: - return DPCTL_PARTITION_BY_AFFINITY_DOMAIN; - default: - // TODO: investigate ext_intel_partition_by_cslice extension - break; - } + return DPCTL_SyclPartitionPropertyToDPCTLType(pp); } catch (std::exception const &e) { error_handler(e, __FILE__, __func__, __LINE__); } } - return DPCTL_PARTITION_NO_PARTITION; + return DPCTL_PARTITION_UNKNOWN; } DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( @@ -1193,108 +1174,13 @@ DPCTLPartitionAffinityDomainType DPCTLDevice_GetPartitionTypeAffinityDomain( error_handler(e, __FILE__, __func__, __LINE__); } } - return DPCTLPartitionAffinityDomainType::not_applicable; + return DPCTLPartitionAffinityDomainType:: + DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN; } namespace { -int dpctl_fp_config_to_int(info::fp_config fc) -{ - switch (fc) { - case info::fp_config::denorm: - return DPCTL_FP_DENORM; - case info::fp_config::inf_nan: - return DPCTL_FP_INF_NAN; - case info::fp_config::round_to_nearest: - return DPCTL_FP_ROUND_TO_NEAREST; - case info::fp_config::round_to_zero: - return DPCTL_FP_ROUND_TO_ZERO; - case info::fp_config::round_to_inf: - return DPCTL_FP_ROUND_TO_INF; - case info::fp_config::fma: - return DPCTL_FP_FMA; - case info::fp_config::correctly_rounded_divide_sqrt: - return DPCTL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT; - case info::fp_config::soft_float: - return DPCTL_FP_SOFT_FLOAT; - } - return -1; -} - -int dpctl_memory_order_to_int(sycl::memory_order mo) -{ - switch (mo) { - case sycl::memory_order::relaxed: - return DPCTL_MEMORY_ORDER_RELAXED; - case sycl::memory_order::acquire: - return DPCTL_MEMORY_ORDER_ACQUIRE; - case sycl::memory_order::release: - return DPCTL_MEMORY_ORDER_RELEASE; - case sycl::memory_order::acq_rel: - return DPCTL_MEMORY_ORDER_ACQ_REL; - case sycl::memory_order::seq_cst: - return DPCTL_MEMORY_ORDER_SEQ_CST; - default: - return -1; - } -} - -int dpctl_memory_scope_to_int(sycl::memory_scope ms) -{ - switch (ms) { - case sycl::memory_scope::work_item: - return DPCTL_MEMORY_SCOPE_WORK_ITEM; - case sycl::memory_scope::sub_group: - return DPCTL_MEMORY_SCOPE_SUB_GROUP; - case sycl::memory_scope::work_group: - return DPCTL_MEMORY_SCOPE_WORK_GROUP; - case sycl::memory_scope::device: - return DPCTL_MEMORY_SCOPE_DEVICE; - case sycl::memory_scope::system: - return DPCTL_MEMORY_SCOPE_SYSTEM; - } - return -1; -} - -int dpctl_partition_property_to_int(info::partition_property pp) -{ - switch (pp) { - case info::partition_property::no_partition: - return DPCTL_PARTITION_NO_PARTITION; - case info::partition_property::partition_equally: - return DPCTL_PARTITION_EQUALLY; - case info::partition_property::partition_by_counts: - return DPCTL_PARTITION_BY_COUNTS; - case info::partition_property::partition_by_affinity_domain: - return DPCTL_PARTITION_BY_AFFINITY_DOMAIN; - default: - // TODO: investigate ext_intel_partition_by_cslice extension - return -1; - } -} - -int dpctl_partition_affinity_domain_to_int(info::partition_affinity_domain pad) -{ - switch (pad) { - case info::partition_affinity_domain::not_applicable: - return DPCTLPartitionAffinityDomainType::not_applicable; - case info::partition_affinity_domain::numa: - return DPCTLPartitionAffinityDomainType::numa; - case info::partition_affinity_domain::L4_cache: - return DPCTLPartitionAffinityDomainType::L4_cache; - case info::partition_affinity_domain::L3_cache: - return DPCTLPartitionAffinityDomainType::L3_cache; - case info::partition_affinity_domain::L2_cache: - return DPCTLPartitionAffinityDomainType::L2_cache; - case info::partition_affinity_domain::L1_cache: - return DPCTLPartitionAffinityDomainType::L1_cache; - case info::partition_affinity_domain::next_partitionable: - return DPCTLPartitionAffinityDomainType::next_partitionable; - } - return DPCTLPartitionAffinityDomainType::not_applicable; -} - template int *get_info_enum_array(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len, @@ -1330,7 +1216,7 @@ DPCTLDevice_GetHalfFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_fp_config_to_int); + DRef, res_len, DPCTL_SyclFPConfigToDPCTLType); } __dpctl_give int * @@ -1338,7 +1224,7 @@ DPCTLDevice_GetSingleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_fp_config_to_int); + DRef, res_len, DPCTL_SyclFPConfigToDPCTLType); } __dpctl_give int * @@ -1346,7 +1232,7 @@ DPCTLDevice_GetDoubleFPConfig(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_fp_config_to_int); + DRef, res_len, DPCTL_SyclFPConfigToDPCTLType); } __dpctl_give int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( @@ -1354,7 +1240,7 @@ __dpctl_give int *DPCTLDevice_GetAtomicMemoryOrderCapabilities( size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_memory_order_to_int); + DRef, res_len, DPCTL_SyclMemoryOrderToDPCTLType); } __dpctl_give int *DPCTLDevice_GetAtomicFenceOrderCapabilities( @@ -1362,7 +1248,7 @@ __dpctl_give int *DPCTLDevice_GetAtomicFenceOrderCapabilities( size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_memory_order_to_int); + DRef, res_len, DPCTL_SyclMemoryOrderToDPCTLType); } __dpctl_give int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( @@ -1370,7 +1256,7 @@ __dpctl_give int *DPCTLDevice_GetAtomicMemoryScopeCapabilities( size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_memory_scope_to_int); + DRef, res_len, DPCTL_SyclMemoryScopeToDPCTLType); } __dpctl_give int *DPCTLDevice_GetAtomicFenceScopeCapabilities( @@ -1378,7 +1264,7 @@ __dpctl_give int *DPCTLDevice_GetAtomicFenceScopeCapabilities( size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_memory_scope_to_int); + DRef, res_len, DPCTL_SyclMemoryScopeToDPCTLType); } __dpctl_give int * @@ -1386,7 +1272,7 @@ DPCTLDevice_GetPartitionProperties(__dpctl_keep const DPCTLSyclDeviceRef DRef, size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_partition_property_to_int); + DRef, res_len, DPCTL_SyclPartitionPropertyToDPCTLType); } __dpctl_give int *DPCTLDevice_GetPartitionAffinityDomains( @@ -1394,5 +1280,5 @@ __dpctl_give int *DPCTLDevice_GetPartitionAffinityDomains( size_t *res_len) { return get_info_enum_array( - DRef, res_len, dpctl_partition_affinity_domain_to_int); + DRef, res_len, DPCTL_SyclPartitionAffinityDomainToDPCTLType); } diff --git a/libsyclinterface/tests/test_sycl_device_interface.cpp b/libsyclinterface/tests/test_sycl_device_interface.cpp index 277f112767..ba6f42505d 100644 --- a/libsyclinterface/tests/test_sycl_device_interface.cpp +++ b/libsyclinterface/tests/test_sycl_device_interface.cpp @@ -633,10 +633,10 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionTypeProperty) { DPCTLPartitionPropertyType ptp; EXPECT_NO_FATAL_FAILURE(ptp = DPCTLDevice_GetPartitionTypeProperty(DRef)); - EXPECT_TRUE(ptp == DPCTL_PARTITION_NO_PARTITION || - ptp == DPCTL_PARTITION_EQUALLY || - ptp == DPCTL_PARTITION_BY_COUNTS || - ptp == DPCTL_PARTITION_BY_AFFINITY_DOMAIN); + EXPECT_TRUE( + ptp == DPCTL_PARTITION_UNKNOWN || ptp == DPCTL_PARTITION_NO_PARTITION || + ptp == DPCTL_PARTITION_EQUALLY || ptp == DPCTL_PARTITION_BY_COUNTS || + ptp == DPCTL_PARTITION_BY_AFFINITY_DOMAIN); } TEST_P(TestDPCTLSyclDeviceInterface, ChkGetHalfFPConfig) @@ -772,7 +772,8 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkGetPartitionAffinityDomains) for (size_t i = 0; i < len; ++i) { EXPECT_TRUE( arr[i] >= DPCTLPartitionAffinityDomainType::not_applicable && - arr[i] <= DPCTLPartitionAffinityDomainType::next_partitionable); + arr[i] <= DPCTLPartitionAffinityDomainType::next_partitionable) + << "Unrecognized partition affinity domain reported"; } EXPECT_NO_FATAL_FAILURE(DPCTLInt_Array_Delete(arr)); } @@ -1228,7 +1229,8 @@ TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionTypeAffinityDomain) DPCTLPartitionAffinityDomainType::numa; EXPECT_NO_FATAL_FAILURE( res = DPCTLDevice_GetPartitionTypeAffinityDomain(Null_DRef)); - ASSERT_TRUE(res == DPCTLPartitionAffinityDomainType::not_applicable); + ASSERT_TRUE(res == DPCTLPartitionAffinityDomainType:: + DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN); } TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetVendorId) @@ -1299,7 +1301,7 @@ TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetLocalMemType) { DPCTLLocalMemType res = DPCTL_LOCAL_MEM_TYPE_LOCAL; EXPECT_NO_FATAL_FAILURE(res = DPCTLDevice_GetLocalMemType(Null_DRef)); - ASSERT_TRUE(res == DPCTL_LOCAL_MEM_TYPE_NONE); + ASSERT_TRUE(res == DPCTL_LOCAL_MEM_TYPE_UNKNOWN); } TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionTypeProperty) @@ -1307,7 +1309,7 @@ TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetPartitionTypeProperty) DPCTLPartitionPropertyType res = DPCTL_PARTITION_EQUALLY; EXPECT_NO_FATAL_FAILURE( res = DPCTLDevice_GetPartitionTypeProperty(Null_DRef)); - ASSERT_TRUE(res == DPCTL_PARTITION_NO_PARTITION); + ASSERT_TRUE(res == DPCTL_PARTITION_UNKNOWN); } TEST_F(TestDPCTLSyclDeviceNullArgs, ChkGetSingleFPConfig) diff --git a/libsyclinterface/tests/test_sycl_device_subdevices.cpp b/libsyclinterface/tests/test_sycl_device_subdevices.cpp index 710389d76e..4ad2acda40 100644 --- a/libsyclinterface/tests/test_sycl_device_subdevices.cpp +++ b/libsyclinterface/tests/test_sycl_device_subdevices.cpp @@ -41,7 +41,16 @@ using namespace sycl; using namespace dpctl::syclinterface; const DPCTLPartitionAffinityDomainType a_dpctl_domain = - DPCTLPartitionAffinityDomainType::not_applicable; + DPCTLPartitionAffinityDomainType::DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN; + +/*! Tells whether a domain was recognized by + * DPCTL_SyclPartitionAffinityDomainToDPCTLType. + */ +inline bool is_known(DPCTLPartitionAffinityDomainType domain) +{ + return domain != DPCTLPartitionAffinityDomainType:: + DPCTL_PARTITION_AFFINITY_DOMAIN_UNKNOWN; +} struct TestDPCTLSyclDeviceInterface : public ::testing::TestWithParam @@ -133,7 +142,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityNotApplicable) DPCTLPartitionAffinityDomainType dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -162,7 +171,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityNuma) EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -193,7 +202,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityL4Cache) EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -224,7 +233,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityL3Cache) EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -255,7 +264,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityL2Cache) EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -286,7 +295,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, ChkCreateSubDevicesByAffinityL1Cache) EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain)); @@ -318,7 +327,7 @@ TEST_P(TestDPCTLSyclDeviceInterface, EXPECT_NO_FATAL_FAILURE( dpctl_domain = DPCTL_SyclPartitionAffinityDomainToDPCTLType(domain)); - if (dpctl_domain) { + if (is_known(dpctl_domain)) { EXPECT_NO_FATAL_FAILURE( DVRef = DPCTLDevice_CreateSubDevicesByAffinity(DRef, dpctl_domain));