cuda.core 1.2.0 Release Notes#

Fixes and enhancements#

  • A Buffer is now freed correctly even when the CUDA context current at teardown is not the one it was allocated in, or when no context is current at all. This happens routinely when a buffer is released by the garbage collector on another thread or by deferred CUDA graph cleanup; previously the free could fail or be skipped, leaking the allocation. (#2497)

  • Buffer.from_handle() and ManagedBuffer.from_handle() accept a keyword-only stream that records the stream used to order the buffer’s deallocation when the memory resource owns the pointer. It defaults to default_stream(), which requires a CUDA context to be current so the free recipe can pin that context. (#2497)

  • Explicit calls to deallocate() on pool-backed memory resources and GraphMemoryResource now propagate errors from the underlying CUDA free operation. Previously, these errors could be suppressed. Automatic buffer cleanup remains non-raising and reports failures as warnings.

  • Graph node resources are now retained independently across graph clones, executable graphs, updates, node deletion, and in-flight launches. Previously, modifying a graph definition could release resources still used by an existing executable graph. Releasing graph-attached objects could also call CUDA from a CUDA-invoked callback, where CUDA API calls are prohibited; these objects are now released from a safe context. (#2357, #2371)

  • Added update() methods to kernel, memcpy, memset, child-graph, event record, event wait, and host-callback graph definition nodes. Updates change parameters used by future graph instantiations without affecting existing executable graphs. This feature requires CUDA driver and cuda.bindings versions 12.2 or newer. (#2352)

  • Added graph[node] views for updating nodes in an executable graph. Kernel, memcpy, memset, child-graph, event, and host-callback parameters can be replaced without reinstantiating the graph. Kernel, memcpy, and memset nodes can also be enabled or disabled. Resources introduced by these updates remain alive through in-flight launches. Superseded resources stay retained until a successful whole-graph update or executable graph destruction. This feature requires CUDA driver and cuda.bindings versions 12.2 or newer. (#2353, #2354)

  • The default-stream singletons LEGACY_DEFAULT_STREAM and PER_THREAD_DEFAULT_STREAM no longer cache the first context and device they observe. A default-stream token refers to whatever context is current, so Stream.context, Stream.device, Stream.resources, and Stream.record() now resolve against the current context on every call. Previously the first query pinned the singleton to one context for the lifetime of the process, which also kept that context alive. (#2485)

  • Linker.which_backend() and constructing a Linker no longer raise FunctionNotFoundError when an nvJitLink older than 12.3 (12.0–12.2) is installed. These versions do not export the unversioned nvJitLinkVersion symbol, so probing the version crashed instead of falling back. cuda.core now warns and falls back to the driver (cuLink) backend, restoring the pre-0.7.0 behavior. (#2409, closes #2408)

  • ProgramOptions now accepts name=None and falls back to the documented default "default_program". Previously the annotated and documented None raised AttributeError during construction. (#2517, closes #2516)

  • cuda.core now checks ctypes host callbacks against the driver’s CUhostFn signature (void (*)(void*)) before passing the function pointer to CUDA. graph.GraphNode.callback(), graph.GraphBuilder.callback(), and the host-callback update() methods raise TypeError for a mismatched prototype, rather than leaving the driver to call through an incompatible signature, which is undefined behavior. Declarations that previously reached the driver, such as ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p), are now rejected at the call site. A function pointer obtained from a shared library keeps ctypes’ default c_int result type until it is declared, so set its restype and argtypes (or cast it to the prototype above) before passing it. On Windows, both ctypes.CFUNCTYPE and ctypes.WINFUNCTYPE are accepted. (#2439)

Deprecation Notices#

  • Support for using cuda-core with Python 3.10 is deprecated and will be removed in a future version. Python 3.10 reaches end of life in October 2026 per the CPython support cycle.