Skip to content

Make Linker.backend a classmethod#1910

Open
cpcloud wants to merge 4 commits intoNVIDIA:mainfrom
cpcloud:linker-backend-classmethod-714
Open

Make Linker.backend a classmethod#1910
cpcloud wants to merge 4 commits intoNVIDIA:mainfrom
cpcloud:linker-backend-classmethod-714

Conversation

@cpcloud
Copy link
Copy Markdown
Contributor

@cpcloud cpcloud commented Apr 14, 2026

Summary

  • Converts Linker.backend from an instance property to a classmethod so callers can query the linking backend without constructing a Linker
  • Classmethod calls _decide_nvjitlink_or_driver() (existing memoised probe) and maps the return value to "nvJitLink" or "driver"
  • Updates the one in-repo call site in _program.pyx and existing test assertion to use parens
  • Adds 6 GPU-free tests via monkeypatch (no Device() / cuInit required)
  • Adds 0.8.0-notes.rst documenting the breaking change

Breaking change: linker.backend (attribute access) now returns a bound method, not a string. All call sites must use Linker.backend(). Only 2 in-repo call sites affected; numba-cuda (the requester) will adopt Linker.backend() from day one.

Test plan

  • 6 GPU-free tests pass locally (monkeypatch on module globals)
  • CI: existing GPU test test_linker_init passes with updated paren call
  • CI: Cython compile succeeds

Closes #714

🤖 Generated with Claude Code

@cpcloud cpcloud added this to the cuda.core v1.0.0 milestone Apr 14, 2026
@cpcloud cpcloud added enhancement Any code-related improvements P0 High priority - Must do! cuda.core Everything related to the cuda.core module breaking Breaking changes are introduced labels Apr 14, 2026
@cpcloud cpcloud self-assigned this Apr 14, 2026
@github-actions
Copy link
Copy Markdown

@cpcloud cpcloud force-pushed the linker-backend-classmethod-714 branch 2 times, most recently from dbe6176 to 215418a Compare April 16, 2026 21:45
@cpcloud cpcloud requested a review from leofang April 17, 2026 12:58
Copy link
Copy Markdown
Member

@leofang leofang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Phillip! Implementation-wise LGTM. Left a few suggestions.

Comment thread cuda_core/docs/source/release/1.0.0-notes.rst
Comment thread cuda_core/tests/test_linker_backend.py Outdated
Comment thread cuda_core/tests/test_linker_backend.py Outdated
Comment thread cuda_core/docs/source/release/1.0.0-notes.rst
cpcloud added 3 commits April 21, 2026 11:14
Allows querying the linking backend without constructing a Linker
instance — useful for dispatching on input format (PTX vs. LTOIR)
before linking.

Updates existing call sites (Program init, test_linker) to use the
new invocation form Linker.backend().
Covers classmethod invocation (Linker.backend() without an instance),
memoisation flag handling, probe-on-first-use, and non-property
attribute semantics.
Breaking change: Linker.backend is now a classmethod, so call sites
must use parens: Linker.backend().
@cpcloud cpcloud force-pushed the linker-backend-classmethod-714 branch from 215418a to 12d291b Compare April 21, 2026 15:21
@cpcloud cpcloud requested a review from leofang April 21, 2026 19:48
Copy link
Copy Markdown
Member

@leofang leofang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we just recently went to the opposite direction (converting some methods to properties, #1945 & #1986), it'd be better to have @mdboom or @Andy-Jost to chime in from the design consistency perspective. It might be possible that we need to re-evaluate if #714 is really necessary.

Comment on lines -170 to +185
@property
def backend(self) -> str:
"""Return this Linker instance's underlying backend."""
return "nvJitLink" if self._use_nvjitlink else "driver"
@classmethod
def backend(cls) -> str:
"""Return which linking backend will be used.

Returns ``"nvJitLink"`` when the nvJitLink library is available
and meets the minimum version requirement, otherwise ``"driver"``.

.. note::

Prefer letting :class:`Linker` decide. Query ``backend()``
only when you need to dispatch based on input format (for
example: choose PTX vs. LTOIR before constructing a
``Linker``). The returned string names an implementation
detail whose support matrix may shift across CTK releases.
"""
return "driver" if _decide_nvjitlink_or_driver() else "nvJitLink"
Copy link
Copy Markdown
Contributor

@Andy-Jost Andy-Jost May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We did just complete a sweep to standardize the property/method distinction. It would be great to keep that as clean as possible.

One option is to roll our own classproperty:

class classproperty:
    def __init__(self, func):
        self.func = func
    def __get__(self, instance, owner):
        return self.func(owner)

class Linker:
    @classproperty
    def backend(cls):
        . . .

Related: python/cpython#89519

There are caveats and hazards in complex cases, but they wouldn't come into play here.

Another option would be to keep the property while adding a module-level function get_backend().

Is there any risk that the backend selection might become dependent on constructor args? If so, it would be better to use a freestanding function IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Breaking changes are introduced cuda.core Everything related to the cuda.core module enhancement Any code-related improvements P0 High priority - Must do!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA]: Make Linker.backend a classmethod

4 participants