Repository navigation
Commit 657bbaf
cuda.core: fix pool setup and builder teardown under stream capture (#2838)
* cuda.core: fix pool setup and builder teardown under stream capture
DeviceMemoryResource(device) with no options raises the release threshold
of the driver's pool with cuMemPoolGetAttribute and cuMemPoolSetAttribute.
The driver refuses both as potentially unsafe calls while the calling
thread is inside a global or thread-local capture, and it invalidates the
capture. Device.memory_resource constructs the resource lazily, so a first
allocation could invalidate a capture in progress. Make the two calls in
relaxed capture mode and restore the thread's previous mode afterwards. A
failure to restore the mode is attached to the propagating error as a note.
Ending an invalidated capture made the builder destroy a graph the driver
had already destroyed. cuStreamEndCapture returns a NULL graph for an
invalidated (or unjoined) capture and releases the capture graph itself,
but the builder kept the owning handle it took from cuStreamGetCaptureInfo
and its deleter called cuGraphDestroy again: a use-after-free that
segfaulted at close() or garbage collection. Add invalidate_root_graph_state
to retire the hierarchy when the driver discards the root graph, and route
end_building(), close() and __dealloc__ through one GB_end_capture helper
that settles graph ownership from the end-capture result. end_building()
now ends an invalidated capture and raises the driver error; the builder
then holds no graph (new CAPTURE_INVALIDATED state), and complete(),
debug_dot_print(), graph_definition, embed() and Graph.update() say so.
close() closes the builder before raising. end_building() on a forked
builder is rejected with RuntimeError instead of invalidating the capture.
Fixes #2834.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: scope the invalidated-capture recovery to top-level builders
The driver also discards the body graph of a conditional node when the
body capture ends invalidated, and the parent graph keeps referring to
it, which cuda.core cannot repair. Say so in end_building(), the release
note, and the GB_end_capture comment. Scope the DeviceMemoryResource
note to the default-pool constructor, since cuMemPoolCreate is still
refused under capture. Drop the end_building() call on a forked builder
from the skip path of test_graph_conditional_on_forked_builder.
Issue #2834
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: close unjoined forks when GraphBuilder.join fails
join() waits on each forked builder's stream and then closes it. When a
wait raised partway through, the forks the loop had not reached stayed
open with capturing streams, and destroying them later during garbage
collection crashed the interpreter.
Close every fork the loop did not reach before the error propagates.
The capture cannot complete without the work captured on those forks,
so end_building() then raises the driver's unjoined-capture error and
the builder closes cleanly, which #2834 made possible.
Issue #2776
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: fold the join cleanup into the capture-teardown release note
PR #2881 is folded into this PR: its join() cleanup relies on the
invalidated-capture handling here, and the #2776 crash is the same
double destroy of a graph the driver already discarded. Merge the two
release-note entries and correct the test docstring, which attributed
the crash to the fork rather than to the builder's teardown.
Issue #2834, #2776
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: point the conditional-body limitation at issue #2918
An invalidated capture of a conditional body leaves the parent graph
invalid, and ending the parent capture afterwards crashes inside the
driver (#2918, a CUDA driver bug reproduced with the
driver API alone). Say so in the end_building docstring and the release
note instead of explaining the mechanism.
Issue #2834
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: keep GraphBuilder.join's cleanup going when a close fails
join() closes the builders it did not join before its error propagates.
That sweep ran in a finally block and called close() on each builder. A
builder from another capture makes the root's wait fail, and the driver
invalidates that builder's capture as well, so its close() raised too.
The raise stopped the sweep, stranded the later builders with capturing
streams, and replaced the merge error with the close error.
Run the sweep in an except block, close each builder through GB_close,
which returns the driver status instead of raising, and attach a failed
close to the propagating error as a note (error handling policy). The
original error is re-raised unchanged.
Review feedback on #2838.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test(cuda.core): cover a failing close inside GraphBuilder.join's cleanup
The existing test provokes the join failure with a forked builder, whose
close() cannot raise, so the sweep's own failure path went untested. Join
two separate primaries into a capture: the driver refuses the
cross-capture wait and invalidates the other capture, so closing that
builder fails. The test checks that every builder is closed, that the
merge error propagates, and that the failed close is attached as a note
(or reported as a CUDAWarning on Python 3.10).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* cuda.core: factor retire_graph out of the graph invalidation sweeps
invalidate_child_graph_state and invalidate_root_graph_state repeated the
per-box retirement: detach node handles, drop the registry entry and
attachments, move the box to the graveyard. Both now call retire_graph
and differ only in which boxes they select. No behavior change.
Review feedback on #2838.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>1 parent 1db44ec commit 657bbaf
11 files changed
Lines changed: 488 additions & 70 deletions
File tree
- cuda_core
- cuda/core
- _cpp/rt
- _memory
- graph
- docs/source/release
- tests/graph
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
357 | 357 | | |
358 | 358 | | |
359 | 359 | | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
360 | 366 | | |
361 | 367 | | |
362 | 368 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
679 | 679 | | |
680 | 680 | | |
681 | 681 | | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
| 692 | + | |
| 693 | + | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
682 | 702 | | |
683 | 703 | | |
684 | 704 | | |
| |||
701 | 721 | | |
702 | 722 | | |
703 | 723 | | |
704 | | - | |
705 | | - | |
| 724 | + | |
| 725 | + | |
706 | 726 | | |
| 727 | + | |
| 728 | + | |
707 | 729 | | |
708 | | - | |
709 | | - | |
710 | | - | |
711 | | - | |
712 | | - | |
713 | | - | |
714 | | - | |
715 | | - | |
716 | | - | |
717 | | - | |
718 | | - | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
719 | 746 | | |
720 | 747 | | |
721 | 748 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
311 | 312 | | |
312 | 313 | | |
313 | 314 | | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
314 | 324 | | |
315 | 325 | | |
316 | 326 | | |
317 | 327 | | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
318 | 331 | | |
319 | | - | |
320 | | - | |
321 | | - | |
322 | | - | |
323 | | - | |
324 | | - | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
325 | 338 | | |
326 | | - | |
327 | | - | |
| 339 | + | |
| 340 | + | |
328 | 341 | | |
329 | 342 | | |
330 | 343 | | |
331 | | - | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
332 | 357 | | |
333 | 358 | | |
334 | 359 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
305 | 305 | | |
306 | 306 | | |
307 | 307 | | |
| 308 | + | |
308 | 309 | | |
309 | 310 | | |
310 | 311 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
212 | 212 | | |
213 | 213 | | |
214 | 214 | | |
| 215 | + | |
| 216 | + | |
215 | 217 | | |
216 | 218 | | |
217 | 219 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
139 | | - | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
140 | 144 | | |
141 | 145 | | |
142 | 146 | | |
| |||
212 | 216 | | |
213 | 217 | | |
214 | 218 | | |
215 | | - | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
216 | 235 | | |
217 | 236 | | |
218 | 237 | | |
| |||
261 | 280 | | |
262 | 281 | | |
263 | 282 | | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
264 | 286 | | |
265 | 287 | | |
266 | 288 | | |
| |||
0 commit comments