Skip to content

fix(core): reject use_libdevice on the NVRTC and PTX backends - #2573

Open
LeSingh1 wants to merge 1 commit into
NVIDIA:mainfrom
LeSingh1:program-use-libdevice-guard
Open

fix(core): reject use_libdevice on the NVRTC and PTX backends#2573
LeSingh1 wants to merge 1 commit into
NVIDIA:mainfrom
LeSingh1:program-use-libdevice-guard

Conversation

@LeSingh1

@LeSingh1 LeSingh1 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Problem

ProgramOptions.use_libdevice is documented as "Only supported for the NVVM backend" (_program.pyx:465-468). The guard that was supposed to enforce that sits in Program_init's final else — the branch reached only when code_type is not a backend at all:

    else:
        supported_code_types = tuple(x.value for x in SourceCodeType)
        if options.use_libdevice:
            raise ValueError("use_libdevice is only supported by the NVVM backend")
        raise RuntimeError(f"Unsupported {code_type=} ({supported_code_types=})")

Two wrong behaviours follow:

1. The two real non-NVVM backends accept the option silently. Program(src, "c++", ProgramOptions(use_libdevice=True)) and the "ptx" equivalent construct fine. self._use_libdevice is initialised to False (_program.pyx:765) and only flipped inside the nvvm branch, so libdevice is never loaded — the caller finds out via undefined-symbol errors at link time instead of via the documented up-front ValueError.

2. A typo'd code_type reports the wrong error. Program(src, "bogus", ProgramOptions(use_libdevice=True)) raises "use_libdevice is only supported by the NVVM backend" and never mentions that code_type is the actual problem.

The sibling option shows the intended shape: extra_sources has the same "NVVM only" contract, and its guard is duplicated into each real branch — _program.pyx:772-773 (c++) and :790-791 (ptx).

Fix

Move the use_libdevice check next to those extra_sources guards in the c++ and ptx branches, and drop it from the else so an unrecognised code_type reports itself. No behaviour changes for code_type="nvvm".

This is an error-path-only change: any program that compiled before still compiles, and any program that is newly rejected was already producing a build the user did not ask for.

Tests

Three cases in cuda_core/tests/test_program.py, placed next to the existing extra_sources tests they mirror:

  • test_cpp_program_with_use_libdevice — NVRTC rejects it.
  • test_ptx_program_use_libdevice_unsupported — the PTX/linker path rejects it.
  • test_program_init_invalid_code_type_reports_the_code_typeuse_libdevice=True no longer shadows the unrecognised-code_type error.

What I ran

Environment: macOS, no CUDA driver and no CUDA toolkit, so cuda.core cannot be built or imported here.

  • Did not run: the three new tests, or anything else in cuda_core/tests/ — they need a built cuda.core and a GPU. They are written against the existing extra_sources tests immediately adjacent to them, which use the same fixtures.
  • Ran: a reduction of Program_init's dispatch with the CUDA calls removed and the guard placement kept verbatim, before and after the change:
--- before ---
  code_type='c++'      use_libdevice=True -> accepted, _use_libdevice=False
  code_type='ptx'      use_libdevice=True -> accepted, _use_libdevice=False
  code_type='nvvm'     use_libdevice=True -> accepted, _use_libdevice=True
  code_type='fortran'  use_libdevice=True -> ValueError: use_libdevice is only supported by the NVVM backend
--- after ---
  code_type='c++'      use_libdevice=True -> ValueError: use_libdevice is not supported by the NVRTC backend (C++ code_type)
  code_type='ptx'      use_libdevice=True -> ValueError: use_libdevice is not supported by the PTX backend.
  code_type='nvvm'     use_libdevice=True -> accepted, _use_libdevice=True
  code_type='fortran'  use_libdevice=True -> RuntimeError: Unsupported code_type='fortran' (SUPPORTED=('c++', 'ptx', 'nvvm'))
  • Ran: ruff check / ruff format --check on cuda_core/tests/test_program.py — clean, no new findings against a main baseline for that file.
  • Checked: use_libdevice appears in _program.pyx only at the two sites above (the nvvm set and this guard), so nothing else depended on the old placement. test_program_init_invalid_code_type still passes unchanged because its ProgramOptions leaves use_libdevice at its False default.

`ProgramOptions.use_libdevice` is documented "Only supported for the NVVM
backend", but the guard enforcing that was written in `Program_init`'s final
`else` -- the branch reached only when `code_type` is not a backend at all:

    else:
        supported_code_types = tuple(x.value for x in SourceCodeType)
        if options.use_libdevice:
            raise ValueError("use_libdevice is only supported by the NVVM backend")
        raise RuntimeError(f"Unsupported {code_type=} ({supported_code_types=})")

So it never fires for the two real non-NVVM backends, and it fires for the
wrong reason on a typo:

* `Program(src, "c++", ProgramOptions(use_libdevice=True))` and the "ptx"
  equivalent are accepted silently. `self._use_libdevice` is initialised to
  False and only set inside the `nvvm` branch, so libdevice is never loaded
  and the caller learns about it from undefined-symbol errors at link time
  instead of from the documented up-front ValueError.
* `Program(src, "bogus", ProgramOptions(use_libdevice=True))` raises
  "use_libdevice is only supported by the NVVM backend", which says nothing
  about the code_type that is the actual problem.

Move the check next to the per-branch `extra_sources` guards, which are the
sibling option with the same "NVVM only" contract and are already duplicated
into the "c++" and "ptx" branches, and drop it from the `else` so an
unrecognised code_type reports itself.
@copy-pr-bot

copy-pr-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the cuda.core Everything related to the cuda.core module label Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cuda.core Everything related to the cuda.core module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant