From 8c51fb5f9946517d5396b43d0e20991e8de5be23 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 29 Aug 2025 07:56:27 -0400 Subject: [PATCH 01/18] Fix #702: Update cyruntime.getLocalRuntimeVersion to use pathfinder --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 38 ++++++++++---------- cuda_bindings/tests/test_cudart.py | 6 ++++ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 7f5c96e05c..9690dfd021 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -2,9 +2,18 @@ # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE # This code was automatically generated with version 13.0.0. Do not modify it directly. +from libc.stdint cimport uintptr_t cimport cuda.bindings._bindings.cyruntime as cyruntime cimport cython +from cuda.pathfinder import load_nvidia_dynamic_lib +from pathlib import Path +{{if 'Windows' == platform.system()}} +import win32api +{{else}} +cimport cuda.bindings._lib.dlfcn as dlfcn +{{endif}} + {{if 'cudaDeviceReset' in found_functions}} cdef cudaError_t cudaDeviceReset() except ?cudaErrorCallRequiresNewerDriver nogil: @@ -1885,35 +1894,28 @@ cdef cudaError_t cudaGraphicsVDPAURegisterOutputSurface(cudaGraphicsResource** r {{if True}} -{{if 'Windows' != platform.system()}} -cimport cuda.bindings._lib.dlfcn as dlfcn -{{endif}} - cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCallRequiresNewerDriver nogil: - {{if 'Windows' == platform.system()}} with gil: - raise NotImplementedError('"getLocalRuntimeVersion" is unsupported on Windows') - {{else}} - # Load - handle = dlfcn.dlopen('libcudart.so.13', dlfcn.RTLD_NOW) - if handle == NULL: - with gil: - raise RuntimeError(f'Failed to dlopen libcudart.so.13') + lib = load_nvidia_dynamic_lib("cudart") + filename = Path(lib.abs_path).name + handle = lib._handle_uint + {{if 'Windows' == platform.system()}} + try: + __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') + except: + pass + {{else}} __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') + {{endif}} if __cudaRuntimeGetVersion == NULL: with gil: - raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in libcudart.so.13') + raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {filename}') - # Call cdef cudaError_t err = cudaSuccess err = ( __cudaRuntimeGetVersion)(runtimeVersion) - # Unload - dlfcn.dlclose(handle) - # Return return err - {{endif}} {{endif}} diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index 21e902733f..6ed31b7ce2 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -1400,3 +1400,9 @@ def test_struct_pointer_comparison(target): c = target(456) assert a != c assert hash(a) != hash(c) + + +def test_getLocalRuntimeVersion(): + err, version = cudart.getLocalRuntimeVersion() + assertSuccess(err) + assert version >= 10000 # CUDA 10.0 From bebad2c4f2ee051e88688614ddbfb1b8122f9cf5 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 29 Aug 2025 08:35:57 -0400 Subject: [PATCH 02/18] Try to fix Windows build --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 9690dfd021..6cbc2ed4f8 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1902,7 +1902,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa {{if 'Windows' == platform.system()}} try: - __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') + __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') except: pass {{else}} From be34ebebba499ddfbc976788485e6bb5f5cae728 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 29 Aug 2025 08:46:30 -0400 Subject: [PATCH 03/18] Fix Windows --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 6cbc2ed4f8..7930fba876 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1901,10 +1901,11 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa handle = lib._handle_uint {{if 'Windows' == platform.system()}} - try: - __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') - except: - pass + with gil: + try: + __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') + except: + pass {{else}} __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') {{endif}} From 5da54bb36972ff5caa31bdb838e8227a27c40e7d Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Fri, 29 Aug 2025 10:11:06 -0400 Subject: [PATCH 04/18] More realistic minimum version --- cuda_bindings/tests/test_cudart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index 6ed31b7ce2..23c172a3e0 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -1405,4 +1405,4 @@ def test_struct_pointer_comparison(target): def test_getLocalRuntimeVersion(): err, version = cudart.getLocalRuntimeVersion() assertSuccess(err) - assert version >= 10000 # CUDA 10.0 + assert version >= 12000 # CUDA 12.0 From 583f7f16e79e841c865d9c19ecbf94dcf1cf490a Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 2 Sep 2025 08:41:17 -0400 Subject: [PATCH 05/18] Simplify gil handling --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 7930fba876..91db872340 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1898,20 +1898,18 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa with gil: lib = load_nvidia_dynamic_lib("cudart") filename = Path(lib.abs_path).name - handle = lib._handle_uint + handle = (lib._handle_uint) - {{if 'Windows' == platform.system()}} - with gil: + {{if 'Windows' == platform.system()}} try: __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') except: pass - {{else}} - __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') - {{endif}} + {{else}} + __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') + {{endif}} - if __cudaRuntimeGetVersion == NULL: - with gil: + if __cudaRuntimeGetVersion == NULL: raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {filename}') cdef cudaError_t err = cudaSuccess From 55c8039a0069c48d821927271337ee378ca68c6c Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 2 Sep 2025 11:47:26 -0400 Subject: [PATCH 06/18] Unload module when done with it --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 91db872340..597062130e 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1915,6 +1915,11 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa cdef cudaError_t err = cudaSuccess err = ( __cudaRuntimeGetVersion)(runtimeVersion) + {{if 'Windows' != platform.system()}} + with gil: + dlfcn.dlclose(handle) + {{endif}} + # Return return err {{endif}} From 349d16bd079492448a38f0b36a292350062c7006 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 2 Sep 2025 12:03:50 -0400 Subject: [PATCH 07/18] Don't need try/except on Windows --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 597062130e..2ceac95054 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1901,10 +1901,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa handle = (lib._handle_uint) {{if 'Windows' == platform.system()}} - try: - __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') - except: - pass + __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') {{else}} __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') {{endif}} From 4180f37e5aa3e407ed264f78bd11b2a39cbb3d63 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 2 Sep 2025 12:12:21 -0400 Subject: [PATCH 08/18] Don't need gil --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 2ceac95054..fa14f07285 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1913,8 +1913,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa err = ( __cudaRuntimeGetVersion)(runtimeVersion) {{if 'Windows' != platform.system()}} - with gil: - dlfcn.dlclose(handle) + dlfcn.dlclose(handle) {{endif}} # Return From cfb3a03559ae3e6ce4cde39df884a5d71839fd18 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 4 Sep 2025 09:20:44 -0400 Subject: [PATCH 09/18] Fix message --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index fa14f07285..5846624037 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -7,7 +7,6 @@ cimport cuda.bindings._bindings.cyruntime as cyruntime cimport cython from cuda.pathfinder import load_nvidia_dynamic_lib -from pathlib import Path {{if 'Windows' == platform.system()}} import win32api {{else}} @@ -1897,7 +1896,6 @@ cdef cudaError_t cudaGraphicsVDPAURegisterOutputSurface(cudaGraphicsResource** r cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCallRequiresNewerDriver nogil: with gil: lib = load_nvidia_dynamic_lib("cudart") - filename = Path(lib.abs_path).name handle = (lib._handle_uint) {{if 'Windows' == platform.system()}} @@ -1907,7 +1905,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa {{endif}} if __cudaRuntimeGetVersion == NULL: - raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {filename}') + raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {lib.abs_path}') cdef cudaError_t err = cudaSuccess err = ( __cudaRuntimeGetVersion)(runtimeVersion) From bd98f21449adc5d41d0f3ee057c47a225b83affe Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 4 Sep 2025 09:21:05 -0400 Subject: [PATCH 10/18] Fix test --- cuda_bindings/tests/test_cudart.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index 23c172a3e0..e065a079a3 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -9,6 +9,7 @@ import cuda.bindings.driver as cuda import cuda.bindings.runtime as cudart +from cuda import pathfinder from cuda.bindings import runtime @@ -1403,6 +1404,10 @@ def test_struct_pointer_comparison(target): def test_getLocalRuntimeVersion(): - err, version = cudart.getLocalRuntimeVersion() - assertSuccess(err) - assert version >= 12000 # CUDA 12.0 + try: + err, version = cudart.getLocalRuntimeVersion() + except pathfinder.DynamicLibraryNotFoundError: + pass + else: + assertSuccess(err) + assert version >= 12000 # CUDA 12.0 From 1c1547e55c50a88faaf3f24bdf4c31281846dd91 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Thu, 4 Sep 2025 15:10:53 -0400 Subject: [PATCH 11/18] DynamicLibrary -> DynamicLib --- cuda_bindings/tests/test_cudart.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index e065a079a3..d400dbf45d 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -1406,7 +1406,7 @@ def test_struct_pointer_comparison(target): def test_getLocalRuntimeVersion(): try: err, version = cudart.getLocalRuntimeVersion() - except pathfinder.DynamicLibraryNotFoundError: + except pathfinder.DynamicLibNotFoundError: pass else: assertSuccess(err) From ed44ae1159ef120c71f69c5b1b424cf55a29009f Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 15 Sep 2025 11:26:12 -0400 Subject: [PATCH 12/18] Update to not use pywin32 --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 35 +++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 5846624037..c199157a73 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -2,17 +2,9 @@ # SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE # This code was automatically generated with version 13.0.0. Do not modify it directly. -from libc.stdint cimport uintptr_t cimport cuda.bindings._bindings.cyruntime as cyruntime cimport cython -from cuda.pathfinder import load_nvidia_dynamic_lib -{{if 'Windows' == platform.system()}} -import win32api -{{else}} -cimport cuda.bindings._lib.dlfcn as dlfcn -{{endif}} - {{if 'cudaDeviceReset' in found_functions}} cdef cudaError_t cudaDeviceReset() except ?cudaErrorCallRequiresNewerDriver nogil: @@ -1893,23 +1885,36 @@ cdef cudaError_t cudaGraphicsVDPAURegisterOutputSurface(cudaGraphicsResource** r {{if True}} +from libc.stdint cimport uintptr_t +from cuda.pathfinder import load_nvidia_dynamic_lib +{{if 'Windows' == platform.system()}} +cimport cuda.bindings._lib.windll as windll +{{else}} +cimport cuda.bindings._lib.dlfcn as dlfcn +{{endif}} + cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCallRequiresNewerDriver nogil: + + # Load with gil: lib = load_nvidia_dynamic_lib("cudart") - handle = (lib._handle_uint) + handle = lib._handle_uint - {{if 'Windows' == platform.system()}} - __cudaRuntimeGetVersion = win32api.GetProcAddress(handle, 'cudaRuntimeGetVersion') - {{else}} - __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') - {{endif}} + {{if 'Windows' == platform.system()}} + __cudaRuntimeGetVersion = windll.GetProcAddress(handle, b'cudaRuntimeGetVersion') + {{else}} + __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') + {{endif}} - if __cudaRuntimeGetVersion == NULL: + if __cudaRuntimeGetVersion == NULL: + with gil: raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {lib.abs_path}') + # Call cdef cudaError_t err = cudaSuccess err = ( __cudaRuntimeGetVersion)(runtimeVersion) + # Unload {{if 'Windows' != platform.system()}} dlfcn.dlclose(handle) {{endif}} From d240e09d630ece0d28a924c6e7ede866d15e1d60 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 15 Sep 2025 11:59:36 -0400 Subject: [PATCH 13/18] Add cast --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index c199157a73..07b7411d54 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1901,7 +1901,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa handle = lib._handle_uint {{if 'Windows' == platform.system()}} - __cudaRuntimeGetVersion = windll.GetProcAddress(handle, b'cudaRuntimeGetVersion') + __cudaRuntimeGetVersion = windll.GetProcAddress(handle, b'cudaRuntimeGetVersion') {{else}} __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') {{endif}} From eb9fdb481c7c4585dc9b894cbe3e5f89449536b5 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 15 Sep 2025 12:10:44 -0400 Subject: [PATCH 14/18] Try to fix cast again --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 07b7411d54..ed20de1d04 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1898,10 +1898,14 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa # Load with gil: lib = load_nvidia_dynamic_lib("cudart") + {{if 'Windows' == platform.system()}} + handle = lib._handle_uint + {{else}} handle = lib._handle_uint + {{endif}} {{if 'Windows' == platform.system()}} - __cudaRuntimeGetVersion = windll.GetProcAddress(handle, b'cudaRuntimeGetVersion') + __cudaRuntimeGetVersion = windll.GetProcAddress(handle, b'cudaRuntimeGetVersion') {{else}} __cudaRuntimeGetVersion = dlfcn.dlsym(handle, 'cudaRuntimeGetVersion') {{endif}} From 43b71f0d160feafa3d5c146d209d568da07df7ed Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 15 Sep 2025 12:13:58 -0400 Subject: [PATCH 15/18] Try to fix cast again --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index ed20de1d04..9f599593b9 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1899,7 +1899,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa with gil: lib = load_nvidia_dynamic_lib("cudart") {{if 'Windows' == platform.system()}} - handle = lib._handle_uint + handle = lib._handle_uint {{else}} handle = lib._handle_uint {{endif}} From cc44883e5a094082af60e52d981c759d2c66a245 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 16 Sep 2025 09:26:02 -0400 Subject: [PATCH 16/18] Address comments in PR --- cuda_bindings/cuda/bindings/_lib/windll.pxd | 6 ++++++ cuda_bindings/cuda/bindings/cyruntime.pyx.in | 8 +++++--- cuda_bindings/tests/test_cudart.py | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cuda_bindings/cuda/bindings/_lib/windll.pxd b/cuda_bindings/cuda/bindings/_lib/windll.pxd index e3f86285e0..7b190f3595 100644 --- a/cuda_bindings/cuda/bindings/_lib/windll.pxd +++ b/cuda_bindings/cuda/bindings/_lib/windll.pxd @@ -12,6 +12,7 @@ cdef extern from "windows.h" nogil: ctypedef unsigned long DWORD ctypedef const wchar_t *LPCWSTR ctypedef const char *LPCSTR + ctypedef int BOOL cdef DWORD LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 @@ -23,6 +24,8 @@ cdef extern from "windows.h" nogil: FARPROC _GetProcAddress "GetProcAddress"(HMODULE hModule, LPCSTR lpProcName) + BOOL _FreeLibrary "FreeLibrary"(HMODULE hLibModule) + cdef inline uintptr_t LoadLibraryExW(str path, HANDLE hFile, DWORD dwFlags): cdef uintptr_t result cdef wchar_t* wpath = PyUnicode_AsWideCharString(path, NULL) @@ -37,3 +40,6 @@ cdef inline uintptr_t LoadLibraryExW(str path, HANDLE hFile, DWORD dwFlags): cdef inline FARPROC GetProcAddress(uintptr_t hModule, const char* lpProcName) nogil: return _GetProcAddress(hModule, lpProcName) + +cdef inline BOOL FreeLibrary(uintptr_t hLibModule) nogil: + return _FreeLibrary(hLibModule) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 9f599593b9..0e382e209a 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1897,7 +1897,7 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa # Load with gil: - lib = load_nvidia_dynamic_lib("cudart") + loaded_dl = load_nvidia_dynamic_lib("cudart") {{if 'Windows' == platform.system()}} handle = lib._handle_uint {{else}} @@ -1912,14 +1912,16 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa if __cudaRuntimeGetVersion == NULL: with gil: - raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {lib.abs_path}') + raise RuntimeError(f'Function "cudaRuntimeGetVersion" not found in {loaded_dl.abs_path}') # Call cdef cudaError_t err = cudaSuccess err = ( __cudaRuntimeGetVersion)(runtimeVersion) # Unload - {{if 'Windows' != platform.system()}} + {{if 'Windows' == platform.system()}} + windll.FreeLibrary(handle) + {{else}} dlfcn.dlclose(handle) {{endif}} diff --git a/cuda_bindings/tests/test_cudart.py b/cuda_bindings/tests/test_cudart.py index d400dbf45d..6f8fc009eb 100644 --- a/cuda_bindings/tests/test_cudart.py +++ b/cuda_bindings/tests/test_cudart.py @@ -1407,7 +1407,7 @@ def test_getLocalRuntimeVersion(): try: err, version = cudart.getLocalRuntimeVersion() except pathfinder.DynamicLibNotFoundError: - pass + pytest.skip("cudart dynamic lib not available") else: assertSuccess(err) assert version >= 12000 # CUDA 12.0 From aedcd23e86eeac7c2bab73dda5c9d8996a15990b Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 16 Sep 2025 11:00:16 -0400 Subject: [PATCH 17/18] Fix lib -> loaded_dl --- cuda_bindings/cuda/bindings/cyruntime.pyx.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cuda_bindings/cuda/bindings/cyruntime.pyx.in b/cuda_bindings/cuda/bindings/cyruntime.pyx.in index 0e382e209a..950e106c53 100644 --- a/cuda_bindings/cuda/bindings/cyruntime.pyx.in +++ b/cuda_bindings/cuda/bindings/cyruntime.pyx.in @@ -1899,9 +1899,9 @@ cdef cudaError_t getLocalRuntimeVersion(int* runtimeVersion) except ?cudaErrorCa with gil: loaded_dl = load_nvidia_dynamic_lib("cudart") {{if 'Windows' == platform.system()}} - handle = lib._handle_uint + handle = loaded_dl._handle_uint {{else}} - handle = lib._handle_uint + handle = loaded_dl._handle_uint {{endif}} {{if 'Windows' == platform.system()}} From 5abebbde735320d643bda6bc322212f3071d3c23 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 16 Sep 2025 16:02:08 -0400 Subject: [PATCH 18/18] Add changelog --- cuda_bindings/docs/source/release/12.9.X-notes.rst | 1 + cuda_bindings/docs/source/release/13.X.Y-notes.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/cuda_bindings/docs/source/release/12.9.X-notes.rst b/cuda_bindings/docs/source/release/12.9.X-notes.rst index 76de5d795f..7a4713a89b 100644 --- a/cuda_bindings/docs/source/release/12.9.X-notes.rst +++ b/cuda_bindings/docs/source/release/12.9.X-notes.rst @@ -15,6 +15,7 @@ Highlights * Automatic CUDA library path detection based on ``CUDA_HOME``, eliminating the need to manually set ``LIBRARY_PATH`` environment variables for installation. * The Python overhead of calling functions in CUDA bindings in ``driver``, ``runtime`` and ``nvrtc`` has been reduced by approximately 30%. * Updated the ``cuda.bindings.runtime`` module to statically link against the CUDA Runtime library from CUDA Toolkit 12.9.1. +* ``cyruntime.getLocalRuntimeVersion`` now uses pathfinder to find the CUDA runtime. Known issues diff --git a/cuda_bindings/docs/source/release/13.X.Y-notes.rst b/cuda_bindings/docs/source/release/13.X.Y-notes.rst index 9e57410ff0..2f29a9dc08 100644 --- a/cuda_bindings/docs/source/release/13.X.Y-notes.rst +++ b/cuda_bindings/docs/source/release/13.X.Y-notes.rst @@ -18,6 +18,7 @@ Highlights * The Python overhead of calling functions in CUDA bindings in ``driver``, ``runtime`` and ``nvrtc`` has been reduced by approximately 30%. * On Windows, the ``pywin32`` dependency has been removed. The necessary Windows API functions are now accessed directly. * Updated the ``cuda.bindings.runtime`` module to statically link against the CUDA Runtime library from CUDA Toolkit 13.0.1. +* ``cyruntime.getLocalRuntimeVersion`` now uses pathfinder to find the CUDA runtime. Known issues