Skip to content

Commit 20cdfd6

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix/check-cython-abi-anon-struct-renames
2 parents 7f3c0c4 + 339d7c7 commit 20cdfd6

13 files changed

Lines changed: 525 additions & 54 deletions

.github/dependabot.yml

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,51 @@
1-
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
1+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

55
version: 2
66
updates:
7+
# Python test-dependency updates for cuda_bindings
8+
- package-ecosystem: pip
9+
directory: /cuda_bindings
10+
schedule:
11+
interval: "monthly"
12+
time: "09:00"
13+
timezone: "America/Los_Angeles"
14+
open-pull-requests-limit: 5
15+
groups:
16+
test-deps:
17+
applies-to: version-updates
18+
patterns: ["*"]
19+
update-types: ["major", "minor", "patch"]
20+
21+
# Python test-dependency updates for cuda_core
22+
- package-ecosystem: pip
23+
directory: /cuda_core
24+
schedule:
25+
interval: "monthly"
26+
time: "09:00"
27+
timezone: "America/Los_Angeles"
28+
open-pull-requests-limit: 5
29+
groups:
30+
test-deps:
31+
applies-to: version-updates
32+
patterns: ["*"]
33+
update-types: ["major", "minor", "patch"]
34+
35+
# Python test-dependency updates for cuda_pathfinder
36+
- package-ecosystem: pip
37+
directory: /cuda_pathfinder
38+
schedule:
39+
interval: "monthly"
40+
time: "09:00"
41+
timezone: "America/Los_Angeles"
42+
open-pull-requests-limit: 5
43+
groups:
44+
test-deps:
45+
applies-to: version-updates
46+
patterns: ["*"]
47+
update-types: ["major", "minor", "patch"]
48+
749
# GitHub Actions updates targeting the default branch (main)
850
- package-ecosystem: github-actions
951
directory: /

cuda_bindings/pyproject.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ all = [
4646
[dependency-groups]
4747
test = [
4848
"cython>=3.2,<3.3",
49-
"setuptools>=77.0.0",
49+
"setuptools>=80.0.0",
5050
# TODO: remove the Python 3.15 guard once 3.15 is officially supported
51-
"matplotlib>=3.5.0; python_version < '3.15'",
52-
"numpy>=1.21.1",
53-
"pytest>=6.2.4",
54-
"pytest-benchmark>=3.4.1",
55-
"pytest-repeat",
56-
"pytest-randomly",
57-
"pyglet>=2.1.9",
51+
"matplotlib>=3.5.0,<=3.10.9; python_version < '3.15'",
52+
"numpy>=1.21.1,<=2.5.0",
53+
"pytest==9.1.0",
54+
"pytest-benchmark==5.2.3",
55+
"pytest-repeat==0.9.4",
56+
"pytest-randomly==4.1.0",
57+
"pyglet==2.1.14",
5858
]
5959

6060
[project.urls]

cuda_core/pyproject.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,18 @@ cu13 = ["cuda-bindings[all]==13.*", "cuda-toolkit==13.*"]
6060

6161
[dependency-groups]
6262
test = [
63-
"cython>=3.2,<3.3", "setuptools", "pytest>=6.2.4", "pytest-benchmark",
64-
"pytest-randomly", "pytest-repeat", "pytest-rerunfailures", "pytest-timeout",
65-
"cloudpickle", "psutil",
63+
"cython>=3.2,<3.3",
64+
"setuptools>=80",
65+
"pytest==9.1.0",
66+
"pytest-benchmark==5.2.3",
67+
"pytest-randomly==4.1.0",
68+
"pytest-repeat==0.9.4",
69+
"pytest-rerunfailures==16.3",
70+
"pytest-timeout==2.4.0",
71+
"cloudpickle==3.1.2",
72+
"psutil==7.2.2",
6673
# TODO: remove the Python 3.15 guard once 3.15 is officially supported
67-
"cffi; python_version < '3.15'",
74+
"cffi==2.0.0; python_version < '3.15'",
6875
]
6976
ml-dtypes = ["ml-dtypes>=0.5.4,<0.6.0"]
7077
test-cu12 = [ {include-group = "ml-dtypes" }, {include-group = "test" }, "cupy-cuda12x; python_version < '3.14'", "cuda-toolkit[cudart]==12.*"] # runtime headers needed by CuPy

cuda_core/tests/conftest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ def ipc_memory_resource(request, ipc_device):
290290
assert mr.is_ipc_enabled
291291
yield mr
292292
mr.close()
293+
# TODO(seberg): Make sure the `mr` and it's buffers are fully torn down.
294+
# May be unnecessary as `mr.close()` is not parallel with other work.
295+
ipc_device.sync()
293296

294297

295298
@pytest.fixture

cuda_core/tests/memory_ipc/test_peer_access.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ def test_main(self, ipc_mempool_device_x2, grant_access_in_parent):
9292
assert process.exitcode == 0
9393

9494
buffer.close()
95+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
96+
dev1.sync()
9597
mr.close()
9698

9799
def child_main(self, mr, buffer):
@@ -129,4 +131,6 @@ def child_main(self, mr, buffer):
129131
PatternGen(dev0, NBYTES).verify_buffer(buffer, seed=False)
130132

131133
buffer.close()
134+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
135+
dev1.sync()
132136
mr.close()

cuda_core/tests/memory_ipc/test_send_buffers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def test_main(self, ipc_device, nmrs):
2929
device = ipc_device
3030
options = DeviceMemoryResourceOptions(max_size=POOL_SIZE, ipc_enabled=True)
3131
mrs = [DeviceMemoryResource(device, options=options) for _ in range(nmrs)]
32+
buffers = []
3233

3334
try:
3435
# Allocate and fill memory.
@@ -54,6 +55,10 @@ def test_main(self, ipc_device, nmrs):
5455
pgen.verify_buffer(buffer, seed=True)
5556
buffer.close()
5657
finally:
58+
for buffer in buffers:
59+
buffer.close()
60+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
61+
device.sync()
5762
for mr in mrs:
5863
mr.close()
5964

cuda_core/tests/memory_ipc/test_workerpool.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def test_main(self, ipc_device, nmrs):
3535
device = ipc_device
3636
options = DeviceMemoryResourceOptions(max_size=POOL_SIZE, ipc_enabled=True)
3737
mrs = [DeviceMemoryResource(device, options=options) for _ in range(nmrs)]
38+
buffers = []
3839

3940
try:
4041
buffers = [mr.allocate(NBYTES, stream=device.default_stream) for mr, _ in zip(cycle(mrs), range(NTASKS))]
@@ -45,8 +46,11 @@ def test_main(self, ipc_device, nmrs):
4546
pgen = PatternGen(device, NBYTES)
4647
for buffer in buffers:
4748
pgen.verify_buffer(buffer, seed=True)
48-
buffer.close()
4949
finally:
50+
for buffer in buffers:
51+
buffer.close()
52+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
53+
device.sync()
5054
for mr in mrs:
5155
mr.close()
5256

@@ -77,6 +81,7 @@ def test_main(self, ipc_device, nmrs):
7781
device = ipc_device
7882
options = DeviceMemoryResourceOptions(max_size=POOL_SIZE, ipc_enabled=True)
7983
mrs = [DeviceMemoryResource(device, options=options) for _ in range(nmrs)]
84+
buffers = []
8085

8186
try:
8287
buffers = [mr.allocate(NBYTES, stream=device.default_stream) for mr, _ in zip(cycle(mrs), range(NTASKS))]
@@ -90,8 +95,11 @@ def test_main(self, ipc_device, nmrs):
9095
pgen = PatternGen(device, NBYTES)
9196
for buffer in buffers:
9297
pgen.verify_buffer(buffer, seed=True)
93-
buffer.close()
9498
finally:
99+
for buffer in buffers:
100+
buffer.close()
101+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
102+
device.sync()
95103
for mr in mrs:
96104
mr.close()
97105

@@ -127,6 +135,7 @@ def test_main(self, ipc_device, nmrs):
127135
device = ipc_device
128136
options = DeviceMemoryResourceOptions(max_size=POOL_SIZE, ipc_enabled=True)
129137
mrs = [DeviceMemoryResource(device, options=options) for _ in range(nmrs)]
138+
buffers = []
130139

131140
try:
132141
buffers = [mr.allocate(NBYTES, stream=device.default_stream) for mr, _ in zip(cycle(mrs), range(NTASKS))]
@@ -137,8 +146,11 @@ def test_main(self, ipc_device, nmrs):
137146
pgen = PatternGen(device, NBYTES)
138147
for buffer in buffers:
139148
pgen.verify_buffer(buffer, seed=True)
140-
buffer.close()
141149
finally:
150+
for buffer in buffers:
151+
buffer.close()
152+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
153+
device.sync()
142154
for mr in mrs:
143155
mr.close()
144156

cuda_core/tests/test_memory.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,8 @@ def test_device_memory_resource_with_options(init_cuda):
11031103
device.sync()
11041104
dst_buffer.close()
11051105
src_buffer.close()
1106+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
1107+
device.sync()
11061108

11071109

11081110
def test_pinned_memory_resource_with_options(init_cuda):
@@ -1149,6 +1151,8 @@ def test_pinned_memory_resource_with_options(init_cuda):
11491151
device.sync()
11501152
dst_buffer.close()
11511153
src_buffer.close()
1154+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
1155+
device.sync()
11521156

11531157

11541158
def test_managed_memory_resource_with_options(init_cuda):
@@ -1365,6 +1369,8 @@ def test_mempool_ipc_errors(mempool_device):
13651369
Buffer.from_ipc_descriptor(mr, handle, stream=device.default_stream)
13661370

13671371
buffer.close()
1372+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
1373+
device.sync()
13681374

13691375

13701376
def test_pinned_mempool_ipc_basic():
@@ -1405,6 +1411,8 @@ def test_pinned_mempool_ipc_basic():
14051411
assert ipc_desc.size == 1024
14061412

14071413
buffer.close()
1414+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
1415+
device.sync()
14081416
mr.close()
14091417

14101418

@@ -1436,6 +1444,8 @@ def test_pinned_mempool_ipc_errors():
14361444
Buffer.from_ipc_descriptor(mr, handle, stream=device.default_stream)
14371445

14381446
buffer.close()
1447+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
1448+
device.sync()
14391449
mr.close()
14401450

14411451

cuda_core/tests/test_object_protocols.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,11 @@ def sample_ipc_buffer_descriptor(ipc_device):
233233
options = DeviceMemoryResourceOptions(max_size=POOL_SIZE, ipc_enabled=True)
234234
mr = DeviceMemoryResource(ipc_device, options=options)
235235
buf = mr.allocate(64, stream=ipc_device.default_stream)
236-
return buf.ipc_descriptor
236+
descriptor = buf.ipc_descriptor
237+
buf.close()
238+
# TODO(seberg): 2026-06: mr close may be unsafe with incomplete `buf.close()`
239+
ipc_device.sync()
240+
return descriptor
237241

238242

239243
@pytest.fixture

cuda_core/tests/test_tensor_map.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,22 @@ def test_invalid_data_type(self, dev, skip_if_no_tma):
308308
data_type=42,
309309
)
310310

311+
def test_as_tensor_map_host_view_rejected_without_tma(self):
312+
"""``as_tensor_map`` rejects a non-device-accessible (host) view with a
313+
clear error, exercising the ``as_tensor_map`` -> ``_from_tiled`` path
314+
without needing TMA-capable hardware."""
315+
host = np.zeros((64, 64), dtype=np.float32)
316+
view = StridedMemoryView.from_any_interface(host, stream_ptr=-1)
317+
with pytest.raises(ValueError, match="device-accessible"):
318+
view.as_tensor_map(
319+
box_dim=(32, 32),
320+
data_type=TensorMapDataType.FLOAT32,
321+
element_strides=(1, 1),
322+
swizzle=TensorMapSwizzle.SWIZZLE_128B,
323+
l2_promotion=TensorMapL2Promotion.L2_128B,
324+
oob_fill=TensorMapOOBFill.NAN_REQUEST_ZERO_FMA,
325+
)
326+
311327

312328
class TestTensorMapDtypeMapping:
313329
"""Test automatic dtype inference from numpy dtypes."""

0 commit comments

Comments
 (0)