Repository navigation
cuda.core tests: memory_ipc/test_errors.py is not thread-safe under pytest-run-parallel (SEGV in cuMemPoolDestroy, shared harness state) #2784
Description
Summary
Two tests added by #2728 in cuda_core/tests/memory_ipc/test_errors.py fail on the free-threaded CI jobs (Test linux-aarch64 / Python 3.14t), where pytest-run-parallel executes each test body concurrently in several threads (the module sets pytestmark = pytest.mark.parallel_threads_limit(4)). One failure is a segmentation fault inside cuMemPoolDestroy; the other is a data race on the test class instance. Both reproduce on main itself, independent of the PR they were first noticed on.
Failure 1: SEGV in cuMemPoolDestroy from test_allocation_handle_forking_pickler_roundtrip
Observed on main for the #2728 merge commit bcfbe72c8c7 (run 34230002523, job 102076702071, CUDA 12.9.1 local, L4) and again on #2759 (run 34253228097, job 102163403217, CUDA 13.0.2 wheels, A100). The faulthandler dump is the same in both:
Fatal Python error: Segmentation fault
Stack (most recent call first):
File ".../cuda_core/tests/memory_ipc/test_errors.py", line 327 in test_allocation_handle_forking_pickler_roundtrip
File ".../cuda_core/tests/conftest.py", line 104 in wrapper
File ".../pytest_run_parallel/plugin.py", line 83 in closure
Current thread's C stack trace (most recent call first):
libcuda.so.1 ...
libcuda.so.1, at cuMemPoolDestroy+0x30
cuda/bindings/_bindings/cydriver...
cuda/core/cu13/_resource_handles...
cuda/core/cu13/_memory/_memory_pool...
Line 327 is the mr.close() in the test's finally. Each of the four threads creates its own IPC-enabled DeviceMemoryResource, reads mr.allocation_handle, round-trips it through multiprocessing.reduction.ForkingPickler, closes the restored handle, and destroys its pool. The crash is inside the driver's cuMemPoolDestroy while the other threads are exporting or destroying their own IPC pools. Whether this is a driver-level restriction on concurrent IPC pool export/destroy or a cuda.core teardown problem is not established; either way the test cannot run in parallel threads as written.
Failure 2: TestImportWrongMR.test_main[PinnedMR] pickles another thread's closed resource
Observed on #2759 (run 34253228097, job 102163403408, CUDA 13.3.0 local, L4). The test is marked flaky(reruns=2) and failed all three attempts:
RuntimeError: DeviceMemoryResource has been closed
when serializing cuda.core._memory._buffer.Buffer object
when serializing dict item 'buffer'
when serializing test_errors.TestImportWrongMR state
when serializing multiprocessing.context.Process object
ChildErrorHarness.test_main stores its fixtures on the instance (self.device, self.mr, self._extra_mrs, and self.buffer set by PARENT_ACTION) and spawns the child with target=self.child_main, which pickles self. pytest-run-parallel runs the four threads against the same test instance and the same function-scoped ipc_memory_resource value, so one thread pickles a Buffer whose resource another thread has already closed. The same shared-state pattern applies to every subclass of ChildErrorHarness in the file; this one just lost the race first.
Suggested fix
- Mark the
ChildErrorHarnesssubclasses andtest_allocation_handle_forking_pickler_roundtrip@pytest.mark.thread_unsafe(reason: shared instance state andmultiprocessingspawn; concurrent IPC pool export/destroy), or drop the module-levelparallel_threads_limit(4)in favour of per-test marks. - Separately investigate whether concurrent
cuMemPoolDestroyof IPC-enabled pools from several threads is supposed to be safe; if it is, the SEGV is a cuda.core bug in pool teardown rather than a test-only issue.
Environment
GitHub Actions, linux-aarch64, Python 3.14.7 free-threaded, cuda-bindings 13.x, pytest-run-parallel, CUDA 12.9.1 / 13.0.2 / 13.3.0.
Refs: #2728 (tests added), #2759 (where the failures were analysed).
Activity
rluo8 commentedon Sep 9, 2026
Hi @Andy-Jost @seberg , I opened a PR #2785 to serialize the thread-unsafe tests in test_errors.py. It does not fix the
cuMemPoolDestroySEGV root cause. Thanks!leofang commentedon Sep 9, 2026
Andy-Jost commentedon Sep 9, 2026
Tests serialized in #2785 (merged).
ChildErrorHarness.test_main,test_from_allocation_handle_raw_fd_imports_mapped_pool,test_allocation_handle_forking_pickler_roundtrip, andtest_ipc_registry_dedups_repeated_importsare now markedthread_unsafeso CI is unblocked. Root cause (SEGV incuMemPoolDestroyunder concurrent IPC pool export/destroy, and the shared-harness-state pickling issue) is still open; this issue stays open to track that. (#2791 closed as a duplicate/superseded fix.)Andy-Jost commentedon Sep 10, 2026
Closing. Root-caused to the CUDA driver, not cuda.core: the crash reproduces with a driver-API-only C program and no Python involved. #2785 keeps the affected tests serialized. Follow-up is happening outside this tracker.
Andy-Jost commentedon Sep 11, 2026
SEGV tracked internally as nvbug 6763003