@@ -61,6 +61,8 @@ from ._backend cimport ( # noqa: E211
61
61
DPCTLDevice_IsCPU,
62
62
DPCTLDevice_IsGPU,
63
63
DPCTLDevice_IsHost,
64
+ DPCTLDeviceMgr_GetDevices,
65
+ DPCTLDeviceMgr_GetPositionInDevices,
64
66
DPCTLDeviceMgr_GetRelativeId,
65
67
DPCTLDeviceMgr_PrintDeviceInfo,
66
68
DPCTLDeviceSelector_Delete,
@@ -825,8 +827,23 @@ cdef class SyclDevice(_SyclDevice):
825
827
826
828
@property
827
829
def filter_string (self ):
828
- """ For a parent device, returns a ``tuple (backend, device_kind,
829
- relative_id)``. Raises an exception for sub-devices.
830
+ """
831
+ For a parent device, returns a fully specified filter selector
832
+ string``backend:device_type:relative_id`` selecting the device.
833
+
834
+ Raises an exception for sub-devices.
835
+
836
+ :Example:
837
+ .. code-block:: python
838
+
839
+ import dpctl
840
+
841
+ # Create a SyclDevice with an explicit filter string,
842
+ # in this case the first level_zero gpu device.
843
+ level_zero_gpu = dpctl.SyclDevice("level_zero:gpu:0")
844
+ # filter_string property should be "level_zero:gpu:0"
845
+ dev = dpctl.SyclDevice(level_zero_gpu.filter_string)
846
+ assert level_zero_gpu == dev
830
847
"""
831
848
cdef DPCTLSyclDeviceRef pDRef = NULL
832
849
cdef DPCTLSyclBackendType BTy
@@ -846,3 +863,134 @@ cdef class SyclDevice(_SyclDevice):
846
863
# this a sub-device, free it, and raise an exception
847
864
DPCTLDevice_Delete(pDRef)
848
865
raise TypeError (" This SyclDevice is not a root device" )
866
+
867
+ cdef int get_backend_and_device_type_ordinal(self ):
868
+ """
869
+ If this device is a root ``sycl::device`` returns the ordinal
870
+ position of this device in the vector
871
+ ``sycl::device::get_devices(device_type_of_this_device)``
872
+ filtered to contain only devices with the same backend as this
873
+ device.
874
+
875
+ Returns -1 if the device is a sub-device, or the device could not
876
+ be found in the vector.
877
+ """
878
+ cdef int64_t relId = DPCTLDeviceMgr_GetRelativeId(self ._device_ref)
879
+ return relId
880
+
881
+ cdef int get_device_type_ordinal(self ):
882
+ """
883
+ If this device is a root ``sycl::device`` returns the ordinal
884
+ position of this device in the vector
885
+ ``sycl::device::get_devices(device_type_of_this_device)``
886
+
887
+ Returns -1 if the device is a sub-device, or the device could not
888
+ be found in the vector.
889
+ """
890
+ cdef DPCTLSyclDeviceType DTy
891
+ cdef int64_t relId = - 1
892
+
893
+ DTy = DPCTLDevice_GetDeviceType(self ._device_ref)
894
+ relId = DPCTLDeviceMgr_GetPositionInDevices(
895
+ self ._device_ref, _backend_type._ALL_BACKENDS | DTy)
896
+ return relId
897
+
898
+ cdef int get_backend_ordinal(self ):
899
+ """
900
+ If this device is a root ``sycl::device`` returns the ordinal
901
+ position of this device in the vector ``sycl::device::get_devices()``
902
+ filtered to contain only devices with the same backend as this
903
+ device.
904
+
905
+ Returns -1 if the device is a sub-device, or the device could not
906
+ be found in the vector.
907
+ """
908
+ cdef DPCTLSyclBackendType BTy
909
+ cdef int64_t relId = - 1
910
+
911
+ BTy = DPCTLDevice_GetBackend(self ._device_ref)
912
+ relId = DPCTLDeviceMgr_GetPositionInDevices(
913
+ self ._device_ref, BTy | _device_type._ALL_DEVICES)
914
+ return relId
915
+
916
+ cdef int get_overall_ordinal(self ):
917
+ """
918
+ If this device is a root ``sycl::device`` returns the ordinal
919
+ position of this device in the vector ``sycl::device::get_devices()``
920
+ filtered to contain only devices with the same backend as this
921
+ device.
922
+
923
+ Returns -1 if the device is a sub-device, or the device could not
924
+ be found in the vector.
925
+ """
926
+ cdef int64_t relId = - 1
927
+
928
+ relId = DPCTLDeviceMgr_GetPositionInDevices(
929
+ self ._device_ref,
930
+ (_backend_type._ALL_BACKENDS | _device_type._ALL_DEVICES)
931
+ )
932
+ return relId
933
+
934
+ def get_filter_string (self , include_backend = True , include_device_type = True ):
935
+ """
936
+ For a parent device returns a filter selector string
937
+ that includes backend or device type based on the value
938
+ of the given keyword arguments.
939
+
940
+ Raises a TypeError if this devices is a sub-device, or
941
+ a ValueError if no match was found in the vector returned
942
+ by ``sycl::device::get_devices()``.
943
+
944
+ :Example:
945
+ .. code-block:: python
946
+
947
+ import dpctl
948
+
949
+ # Create a GPU SyclDevice
950
+ gpu_dev = dpctl.SyclDevice("gpu:0")
951
+ # filter string should be "gpu:0"
952
+ fs = gpu_dev.get_filter_string(use_backend=False)
953
+ dev = dpctl.SyclDevice(fs)
954
+ assert gpu _dev == dev
955
+ """
956
+ cdef int relId = - 1
957
+ cdef DPCTLSyclDeviceRef pDRef = NULL
958
+ cdef DPCTLSyclDeviceType DTy
959
+ cdef DPCTLSyclBackendType BTy
960
+
961
+ if include_backend:
962
+ if include_device_type:
963
+ relId = self .get_backend_and_device_type_ordinal()
964
+ else :
965
+ relId = self .get_backend_ordinal()
966
+ else :
967
+ if include_device_type:
968
+ relId = self .get_device_type_ordinal()
969
+ else :
970
+ relId = self .get_overall_ordinal()
971
+
972
+ if relId < 0 :
973
+ pDRef = DPCTLDevice_GetParentDevice(self ._device_ref)
974
+ if (pDRef is NULL ):
975
+ raise ValueError
976
+ else :
977
+ # this a sub-device, free it, and raise an exception
978
+ DPCTLDevice_Delete(pDRef)
979
+ raise TypeError (" This SyclDevice is not a root device" )
980
+ else :
981
+ if include_backend:
982
+ BTy = DPCTLDevice_GetBackend(self ._device_ref)
983
+ be_str = _backend_type_to_filter_string_part(BTy)
984
+ if include_device_type:
985
+ DTy = DPCTLDevice_GetDeviceType(self ._device_ref)
986
+ dt_str = _device_type_to_filter_string_part(DTy)
987
+ return " :" .join((be_str, dt_str, str (relId)))
988
+ else :
989
+ return " :" .join((be_str, str (relId)))
990
+ else :
991
+ if include_device_type:
992
+ DTy = DPCTLDevice_GetDeviceType(self ._device_ref)
993
+ dt_str = _device_type_to_filter_string_part(DTy)
994
+ return " :" .join((dt_str, str (relId)))
995
+ else :
996
+ return str (relId)
0 commit comments