@@ -283,7 +283,8 @@ cdef class SyclDevice(_SyclDevice):
283283
284284 Args:
285285 arg (str, optional):
286- The argument can be a selector string or ``None``.
286+ The argument can be a selector string, another
287+ :class:`dpctl.SyclDevice`, or ``None``.
287288 Defaults to ``None``.
288289
289290 Raises:
@@ -293,9 +294,7 @@ cdef class SyclDevice(_SyclDevice):
293294 SyclDeviceCreationError:
294295 If the :class:`dpctl.SyclDevice` object creation failed.
295296 TypeError:
296- If the list of :class:`dpctl.SyclDevice` objects was empty,
297- or the input capsule contained a null pointer or could not
298- be renamed.
297+ If the argument is not a :class:`dpctl.SyclDevice` or string.
299298 """
300299 @staticmethod
301300 cdef SyclDevice _create(DPCTLSyclDeviceRef dref):
@@ -363,9 +362,9 @@ cdef class SyclDevice(_SyclDevice):
363362 " Could not create a SyclDevice from default selector"
364363 )
365364 else :
366- raise ValueError (
365+ raise TypeError (
367366 " Invalid argument. Argument should be a str object specifying "
368- " a SYCL filter selector string."
367+ " a SYCL filter selector string or another SyclDevice ."
369368 )
370369
371370 def print_device_info (self ):
@@ -1557,7 +1556,7 @@ cdef class SyclDevice(_SyclDevice):
15571556 cdef int i
15581557
15591558 if ncounts == 0 :
1560- raise TypeError (
1559+ raise ValueError (
15611560 " Non-empty object representing list of counts is expected."
15621561 )
15631562 counts_buff = < size_t * > malloc((< size_t> ncounts) * sizeof(size_t))
@@ -1659,7 +1658,7 @@ cdef class SyclDevice(_SyclDevice):
16591658 Created sub-devices.
16601659
16611660 Raises:
1662- TypeError :
1661+ ValueError :
16631662 If the ``partition`` keyword argument is not specified or
16641663 the affinity domain string is not legal or is not one of the
16651664 three supported options.
@@ -1695,7 +1694,7 @@ cdef class SyclDevice(_SyclDevice):
16951694 _partition_affinity_domain_type._next_partitionable
16961695 )
16971696 else :
1698- raise TypeError (
1697+ raise ValueError (
16991698 " Partition affinity domain {} is not understood." .format(
17001699 partition
17011700 )
@@ -1708,11 +1707,11 @@ cdef class SyclDevice(_SyclDevice):
17081707 else :
17091708 try :
17101709 partition = int (partition)
1711- return self .create_sub_devices_equally(partition)
17121710 except Exception as e:
17131711 raise TypeError (
17141712 " Unsupported type of sub-device argument"
17151713 ) from e
1714+ return self .create_sub_devices_equally(partition)
17161715
17171716 @property
17181717 def parent_device (self ):
@@ -1877,7 +1876,7 @@ cdef class SyclDevice(_SyclDevice):
18771876 A Python string representing a filter selector string.
18781877
18791878 Raises:
1880- TypeError :
1879+ ValueError :
18811880 If the device is a sub-device.
18821881
18831882 :Example:
@@ -1902,7 +1901,7 @@ cdef class SyclDevice(_SyclDevice):
19021901 else :
19031902 # this a sub-device, free it, and raise an exception
19041903 DPCTLDevice_Delete(pDRef)
1905- raise TypeError (" This SyclDevice is not a root device" )
1904+ raise ValueError (" This SyclDevice is not a root device" )
19061905
19071906 cdef int get_backend_and_device_type_ordinal(self ):
19081907 """ If this device is a root ``sycl::device``, returns the ordinal
@@ -1950,9 +1949,7 @@ cdef class SyclDevice(_SyclDevice):
19501949
19511950 cdef int get_overall_ordinal(self ):
19521951 """ If this device is a root ``sycl::device``, returns the ordinal
1953- position of this device in the vector ``sycl::device::get_devices()``
1954- filtered to contain only devices with the same backend as this
1955- device.
1952+ position of this device in the vector ``sycl::device::get_devices()``.
19561953
19571954 Returns -1 if the device is a sub-device, or the device could not
19581955 be found in the vector.
@@ -1985,9 +1982,9 @@ cdef class SyclDevice(_SyclDevice):
19851982 A Python string representing a filter selector string.
19861983
19871984 Raises:
1988- TypeError:
1989- If the device is a sub-device.
19901985 ValueError:
1986+ If the device is a sub-device.
1987+
19911988 If no match for the device was found in the vector
19921989 returned by ``sycl::device::get_devices()``
19931990
@@ -2026,7 +2023,7 @@ cdef class SyclDevice(_SyclDevice):
20262023 else :
20272024 # this a sub-device, free it, and raise an exception
20282025 DPCTLDevice_Delete(pDRef)
2029- raise TypeError (" This SyclDevice is not a root device" )
2026+ raise ValueError (" This SyclDevice is not a root device" )
20302027 else :
20312028 if include_backend:
20322029 BTy = DPCTLDevice_GetBackend(self ._device_ref)
@@ -2045,6 +2042,64 @@ cdef class SyclDevice(_SyclDevice):
20452042 else :
20462043 return str (relId)
20472044
2045+ def get_unpartitioned_parent_device (self ):
2046+ """ get_unpartitioned_parent_device()
2047+
2048+ Returns the unpartitioned parent device of this device.
2049+
2050+ If this device is already an unpartitioned, root device,
2051+ the same device is returned.
2052+
2053+ Returns:
2054+ dpctl.SyclDevice:
2055+ A parent, unpartitioned :class:`dpctl.SyclDevice` instance, or
2056+ ``self`` if already a root device.
2057+ """
2058+ cdef DPCTLSyclDeviceRef pDRef = NULL
2059+ cdef DPCTLSyclDeviceRef tDRef = NULL
2060+ pDRef = DPCTLDevice_GetParentDevice(self ._device_ref)
2061+ if pDRef is NULL :
2062+ return self
2063+ else :
2064+ tDRef = DPCTLDevice_GetParentDevice(pDRef)
2065+ while tDRef is not NULL :
2066+ DPCTLDevice_Delete(pDRef)
2067+ pDRef = tDRef
2068+ tDRef = DPCTLDevice_GetParentDevice(pDRef)
2069+ return SyclDevice._create(pDRef)
2070+
2071+ def get_device_id (self ):
2072+ """ get_device_id()
2073+ For an unpartitioned device, returns the canonical index of this device
2074+ in the list of devices visible to dpctl.
2075+
2076+ Returns:
2077+ int:
2078+ The index of the device.
2079+
2080+ Raises:
2081+ ValueError:
2082+ If the device could not be found.
2083+
2084+ :Example:
2085+ .. code-block:: python
2086+
2087+ import dpctl
2088+ gpu_dev = dpctl.SyclDevice("gpu")
2089+ i = gpu_dev.get_device_id
2090+ devs = dpctl.get_devices()
2091+ assert devs[i] == gpu_dev
2092+ """
2093+ cdef int dev_id = - 1
2094+ cdef SyclDevice dev
2095+
2096+ dev = self .get_unpartitioned_parent_device()
2097+ dev_id = dev.get_overall_ordinal()
2098+ if dev_id < 0 :
2099+ raise ValueError (" device could not be found" )
2100+ return dev_id
2101+
2102+
20482103cdef api DPCTLSyclDeviceRef SyclDevice_GetDeviceRef(SyclDevice dev):
20492104 """
20502105 C-API function to get opaque device reference from
0 commit comments