Skip to content

Add identity preserving pattern to critical_sections - #2453

Open
seberg wants to merge 1 commit into
NVIDIA:mainfrom
seberg:ft-fixes-identity-preserving
Open

Add identity preserving pattern to critical_sections#2453
seberg wants to merge 1 commit into
NVIDIA:mainfrom
seberg:ft-fixes-identity-preserving

Conversation

@seberg

@seberg seberg commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Split from gh-2194 just to shrink it a bit.

These commits are straight-forward and an attempt to guarantee identity results (not a single creation of the internal object). One of these ran into an issue in the tests. It probably doesn't matter for most, but it also doesn't hurt.

To explain what is going on: Critical sections are like the GIL. When we call arbitrary Python code they can be suspended (they definitely will be suspended in with nogil:, i.e. when the Python thread-state is detached!).

So, the callbacks can run in multiple threads, but after that we double-check and if self.attr is None: self.attr = obj is all pure C code, so only one thread can hold the critical section lock for that chunk of code.

@github-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Jul 29, 2026
@seberg seberg self-assigned this Jul 29, 2026
@seberg seberg added bug Something isn't working P1 Medium priority - Should do labels Jul 29, 2026
@seberg seberg added this to the cuda.core 1.2.0 milestone Jul 29, 2026
@github-actions

Copy link
Copy Markdown

this is annoying, but at least the library and probably kernel
attributes should be idempotent.
But critical sections *can and will be* released (similar to the GIL
although not sure what is more likely).

The important thing to note here is that the final attribute setting
section is self-contained and holds the lock (even if another thread
may have already set the attribute or still be executing the code
above).
@seberg
seberg force-pushed the ft-fixes-identity-preserving branch from 38345fa to 1e52ae3 Compare July 29, 2026 19:42

@kkraus14 kkraus14 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One concurrency concern in the lazy module loader.

if not _h_library:
HANDLE_RETURN(get_last_error())

if not self._h_library:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical_section is only a publication guard here, not an exactly-once initializer. create_library_handle_from_*() releases the Python thread state via GILReleaseGuard, so two callers can both reach cuLibraryLoad*() before either publishes _h_library. This second check preserves one handle identity, but the losing LibraryHandle is discarded while its deleter currently does not call cuLibraryUnload, leaving an extra CUDA library loaded for the process. Could we use a true single-flight primitive for _lazy_load_module (for example Cython's py_safe_call_once/py_safe_once_flag, or an equivalent persistent lock) and add a free-threaded concurrent-first-load regression test?

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

Labels

bug Something isn't working cuda.core Everything related to the cuda.core module P1 Medium priority - Should do

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants