1414import pytest
1515from helpers .graph_kernels import compile_common_kernels
1616
17- from cuda .core import LaunchConfig , LegacyPinnedMemoryResource
17+ from cuda .core import Device , LaunchConfig , LegacyPinnedMemoryResource
1818from cuda .core ._utils ._weak_handles import weak_handle
1919from cuda .core ._utils .cuda_utils import CUDAError , driver , handle_return
2020from cuda .core ._utils .version import driver_version
@@ -619,7 +619,10 @@ def assert_exec_uses(graph, expected):
619619def definition_update_case (request , init_cuda ):
620620 if driver_version () < (12 , 2 , 0 ):
621621 pytest .skip ("individual graph node updates require CUDA 12.2+" )
622- return request .param (init_cuda )
622+ factory = request .param
623+ # pytest-run-parallel shares this fixture object across workers. Build the
624+ # case at call time on Device() so each worker gets its own graph/node.
625+ return lambda : factory (Device ())
623626
624627
625628@pytest .mark .agent_authored (model = "gpt-5.6" )
@@ -745,7 +748,7 @@ def test_memcpy_update_between_host_and_device(init_cuda, device_operand):
745748def test_definition_node_update_changes_future_instantiations (
746749 definition_update_case ,
747750):
748- case = definition_update_case
751+ case = definition_update_case ()
749752 assert case .original != case .replacement
750753 old_graph = case .graph_def .instantiate ()
751754
@@ -762,7 +765,7 @@ def test_definition_node_update_changes_future_instantiations(
762765def test_destroyed_definition_node_rejects_update (
763766 definition_update_case ,
764767):
765- case = definition_update_case
768+ case = definition_update_case ()
766769 case .node .destroy ()
767770
768771 assert not case .node .is_valid
@@ -777,7 +780,7 @@ def test_destroyed_definition_node_rejects_update(
777780def test_failed_definition_node_update_preserves_state (
778781 definition_update_case ,
779782):
780- case = definition_update_case
783+ case = definition_update_case ()
781784
782785 assert case .invalid_update is not None
783786 assert case .invalid_exception is not None
@@ -793,17 +796,18 @@ def test_failed_definition_node_update_preserves_state(
793796def test_definition_node_update_rejects_wrong_type (
794797 definition_update_case ,
795798):
796- if definition_update_case .invalid_argument_update is None :
799+ case = definition_update_case ()
800+ if case .invalid_argument_update is None :
797801 pytest .skip ("update method has no typed positional argument" )
798802 with pytest .raises (TypeError ):
799- definition_update_case .invalid_argument_update ()
803+ case .invalid_argument_update ()
800804
801805
802806@pytest .mark .agent_authored (model = "gpt-5.6" )
803807def test_executable_node_update_changes_existing_exec (
804808 definition_update_case ,
805809):
806- case = definition_update_case
810+ case = definition_update_case ()
807811 graph = case .graph_def .instantiate ()
808812
809813 _update_executable_case (graph , case )
@@ -974,6 +978,7 @@ def test_rejected_executable_update_rolls_back_owners(init_cuda):
974978 assert ctypes .c_int .from_address (int (active .handle )).value == 1
975979
976980
981+ @pytest .mark .thread_unsafe (reason = "deferred cleanup on main thread which would wait" )
977982@pytest .mark .agent_authored (model = "gpt-5.6" )
978983def test_whole_update_replaces_executable_attachment_accumulator (init_cuda ):
979984 if driver_version () < (12 , 2 , 0 ):
@@ -1132,6 +1137,7 @@ def second():
11321137 _wait_until (lambda : first_weak () is None and second_weak () is None )
11331138
11341139
1140+ @pytest .mark .thread_unsafe (reason = "deferred cleanup on main thread which would wait" )
11351141@pytest .mark .agent_authored (model = "claude-opus-5" )
11361142def test_child_graph_update_transfers_source_owners_to_executable (init_cuda ):
11371143 if driver_version () < (12 , 2 , 0 ):
0 commit comments