@@ -949,7 +949,7 @@ class Device:
949949 Default value of `None` return the currently used device.
950950
951951 """
952- __slots__ = (" _id" , " _mr" , " _has_inited" , " _properties" )
952+ __slots__ = (" _id" , " _mr" , " _has_inited" , " _properties" , " _uuid " )
953953
954954 def __new__(cls , device_id: int | None = None ):
955955 global _is_cuInit
@@ -1002,6 +1002,7 @@ class Device:
10021002
10031003 device._has_inited = False
10041004 device._properties = None
1005+ device._uuid = None
10051006 devices.append(device)
10061007
10071008 try :
@@ -1146,25 +1147,30 @@ class Device:
11461147 return f" <Device {self._id} ({self.name})>"
11471148
11481149 def __hash__ (self ) -> int:
1149- """Return hash based on the device ordinal .
1150+ """Return hash based on the device UUID .
11501151
11511152 This enables Device objects to be used as dictionary keys and in sets.
1152- Device objects with the same device_id will hash to the same value
1153- and be considered equal , even if they are different Python objects or
1154- exist on different threads .
1153+ Device objects representing the same physical device will hash to the
1154+ same value , even if they have different device_id values due to
1155+ CUDA_VISIBLE_DEVICES or exist across different processes .
11551156
11561157 Returns
11571158 -------
11581159 int
1159- Hash value based on the device ordinal ( device_id ) .
1160+ Hash value based on the device UUID .
11601161
11611162 Notes
11621163 -----
1163- Device is a per-thread singleton , but equality is based on logical
1164- device identity (device_id ), not Python object identity. This means
1165- Device(0) on thread A equals Device(0) on thread B.
1164+ Uses UUID to ensure consistency across processes where
1165+ CUDA_VISIBLE_DEVICES may change the device ordinal mapping. The UUID
1166+ uniquely identifies the physical device and remains stable regardless of
1167+ how devices are ordered or filtered.
1168+
1169+ The UUID is cached after first access to avoid repeated CUDA API calls.
11661170 """
1167- return hash((type(self ), self._id ))
1171+ if self._uuid is None:
1172+ self._uuid = self .uuid
1173+ return hash((type(self ), self._uuid ))
11681174
11691175 def __eq__(self , other ) -> bool:
11701176 """Check equality based on the device ordinal.
0 commit comments