Skip to content

Commit ebab5f5

Browse files
committed
Limit incremental LTO cache workaround to nvJitLink before 13.6
1 parent 594e54e commit ebab5f5

3 files changed

Lines changed: 30 additions & 21 deletions

File tree

‎cuda_core/cuda/core/_linker.pyi‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ class LinkerOptions:
154154
Perform an incremental link. The result can be passed
155155
directly to a later :class:`Linker`. Requires nvJitLink 13.2 or newer
156156
and is not supported by the driver linker backend. Intermediate
157-
caching is disabled automatically when combined with link-time
158-
optimization.
157+
caching is disabled on nvJitLink versions older than 13.6 when combined
158+
with link-time optimization, to work around an nvJitLink bug.
159159
Default: False.
160160
ptx : bool, optional
161161
Emit PTX after linking instead of CUBIN; only supported with ``link_time_optimization=True``.
@@ -200,8 +200,9 @@ class LinkerOptions:
200200
Default: 1.
201201
no_cache : bool, optional
202202
Do not cache the intermediate steps of nvJitLink.
203-
This is also enabled automatically for incremental links that use
204-
link-time optimization.
203+
Caching is also disabled automatically for incremental links that use
204+
link-time optimization on nvJitLink versions older than 13.6, to work
205+
around an nvJitLink bug.
205206
Default: False.
206207
numba_debug : bool, optional
207208
Non-functional. ``numba_debug`` is an NVVM/NVRTC *compiler* option;

‎cuda_core/cuda/core/_linker.pyx‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ class LinkerOptions:
272272
Perform an incremental link. The result can be passed
273273
directly to a later :class:`Linker`. Requires nvJitLink 13.2 or newer
274274
and is not supported by the driver linker backend. Intermediate
275-
caching is disabled automatically when combined with link-time
276-
optimization.
275+
caching is disabled on nvJitLink versions older than 13.6 when combined
276+
with link-time optimization, to work around an nvJitLink bug.
277277
Default: False.
278278
ptx : bool, optional
279279
Emit PTX after linking instead of CUBIN; only supported with ``link_time_optimization=True``.
@@ -318,8 +318,9 @@ class LinkerOptions:
318318
Default: 1.
319319
no_cache : bool, optional
320320
Do not cache the intermediate steps of nvJitLink.
321-
This is also enabled automatically for incremental links that use
322-
link-time optimization.
321+
Caching is also disabled automatically for incremental links that use
322+
link-time optimization on nvJitLink versions older than 13.6, to work
323+
around an nvJitLink bug.
323324
Default: False.
324325
numba_debug : bool, optional
325326
Non-functional. ``numba_debug`` is an NVVM/NVRTC *compiler* option;
@@ -435,10 +436,10 @@ class LinkerOptions:
435436
options.append(f"-split-compile={int(self.split_compile)}")
436437
if self.split_compile_extended is not None:
437438
options.append(f"-split-compile-extended={int(self.split_compile_extended)}")
438-
# Repeated incremental LTO links can crash in nvJitLink's intermediate
439-
# cache (reproduced with 13.4.92 on Windows). Avoid reusing cached
440-
# state for each incremental stage.
441-
if self.no_cache is True or (self.incremental and self.link_time_optimization):
439+
# nvbugs 6659652
440+
if self.no_cache is True or (
441+
_nvjitlink_version < (13, 6) and self.incremental and self.link_time_optimization
442+
):
442443
options.append("-no-cache")
443444

444445
if as_bytes:

‎cuda_core/tests/test_linker.py‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,15 +246,22 @@ def test_linker_options_incremental_as_bytes(value, expected_count):
246246

247247
@pytest.mark.agent_authored(model="gpt-6")
248248
@pytest.mark.skipif(is_culink_backend, reason="as_bytes() only supported for nvjitlink backend")
249-
def test_linker_options_incremental_lto_disables_cache():
250-
options = LinkerOptions(arch="sm_80", incremental=True, link_time_optimization=True)
251-
assert b"-no-cache" in options.as_bytes()
252-
253-
options = LinkerOptions(arch="sm_80", incremental=True)
254-
assert b"-no-cache" not in options.as_bytes()
255-
256-
options = LinkerOptions(arch="sm_80", link_time_optimization=True)
257-
assert b"-no-cache" not in options.as_bytes()
249+
@pytest.mark.parametrize(
250+
"version,needs_workaround", [((13, 4), True), ((13, 5), True), ((13, 6), False), ((14, 0), False)]
251+
)
252+
@pytest.mark.parametrize(
253+
"incremental,link_time_optimization", [(False, False), (False, True), (True, False), (True, True)]
254+
)
255+
@pytest.mark.parametrize("no_cache", [None, False, True])
256+
def test_linker_options_incremental_lto_disables_cache(
257+
monkeypatch, version, needs_workaround, incremental, link_time_optimization, no_cache
258+
):
259+
options = LinkerOptions(
260+
arch="sm_80", incremental=incremental, link_time_optimization=link_time_optimization, no_cache=no_cache
261+
)
262+
monkeypatch.setattr(_linker, "_nvjitlink_version", version)
263+
expected = no_cache is True or (needs_workaround and incremental and link_time_optimization)
264+
assert options.as_bytes().count(b"-no-cache") == int(expected)
258265

259266

260267
@pytest.mark.parametrize("backend", ("invalid", "driver"))

0 commit comments

Comments
 (0)