Skip to content

Commit c5bc597

Browse files
committed
Extract requires() mark to eliminate repeated version checks
Add helpers/marks.py with a reusable requires() decorator and replace all inline numpy version skipif patterns across test files. Made-with: Cursor
1 parent fc1ff27 commit c5bc597

File tree

7 files changed

+57
-17
lines changed

7 files changed

+57
-17
lines changed

cuda_core/tests/graph/test_advanced.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
import numpy as np
77
import pytest
88
from helpers.graph_kernels import compile_common_kernels, compile_conditional_kernels
9+
from helpers.marks import requires
910

1011
from cuda.core import Device, LaunchConfig, LegacyPinnedMemoryResource, launch
1112

1213

13-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
14+
@requires(np, 2, 1)
1415
def test_graph_child_graph(init_cuda):
1516
mod = compile_common_kernels()
1617
add_one = mod.get_kernel("add_one")
@@ -63,7 +64,7 @@ def test_graph_child_graph(init_cuda):
6364
b.close()
6465

6566

66-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
67+
@requires(np, 2, 1)
6768
def test_graph_update(init_cuda):
6869
mod = compile_conditional_kernels(int)
6970
add_one = mod.get_kernel("add_one")

cuda_core/tests/graph/test_basic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
import pytest
88
from helpers.graph_kernels import compile_common_kernels
9+
from helpers.marks import requires
910

1011
from cuda.core import Device, GraphBuilder, LaunchConfig, LegacyPinnedMemoryResource, launch
1112

@@ -116,7 +117,7 @@ def test_graph_is_join_required(init_cuda):
116117
gb.end_building().complete()
117118

118119

119-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
120+
@requires(np, 2, 1)
120121
def test_graph_repeat_capture(init_cuda):
121122
mod = compile_common_kernels()
122123
add_one = mod.get_kernel("add_one")

cuda_core/tests/graph/test_conditional.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@
88
import numpy as np
99
import pytest
1010
from helpers.graph_kernels import compile_conditional_kernels
11+
from helpers.marks import requires
1112

1213
from cuda.core import Device, GraphBuilder, LaunchConfig, LegacyPinnedMemoryResource, launch
1314

1415

1516
@pytest.mark.parametrize(
1617
"condition_value", [True, False, ctypes.c_bool(True), ctypes.c_bool(False), np.bool_(True), np.bool_(False), 1, 0]
1718
)
18-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
19+
@requires(np, 2, 1)
1920
def test_graph_conditional_if(init_cuda, condition_value):
2021
mod = compile_conditional_kernels(type(condition_value))
2122
add_one = mod.get_kernel("add_one")
@@ -79,7 +80,7 @@ def test_graph_conditional_if(init_cuda, condition_value):
7980
@pytest.mark.parametrize(
8081
"condition_value", [True, False, ctypes.c_bool(True), ctypes.c_bool(False), np.bool_(True), np.bool_(False), 1, 0]
8182
)
82-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
83+
@requires(np, 2, 1)
8384
def test_graph_conditional_if_else(init_cuda, condition_value):
8485
mod = compile_conditional_kernels(type(condition_value))
8586
add_one = mod.get_kernel("add_one")
@@ -151,7 +152,7 @@ def test_graph_conditional_if_else(init_cuda, condition_value):
151152

152153

153154
@pytest.mark.parametrize("condition_value", [0, 1, 2, 3])
154-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
155+
@requires(np, 2, 1)
155156
def test_graph_conditional_switch(init_cuda, condition_value):
156157
mod = compile_conditional_kernels(type(condition_value))
157158
add_one = mod.get_kernel("add_one")
@@ -242,7 +243,7 @@ def test_graph_conditional_switch(init_cuda, condition_value):
242243

243244

244245
@pytest.mark.parametrize("condition_value", [True, False, 1, 0])
245-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
246+
@requires(np, 2, 1)
246247
def test_graph_conditional_while(init_cuda, condition_value):
247248
mod = compile_conditional_kernels(type(condition_value))
248249
add_one = mod.get_kernel("add_one")

cuda_core/tests/graph/test_device_launch.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import numpy as np
1414
import pytest
15+
from helpers.marks import requires
1516

1617
from cuda.core import (
1718
Device,
@@ -82,7 +83,7 @@ def _compile_device_launcher_kernel():
8283
Device().compute_capability.major < 9,
8384
reason="Device-side graph launch requires Hopper (sm_90+) architecture",
8485
)
85-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
86+
@requires(np, 2, 1)
8687
def test_device_launch_basic(init_cuda):
8788
"""Test basic device-side graph launch functionality.
8889
@@ -134,7 +135,7 @@ def test_device_launch_basic(init_cuda):
134135
Device().compute_capability.major < 9,
135136
reason="Device-side graph launch requires Hopper (sm_90+) architecture",
136137
)
137-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
138+
@requires(np, 2, 1)
138139
def test_device_launch_multiple(init_cuda):
139140
"""Test that device-side graph launch can be executed multiple times.
140141

cuda_core/tests/helpers/marks.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
3+
4+
"""Reusable pytest marks for cuda_core tests."""
5+
6+
import importlib
7+
import types
8+
9+
import pytest
10+
11+
12+
def requires(module, *version):
13+
"""Skip the test if a module is missing or older than the given version.
14+
15+
Usage::
16+
17+
@requires(np, 2, 1)
18+
def test_foo(): ...
19+
20+
21+
@requires("scipy", 1, 12)
22+
def test_bar(): ...
23+
"""
24+
if isinstance(module, str):
25+
name = module
26+
try:
27+
module = importlib.import_module(name)
28+
except ImportError:
29+
return pytest.mark.skip(reason=f"{name} is not installed")
30+
elif isinstance(module, types.ModuleType):
31+
name = module.__name__
32+
else:
33+
raise TypeError(f"expected module or string, got {type(module).__name__}")
34+
35+
n = len(version)
36+
parts = module.__version__.split(".")[:n]
37+
installed = tuple(int(p) for p in parts)
38+
ver_str = ".".join(str(v) for v in version)
39+
return pytest.mark.skipif(installed < version, reason=f"need {name} {ver_str}+")

cuda_core/tests/test_launcher.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import ctypes
55

66
import helpers
7+
from helpers.marks import requires
78
from helpers.misc import StreamWrapper
89

910
try:
@@ -190,7 +191,7 @@ def test_launch_invalid_values(init_cuda):
190191

191192

192193
@pytest.mark.parametrize("python_type, cpp_type, init_value", PARAMS)
193-
@pytest.mark.skipif(tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+")
194+
@requires(np, 2, 1)
194195
def test_launch_scalar_argument(python_type, cpp_type, init_value):
195196
dev = Device()
196197
dev.set_current()
@@ -289,10 +290,7 @@ def test_cooperative_launch():
289290
"device_memory_resource", # kludgy, but can go away after #726 is resolved
290291
pytest.param(
291292
LegacyPinnedMemoryResource,
292-
marks=pytest.mark.skipif(
293-
tuple(int(i) for i in np.__version__.split(".")[:3]) < (2, 2, 5),
294-
reason="need numpy 2.2.5+, numpy GH #28632",
295-
),
293+
marks=requires(np, 2, 2, 5),
296294
),
297295
],
298296
)

cuda_core/tests/test_utils.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
ml_dtypes = None
2727
import numpy as np
2828
import pytest
29+
from helpers.marks import requires
2930

3031
from cuda.core import Device
3132
from cuda.core._dlpack import DLDeviceType
@@ -85,9 +86,7 @@ def convert_strides_to_counts(strides, itemsize):
8586
# readonly is fixed recently (numpy/numpy#26501)
8687
pytest.param(
8788
np.frombuffer(b""),
88-
marks=pytest.mark.skipif(
89-
tuple(int(i) for i in np.__version__.split(".")[:2]) < (2, 1), reason="need numpy 2.1.0+"
90-
),
89+
marks=requires(np, 2, 1),
9190
),
9291
),
9392
)

0 commit comments

Comments
 (0)