Skip to content

fix: TensorRT-RTX Turing (SM 7.5) capability guards and compute-capability targeting - #4643

Open
tp5uiuc wants to merge 3 commits into
mainfrom
tp5uiuc/trtrtx-turing-foundation
Open

fix: TensorRT-RTX Turing (SM 7.5) capability guards and compute-capability targeting#4643
tp5uiuc wants to merge 3 commits into
mainfrom
tp5uiuc/trtrtx-turing-foundation

Conversation

@tp5uiuc

@tp5uiuc tp5uiuc commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

What — Adds a target_compute_capabilities compilation setting, declares it on the TensorRT-RTX
builder config, and falls back to PyTorch for the ops TensorRT-RTX cannot serve on Turing.

Why — TensorRT-RTX runs on SM 7.5 and up, but its support matrix carves Turing out of several
paths: FP32 GEMMs and 3D convolutions are unsupported at compute capability 7.5, and Turing has no
bfloat16 hardware. Torch-TensorRT had no notion of this and handed those ops over anyway:

  • FP32 GEMM, static shapes — createExecutionContext() returns null
  • FP32 GEMM, dynamic shapes — the engine builds and runs, returning an all-zero tensor of the
    correct shape and dtype, with no exception
  • 3D convolution — null execution context
  • bfloat16 — segmentation fault

The dynamic-shape GEMM is the motivating case, because it fails silently.

Separately, the builder was never told which architecture it was building for. With
num_compute_capabilities == 0, Myelin looks for a precompiled module instead of JIT-ing one and
the build dies — Compatible cubin or ptx module for device target '75' not found — so on Turing
every refittable build failed.

How — Guards key off the capabilities being built for, not the build host, so an
ahead-of-time build for another architecture partitions correctly instead of baking in the build
machine. An undeclared target is resolved rather than skipped, to the current device, matching how
partitioning already resolved it — and by naming ComputeCapability.CURRENT rather than looking up
SM<major><minor>, because TensorRT-RTX names only a subset of architectures and the implicit path
must not start failing on hosts that build fine today.

The GEMM guard keys on fp32 operands only, so fp16 GEMMs accumulating in fp32 are unaffected. The
convolution guard covers forward 3D only, since transposed 3D works on Turing. bfloat16 is gated at
the partitioner rather than per-converter because the crash is not operator-specific, mirroring the
existing complex-dtype handling. Converter unit tests bypass the partitioner, so a rejected node
raises instead of falling back; those tests skip explicitly.

Testing — Confirmation sweep at the series tip, T4 (SM 7.5) and L40S (SM 8.9), driver 595.58.03,
identical stacks: T4 2668 passed / 17 failed / 226 skipped; L40S 2780 / 13 / 118; 2911 collected on
each.
Declaring the capability alone closes 42 of the 91 original Turing failures. Defaulting
costs nothing off Turing: on an L40S, engines built with the default and with an explicit [(8, 9)]
are byte-identical (280148 B and 287100 B for a small conv net; 47148116 B and 24184052 B for
resnet18), with no measurable build-time difference. On the L40S there is not one status change
across all six test modules
— every guard is inert off Turing.

Cost / Gotchas

  • The guards switch off 105 tests on Turing, 97 of them in conversion/: the T4 runs 1981 of
    2126 tests where the L40S runs 2079. Green on Turing does not mean equally tested on Turing.
  • Also clears two pre-existing lint failures in aten_ops_converters.py (an unused
    type: ignore[assignment] and a spelling the typos hook rejects). Both predate this change, but
    the file is now in the changed set so pre-commit blocks on them.

Followups — Three more capability gaps ship as stacked PRs on this branch: 3D convolution behind
the pad-folding pass, the GEMM cdist emits internally, and FP32 GEMMs reaching TensorRT-RTX through
linear and attention.

🤖 Generated with Claude Code

@meta-cla meta-cla Bot added the cla signed label Aug 29, 2026
@github-actions github-actions Bot added component: tests Issues re: Tests component: conversion Issues re: Conversion stage component: core Issues re: The core compiler component: api [Python] Issues re: Python API component: dynamo Issues relating to the `torch.compile` or `torch._dynamo.export` paths labels Aug 29, 2026
@github-actions
github-actions Bot requested a review from zewenli98 August 29, 2026 17:53
@tp5uiuc tp5uiuc self-assigned this Aug 29, 2026
@tp5uiuc
tp5uiuc force-pushed the tp5uiuc/trtrtx-turing-foundation branch 2 times, most recently from 0828d80 to 60522c1 Compare August 29, 2026 23:01
@github-actions github-actions Bot added the component: converters Issues re: Specific op converters label Aug 29, 2026
Comment thread py/torch_tensorrt/dynamo/conversion/impl/normalization/ops.py Outdated
Comment thread py/torch_tensorrt/_utils.py
Comment thread py/torch_tensorrt/_utils.py
Comment thread py/torch_tensorrt/_utils.py Outdated
Comment thread py/torch_tensorrt/dynamo/conversion/_TRTInterpreter.py Outdated
Comment thread py/torch_tensorrt/dynamo/_compiler.py
Comment thread py/torch_tensorrt/dynamo/_defaults.py Outdated
Comment thread py/torch_tensorrt/dynamo/_settings.py Outdated
Comment thread py/torch_tensorrt/dynamo/_settings.py
Comment thread py/torch_tensorrt/dynamo/_settings.py Outdated
@tp5uiuc
tp5uiuc force-pushed the tp5uiuc/trtrtx-turing-foundation branch from 60522c1 to bb9c235 Compare August 30, 2026 00:49
Adds a target_compute_capabilities setting naming the architectures an engine is
built for, and declares them on the TensorRT-RTX builder config, so an artifact
can be produced for something other than the build host. Declaring it on standard
TensorRT raises: that backend always builds for the current device.

An undeclared target is now resolved rather than skipped. Left at the builder
default num_compute_capabilities stays 0, and a refittable graph then fails with
"Compatible cubin or ptx module for device target '75' not found" -- so on Turing
every refittable build failed. It now resolves to the current device the way
partitioning already did via get_target_compute_capabilities(), naming
ComputeCapability.CURRENT rather than an SM<major><minor> lookup because
TensorRT-RTX names only a subset of architectures.

The builder-config work lives in set_rtx_compute_capabilities() so it can be unit
tested against a stub config, with no GPU and no engine build.

Not exposed on cross_compile_for_windows: TensorRT-RTX does not support that path.

The setting is engine-invariant: an engine built for one capability set must not
be reused for a compile targeting another.
TensorRT-RTX does not support FP32 GEMMs or 3D convolutions on Turing (SM 7.5),
and Turing has no bfloat16 hardware. Handed those ops anyway it returns a null
execution context, segfaults on bf16, or -- under dynamic shapes -- builds, runs
and returns an all-zero tensor with no exception. That silent case is the
motivating one.

Guards key off the capabilities being built for rather than the build host, so an
ahead-of-time build for another architecture partitions correctly. The GEMM guard
keys on fp32 operands only; the convolution guard covers forward 3D only, since
transposed 3D works on Turing. bfloat16 is gated in the partitioners because the
crash is not operator-specific, mirroring the existing complex-dtype handling.

Converter unit tests need explicit skips: DispatchTestCase bypasses the
partitioner, so a guarded node raises UnsupportedOperatorException instead of
falling back and an unguarded one reaches TensorRT-RTX and fails.

The cdist skips state the converter's condition rather than p == 2, because a
GEMM is only emitted for compute_mode 1, or 0/absent with an operand above the
row threshold. Measured on a T4: the 3 cases outside that condition pass, the 9
inside it fail. Rather than hand-copy the branch, it is extracted from
cdist_forward as cdist_emits_matmul/CDIST_MATMUL_ROW_THRESHOLD -- the converter
now consumes its own predicate, and the test and the Turing capability validator
consume the same one, so none of the three can drift. The threshold was a bare
literal in the converter until now. Four parameterisations named for a
compute_mode they do not use are renamed.

Also clears two pre-existing lint failures in aten_ops_converters.py that
pre-commit blocks on now the file is in the changed set: an unused
type: ignore[assignment] and a "mis-evaluate" spelling.
Adds the regression tests for the fallbacks introduced alongside the Turing
(SM 7.5) capability guards: FP32 GEMM, 3D convolution and bfloat16 must fall
back to PyTorch, while FP16 GEMM, 2D convolution and transposed 3D convolution
must stay on TensorRT.

Most of the coverage is written against target_compute_capabilities=[(7, 5)],
which forces Turing's partitioning on any GPU, so the guards are exercised in
CI without Turing hardware. A second class repeats the same checks natively and
is skipped off SM 7.5; it also pins the two failure modes that motivated the
guards -- a null execution context under static shapes and a silently all-zero
result under dynamic shapes.

Two further cases assert on the builder config rather than on compile success,
which is what makes them meaningful off Turing: everywhere except SM 7.5 an
undeclared compute capability is silent.
@tp5uiuc
tp5uiuc force-pushed the tp5uiuc/trtrtx-turing-foundation branch from bb9c235 to 633444a Compare August 30, 2026 18:37
@tp5uiuc

tp5uiuc commented Aug 30, 2026

Copy link
Copy Markdown
Collaborator Author

CI summary

failing check cause
standard / test (dynamo-models, standard, l2) test_cross_runtime_serde::test_save_cpp_load_python and ::test_save_python_load_cpp — Windows only
standard / test (dynamo-models-critical, standard, l1) test_hf_gqa_model::test_dynamic_head_dim_with_hf_model[False-dtype0]Tensor-likes are not close
executorch-runtime-test OSError: libcurand.so.10
gate ×2 aggregators

Suites ran to completion: 2 failed, 150 passed, 52 skipped, 4 xpassed and 1 failed, 52 passed.

Why these are not from this PR: the same test_cross_runtime_serde pair fails identically on #4643, #4644, #4645, #4646, #4647 and #4648, whose change sets are disjoint — e.g. #4648 changes _exporter.py (the save path) and #4647 changes neither that nor anything else in common, yet both fail the same two tests with byte-identical error text. executorch-runtime-test reproduces on main nightlies and on unrelated PRs (#4638, #4642). The gate entries are aggregators of the above. test_hf_gqa_model also fails on #4645 and #4647 and has no overlap with anything this PR changes.

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

Labels

ci: full cla signed component: api [Python] Issues re: Python API component: conversion Issues re: Conversion stage component: converters Issues re: Specific op converters component: core Issues re: The core compiler component: dynamo Issues relating to the `torch.compile` or `torch._dynamo.export` paths component: tests Issues re: Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant