Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/_test-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ jobs:
script: |
set -euo pipefail
if [[ "${{ matrix.suite }}" == "executorch-windows" ]]; then
# A development ExecuTorch pin is on the nightly channel, a release pin on the test channel.
# Windows uses torchao's Python-only nightly wheel from the CPU index.
python -m pip install --pre pyyaml \
--extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/nightly/cpu" \
-r packaging/executorch_pin.txt
runtime_wheels=("${RUNNER_TEMP}"/artifacts/torch_tensorrt_executorch_runtime-*.whl)
Expand Down
21 changes: 15 additions & 6 deletions .github/workflows/build_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ jobs:
key: trt-bazel-${{ inputs.architecture }}-${{ matrix.desired_cuda }}-rtx${{ inputs.use-rtx }}-${{ hashFiles('**/MODULE.bazel', '**/WORKSPACE', '**/.bazelrc', '**/dev_dep_versions.yml') }}
restore-keys: |
trt-bazel-${{ inputs.architecture }}-${{ matrix.desired_cuda }}-rtx${{ inputs.use-rtx }}-
# Named before either wheel is built: the main wheel's executorch extra requires exactly this
# Named before either wheel is built: the main wheel's executorch extra can require exactly this
# companion, and the companion build below takes its version from the same variable.
- name: Name the ExecuTorch runtime companion
if: ${{ inputs.build-executorch-runtime }}
Expand All @@ -348,6 +348,13 @@ jobs:
source "${BUILD_ENV_FILE}"
version="$(${CONDA_RUN} python packaging/executorch_runtime_version.py ${{ inputs.is-release-wheel }})"
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION=${version}" >> "${GITHUB_ENV}"
# A release wheel has no CUDA label, the form PyPI needs; its cu132 build goes to PyPI. Any
# other build goes to this run's PyTorch channel.
if [[ ${{ inputs.is-release-wheel }} == true ]]; then
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_CHANNEL=pypi" >> "${GITHUB_ENV}"
else
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_CHANNEL=${CHANNEL}" >> "${GITHUB_ENV}"
fi
- name: Build the wheel (python-build-package)
if: ${{ inputs.build-platform == 'python-build-package' }}
working-directory: ${{ inputs.repository }}
Expand Down Expand Up @@ -447,17 +454,19 @@ jobs:
sys.exit("The main wheel declares no CUDA 13 TensorRT dependencies")
subprocess.check_call([sys.executable, "-m", "pip", "install", *tensorrt])
PY
# The nightly channel is named directly rather than through the channel variable, on release
# rows too, because the pin is a dated development build that only that channel carries.
# The default index stays in the set for the other requirements, which means a pin naming a
# version the default index also publishes could resolve to the processor-only build from
# there. What refuses that is the delegate's own build, which reads the installed
# Both channels that carry a pinned ExecuTorch are named directly rather than through the
# channel variable: a dated development build is only on the nightly channel, and a release
# is on the test channel. The default index stays in the set for the other requirements,
# which means a pin naming a version the default index also publishes could resolve to the
# processor-only build from there. pip prefers the labelled CUDA build of the same version,
# and what refuses the other is the delegate's own build, which reads the installed
# ExecuTorch's local label and stops unless it names a CUDA build, so the failure is a clear
# message rather than a configure error about a missing extension.
# The version itself comes from the requirement file, so moving the pin to a newer
# nightly changes no file in this directory.
${CONDA_RUN} python -m pip install pyyaml patchelf "wheel>=0.40" \
--extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" \
-r packaging/executorch_pin.txt
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION=${TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION:?}"
${CONDA_RUN} python -m pip wheel --no-build-isolation --no-deps --wheel-dir dist \
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/build_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ jobs:
else
export PYTORCH_VERSION="$(${CONDA_RUN} pip show torch | grep ^Version: | sed 's/Version: *//')"
fi
# Named before either wheel is built: the main wheel's executorch extra requires exactly this
# Named before either wheel is built: the main wheel's executorch extra can require exactly this
# companion, and the companion build below takes its version from the same variable.
- name: Name the ExecuTorch runtime companion
if: ${{ inputs.build-executorch-runtime && inputs.architecture == 'x64' && !inputs.cross-compile && !inputs.python-only && !inputs.use-rtx && !inputs.is-release-tarball }}
Expand All @@ -439,6 +439,12 @@ jobs:
source "${BUILD_ENV_FILE}"
version="$(${CONDA_RUN} python packaging/executorch_runtime_version.py ${{ inputs.is-release-wheel }})"
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION=${version}" >> "${GITHUB_ENV}"
# A release wheel has the form PyPI needs, and PyPI's Windows ExecuTorch is the CPU build the
# delegate cannot load, so it records no channel and its extra leaves the delegate out. Any
# other build goes to this run's PyTorch channel.
if [[ ${{ inputs.is-release-wheel }} != true ]]; then
echo "TORCH_TENSORRT_EXECUTORCH_RUNTIME_CHANNEL=${CHANNEL}" >> "${GITHUB_ENV}"
fi
- name: Build the wheel (python-build-package) X64
if: ${{ inputs.build-platform == 'python-build-package' && inputs.architecture == 'x64' && inputs.cross-compile == false }}
working-directory: ${{ inputs.repository }}
Expand Down Expand Up @@ -490,17 +496,22 @@ jobs:
else
${CONDA_RUN} ${ENV_SCRIPT} python setup.py bdist_wheel ${BUILD_PARAMS}
fi
# A release wheel has the form PyPI needs, and the delegate cannot load PyPI's Windows
# ExecuTorch, so its job builds no delegate. The version is still recorded above for the install
# advice.
- name: Build the ExecuTorch runtime wheel
if: ${{ env.TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION != '' }}
if: ${{ env.TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION != '' && !inputs.is-release-wheel }}
working-directory: ${{ inputs.repository }}
run: |
set -euxo pipefail
source "${BUILD_ENV_FILE}"
case "${CU_VERSION}" in cu132|cu134) ;; *) echo "Unsupported ExecuTorch CUDA row: ${CU_VERSION}" >&2; exit 1 ;; esac
${CONDA_RUN} python -m pip install --no-deps dist/torch_tensorrt-*.whl
# A development ExecuTorch pin is on the nightly channel, a release pin on the test channel.
# Windows uses torchao's Python-only nightly wheel from the CPU index.
${CONDA_RUN} python -m pip install --pre "cmake>=3.28" ninja pyyaml "wheel>=0.40" \
--extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/nightly/cpu" \
-r packaging/executorch_pin.txt
# The core build has fetched the TensorRT SDK containing headers and import libraries.
Expand Down
31 changes: 22 additions & 9 deletions .github/workflows/executorch-test-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,14 @@ jobs:
chmod +x "${RUNNER_TEMP}/bin/bazel"
export PATH="${RUNNER_TEMP}/bin:${PATH}"

# ExecuTorch's CUDA wheels live only on the PyTorch nightly index, so the channel is
# needed. No --pre: a specifier naming a prerelease admits prereleases by itself, and
# --pre would apply to every other requirement in the same command too. The version
# comes from the requirement file so a bump changes no file in this directory.
# ExecuTorch's CUDA wheels live only on the PyTorch indexes: a development build on the
# nightly one, a release on the test one. No --pre: a specifier naming a prerelease admits
# prereleases by itself, and --pre would apply to every other requirement in the same
# command too. The version comes from the requirement file so a bump changes no file in
# this directory.
python -m pip install pyyaml "wheel>=0.40" \
--extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" \
-r packaging/executorch_pin.txt

# The shared artifact carries the matching core and companion wheels.
Expand Down Expand Up @@ -108,31 +110,42 @@ jobs:
# Resolve the user-facing range without reusing the build's installed pin.
python -m venv "${RUNNER_TEMP}/range-check-venv"
# pin-check: range-ok
"${RUNNER_TEMP}/range-check-venv/bin/python" -m pip install --no-deps --extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" -r packaging/executorch_range.txt
"${RUNNER_TEMP}/range-check-venv/bin/python" -m pip install --no-deps --extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" --extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" -r packaging/executorch_range.txt

# pip does not fail when an extra cannot be satisfied; it quietly picks an older
# torch-tensorrt. So check here that the main wheel's executorch extra requires exactly the
# companion built beside it, and that pip resolves that extra for the version just built.
# torch-tensorrt. So check here that the executorch extra requires exactly the companion
# built beside it when this run's channel also carries the ExecuTorch build that companion
# pins (nightly for a development build, test for a release), that it requires none
# otherwise, and that pip resolves that extra for the version just built.
python - <<'PY'
import importlib.metadata as metadata
import os
import sys

from packaging.requirements import Requirement

companion = metadata.version("torch-tensorrt-executorch-runtime")
(executorch,) = [
r
for r in map(Requirement, metadata.requires("torch-tensorrt-executorch-runtime") or [])
if r.name == "executorch"
]
executorch_channel = "nightly" if ".dev" in str(executorch.specifier) else "test"
pins = [
r
for r in map(Requirement, metadata.requires("torch-tensorrt") or [])
if r.name == "torch-tensorrt-executorch-runtime"
and r.marker is not None
and r.marker.evaluate({"extra": "executorch"})
]
if [str(r.specifier) for r in pins] != [f"=={companion}"]:
sys.exit(f"the executorch extra requires {pins}, not the companion built beside it ({companion})")
expected = [f"=={companion}"] if os.environ["CHANNEL"] == executorch_channel else []
if [str(r.specifier) for r in pins] != expected:
sys.exit(f"the executorch extra requires {pins}, not {expected} (companion {companion}, channel {os.environ['CHANNEL']}, {executorch})")
PY
built="$(python -c 'import importlib.metadata as m; print(m.version("torch-tensorrt"))')"
python -m pip install --pre --dry-run --find-links /opt/torch-tensorrt-builds \
--extra-index-url "https://download.pytorch.org/whl/nightly/${CU_VERSION}" \
--extra-index-url "https://download.pytorch.org/whl/test/${CU_VERSION}" \
--extra-index-url https://pypi.nvidia.com \
"torch-tensorrt[executorch]==${built}"

Expand Down
7 changes: 7 additions & 0 deletions docsrc/RELEASE_CHECKLIST.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,10 @@ will result in a minor version bump and significant bug fixes will result in a p
- TODO: Build a manylinux container for aarch64
- `docker run -it -v$(pwd)/..:/workspace/Torch-TensorRT build_torch_tensorrt_wheel /bin/bash /workspace/Torch-TensorRT/py/build_whl.sh` generates all wheels
- To build container `docker build -t build_torch_tensorrt_wheel .`

7. Publish ExecuTorch and the ExecuTorch delegate before torch-tensorrt
- Before building the release wheels, move the ExecuTorch pin to an ExecuTorch release that has CUDA wheels, in every pin site that `.github/scripts/update_executorch_pin.py` lists (`dev_dep_versions.yml`, `MODULE.bazel`, `packaging/executorch_pin.txt` and the rest). While the pin is a development build, a release wheel's `executorch` extra leaves out `torch-tensorrt-executorch-runtime`.
- When a release pins an ExecuTorch release, its `executorch` extra requires `torch-tensorrt-executorch-runtime`. If pip cannot find that package, it does not fail. It quietly installs an older torch-tensorrt, which brings no delegate.
- Stable index: in pytorch/test-infra, set `TORCH_TENSORRT_EXECUTORCH_RUNTIME_VERSION` in `release/release_versions.sh` with the other release versions. Then promote `executorch`, then `torch_tensorrt_executorch_runtime`, then `torch_tensorrt`.
- PyPI: the release workflows build every wheel for cu132 and cu134. Release wheels carry no CUDA label, so the cu132 and cu134 wheels share file names and only one set can go to PyPI. Upload the cu132 set, because PyTorch's and ExecuTorch's Linux wheels on PyPI are CUDA 13.2 builds. First check that `executorch` is on PyPI and that its Linux wheels are its CUDA 13.2 build. Then upload the cu132 Linux `torch-tensorrt-executorch-runtime` wheels, then the cu132 `torch-tensorrt` wheels. Do not upload the Windows delegate: PyPI's Windows ExecuTorch is the CPU build, which the delegate cannot load.
- Then check on Linux, in a fresh environment, that `pip install --dry-run "torch_tensorrt[executorch]"` lists `torch-tensorrt-executorch-runtime`.
59 changes: 29 additions & 30 deletions docsrc/user_guide/runtime_performance/executorch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,18 @@ program, so the whole model stays on the GPU.
Installation
-------------

Install Torch-TensorRT with the ``executorch`` extra from the PyTorch channel for your CUDA
version. Swap ``cu132`` for ``cu134`` on CUDA 13.4:
One command installs everything: PyTorch, Torch-TensorRT, TensorRT, the CUDA build of
ExecuTorch, and the TensorRT delegate. Use a fresh virtual environment.

.. code-block:: bash

pip install "torch-tensorrt[executorch]" \
--index-url https://download.pytorch.org/whl/cu132 \
--extra-index-url https://pypi.org/simple

The PyTorch channel is needed because the CUDA build of ExecuTorch is published only there.

What the command installs
^^^^^^^^^^^^^^^^^^^^^^^^^^
Releases
^^^^^^^^^

* ExecuTorch, the CUDA build, from the ``executorch`` extra. That is all you need to export.
* ``torch-tensorrt-executorch-runtime``, one shared library holding the TensorRT delegate,
which you need to run a ``.pte``. The extra installs the one built together with your
Torch-TensorRT wheel, for the same CUDA version. It requires the exact ExecuTorch build
it was compiled against, so you get that one rather than the newest.
.. code-block:: bash

This works for the standard Linux (x86-64 and aarch64) and Windows x86-64 wheels. On aarch64
it needs glibc 2.35 or newer, the same as TensorRT itself. The TensorRT-RTX and Python-only
builds have no delegate.
pip install "torch_tensorrt[executorch]"

Use a fresh virtual environment. To export a coalesced program you also need a CUDA toolkit,
because ExecuTorch's CUDA backend compiles the leftover operators with ``nvcc``.
This installs the CUDA 13.2 builds. On Windows, PyPI has only the CPU builds of PyTorch and
ExecuTorch, so add ``--extra-index-url https://download.pytorch.org/whl/cu132``.

Nightly builds
^^^^^^^^^^^^^^^
Expand All @@ -63,15 +49,28 @@ To pick up a change before it ships, or to report a problem against ``main``:

.. code-block:: bash

pip install --pre --upgrade "torch-tensorrt[executorch]" \
--index-url https://download.pytorch.org/whl/nightly/cu132 \
--extra-index-url https://pypi.org/simple
pip install --pre "torch_tensorrt[executorch]" --index-url https://download.pytorch.org/whl/nightly/cu132

Swap ``cu132`` for ``cu134`` on CUDA 13.4.

* ``--pre`` is required. Without it pip takes the stable release instead.
* ``--upgrade`` is required if a nightly is already installed, or pip keeps the old one and
tells you nothing.
* PyPI stays in the list because TensorRT is not published on the nightly channel.
* Keep PyTorch, ExecuTorch and Torch-TensorRT on the same channel.
What these commands install
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

* PyTorch and TensorRT, which Torch-TensorRT depends on.
* ExecuTorch, the CUDA build. That is all you need to export.
* ``torch-tensorrt-executorch-runtime``, one shared library holding the TensorRT delegate,
which you need to run a ``.pte``. It is the one built together with your Torch-TensorRT wheel,
for the same CUDA version. It requires the exact ExecuTorch build it was compiled against, so
you get that one rather than the newest.

A wheel you build yourself does not bring the delegate. Build it as well, as the runtime wheel
README shows.

The delegate is built for the standard Linux wheels (x86-64 and aarch64), and for Windows x86-64.
On aarch64 it needs glibc 2.35 or newer, the same as TensorRT itself.
The TensorRT-RTX and Python-only builds have no delegate. To export a coalesced program you also
need a CUDA toolkit, because ExecuTorch's CUDA backend compiles the leftover operators with
``nvcc``.

----

Expand Down
Loading
Loading