Skip to content

Commit 6963c4f

Browse files
committed
Add missing device attributes to cuda.core
- Add 22 missing device attributes to DeviceProperties class - Update test_device.py with new attributes and proper version handling - Remove deprecated CUDA 11 specific handling - Add CUDA 13+ specific attributes with proper version detection - Fix line length issues and improve code formatting Resolves #675
1 parent 62d6963 commit 6963c4f

File tree

2 files changed

+327
-8
lines changed

2 files changed

+327
-8
lines changed

cuda_core/cuda/core/experimental/_device.py

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,285 @@ def multicast_supported(self) -> bool:
930930
"""
931931
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MULTICAST_SUPPORTED))
932932

933+
@property
934+
def surface_alignment(self) -> int:
935+
"""
936+
int: Surface alignment requirement in bytes.
937+
"""
938+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT)
939+
940+
@property
941+
def async_engine_count(self) -> int:
942+
"""
943+
int: Number of asynchronous engines.
944+
"""
945+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT)
946+
947+
@property
948+
def can_tex2d_gather(self) -> bool:
949+
"""
950+
bool: True if device supports 2D texture gather operations, False if not.
951+
"""
952+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_CAN_TEX2D_GATHER))
953+
954+
@property
955+
def maximum_texture2d_gather_width(self) -> int:
956+
"""
957+
int: Maximum 2D texture gather width.
958+
"""
959+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_WIDTH)
960+
961+
@property
962+
def maximum_texture2d_gather_height(self) -> int:
963+
"""
964+
int: Maximum 2D texture gather height.
965+
"""
966+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_GATHER_HEIGHT)
967+
968+
@property
969+
def stream_priorities_supported(self) -> bool:
970+
"""
971+
bool: True if device supports stream priorities, False if not.
972+
"""
973+
return bool(
974+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_STREAM_PRIORITIES_SUPPORTED)
975+
)
976+
977+
978+
@property
979+
def cooperative_multi_device_launch(self) -> bool:
980+
"""
981+
bool: True if device supports cooperative multi-device launch, False if not.
982+
"""
983+
return bool(
984+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_COOPERATIVE_MULTI_DEVICE_LAUNCH)
985+
)
986+
987+
@property
988+
def can_flush_remote_writes(self) -> bool:
989+
"""
990+
bool: True if device can flush remote writes, False if not.
991+
"""
992+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_CAN_FLUSH_REMOTE_WRITES))
993+
994+
@property
995+
def host_register_supported(self) -> bool:
996+
"""
997+
bool: True if device supports host memory registration, False if not.
998+
"""
999+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_REGISTER_SUPPORTED))
1000+
1001+
@property
1002+
def virtual_address_management_supported(self) -> bool:
1003+
"""
1004+
bool: True if device supports virtual address management, False if not.
1005+
"""
1006+
return bool(
1007+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_VIRTUAL_ADDRESS_MANAGEMENT_SUPPORTED)
1008+
)
1009+
1010+
@property
1011+
def timeline_semaphore_interop_supported(self) -> bool:
1012+
"""
1013+
bool: True if device supports timeline semaphore interop, False if not.
1014+
"""
1015+
return bool(
1016+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_TIMELINE_SEMAPHORE_INTEROP_SUPPORTED)
1017+
)
1018+
1019+
@property
1020+
def cluster_launch(self) -> bool:
1021+
"""
1022+
bool: True if device supports cluster launch, False if not.
1023+
"""
1024+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_CLUSTER_LAUNCH))
1025+
1026+
@property
1027+
def can_use_64_bit_stream_mem_ops(self) -> bool:
1028+
"""
1029+
bool: True if device supports 64-bit stream memory operations, False if not.
1030+
"""
1031+
return bool(
1032+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_CAN_USE_64_BIT_STREAM_MEM_OPS)
1033+
)
1034+
1035+
@property
1036+
def can_use_stream_wait_value_nor(self) -> bool:
1037+
"""
1038+
bool: True if device supports stream wait value NOR operations, False if not.
1039+
"""
1040+
return bool(
1041+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_CAN_USE_STREAM_WAIT_VALUE_NOR)
1042+
)
1043+
1044+
@property
1045+
def dma_buf_supported(self) -> bool:
1046+
"""
1047+
bool: True if device supports DMA buffer operations, False if not.
1048+
"""
1049+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_DMA_BUF_SUPPORTED))
1050+
1051+
@property
1052+
def ipc_event_supported(self) -> bool:
1053+
"""
1054+
bool: True if device supports IPC event operations, False if not.
1055+
"""
1056+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORTED))
1057+
1058+
@property
1059+
def mem_sync_domain_count(self) -> int:
1060+
"""
1061+
int: Number of memory synchronization domains.
1062+
"""
1063+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEM_SYNC_DOMAIN_COUNT)
1064+
1065+
@property
1066+
def tensor_map_access_supported(self) -> bool:
1067+
"""
1068+
bool: True if device supports tensor map access, False if not.
1069+
"""
1070+
return bool(
1071+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_TENSOR_MAP_ACCESS_SUPPORTED)
1072+
)
1073+
1074+
@property
1075+
def handle_type_fabric_supported(self) -> bool:
1076+
"""
1077+
bool: True if device supports fabric handle type, False if not.
1078+
"""
1079+
return bool(
1080+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HANDLE_TYPE_FABRIC_SUPPORTED)
1081+
)
1082+
1083+
@property
1084+
def unified_function_pointers(self) -> bool:
1085+
"""
1086+
bool: True if device supports unified function pointers, False if not.
1087+
"""
1088+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_UNIFIED_FUNCTION_POINTERS))
1089+
1090+
@property
1091+
def mps_enabled(self) -> bool:
1092+
"""
1093+
bool: True if MPS (Multi-Process Service) is enabled, False if not.
1094+
"""
1095+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MPS_ENABLED))
1096+
1097+
@property
1098+
def host_numa_id(self) -> int:
1099+
"""
1100+
int: Host NUMA node ID.
1101+
"""
1102+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_ID)
1103+
1104+
@property
1105+
def d3d12_cig_supported(self) -> bool:
1106+
"""
1107+
bool: True if device supports D3D12 CIG (Compute Interop Graphics), False if not.
1108+
"""
1109+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_D3D12_CIG_SUPPORTED))
1110+
1111+
@property
1112+
def mem_decompress_algorithm_mask(self) -> int:
1113+
"""
1114+
int: Memory decompression algorithm mask.
1115+
"""
1116+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEM_DECOMPRESS_ALGORITHM_MASK)
1117+
1118+
@property
1119+
def mem_decompress_maximum_length(self) -> int:
1120+
"""
1121+
int: Maximum length for memory decompression.
1122+
"""
1123+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_MEM_DECOMPRESS_MAXIMUM_LENGTH)
1124+
1125+
@property
1126+
def vulkan_cig_supported(self) -> bool:
1127+
"""
1128+
bool: True if device supports Vulkan CIG (Compute Interop Graphics), False if not.
1129+
"""
1130+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_VULKAN_CIG_SUPPORTED))
1131+
1132+
@property
1133+
def gpu_pci_device_id(self) -> int:
1134+
"""
1135+
int: GPU PCI device ID.
1136+
"""
1137+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_GPU_PCI_DEVICE_ID)
1138+
1139+
@property
1140+
def gpu_pci_subsystem_id(self) -> int:
1141+
"""
1142+
int: GPU PCI subsystem ID.
1143+
"""
1144+
return self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_GPU_PCI_SUBSYSTEM_ID)
1145+
1146+
@property
1147+
def host_numa_virtual_memory_management_supported(self) -> bool:
1148+
"""
1149+
bool: True if device supports host NUMA virtual memory management, False if not.
1150+
"""
1151+
return bool(
1152+
self._get_cached_attribute(
1153+
driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_VIRTUAL_MEMORY_MANAGEMENT_SUPPORTED
1154+
)
1155+
)
1156+
1157+
@property
1158+
def host_numa_memory_pools_supported(self) -> bool:
1159+
"""
1160+
bool: True if device supports host NUMA memory pools, False if not.
1161+
"""
1162+
return bool(
1163+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_MEMORY_POOLS_SUPPORTED)
1164+
)
1165+
1166+
@property
1167+
def host_numa_multinode_ipc_supported(self) -> bool:
1168+
"""
1169+
bool: True if device supports host NUMA multinode IPC, False if not.
1170+
"""
1171+
return bool(
1172+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_NUMA_MULTINODE_IPC_SUPPORTED)
1173+
)
1174+
1175+
@property
1176+
def host_memory_pools_supported(self) -> bool:
1177+
"""
1178+
bool: True if device supports host memory pools, False if not.
1179+
"""
1180+
return bool(self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_MEMORY_POOLS_SUPPORTED))
1181+
1182+
@property
1183+
def host_virtual_memory_management_supported(self) -> bool:
1184+
"""
1185+
bool: True if device supports host virtual memory management, False if not.
1186+
"""
1187+
return bool(
1188+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_VIRTUAL_MEMORY_MANAGEMENT_SUPPORTED)
1189+
)
1190+
1191+
@property
1192+
def host_alloc_dma_buf_supported(self) -> bool:
1193+
"""
1194+
bool: True if device supports host allocation DMA buffer operations, False if not.
1195+
"""
1196+
return bool(
1197+
self._get_cached_attribute(driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_HOST_ALLOC_DMA_BUF_SUPPORTED)
1198+
)
1199+
1200+
@property
1201+
def only_partial_host_native_atomic_supported(self) -> bool:
1202+
"""
1203+
bool: True if device supports only partial host native atomic operations, False if not.
1204+
"""
1205+
return bool(
1206+
self._get_cached_attribute(
1207+
driver.CUdevice_attribute.CU_DEVICE_ATTRIBUTE_ONLY_PARTIAL_HOST_NATIVE_ATOMIC_SUPPORTED
1208+
)
1209+
)
1210+
1211+
9331212

9341213
_SUCCESS = driver.CUresult.CUDA_SUCCESS
9351214
_INVALID_CTX = driver.CUresult.CUDA_ERROR_INVALID_CONTEXT

cuda_core/tests/test_device.py

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test_pci_bus_id():
7676
def test_uuid():
7777
device = Device()
7878
driver_ver = handle_return(driver.cuDriverGetVersion())
79-
if 11040 <= driver_ver < 13000:
79+
if driver_ver < 13000:
8080
uuid = handle_return(driver.cuDeviceGetUuid_v2(device.device_id))
8181
else:
8282
uuid = handle_return(driver.cuDeviceGetUuid(device.device_id))
@@ -224,15 +224,53 @@ def test_arch():
224224
("gpu_direct_rdma_writes_ordering", int),
225225
("mempool_supported_handle_types", int),
226226
("deferred_mapping_cuda_array_supported", bool),
227+
("surface_alignment", int),
228+
("async_engine_count", int),
229+
("can_tex2d_gather", bool),
230+
("maximum_texture2d_gather_width", int),
231+
("maximum_texture2d_gather_height", int),
232+
("stream_priorities_supported", bool),
233+
("cooperative_multi_device_launch", bool),
234+
("can_flush_remote_writes", bool),
235+
("host_register_supported", bool),
236+
("virtual_address_management_supported", bool),
237+
("timeline_semaphore_interop_supported", bool),
238+
("cluster_launch", bool),
239+
("can_use_64_bit_stream_mem_ops", bool),
240+
("can_use_stream_wait_value_nor", bool),
241+
("dma_buf_supported", bool),
242+
("ipc_event_supported", bool),
243+
("mem_sync_domain_count", int),
244+
("tensor_map_access_supported", bool),
245+
("handle_type_fabric_supported", bool),
246+
("unified_function_pointers", bool),
247+
("numa_config", int),
248+
("numa_id", int),
249+
("multicast_supported", bool),
250+
("mps_enabled", bool),
251+
("host_numa_id", int),
252+
("d3d12_cig_supported", bool),
253+
("mem_decompress_algorithm_mask", int),
254+
("mem_decompress_maximum_length", int),
255+
("vulkan_cig_supported", bool),
256+
("gpu_pci_device_id", int),
257+
("gpu_pci_subsystem_id", int),
258+
("host_numa_virtual_memory_management_supported", bool),
259+
("host_numa_memory_pools_supported", bool),
260+
("host_numa_multinode_ipc_supported", bool),
227261
]
228262

229-
cuda_12_properties = [("numa_config", int), ("numa_id", int), ("multicast_supported", bool)]
263+
# CUDA 13+ specific attributes
264+
cuda_13_properties = [
265+
("host_memory_pools_supported", bool),
266+
("host_virtual_memory_management_supported", bool),
267+
("host_alloc_dma_buf_supported", bool),
268+
("only_partial_host_native_atomic_supported", bool),
269+
]
230270

231271
version = get_binding_version()
232-
cuda_11 = True
233-
if version[0] >= 12 and version[1] >= 12000:
234-
cuda_base_properties += cuda_12_properties
235-
cuda_11 = False
272+
if version[0] >= 13 and version[1] >= 13000:
273+
cuda_base_properties += cuda_13_properties
236274

237275

238276
@pytest.mark.parametrize("property_name, expected_type", cuda_base_properties)
@@ -246,8 +284,10 @@ def test_device_properties_complete():
246284
live_props = set(attr for attr in dir(device.properties) if not attr.startswith("_"))
247285
tab_props = set(attr for attr, _ in cuda_base_properties)
248286

249-
# Exclude specific properties from the comparison when unsupported by CTK.
250-
excluded_props = {"numa_config", "multicast_supported", "numa_id"} if cuda_11 else set()
287+
excluded_props = set()
288+
# Exclude CUDA 13+ specific properties when not available
289+
if version[0] < 13 or version[1] < 13000:
290+
excluded_props.update({prop[0] for prop in cuda_13_properties})
251291

252292
filtered_tab_props = tab_props - excluded_props
253293
filtered_live_props = live_props - excluded_props

0 commit comments

Comments
 (0)