Skip to content

Commit 2e4c603

Browse files
Add Windows arm64 discovery for cuDLA (#2274)
* Add Windows arm64 discovery for cuDLA * Drop redundant assert message in cuDLA Windows consistency test --------- Co-authored-by: Ralf W. Grosse-Kunstleve <rwgkio@gmail.com>
1 parent a96d9f8 commit 2e4c603

9 files changed

Lines changed: 368 additions & 10 deletions

File tree

cuda_bindings/cuda/bindings/_internal/cudla.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
33

4-
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1719+g565f73f4e. Do not modify it directly.
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
55

66
from ..cycudla cimport *
77

cuda_bindings/cuda/bindings/_internal/cudla_linux.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
33

4-
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1719+g565f73f4e. Do not modify it directly.
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
55

66
from libc.stdint cimport intptr_t, uintptr_t
77

Lines changed: 348 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,348 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
3+
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
5+
6+
from libc.stdint cimport intptr_t
7+
8+
import threading
9+
from .utils import FunctionNotFoundError, NotSupportedError
10+
11+
from cuda.pathfinder import load_nvidia_dynamic_lib
12+
13+
from libc.stddef cimport wchar_t
14+
from libc.stdint cimport uintptr_t
15+
from cpython cimport PyUnicode_AsWideCharString, PyMem_Free
16+
17+
# You must 'from .utils import NotSupportedError' before using this template
18+
19+
cdef extern from "windows.h" nogil:
20+
ctypedef void* HMODULE
21+
ctypedef void* HANDLE
22+
ctypedef void* FARPROC
23+
ctypedef unsigned long DWORD
24+
ctypedef const wchar_t *LPCWSTR
25+
ctypedef const char *LPCSTR
26+
27+
cdef DWORD LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800
28+
cdef DWORD LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000
29+
cdef DWORD LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100
30+
31+
HMODULE _LoadLibraryExW "LoadLibraryExW"(
32+
LPCWSTR lpLibFileName,
33+
HANDLE hFile,
34+
DWORD dwFlags
35+
)
36+
37+
FARPROC _GetProcAddress "GetProcAddress"(HMODULE hModule, LPCSTR lpProcName)
38+
39+
cdef inline uintptr_t LoadLibraryExW(str path, HANDLE hFile, DWORD dwFlags):
40+
cdef uintptr_t result
41+
cdef wchar_t* wpath = PyUnicode_AsWideCharString(path, NULL)
42+
with nogil:
43+
result = <uintptr_t>_LoadLibraryExW(
44+
wpath,
45+
hFile,
46+
dwFlags
47+
)
48+
PyMem_Free(wpath)
49+
return result
50+
51+
cdef inline void *GetProcAddress(uintptr_t hModule, const char* lpProcName) nogil:
52+
return _GetProcAddress(<HMODULE>hModule, lpProcName)
53+
54+
cdef int get_cuda_version():
55+
cdef int err, driver_ver = 0
56+
57+
# Load driver to check version
58+
handle = LoadLibraryExW("nvcuda.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32)
59+
if handle == 0:
60+
raise NotSupportedError('CUDA driver is not found')
61+
cuDriverGetVersion = GetProcAddress(handle, 'cuDriverGetVersion')
62+
if cuDriverGetVersion == NULL:
63+
raise RuntimeError('Did not find cuDriverGetVersion symbol in nvcuda.dll')
64+
err = (<int (*)(int*) noexcept nogil>cuDriverGetVersion)(&driver_ver)
65+
if err != 0:
66+
raise RuntimeError(f'cuDriverGetVersion returned error code {err}')
67+
68+
return driver_ver
69+
70+
71+
72+
###############################################################################
73+
# Wrapper init
74+
###############################################################################
75+
76+
cdef object __symbol_lock = threading.Lock()
77+
cdef bint __py_cudla_init = False
78+
79+
cdef void* __cudlaGetVersion = NULL
80+
cdef void* __cudlaDeviceGetCount = NULL
81+
cdef void* __cudlaCreateDevice = NULL
82+
cdef void* __cudlaMemRegister = NULL
83+
cdef void* __cudlaModuleLoadFromMemory = NULL
84+
cdef void* __cudlaModuleGetAttributes = NULL
85+
cdef void* __cudlaModuleUnload = NULL
86+
cdef void* __cudlaSubmitTask = NULL
87+
cdef void* __cudlaDeviceGetAttribute = NULL
88+
cdef void* __cudlaMemUnregister = NULL
89+
cdef void* __cudlaGetLastError = NULL
90+
cdef void* __cudlaDestroyDevice = NULL
91+
cdef void* __cudlaSetTaskTimeoutInMs = NULL
92+
93+
94+
cdef int _init_cudla() except -1 nogil:
95+
global __py_cudla_init
96+
97+
with gil, __symbol_lock:
98+
# Recheck the flag after obtaining the locks
99+
if __py_cudla_init:
100+
return 0
101+
102+
# Load library
103+
handle = load_nvidia_dynamic_lib("cudla")._handle_uint
104+
105+
# Load function
106+
global __cudlaGetVersion
107+
__cudlaGetVersion = GetProcAddress(handle, 'cudlaGetVersion')
108+
109+
global __cudlaDeviceGetCount
110+
__cudlaDeviceGetCount = GetProcAddress(handle, 'cudlaDeviceGetCount')
111+
112+
global __cudlaCreateDevice
113+
__cudlaCreateDevice = GetProcAddress(handle, 'cudlaCreateDevice')
114+
115+
global __cudlaMemRegister
116+
__cudlaMemRegister = GetProcAddress(handle, 'cudlaMemRegister')
117+
118+
global __cudlaModuleLoadFromMemory
119+
__cudlaModuleLoadFromMemory = GetProcAddress(handle, 'cudlaModuleLoadFromMemory')
120+
121+
global __cudlaModuleGetAttributes
122+
__cudlaModuleGetAttributes = GetProcAddress(handle, 'cudlaModuleGetAttributes')
123+
124+
global __cudlaModuleUnload
125+
__cudlaModuleUnload = GetProcAddress(handle, 'cudlaModuleUnload')
126+
127+
global __cudlaSubmitTask
128+
__cudlaSubmitTask = GetProcAddress(handle, 'cudlaSubmitTask')
129+
130+
global __cudlaDeviceGetAttribute
131+
__cudlaDeviceGetAttribute = GetProcAddress(handle, 'cudlaDeviceGetAttribute')
132+
133+
global __cudlaMemUnregister
134+
__cudlaMemUnregister = GetProcAddress(handle, 'cudlaMemUnregister')
135+
136+
global __cudlaGetLastError
137+
__cudlaGetLastError = GetProcAddress(handle, 'cudlaGetLastError')
138+
139+
global __cudlaDestroyDevice
140+
__cudlaDestroyDevice = GetProcAddress(handle, 'cudlaDestroyDevice')
141+
142+
global __cudlaSetTaskTimeoutInMs
143+
__cudlaSetTaskTimeoutInMs = GetProcAddress(handle, 'cudlaSetTaskTimeoutInMs')
144+
145+
__py_cudla_init = True
146+
return 0
147+
148+
149+
cdef inline int _check_or_init_cudla() except -1 nogil:
150+
if __py_cudla_init:
151+
return 0
152+
153+
return _init_cudla()
154+
155+
156+
cdef dict func_ptrs = None
157+
158+
159+
cpdef dict _inspect_function_pointers():
160+
global func_ptrs
161+
if func_ptrs is not None:
162+
return func_ptrs
163+
164+
_check_or_init_cudla()
165+
cdef dict data = {}
166+
167+
global __cudlaGetVersion
168+
data["__cudlaGetVersion"] = <intptr_t>__cudlaGetVersion
169+
170+
global __cudlaDeviceGetCount
171+
data["__cudlaDeviceGetCount"] = <intptr_t>__cudlaDeviceGetCount
172+
173+
global __cudlaCreateDevice
174+
data["__cudlaCreateDevice"] = <intptr_t>__cudlaCreateDevice
175+
176+
global __cudlaMemRegister
177+
data["__cudlaMemRegister"] = <intptr_t>__cudlaMemRegister
178+
179+
global __cudlaModuleLoadFromMemory
180+
data["__cudlaModuleLoadFromMemory"] = <intptr_t>__cudlaModuleLoadFromMemory
181+
182+
global __cudlaModuleGetAttributes
183+
data["__cudlaModuleGetAttributes"] = <intptr_t>__cudlaModuleGetAttributes
184+
185+
global __cudlaModuleUnload
186+
data["__cudlaModuleUnload"] = <intptr_t>__cudlaModuleUnload
187+
188+
global __cudlaSubmitTask
189+
data["__cudlaSubmitTask"] = <intptr_t>__cudlaSubmitTask
190+
191+
global __cudlaDeviceGetAttribute
192+
data["__cudlaDeviceGetAttribute"] = <intptr_t>__cudlaDeviceGetAttribute
193+
194+
global __cudlaMemUnregister
195+
data["__cudlaMemUnregister"] = <intptr_t>__cudlaMemUnregister
196+
197+
global __cudlaGetLastError
198+
data["__cudlaGetLastError"] = <intptr_t>__cudlaGetLastError
199+
200+
global __cudlaDestroyDevice
201+
data["__cudlaDestroyDevice"] = <intptr_t>__cudlaDestroyDevice
202+
203+
global __cudlaSetTaskTimeoutInMs
204+
data["__cudlaSetTaskTimeoutInMs"] = <intptr_t>__cudlaSetTaskTimeoutInMs
205+
206+
func_ptrs = data
207+
return data
208+
209+
210+
cpdef _inspect_function_pointer(str name):
211+
global func_ptrs
212+
if func_ptrs is None:
213+
func_ptrs = _inspect_function_pointers()
214+
return func_ptrs[name]
215+
216+
217+
###############################################################################
218+
# Wrapper functions
219+
###############################################################################
220+
221+
cdef cudlaStatus _cudlaGetVersion(uint64_t* const version) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
222+
global __cudlaGetVersion
223+
_check_or_init_cudla()
224+
if __cudlaGetVersion == NULL:
225+
with gil:
226+
raise FunctionNotFoundError("function cudlaGetVersion is not found")
227+
return (<cudlaStatus (*)(uint64_t* const) noexcept nogil>__cudlaGetVersion)(
228+
version)
229+
230+
231+
cdef cudlaStatus _cudlaDeviceGetCount(uint64_t* const pNumDevices) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
232+
global __cudlaDeviceGetCount
233+
_check_or_init_cudla()
234+
if __cudlaDeviceGetCount == NULL:
235+
with gil:
236+
raise FunctionNotFoundError("function cudlaDeviceGetCount is not found")
237+
return (<cudlaStatus (*)(uint64_t* const) noexcept nogil>__cudlaDeviceGetCount)(
238+
pNumDevices)
239+
240+
241+
cdef cudlaStatus _cudlaCreateDevice(const uint64_t device, cudlaDevHandle* const devHandle, const uint32_t flags) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
242+
global __cudlaCreateDevice
243+
_check_or_init_cudla()
244+
if __cudlaCreateDevice == NULL:
245+
with gil:
246+
raise FunctionNotFoundError("function cudlaCreateDevice is not found")
247+
return (<cudlaStatus (*)(const uint64_t, cudlaDevHandle* const, const uint32_t) noexcept nogil>__cudlaCreateDevice)(
248+
device, devHandle, flags)
249+
250+
251+
cdef cudlaStatus _cudlaMemRegister(const cudlaDevHandle devHandle, const uint64_t* const ptr, const size_t size, uint64_t** const devPtr, const uint32_t flags) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
252+
global __cudlaMemRegister
253+
_check_or_init_cudla()
254+
if __cudlaMemRegister == NULL:
255+
with gil:
256+
raise FunctionNotFoundError("function cudlaMemRegister is not found")
257+
return (<cudlaStatus (*)(const cudlaDevHandle, const uint64_t* const, const size_t, uint64_t** const, const uint32_t) noexcept nogil>__cudlaMemRegister)(
258+
devHandle, ptr, size, devPtr, flags)
259+
260+
261+
cdef cudlaStatus _cudlaModuleLoadFromMemory(const cudlaDevHandle devHandle, const uint8_t* const pModule, const size_t moduleSize, cudlaModule* const hModule, const uint32_t flags) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
262+
global __cudlaModuleLoadFromMemory
263+
_check_or_init_cudla()
264+
if __cudlaModuleLoadFromMemory == NULL:
265+
with gil:
266+
raise FunctionNotFoundError("function cudlaModuleLoadFromMemory is not found")
267+
return (<cudlaStatus (*)(const cudlaDevHandle, const uint8_t* const, const size_t, cudlaModule* const, const uint32_t) noexcept nogil>__cudlaModuleLoadFromMemory)(
268+
devHandle, pModule, moduleSize, hModule, flags)
269+
270+
271+
cdef cudlaStatus _cudlaModuleGetAttributes(const cudlaModule hModule, const cudlaModuleAttributeType attrType, cudlaModuleAttribute* const attribute) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
272+
global __cudlaModuleGetAttributes
273+
_check_or_init_cudla()
274+
if __cudlaModuleGetAttributes == NULL:
275+
with gil:
276+
raise FunctionNotFoundError("function cudlaModuleGetAttributes is not found")
277+
return (<cudlaStatus (*)(const cudlaModule, const cudlaModuleAttributeType, cudlaModuleAttribute* const) noexcept nogil>__cudlaModuleGetAttributes)(
278+
hModule, attrType, attribute)
279+
280+
281+
cdef cudlaStatus _cudlaModuleUnload(const cudlaModule hModule, const uint32_t flags) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
282+
global __cudlaModuleUnload
283+
_check_or_init_cudla()
284+
if __cudlaModuleUnload == NULL:
285+
with gil:
286+
raise FunctionNotFoundError("function cudlaModuleUnload is not found")
287+
return (<cudlaStatus (*)(const cudlaModule, const uint32_t) noexcept nogil>__cudlaModuleUnload)(
288+
hModule, flags)
289+
290+
291+
cdef cudlaStatus _cudlaSubmitTask(const cudlaDevHandle devHandle, const cudlaTask* const ptrToTasks, const uint32_t numTasks, void* const stream, const uint32_t flags) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
292+
global __cudlaSubmitTask
293+
_check_or_init_cudla()
294+
if __cudlaSubmitTask == NULL:
295+
with gil:
296+
raise FunctionNotFoundError("function cudlaSubmitTask is not found")
297+
return (<cudlaStatus (*)(const cudlaDevHandle, const cudlaTask* const, const uint32_t, void* const, const uint32_t) noexcept nogil>__cudlaSubmitTask)(
298+
devHandle, ptrToTasks, numTasks, stream, flags)
299+
300+
301+
cdef cudlaStatus _cudlaDeviceGetAttribute(const cudlaDevHandle devHandle, const cudlaDevAttributeType attrib, cudlaDevAttribute* const pAttribute) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
302+
global __cudlaDeviceGetAttribute
303+
_check_or_init_cudla()
304+
if __cudlaDeviceGetAttribute == NULL:
305+
with gil:
306+
raise FunctionNotFoundError("function cudlaDeviceGetAttribute is not found")
307+
return (<cudlaStatus (*)(const cudlaDevHandle, const cudlaDevAttributeType, cudlaDevAttribute* const) noexcept nogil>__cudlaDeviceGetAttribute)(
308+
devHandle, attrib, pAttribute)
309+
310+
311+
cdef cudlaStatus _cudlaMemUnregister(const cudlaDevHandle devHandle, const uint64_t* const devPtr) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
312+
global __cudlaMemUnregister
313+
_check_or_init_cudla()
314+
if __cudlaMemUnregister == NULL:
315+
with gil:
316+
raise FunctionNotFoundError("function cudlaMemUnregister is not found")
317+
return (<cudlaStatus (*)(const cudlaDevHandle, const uint64_t* const) noexcept nogil>__cudlaMemUnregister)(
318+
devHandle, devPtr)
319+
320+
321+
cdef cudlaStatus _cudlaGetLastError(const cudlaDevHandle devHandle) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
322+
global __cudlaGetLastError
323+
_check_or_init_cudla()
324+
if __cudlaGetLastError == NULL:
325+
with gil:
326+
raise FunctionNotFoundError("function cudlaGetLastError is not found")
327+
return (<cudlaStatus (*)(const cudlaDevHandle) noexcept nogil>__cudlaGetLastError)(
328+
devHandle)
329+
330+
331+
cdef cudlaStatus _cudlaDestroyDevice(const cudlaDevHandle devHandle) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
332+
global __cudlaDestroyDevice
333+
_check_or_init_cudla()
334+
if __cudlaDestroyDevice == NULL:
335+
with gil:
336+
raise FunctionNotFoundError("function cudlaDestroyDevice is not found")
337+
return (<cudlaStatus (*)(const cudlaDevHandle) noexcept nogil>__cudlaDestroyDevice)(
338+
devHandle)
339+
340+
341+
cdef cudlaStatus _cudlaSetTaskTimeoutInMs(const cudlaDevHandle devHandle, const uint32_t timeout) except?_CUDLASTATUS_INTERNAL_LOADING_ERROR nogil:
342+
global __cudlaSetTaskTimeoutInMs
343+
_check_or_init_cudla()
344+
if __cudlaSetTaskTimeoutInMs == NULL:
345+
with gil:
346+
raise FunctionNotFoundError("function cudlaSetTaskTimeoutInMs is not found")
347+
return (<cudlaStatus (*)(const cudlaDevHandle, const uint32_t) noexcept nogil>__cudlaSetTaskTimeoutInMs)(
348+
devHandle, timeout)

cuda_bindings/cuda/bindings/cudla.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
33

4-
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1719+g565f73f4e. Do not modify it directly.
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
55

66
from libc.stdint cimport intptr_t
77

cuda_bindings/cuda/bindings/cudla.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
33

4-
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1752+g89e531539. Do not modify it directly.
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
55

66
cimport cython # NOQA
77
from libc.stdint cimport intptr_t, uintptr_t

cuda_bindings/cuda/bindings/cycudla.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-FileCopyrightText: Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
22
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
33

4-
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1719+g565f73f4e. Do not modify it directly.
4+
# This code was automatically generated across versions from 1.5.0 to 13.3.0, generator version 0.3.1.dev1465+gc5c5c8652. Do not modify it directly.
55
# This layer exposes the C header to Cython as-is.
66

77
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t

0 commit comments

Comments
 (0)