Skip to content

Commit 1af5db9

Browse files
authored
Add Nvfatbin Bindings (#1467)
* initial localized test * add rest of APIs * remove local skips * regenerate for CUDA 13.1 and with tile IR API * nvfatbinError -> nvFatbinError * regenerate for get_error_string * enable object creation and testing * remove the LTOIR mismatching arch failure test * encode a legal tileIR into test * update the license year * add an embedded tile program for re-generation * license date: 2026 * cdef const char * * add dependency for CI * add TODO to locate nvcc file * add documentation and release notes * skip tileIR test for <13.1 installation * add an nvcc smoke test to better determine compiler usability * fix typo * add nvfatbin.rst --------- Co-authored-by: Michael Wang <[email protected]>
1 parent 53c8d4a commit 1af5db9

File tree

14 files changed

+1634
-2
lines changed

14 files changed

+1634
-2
lines changed

.github/actions/fetch_ctk/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ inputs:
1414
cuda-components:
1515
description: "A list of the CTK components to install as a comma-separated list. e.g. 'cuda_nvcc,cuda_nvrtc,cuda_cudart'"
1616
required: false
17-
default: "cuda_nvcc,cuda_cudart,cuda_crt,libnvvm,cuda_nvrtc,cuda_profiler_api,cuda_cccl,libnvjitlink,libcufile"
17+
default: "cuda_nvcc,cuda_cudart,cuda_crt,libnvvm,cuda_nvrtc,cuda_profiler_api,cuda_cccl,libnvjitlink,libcufile,libnvfatbin"
1818
cuda-path:
1919
description: "where the CTK components will be installed to, relative to $PWD"
2020
required: false
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
#
3+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
4+
#
5+
# This code was automatically generated across versions from 12.4.1 to 13.1.0. Do not modify it directly.
6+
7+
from ..cynvfatbin cimport *
8+
9+
10+
###############################################################################
11+
# Wrapper functions
12+
###############################################################################
13+
14+
cdef const char* _nvFatbinGetErrorString(nvFatbinResult result) except?NULL nogil
15+
cdef nvFatbinResult _nvFatbinCreate(nvFatbinHandle* handle_indirect, const char** options, size_t optionsCount) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
16+
cdef nvFatbinResult _nvFatbinDestroy(nvFatbinHandle* handle_indirect) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
17+
cdef nvFatbinResult _nvFatbinAddPTX(nvFatbinHandle handle, const char* code, size_t size, const char* arch, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
18+
cdef nvFatbinResult _nvFatbinAddCubin(nvFatbinHandle handle, const void* code, size_t size, const char* arch, const char* identifier) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
19+
cdef nvFatbinResult _nvFatbinAddLTOIR(nvFatbinHandle handle, const void* code, size_t size, const char* arch, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
20+
cdef nvFatbinResult _nvFatbinSize(nvFatbinHandle handle, size_t* size) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
21+
cdef nvFatbinResult _nvFatbinGet(nvFatbinHandle handle, void* buffer) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
22+
cdef nvFatbinResult _nvFatbinVersion(unsigned int* major, unsigned int* minor) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
23+
cdef nvFatbinResult _nvFatbinAddReloc(nvFatbinHandle handle, const void* code, size_t size) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
24+
cdef nvFatbinResult _nvFatbinAddTileIR(nvFatbinHandle handle, const void* code, size_t size, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil
Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
#
3+
# SPDX-License-Identifier: LicenseRef-NVIDIA-SOFTWARE-LICENSE
4+
#
5+
# This code was automatically generated across versions from 12.4.1 to 13.1.0. Do not modify it directly.
6+
7+
from libc.stdint cimport intptr_t, uintptr_t
8+
9+
import threading
10+
from .utils import FunctionNotFoundError, NotSupportedError
11+
12+
from cuda.pathfinder import load_nvidia_dynamic_lib
13+
14+
15+
###############################################################################
16+
# Extern
17+
###############################################################################
18+
19+
# You must 'from .utils import NotSupportedError' before using this template
20+
21+
cdef extern from "<dlfcn.h>" nogil:
22+
void* dlopen(const char*, int)
23+
char* dlerror()
24+
void* dlsym(void*, const char*)
25+
int dlclose(void*)
26+
27+
enum:
28+
RTLD_LAZY
29+
RTLD_NOW
30+
RTLD_GLOBAL
31+
RTLD_LOCAL
32+
33+
const void* RTLD_DEFAULT 'RTLD_DEFAULT'
34+
35+
cdef int get_cuda_version():
36+
cdef void* handle = NULL
37+
cdef int err, driver_ver = 0
38+
39+
# Load driver to check version
40+
handle = dlopen('libcuda.so.1', RTLD_NOW | RTLD_GLOBAL)
41+
if handle == NULL:
42+
err_msg = dlerror()
43+
raise NotSupportedError(f'CUDA driver is not found ({err_msg.decode()})')
44+
cuDriverGetVersion = dlsym(handle, "cuDriverGetVersion")
45+
if cuDriverGetVersion == NULL:
46+
raise RuntimeError('Did not find cuDriverGetVersion symbol in libcuda.so.1')
47+
err = (<int (*)(int*) noexcept nogil>cuDriverGetVersion)(&driver_ver)
48+
if err != 0:
49+
raise RuntimeError(f'cuDriverGetVersion returned error code {err}')
50+
51+
return driver_ver
52+
53+
54+
55+
###############################################################################
56+
# Wrapper init
57+
###############################################################################
58+
59+
cdef object __symbol_lock = threading.Lock()
60+
cdef bint __py_nvfatbin_init = False
61+
62+
cdef void* __nvFatbinGetErrorString = NULL
63+
cdef void* __nvFatbinCreate = NULL
64+
cdef void* __nvFatbinDestroy = NULL
65+
cdef void* __nvFatbinAddPTX = NULL
66+
cdef void* __nvFatbinAddCubin = NULL
67+
cdef void* __nvFatbinAddLTOIR = NULL
68+
cdef void* __nvFatbinSize = NULL
69+
cdef void* __nvFatbinGet = NULL
70+
cdef void* __nvFatbinVersion = NULL
71+
cdef void* __nvFatbinAddReloc = NULL
72+
cdef void* __nvFatbinAddTileIR = NULL
73+
74+
75+
cdef void* load_library() except* with gil:
76+
cdef uintptr_t handle = load_nvidia_dynamic_lib("nvfatbin")._handle_uint
77+
return <void*>handle
78+
79+
80+
cdef int _init_nvfatbin() except -1 nogil:
81+
global __py_nvfatbin_init
82+
83+
cdef void* handle = NULL
84+
85+
with gil, __symbol_lock:
86+
# Recheck the flag after obtaining the locks
87+
if __py_nvfatbin_init:
88+
return 0
89+
90+
# Load function
91+
global __nvFatbinGetErrorString
92+
__nvFatbinGetErrorString = dlsym(RTLD_DEFAULT, 'nvFatbinGetErrorString')
93+
if __nvFatbinGetErrorString == NULL:
94+
if handle == NULL:
95+
handle = load_library()
96+
__nvFatbinGetErrorString = dlsym(handle, 'nvFatbinGetErrorString')
97+
98+
global __nvFatbinCreate
99+
__nvFatbinCreate = dlsym(RTLD_DEFAULT, 'nvFatbinCreate')
100+
if __nvFatbinCreate == NULL:
101+
if handle == NULL:
102+
handle = load_library()
103+
__nvFatbinCreate = dlsym(handle, 'nvFatbinCreate')
104+
105+
global __nvFatbinDestroy
106+
__nvFatbinDestroy = dlsym(RTLD_DEFAULT, 'nvFatbinDestroy')
107+
if __nvFatbinDestroy == NULL:
108+
if handle == NULL:
109+
handle = load_library()
110+
__nvFatbinDestroy = dlsym(handle, 'nvFatbinDestroy')
111+
112+
global __nvFatbinAddPTX
113+
__nvFatbinAddPTX = dlsym(RTLD_DEFAULT, 'nvFatbinAddPTX')
114+
if __nvFatbinAddPTX == NULL:
115+
if handle == NULL:
116+
handle = load_library()
117+
__nvFatbinAddPTX = dlsym(handle, 'nvFatbinAddPTX')
118+
119+
global __nvFatbinAddCubin
120+
__nvFatbinAddCubin = dlsym(RTLD_DEFAULT, 'nvFatbinAddCubin')
121+
if __nvFatbinAddCubin == NULL:
122+
if handle == NULL:
123+
handle = load_library()
124+
__nvFatbinAddCubin = dlsym(handle, 'nvFatbinAddCubin')
125+
126+
global __nvFatbinAddLTOIR
127+
__nvFatbinAddLTOIR = dlsym(RTLD_DEFAULT, 'nvFatbinAddLTOIR')
128+
if __nvFatbinAddLTOIR == NULL:
129+
if handle == NULL:
130+
handle = load_library()
131+
__nvFatbinAddLTOIR = dlsym(handle, 'nvFatbinAddLTOIR')
132+
133+
global __nvFatbinSize
134+
__nvFatbinSize = dlsym(RTLD_DEFAULT, 'nvFatbinSize')
135+
if __nvFatbinSize == NULL:
136+
if handle == NULL:
137+
handle = load_library()
138+
__nvFatbinSize = dlsym(handle, 'nvFatbinSize')
139+
140+
global __nvFatbinGet
141+
__nvFatbinGet = dlsym(RTLD_DEFAULT, 'nvFatbinGet')
142+
if __nvFatbinGet == NULL:
143+
if handle == NULL:
144+
handle = load_library()
145+
__nvFatbinGet = dlsym(handle, 'nvFatbinGet')
146+
147+
global __nvFatbinVersion
148+
__nvFatbinVersion = dlsym(RTLD_DEFAULT, 'nvFatbinVersion')
149+
if __nvFatbinVersion == NULL:
150+
if handle == NULL:
151+
handle = load_library()
152+
__nvFatbinVersion = dlsym(handle, 'nvFatbinVersion')
153+
154+
global __nvFatbinAddReloc
155+
__nvFatbinAddReloc = dlsym(RTLD_DEFAULT, 'nvFatbinAddReloc')
156+
if __nvFatbinAddReloc == NULL:
157+
if handle == NULL:
158+
handle = load_library()
159+
__nvFatbinAddReloc = dlsym(handle, 'nvFatbinAddReloc')
160+
161+
global __nvFatbinAddTileIR
162+
__nvFatbinAddTileIR = dlsym(RTLD_DEFAULT, 'nvFatbinAddTileIR')
163+
if __nvFatbinAddTileIR == NULL:
164+
if handle == NULL:
165+
handle = load_library()
166+
__nvFatbinAddTileIR = dlsym(handle, 'nvFatbinAddTileIR')
167+
168+
__py_nvfatbin_init = True
169+
return 0
170+
171+
172+
cdef inline int _check_or_init_nvfatbin() except -1 nogil:
173+
if __py_nvfatbin_init:
174+
return 0
175+
176+
return _init_nvfatbin()
177+
178+
cdef dict func_ptrs = None
179+
180+
181+
cpdef dict _inspect_function_pointers():
182+
global func_ptrs
183+
if func_ptrs is not None:
184+
return func_ptrs
185+
186+
_check_or_init_nvfatbin()
187+
cdef dict data = {}
188+
189+
global __nvFatbinGetErrorString
190+
data["__nvFatbinGetErrorString"] = <intptr_t>__nvFatbinGetErrorString
191+
192+
global __nvFatbinCreate
193+
data["__nvFatbinCreate"] = <intptr_t>__nvFatbinCreate
194+
195+
global __nvFatbinDestroy
196+
data["__nvFatbinDestroy"] = <intptr_t>__nvFatbinDestroy
197+
198+
global __nvFatbinAddPTX
199+
data["__nvFatbinAddPTX"] = <intptr_t>__nvFatbinAddPTX
200+
201+
global __nvFatbinAddCubin
202+
data["__nvFatbinAddCubin"] = <intptr_t>__nvFatbinAddCubin
203+
204+
global __nvFatbinAddLTOIR
205+
data["__nvFatbinAddLTOIR"] = <intptr_t>__nvFatbinAddLTOIR
206+
207+
global __nvFatbinSize
208+
data["__nvFatbinSize"] = <intptr_t>__nvFatbinSize
209+
210+
global __nvFatbinGet
211+
data["__nvFatbinGet"] = <intptr_t>__nvFatbinGet
212+
213+
global __nvFatbinVersion
214+
data["__nvFatbinVersion"] = <intptr_t>__nvFatbinVersion
215+
216+
global __nvFatbinAddReloc
217+
data["__nvFatbinAddReloc"] = <intptr_t>__nvFatbinAddReloc
218+
219+
global __nvFatbinAddTileIR
220+
data["__nvFatbinAddTileIR"] = <intptr_t>__nvFatbinAddTileIR
221+
222+
func_ptrs = data
223+
return data
224+
225+
226+
cpdef _inspect_function_pointer(str name):
227+
global func_ptrs
228+
if func_ptrs is None:
229+
func_ptrs = _inspect_function_pointers()
230+
return func_ptrs[name]
231+
232+
233+
###############################################################################
234+
# Wrapper functions
235+
###############################################################################
236+
237+
cdef const char* _nvFatbinGetErrorString(nvFatbinResult result) except?NULL nogil:
238+
global __nvFatbinGetErrorString
239+
_check_or_init_nvfatbin()
240+
if __nvFatbinGetErrorString == NULL:
241+
with gil:
242+
raise FunctionNotFoundError("function nvFatbinGetErrorString is not found")
243+
return (<const char* (*)(nvFatbinResult) noexcept nogil>__nvFatbinGetErrorString)(
244+
result)
245+
246+
247+
cdef nvFatbinResult _nvFatbinCreate(nvFatbinHandle* handle_indirect, const char** options, size_t optionsCount) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
248+
global __nvFatbinCreate
249+
_check_or_init_nvfatbin()
250+
if __nvFatbinCreate == NULL:
251+
with gil:
252+
raise FunctionNotFoundError("function nvFatbinCreate is not found")
253+
return (<nvFatbinResult (*)(nvFatbinHandle*, const char**, size_t) noexcept nogil>__nvFatbinCreate)(
254+
handle_indirect, options, optionsCount)
255+
256+
257+
cdef nvFatbinResult _nvFatbinDestroy(nvFatbinHandle* handle_indirect) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
258+
global __nvFatbinDestroy
259+
_check_or_init_nvfatbin()
260+
if __nvFatbinDestroy == NULL:
261+
with gil:
262+
raise FunctionNotFoundError("function nvFatbinDestroy is not found")
263+
return (<nvFatbinResult (*)(nvFatbinHandle*) noexcept nogil>__nvFatbinDestroy)(
264+
handle_indirect)
265+
266+
267+
cdef nvFatbinResult _nvFatbinAddPTX(nvFatbinHandle handle, const char* code, size_t size, const char* arch, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
268+
global __nvFatbinAddPTX
269+
_check_or_init_nvfatbin()
270+
if __nvFatbinAddPTX == NULL:
271+
with gil:
272+
raise FunctionNotFoundError("function nvFatbinAddPTX is not found")
273+
return (<nvFatbinResult (*)(nvFatbinHandle, const char*, size_t, const char*, const char*, const char*) noexcept nogil>__nvFatbinAddPTX)(
274+
handle, code, size, arch, identifier, optionsCmdLine)
275+
276+
277+
cdef nvFatbinResult _nvFatbinAddCubin(nvFatbinHandle handle, const void* code, size_t size, const char* arch, const char* identifier) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
278+
global __nvFatbinAddCubin
279+
_check_or_init_nvfatbin()
280+
if __nvFatbinAddCubin == NULL:
281+
with gil:
282+
raise FunctionNotFoundError("function nvFatbinAddCubin is not found")
283+
return (<nvFatbinResult (*)(nvFatbinHandle, const void*, size_t, const char*, const char*) noexcept nogil>__nvFatbinAddCubin)(
284+
handle, code, size, arch, identifier)
285+
286+
287+
cdef nvFatbinResult _nvFatbinAddLTOIR(nvFatbinHandle handle, const void* code, size_t size, const char* arch, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
288+
global __nvFatbinAddLTOIR
289+
_check_or_init_nvfatbin()
290+
if __nvFatbinAddLTOIR == NULL:
291+
with gil:
292+
raise FunctionNotFoundError("function nvFatbinAddLTOIR is not found")
293+
return (<nvFatbinResult (*)(nvFatbinHandle, const void*, size_t, const char*, const char*, const char*) noexcept nogil>__nvFatbinAddLTOIR)(
294+
handle, code, size, arch, identifier, optionsCmdLine)
295+
296+
297+
cdef nvFatbinResult _nvFatbinSize(nvFatbinHandle handle, size_t* size) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
298+
global __nvFatbinSize
299+
_check_or_init_nvfatbin()
300+
if __nvFatbinSize == NULL:
301+
with gil:
302+
raise FunctionNotFoundError("function nvFatbinSize is not found")
303+
return (<nvFatbinResult (*)(nvFatbinHandle, size_t*) noexcept nogil>__nvFatbinSize)(
304+
handle, size)
305+
306+
307+
cdef nvFatbinResult _nvFatbinGet(nvFatbinHandle handle, void* buffer) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
308+
global __nvFatbinGet
309+
_check_or_init_nvfatbin()
310+
if __nvFatbinGet == NULL:
311+
with gil:
312+
raise FunctionNotFoundError("function nvFatbinGet is not found")
313+
return (<nvFatbinResult (*)(nvFatbinHandle, void*) noexcept nogil>__nvFatbinGet)(
314+
handle, buffer)
315+
316+
317+
cdef nvFatbinResult _nvFatbinVersion(unsigned int* major, unsigned int* minor) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
318+
global __nvFatbinVersion
319+
_check_or_init_nvfatbin()
320+
if __nvFatbinVersion == NULL:
321+
with gil:
322+
raise FunctionNotFoundError("function nvFatbinVersion is not found")
323+
return (<nvFatbinResult (*)(unsigned int*, unsigned int*) noexcept nogil>__nvFatbinVersion)(
324+
major, minor)
325+
326+
327+
cdef nvFatbinResult _nvFatbinAddReloc(nvFatbinHandle handle, const void* code, size_t size) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
328+
global __nvFatbinAddReloc
329+
_check_or_init_nvfatbin()
330+
if __nvFatbinAddReloc == NULL:
331+
with gil:
332+
raise FunctionNotFoundError("function nvFatbinAddReloc is not found")
333+
return (<nvFatbinResult (*)(nvFatbinHandle, const void*, size_t) noexcept nogil>__nvFatbinAddReloc)(
334+
handle, code, size)
335+
336+
337+
cdef nvFatbinResult _nvFatbinAddTileIR(nvFatbinHandle handle, const void* code, size_t size, const char* identifier, const char* optionsCmdLine) except?_NVFATBINRESULT_INTERNAL_LOADING_ERROR nogil:
338+
global __nvFatbinAddTileIR
339+
_check_or_init_nvfatbin()
340+
if __nvFatbinAddTileIR == NULL:
341+
with gil:
342+
raise FunctionNotFoundError("function nvFatbinAddTileIR is not found")
343+
return (<nvFatbinResult (*)(nvFatbinHandle, const void*, size_t, const char*, const char*) noexcept nogil>__nvFatbinAddTileIR)(
344+
handle, code, size, identifier, optionsCmdLine)

0 commit comments

Comments
 (0)