Skip to content

feat(cuda.core): support nvJitLink incremental linking - #2867

Merged
leofang merged 10 commits into
NVIDIA:mainfrom
isVoid:fea-2369-draft
Sep 19, 2026
Merged

leofang merged 10 commits into
NVIDIA:mainfrom
isVoid:fea-2369-draft

Conversation

@isVoid

@isVoid isVoid commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • expose nvJitLink incremental linking as LinkerOptions(incremental=True), gated on nvJitLink 13.2+
  • return native partial results as ObjectCode(code_type="cubin") so they round-trip directly into another Linker
  • add Linker.link("ltoir") on nvJitLink 13.3+ so incremental LTO chains can retain IR until final code generation
  • reject unsupported driver-backend and partial-PTX combinations with explicit errors
  • clarify that code_type="object" means a host object containing device code

Design choices

  • A native incremental-link result remains "cubin"; ELF ET_REL describes link state, not a distinct cuda.core transport format.
  • In incremental mode, target_type accepts "cubin", or "ltoir" when LTO is enabled and the getter is available. "ptx" is rejected.
  • Native CUBIN and linked-LTOIR outputs need no wrapper or conversion before being supplied to a later Linker.
  • Intermediate LTO stages should request "ltoir"; requesting "cubin" creates a machine-code boundary that later LTO cannot optimize through.
  • Linked-LTOIR retrieval uses the Python binding dynamically so cuda-core continues to build with supported cuda-bindings 12.x releases whose Cython declarations predate the getter.

Testing

  • CUDA 13.4 linker suite: 82 passed, 3 skipped, including executable native-CUBIN and LTOIR three-stage round trips
  • CUDA 12.9 / published cuda-bindings 12.9.7 compatibility build and linker suite: 74 passed, 6 capability skips
  • Sphinx documentation build
  • repository pre-commit checks for all changed files (Ruff, mypy, Cython lint, generated stubs, SPDX, RST, memory-pool hygiene)

Closes #2369

@copy-pr-bot

copy-pr-bot Bot commented Sep 15, 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 Sep 15, 2026
@leofang

leofang commented Sep 15, 2026

Copy link
Copy Markdown
Member

nit: @isVoid could you post your design doc as a comment in #2369 for posterity, in case your personal branch is removed in the future?

@leofang
leofang self-requested a review September 15, 2026 19:36
@isVoid

isVoid commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

nit: @isVoid could you post your design doc as a comment in #2369 for posterity, in case your personal branch is removed in the future?

This is now posted.

@isVoid
isVoid marked this pull request as ready for review September 17, 2026 20:09
Comment thread cuda_core/cuda/core/_linker.pyi Outdated
link_time_optimization : bool, optional
Perform link time optimization.
Default: False.
relocatable : bool, optional

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Q: Maybe we should call it relocatable_device_code to match what we have in ProgramOptions? Seems like they have the same semantics?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The design doc notes the distinction:

ProgramOptions.relocatable_device_code and the proposed LinkerOptions.relocatable are also distinct:

  • The program option makes a compilation unit suitable for device linking.
  • The linker option permits a link result to remain relocatable and to retain unresolved device references.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I sort of think relocatable_device_code and relocatable are respectively different notions created one on the nvrtc and nvjitlink side. My prior discussion with folks suggests rdc is quite commonly used as a shorthand to refer to the nvrtc behavior. Coercing the linker side to overlap this terminology could introduce some confusion in the future.

ref:
nvjitlink linker options
nvrtc options

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I was confused for a moment when reading even relocatable_device_code and relocatable 😂

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@isVoid good idea, but maybe we should rename it for clarity? Such as incremental_link?

@isVoid isVoid Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

+1. Like incremental_link

Maybe the page didn't refresh when you reply, see #2867 (comment). Do you have specific preference on incremental_link over incremental? @lijinf2

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yes I think page did not refresh on my side. incremental looks good too!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't the driver docs prefer the term "relative" over "incremental" though? Diverging from that could be confusing in a different way.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Don't the driver docs prefer the term "relative" over "incremental" though? Diverging from that could be confusing in a different way.

I can see the term relocatable is used across the board to refer specifically to the output of the linker with -r or compiler with -rdc. But when referring to the -r flag, the nvjitlink do mention both terms, and actually in some sense highlighting the incremental to emphasize the linker behavior.

@Andy-Jost Andy-Jost left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One blocker: link("ltoir") silently drops inputs that carry no LTOIR (details inline, with a repro). Two untested rows of the design matrix, and a few small cleanups. The relocatable and LTOIR round trips themselves look right.

Comment thread cuda_core/cuda/core/_linker.pyx
Comment thread cuda_core/tests/test_linker.py Outdated
Comment thread cuda_core/cuda/core/_linker.pyx Outdated
Comment thread cuda_core/cuda/core/_linker.pyx Outdated
Comment thread cuda_core/cuda/core/_linker.pyx
Comment thread cuda_core/cuda/core/_linker.pyi Outdated
link_time_optimization : bool, optional
Perform link time optimization.
Default: False.
relocatable : bool, optional

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The design doc notes the distinction:

ProgramOptions.relocatable_device_code and the proposed LinkerOptions.relocatable are also distinct:

  • The program option makes a compilation unit suitable for device linking.
  • The linker option permits a link result to remain relocatable and to retain unresolved device references.

@lijinf2 lijinf2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice. Let me write down my understanding. Before this PR, application code had to gather all compiled device inputs (PTX/LTOIR/cubin) before invoking a single Linker. After this PR, application code can do cascading linking — each stage produces a partial result that feeds directly into the next Linker.

Comment thread cuda_core/tests/test_linker.py Outdated
Comment thread cuda_core/tests/test_linker.py
Comment thread cuda_core/cuda/core/_linker.pyx Outdated
Comment thread cuda_core/cuda/core/_linker.pyi Outdated
link_time_optimization : bool, optional
Perform link time optimization.
Default: False.
relocatable : bool, optional

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I was confused for a moment when reading even relocatable_device_code and relocatable 😂

@isVoid isVoid added the feature New feature or request label Sep 18, 2026
@isVoid isVoid added this to the cuda.core 1.3.0 milestone Sep 18, 2026
@isVoid isVoid added the P1 Medium priority - Should do label Sep 18, 2026
@isVoid
isVoid requested a review from Andy-Jost September 18, 2026 06:02

@Andy-Jost Andy-Jost left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

Comment thread cuda_core/cuda/core/LINKER_INCREMENTAL_LINKING_DESIGN.md Outdated
@leofang

leofang commented Sep 18, 2026

Copy link
Copy Markdown
Member

Left a question here: #2867 (comment)

@isVoid

isVoid commented Sep 18, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 3cc270d

@lijinf2 lijinf2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My comments all addressed. Thanks. PR looks good to me!

@github-actions

This comment has been minimized.

@isVoid

isVoid commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test fc8c850

@isVoid
isVoid enabled auto-merge (squash) September 19, 2026 00:46
@isVoid
isVoid disabled auto-merge September 19, 2026 00:46
@isVoid
isVoid requested a review from leofang September 19, 2026 00:46
@leofang
leofang merged commit 8b6e9f5 into NVIDIA:main Sep 19, 2026
115 checks passed
@github-actions

Copy link
Copy Markdown
Contributor
Doc Preview CI
Preview removed because the pull request was closed or merged.

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 feature New feature or request P1 Medium priority - Should do

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA] cuda.core: support nvJitLink partial/incremental linking (CUDA 13.2)

4 participants