Skip to content

Ship only the TensorRT delegate in the ExecuTorch runtime wheel #1324

Ship only the TensorRT delegate in the ExecuTorch runtime wheel

Ship only the TensorRT delegate in the ExecuTorch runtime wheel #1324

Workflow file for this run

name: CI Linux x86_64
# Per-platform entry (one small, independent run — not the old 8-channel mega-run).
# Runs the linux-x86_64 channels: standard, RTX, and python-only. Lane + backend
# come from the shared _decide reusable.
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
pull_request_review:
types: [submitted]
push:
branches: [main, nightly, 'release/**']
workflow_dispatch:
inputs:
lane:
description: "Which lane to run"
type: choice
options: [fast, full, nightly]
default: full
backend:
description: "Which backend(s) to test"
type: choice
options: [standard, rtx, both]
default: both
concurrency:
# Only NON-CI label events (component:*, cla signed, …) get their own per-label
# group, so auto-label churn never cancels the running pipeline. CI-control labels
# (ci:full / ci:nightly / backend:*) and real pushes share the PR group so they
# SUPERSEDE cleanly — exactly ONE pipeline per commit. Coexisting runs would
# otherwise collide inside build_linux.yml's own concurrency and cancel a
# half-built wheel (that is what cancelled the SBSA aarch64 build).
group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}${{ (github.event.action == 'labeled' || github.event.action == 'unlabeled') && !contains(fromJSON('[\"ci: full\", \"ci: nightly\", \"backend: TensorRT\", \"backend: TensorRT-RTX\"]'), github.event.label.name) && format('-label-{0}', github.event.label.name) || '' }}"
cancel-in-progress: true
permissions:
id-token: write
contents: read
jobs:
decide:
# A label event only warrants running the pipeline when the label controls CI;
# auto-labels (component:*, cla signed) must not spawn work — and would each
# start a full run once ci:full is present. Non-label events always proceed.
if: >-
github.event.action != 'labeled' ||
contains(fromJSON('["ci: full", "ci: nightly", "backend: TensorRT", "backend: TensorRT-RTX"]'), github.event.label.name)
uses: ./.github/workflows/_decide.yml
# Generate the build matrix ONCE. generate_binary_build_matrix's concurrency
# group is keyed on (workflow, PR, os) with cancel-in-progress, so calling it
# per-channel makes the channels cancel each other's matrix job. All channels
# share this one output and filter it per-variant.
generate-matrix:
needs: decide
if: needs.decide.result == 'success' && needs.decide.outputs.lane != 'skip'
uses: pytorch/test-infra/.github/workflows/generate_binary_build_matrix.yml@main
with:
package-type: wheel
os: linux
test-infra-repository: pytorch/test-infra
test-infra-ref: main
with-rocm: false
with-cpu: false
# Standard — runs on every non-skip lane, incl. the fast lane (every PR push).
standard:
needs: [decide, generate-matrix]
if: needs.decide.outputs.lane != 'skip' && needs.decide.outputs.backend != 'rtx'
uses: ./.github/workflows/_test-linux.yml
with:
lane: ${{ needs.decide.outputs.lane }}
use-rtx: false
raw-matrix: ${{ needs.generate-matrix.outputs.matrix }}
rtx:
needs: [decide, generate-matrix]
if: needs.decide.outputs.lane != 'skip' && needs.decide.outputs.backend != 'standard'
uses: ./.github/workflows/_test-linux.yml
with:
lane: ${{ needs.decide.outputs.lane }}
use-rtx: true
name-prefix: "RTX - "
raw-matrix: ${{ needs.generate-matrix.outputs.matrix }}
# python-only runs on EVERY non-skip lane incl. fast: PYTHON_ONLY=1 skips Bazel,
# so the wheel builds cheaply and each push smoke-tests the no-C++-runtime path.
python-only:
needs: [decide, generate-matrix]
if: needs.decide.outputs.lane != 'skip' && needs.decide.outputs.backend != 'rtx'
uses: ./.github/workflows/_test-linux.yml
with:
lane: python-only
python-only: true
name-prefix: "Python-only "
raw-matrix: ${{ needs.generate-matrix.outputs.matrix }}
# python-only against TensorRT-RTX (so backend=both runs BOTH python-only variants).
# Runs on any non-skip lane, but only when an RTX backend is selected.
python-only-rtx:
needs: [decide, generate-matrix]
if: needs.decide.outputs.lane != 'skip' && needs.decide.outputs.backend != 'standard'
uses: ./.github/workflows/_test-linux.yml
with:
lane: python-only
python-only: true
use-rtx: true
name-prefix: "Python-only RTX "
raw-matrix: ${{ needs.generate-matrix.outputs.matrix }}
# ExecuTorch runtime is supported by the standard TensorRT wheel only. Wait
# for the standard channel to upload its wheel artifact, but still build the
# runtime if a standard test fails.
#
# A standard channel that was CANCELLED is different from one that failed a test:
# it uploaded no wheel, so this job has nothing to download and dies with
# "Artifact not found for name: pytorch_tensorrt__<py>_<cu>_x86_64" after burning a
# runner. That is reported as a failure and drags `gate` down with it, which is why
# main shows ten red ExecuTorch rows whenever two commits land close together. The
# standard channel has its own concurrency group, so it can be cancelled on its own
# while this run continues.
executorch-runtime-build:
needs: [decide, generate-matrix, standard]
if: >-
!cancelled() &&
needs.decide.result == 'success' &&
needs.generate-matrix.result == 'success' &&
needs.standard.result != 'cancelled' &&
needs.decide.outputs.lane != 'skip' &&
needs.decide.outputs.backend != 'rtx'
uses: ./.github/workflows/executorch-build-linux.yml
with:
repository: pytorch/tensorrt
ref: ""
test-infra-repository: pytorch/test-infra
test-infra-ref: main
build-matrix: ${{ needs.generate-matrix.outputs.matrix }}
executorch-runtime-test:
needs: [decide, generate-matrix, executorch-runtime-build]
if: >-
always() &&
needs.decide.result == 'success' &&
needs.generate-matrix.result == 'success' &&
needs.decide.outputs.lane != 'skip' &&
needs.decide.outputs.backend != 'rtx' &&
needs.executorch-runtime-build.result == 'success'
uses: ./.github/workflows/executorch-test-linux.yml
with:
repository: pytorch/tensorrt
ref: ""
test-infra-repository: pytorch/test-infra
test-infra-ref: main
build-matrix: ${{ needs.generate-matrix.outputs.matrix }}
# Required check. Fails ONLY on a genuine failure; skipped/cancelled don't block.
gate:
needs: [decide, standard, rtx, python-only, python-only-rtx, executorch-runtime-build, executorch-runtime-test]
if: always()
runs-on: ubuntu-latest
steps:
- name: Gate
run: |
set -euo pipefail
if [ "${{ contains(needs.*.result, 'failure') }}" = "true" ]; then
echo "::error::a Linux x86_64 channel failed — see the channel jobs above"
exit 1
fi
echo "Linux x86_64 gate OK (cancelled/skipped channels ignored)."
# Consolidated, agent-friendly report over this run's suites (informational).
report:
needs: [standard, rtx, python-only, python-only-rtx, executorch-runtime-build, executorch-runtime-test]
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.11"
- uses: actions/download-artifact@v7
with:
pattern: junit-*
path: all-results
merge-multiple: true
- name: Consolidated report
run: |
set -uo pipefail
mkdir -p all-results
if [ -z "$(find all-results -name '*.xml' 2>/dev/null)" ]; then
echo "No JUnit results uploaded." >> "$GITHUB_STEP_SUMMARY"; exit 0
fi
python tests/py/utils/junit_summary.py all-results --agent >> "$GITHUB_STEP_SUMMARY" || true
python tests/py/utils/junit_summary.py all-results || true