Repository navigation
Stop checking the exception flags of destroyed contexts - #3447
Merged
Merged
Conversation
`check_exceptions` iterated the table of exception flags without a lock on every synchronization, while compiling a kernel for a new context inserted into it. Keep the flags in a vector that is replaced instead of modified, so readers can iterate a snapshot without locking.
Since #3404, every synchronization checks whether each context with exception flags is still valid, but entries were never removed. After a context is destroyed, `cuCtxGetId` on its handle usually reports `ERROR_CONTEXT_IS_DESTROYED`, but some drivers eventually report it as a green context, i.e., `ERROR_INVALID_CONTEXT`, which `isvalid` rethrew. Every later synchronization in the process then failed. Treat both errors as the context being gone, and drop the exception flags of destroyed contexts so their handles aren't queried (and logged by the driver) on every synchronization.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #3447 +/- ##
==========================================
- Coverage 87.58% 85.69% -1.89%
==========================================
Files 192 191 -1
Lines 19922 19762 -160
==========================================
- Hits 17449 16936 -513
- Misses 2473 2826 +353 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Contributor
CUDA.jl BenchmarksDetails
This comment was automatically generated by workflow using github-action-benchmark. |
maleadt
added a commit
that referenced
this pull request
Oct 26, 2026
`isvalid` passed the handle of a destroyed context to `cuCtxGetId`, but the driver frees the context, so this reads freed memory. That used to return `ERROR_CONTEXT_IS_DESTROYED`; #3447 saw it turn into `ERROR_INVALID_CONTEXT`, and the MultiGPU job has now segfaulted in it while sweeping the disposal streams of destroyed contexts. `unsafe_destroy!` now records the unique ID of the context, and `isvalid` reports those contexts as destroyed without calling the driver. The driver is still queried for contexts destroyed otherwise.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Since #3404, every synchronization checks whether each context that kernels were compiled for is still valid, but the table of exception flags was never pruned. The
core/exceptionstest that launches a kernel in a temporary context leaves an entry behind, so every latersynchronize()on that test worker callscuCtxGetIdon the destroyed context's handle. That usually returnsERROR_CONTEXT_IS_DESTROYED, but on the CI drivers (595.71, 610.43) it eventually returnsERROR_INVALID_CONTEXT:isvalidrethrew that, failing whichever test happened to run next on the worker (seen on main in build 8255, on #3439, and in GPUCompiler.jl's CUDA.jl job on its main branch and in JuliaGPU/GPUCompiler.jl#1052). This PR:ERROR_INVALID_CONTEXTlikeERROR_CONTEXT_IS_DESTROYEDinisvalid, as the pre-CUDA 12 code path already did. ACuContextis only constructed from a handle the driver accepted, so either error means it's gone. This also covers the otherisvalidchecks Don't touch destroyed contexts when releasing their resources #3404 added to the resource release paths;check_exceptionsiterated theDictof flags without a lock while compiling a kernel for a new context inserted into it. The flags are now an immutable vector in an atomic field that writers replace under a lock, so the check on every synchronization stays lock-free.I couldn't get a local driver (615.78) to report
ERROR_INVALID_CONTEXTfor a destroyed handle, so the regression test checks that the destroyed context is no longer tracked after synchronizing.