Skip to content

Commit bc49b17

Browse files
committed
Use subtests where appropriate everywhere
1 parent bdd6447 commit bc49b17

8 files changed

Lines changed: 565 additions & 535 deletions

File tree

cuda_bindings/pixi.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ cuda-version = ["12.*", "13.3.*"]
1414

1515
[feature.test.dependencies]
1616
cuda-bindings = { path = "." }
17-
pytest = ">=6.2.4"
17+
pytest = ">=9.0"
1818
pytest-benchmark = ">=3.4.1"
1919
pytest-randomly = "*"
2020
pytest-repeat = "*"

cuda_bindings/tests/nvml/test_compute_mode.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@
1818

1919

2020
@pytest.mark.skipif(sys.platform == "win32", reason="Test not supported on Windows")
21-
def test_compute_mode_supported_nonroot(all_devices):
21+
def test_compute_mode_supported_nonroot(all_devices, subtests):
2222
for device in all_devices:
23-
with unsupported_before(device, None):
24-
original_compute_mode = nvml.device_get_compute_mode(device)
25-
26-
for cm in COMPUTE_MODES:
27-
try:
28-
nvml.device_set_compute_mode(device, cm)
29-
except nvml.NoPermissionError:
30-
pytest.skip("Insufficient permissions to set compute mode")
31-
nvml.device_set_compute_mode(device, original_compute_mode)
32-
assert original_compute_mode == nvml.device_get_compute_mode(device), "Compute mode shouldn't have changed"
23+
with subtests.test(device=device):
24+
with unsupported_before(device, None):
25+
original_compute_mode = nvml.device_get_compute_mode(device)
26+
27+
for cm in COMPUTE_MODES:
28+
try:
29+
nvml.device_set_compute_mode(device, cm)
30+
except nvml.NoPermissionError:
31+
pytest.skip("Insufficient permissions to set compute mode")
32+
nvml.device_set_compute_mode(device, original_compute_mode)
33+
assert original_compute_mode == nvml.device_get_compute_mode(device), (
34+
"Compute mode shouldn't have changed"
35+
)

cuda_bindings/tests/nvml/test_device.py

Lines changed: 69 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ def test_clk_mon_status_t():
3838
assert not hasattr(obj, "clk_mon_list_size")
3939

4040

41-
def test_current_clock_freqs(all_devices):
41+
def test_current_clock_freqs(all_devices, subtests):
4242
for device in all_devices:
43-
with unsupported_before(device, None):
44-
clk_freqs = nvml.device_get_current_clock_freqs(device)
45-
assert isinstance(clk_freqs, str)
43+
with subtests.test(device=device):
44+
with unsupported_before(device, None):
45+
clk_freqs = nvml.device_get_current_clock_freqs(device)
46+
assert isinstance(clk_freqs, str)
4647

4748

4849
def test_grid_licensable_features(all_devices):
@@ -69,17 +70,18 @@ def test_get_handle_by_uuidv(all_devices):
6970
assert new_handle == device
7071

7172

72-
def test_get_nv_link_supported_bw_modes(all_devices):
73+
def test_get_nv_link_supported_bw_modes(all_devices, subtests):
7374
for device in all_devices:
74-
with unsupported_before(device, None):
75-
modes = nvml.device_get_nvlink_supported_bw_modes(device)
76-
assert isinstance(modes, nvml.NvlinkSupportedBwModes_v1)
77-
# #define NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES 23
78-
assert len(modes.bw_modes) <= 23
79-
assert not hasattr(modes, "total_bw_modes")
75+
with subtests.test(device=device):
76+
with unsupported_before(device, None):
77+
modes = nvml.device_get_nvlink_supported_bw_modes(device)
78+
assert isinstance(modes, nvml.NvlinkSupportedBwModes_v1)
79+
# #define NVML_NVLINK_TOTAL_SUPPORTED_BW_MODES 23
80+
assert len(modes.bw_modes) <= 23
81+
assert not hasattr(modes, "total_bw_modes")
8082

81-
for mode in modes.bw_modes:
82-
assert isinstance(mode, np.uint8)
83+
for mode in modes.bw_modes:
84+
assert isinstance(mode, np.uint8)
8385

8486

8587
def test_device_get_pdi(all_devices):
@@ -88,62 +90,67 @@ def test_device_get_pdi(all_devices):
8890
assert isinstance(pdi, int)
8991

9092

91-
def test_device_get_performance_modes(all_devices):
93+
def test_device_get_performance_modes(all_devices, subtests):
9294
for device in all_devices:
93-
with unsupported_before(device, None):
94-
modes = nvml.device_get_performance_modes(device)
95-
assert isinstance(modes, str)
95+
with subtests.test(device=device):
96+
with unsupported_before(device, None):
97+
modes = nvml.device_get_performance_modes(device)
98+
assert isinstance(modes, str)
9699

97100

98101
@pytest.mark.skipif(cuda_version_less_than(13010), reason="Introduced in 13.1")
99-
def test_device_get_unrepairable_memory_flag(all_devices):
102+
def test_device_get_unrepairable_memory_flag(all_devices, subtests):
100103
for device in all_devices:
101-
with unsupported_before(device, None):
102-
status = nvml.device_get_unrepairable_memory_flag_v1(device)
103-
assert isinstance(status, int)
104+
with subtests.test(device=device):
105+
with unsupported_before(device, None):
106+
status = nvml.device_get_unrepairable_memory_flag_v1(device)
107+
assert isinstance(status, int)
104108

105109

106-
def test_device_vgpu_get_heterogeneous_mode(all_devices):
110+
def test_device_vgpu_get_heterogeneous_mode(all_devices, subtests):
107111
for device in all_devices:
108-
with unsupported_before(device, None):
109-
mode = nvml.device_get_vgpu_heterogeneous_mode(device)
110-
assert isinstance(mode, int)
112+
with subtests.test(device=device):
113+
with unsupported_before(device, None):
114+
mode = nvml.device_get_vgpu_heterogeneous_mode(device)
115+
assert isinstance(mode, int)
111116

112117

113118
@pytest.mark.skipif(cuda_version_less_than(13010), reason="Introduced in 13.1")
114-
def test_read_prm_counters(all_devices):
119+
def test_read_prm_counters(all_devices, subtests):
115120
for device in all_devices:
116-
counters = nvml.PRMCounter_v1(5)
117-
with unsupported_before(device, None):
118-
read_counters = nvml.device_read_prm_counters_v1(device, counters)
119-
assert counters is read_counters
120-
assert len(read_counters) == 5
121+
with subtests.test(device=device):
122+
counters = nvml.PRMCounter_v1(5)
123+
with unsupported_before(device, None):
124+
read_counters = nvml.device_read_prm_counters_v1(device, counters)
125+
assert counters is read_counters
126+
assert len(read_counters) == 5
121127

122128

123129
@pytest.mark.thread_unsafe(reason="API appears to be thread-unsafe (2026-06)")
124-
def test_read_write_prm(all_devices):
130+
def test_read_write_prm(all_devices, subtests):
125131
for device in all_devices:
126-
# Docs say supported in BLACKWELL or later
127-
with unsupported_before(device, None):
128-
try:
129-
result = nvml.device_read_write_prm_v1(device, b"012345678")
130-
except nvml.NoPermissionError:
131-
pytest.skip("No permission to read/write PRM")
132-
assert isinstance(result, tuple)
133-
assert isinstance(result[0], int)
134-
assert isinstance(result[1], bytes)
135-
136-
137-
def test_get_power_management_limit(all_devices):
132+
with subtests.test(device=device):
133+
# Docs say supported in BLACKWELL or later
134+
with unsupported_before(device, None):
135+
try:
136+
result = nvml.device_read_write_prm_v1(device, b"012345678")
137+
except nvml.NoPermissionError:
138+
pytest.skip("No permission to read/write PRM")
139+
assert isinstance(result, tuple)
140+
assert isinstance(result[0], int)
141+
assert isinstance(result[1], bytes)
142+
143+
144+
def test_get_power_management_limit(all_devices, subtests):
138145
for device in all_devices:
139146
# Docs say supported on KEPLER or later
140-
with unsupported_before(device, None):
147+
with subtests.test(device=device), unsupported_before(device, nvml.DeviceArch.KEPLER):
141148
nvml.device_get_power_management_limit(device)
142149

143150

144-
def test_set_power_management_limit(all_devices):
151+
def test_set_power_management_limit(all_devices, subtests):
145152
for device in all_devices:
146-
with unsupported_before(device, nvml.DeviceArch.KEPLER):
153+
with subtests.test(device=device), unsupported_before(device, nvml.DeviceArch.KEPLER):
147154
try:
148155
nvml.device_set_power_management_limit_v2(device, nvml.PowerScope.GPU, 10000)
149156
except nvml.NoPermissionError:
@@ -152,18 +159,19 @@ def test_set_power_management_limit(all_devices):
152159
pytest.skip("Invalid argument when setting power management limit -- probably unsupported")
153160

154161

155-
def test_set_temperature_threshold(all_devices):
162+
def test_set_temperature_threshold(all_devices, subtests):
156163
for device in all_devices:
157-
# Docs say supported on MAXWELL or newer
158-
with unsupported_before(device, None):
159-
temp = nvml.device_get_temperature_threshold(
160-
device, nvml.TemperatureThresholds.TEMPERATURE_THRESHOLD_ACOUSTIC_CURR
161-
)
162-
try:
163-
nvml.device_set_temperature_threshold(
164-
device, nvml.TemperatureThresholds.TEMPERATURE_THRESHOLD_ACOUSTIC_CURR, temp
165-
)
166-
except nvml.NoPermissionError:
167-
pytest.skip("No permission to set temperature threshold")
168-
except nvml.InvalidArgumentError:
169-
pytest.skip("Invalid argument when setting temperature threshold -- this is probably the temp type")
164+
with subtests.test(device=device):
165+
# Docs say supported on MAXWELL or newer
166+
with unsupported_before(device, None):
167+
temp = nvml.device_get_temperature_threshold(
168+
device, nvml.TemperatureThresholds.TEMPERATURE_THRESHOLD_ACOUSTIC_CURR
169+
)
170+
try:
171+
nvml.device_set_temperature_threshold(
172+
device, nvml.TemperatureThresholds.TEMPERATURE_THRESHOLD_ACOUSTIC_CURR, temp
173+
)
174+
except nvml.NoPermissionError:
175+
pytest.skip("No permission to set temperature threshold")
176+
except nvml.InvalidArgumentError:
177+
pytest.skip("Invalid argument when setting temperature threshold -- this is probably the temp type")

cuda_bindings/tests/nvml/test_gpu.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from .conftest import unsupported_before
1111

1212

13-
def test_gpu_get_module_id(nvml_init):
13+
def test_gpu_get_module_id(nvml_init, subtests):
1414
# Unique module IDs cannot exceed the number of GPUs on the system
1515
device_count = nvml.device_get_count_v2()
1616

@@ -21,23 +21,25 @@ def test_gpu_get_module_id(nvml_init):
2121
if util.is_vgpu(device):
2222
continue
2323

24-
with unsupported_before(device, None):
25-
module_id = nvml.device_get_module_id(device)
26-
assert isinstance(module_id, int)
24+
with subtests.test(i=i):
25+
with unsupported_before(device, None):
26+
module_id = nvml.device_get_module_id(device)
27+
assert isinstance(module_id, int)
2728

2829

29-
def test_gpu_get_platform_info(all_devices):
30+
def test_gpu_get_platform_info(all_devices, subtests):
3031
for device in all_devices:
31-
if util.is_vgpu(device):
32-
pytest.skip(f"Not supported on vGPU device {device}")
32+
with subtests.test(device=device):
33+
if util.is_vgpu(device):
34+
pytest.skip(f"Not supported on vGPU device {device}")
3335

34-
# Documentation says Blackwell or newer only, but this does seem to pass
35-
# on some newer GPUs.
36+
# Documentation says Blackwell or newer only, but this does seem to pass
37+
# on some newer GPUs.
3638

37-
with unsupported_before(device, None):
38-
platform_info = nvml.device_get_platform_info(device)
39+
with unsupported_before(device, None):
40+
platform_info = nvml.device_get_platform_info(device)
3941

40-
assert isinstance(platform_info, (nvml.PlatformInfo_v1, nvml.PlatformInfo_v2))
42+
assert isinstance(platform_info, (nvml.PlatformInfo_v1, nvml.PlatformInfo_v2))
4143

4244

4345
# TODO: Test APIs related to GPU instances, which require specific hardware and root
@@ -58,10 +60,10 @@ def test_conf_compute_attestation_report_t(all_devices):
5860
assert report.nonce.dtype == np.uint8
5961

6062

61-
def test_gpu_conf_compute_attestation_report(all_devices):
63+
def test_gpu_conf_compute_attestation_report(all_devices, subtests):
6264
for device in all_devices:
6365
# Documentation says AMPERE or newer
64-
with unsupported_before(device, None), pytest.raises(nvml.UnknownError):
66+
with subtests.test(device=device), unsupported_before(device, None), pytest.raises(nvml.UnknownError):
6567
# The nonce string is nonsensical, so if this "works", we expect an UnknownError
6668
nvml.device_get_conf_compute_gpu_attestation_report(device, nonce=b"12345678")
6769

@@ -74,9 +76,9 @@ def test_conf_compute_gpu_certificate_t():
7476
assert len(cert.attestation_cert_chain) == 0
7577

7678

77-
def test_conf_compute_gpu_certificate(all_devices):
79+
def test_conf_compute_gpu_certificate(all_devices, subtests):
7880
for device in all_devices:
7981
# Documentation says AMPERE or newer
80-
with unsupported_before(device, None), pytest.raises(nvml.UnknownError):
82+
with subtests.test(device=device), unsupported_before(device, None), pytest.raises(nvml.UnknownError):
8183
# This is expected to fail if the device doesn't have a proper certificate
8284
nvml.device_get_conf_compute_gpu_certificate(device)

cuda_bindings/tests/nvml/test_pci.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99
from .conftest import unsupported_before
1010

1111

12-
def test_discover_gpus(all_devices):
12+
def test_discover_gpus(all_devices, subtests):
1313
for device in all_devices:
14-
pci_info = nvml.device_get_pci_info_v3(device)
15-
# Docs say this should be supported on PASCAL and later
16-
with unsupported_before(device, None), contextlib.suppress(nvml.OperatingSystemError):
17-
nvml.device_discover_gpus(pci_info.ptr)
14+
with subtests.test(device=device):
15+
pci_info = nvml.device_get_pci_info_v3(device)
16+
# Docs say this should be supported on PASCAL and later
17+
with unsupported_before(device, None), contextlib.suppress(nvml.OperatingSystemError):
18+
nvml.device_discover_gpus(pci_info.ptr)
1819

1920

2021
def test_bridge_chip_hierarchy_t():
@@ -24,12 +25,13 @@ def test_bridge_chip_hierarchy_t():
2425
assert isinstance(hierarchy.bridge_chip_info, nvml.BridgeChipInfo)
2526

2627

27-
def test_bridge_chip_info(all_devices):
28+
def test_bridge_chip_info(all_devices, subtests):
2829
for device in all_devices:
29-
with unsupported_before(device, None):
30-
info = nvml.device_get_bridge_chip_info(device)
31-
assert isinstance(info, nvml.BridgeChipHierarchy)
32-
for entry in info.bridge_chip_info:
33-
assert isinstance(entry, nvml.BridgeChipInfo)
34-
assert isinstance(entry.type, int)
35-
assert isinstance(entry.fw_version, int)
30+
with subtests.test(device=device):
31+
with unsupported_before(device, None):
32+
info = nvml.device_get_bridge_chip_info(device)
33+
assert isinstance(info, nvml.BridgeChipHierarchy)
34+
for entry in info.bridge_chip_info:
35+
assert isinstance(entry, nvml.BridgeChipInfo)
36+
assert isinstance(entry.type, int)
37+
assert isinstance(entry.fw_version, int)

0 commit comments

Comments
 (0)