Skip to content

cuda.core tests: memory_ipc/test_errors.py is not thread-safe under pytest-run-parallel (SEGV in cuMemPoolDestroy, shared harness state) #2784

Description

@Andy-Jost

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 ChildErrorHarness subclasses and test_allocation_handle_forking_pickler_roundtrip @pytest.mark.thread_unsafe (reason: shared instance state and multiprocessing spawn; concurrent IPC pool export/destroy), or drop the module-level parallel_threads_limit(4) in favour of per-test marks.
  • Separately investigate whether concurrent cuMemPoolDestroy of 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).

@rluo8 and @seberg for viz

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

P1Medium priority - Should dobugSomething isn't workingcuda.coreEverything related to the cuda.core moduletestImprovements or additions to tests

Type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions