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
1 change: 0 additions & 1 deletion .ci/docker/common/install_cuda_windows_cross_compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ INSTALL_DIR="${WINDOWS_CUDA_INSTALL_DIR:-/opt/cuda-windows}"
# Mapping of CUDA versions to their corresponding driver versions for Windows installers
# Source: https://developer.nvidia.com/cuda-toolkit-archive
declare -A CUDA_DRIVER_MAP=(
["12.6"]="12.6.3:561.17"
["12.8"]="12.8.1:572.61"
["12.9"]="12.9.1:576.57"
["13.0"]="13.0.2:"
Expand Down
4 changes: 2 additions & 2 deletions .ci/scripts/cuda_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ def to_v3_format(
workflow_run_id: GitHub workflow run ID
workflow_run_url: GitHub workflow run URL
gpu_name: GPU device name (e.g., "Tesla V100", "A100")
cuda_driver_version: CUDA driver version (e.g., "12.6", "535.104.05")
cuda_driver_version: CUDA driver version (e.g., "13.0", "535.104.05")
Returns:
List of benchmark records in v3 format
Expand Down Expand Up @@ -873,7 +873,7 @@ def main():
"--cuda_driver_version",
type=str,
default=None,
help="CUDA driver version (e.g., '12.6', '535.104.05') - optional for v3 format",
help="CUDA driver version (e.g., '13.0', '535.104.05') - optional for v3 format",
)
parser.add_argument("--verbose", action="store_true", help="Print verbose output")

Expand Down
4 changes: 2 additions & 2 deletions .ci/scripts/tests/test_cu134_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_all_install_steps_preserve_exact_cu134_selection(self):
)

def test_other_cuda_trains_keep_existing_pins(self):
for cuda in ((12, 6), (13, 0), (13, 2)):
for cuda in ((13, 0), (13, 2)):
for machine in ("x86_64", "aarch64"):
with self.subTest(cuda=cuda, machine=machine):
core, local, domains, examples = self.install_commands(
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_cpu_release_dependencies_are_opt_in(self):
)

def test_cpu_release_option_keeps_cuda_pins(self):
for cuda in ((12, 6), (13, 0), (13, 2), (13, 4)):
for cuda in ((13, 0), (13, 2), (13, 4)):
for machine in ("x86_64", "aarch64"):
with self.subTest(cuda=cuda, machine=machine):
self.assertEqual(
Expand Down
8 changes: 2 additions & 6 deletions .ci/scripts/tests/test_cuda_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ def _model_quant(entry):
class CudaWorkflowTest(unittest.TestCase):
def test_build_matrix_preserves_existing_cuda_versions(self):
job = WORKFLOW["jobs"]["test-cuda-builds"]
self.assertEqual(
job["strategy"]["matrix"]["cuda-version"], ["12.6", "13.0", "13.4"]
)
self.assertEqual(job["strategy"]["matrix"]["cuda-version"], ["13.0", "13.4"])
self.assertEqual(job["with"]["gpu-arch-version"], "${{ matrix.cuda-version }}")

def test_cuda_builds_take_the_node_driver_on_an_unpinned_v3(self):
Expand All @@ -58,9 +56,7 @@ def test_cuda_runtime_update_precedes_build_and_propagates_failure(self):
source() { printf 'BUILD %s\n' "$*"; printf 'LIBRARY PATH %s\n' "$LD_LIBRARY_PATH"; }
"""
for version, conda_status in (
(version, status)
for version in ("12.6", "13.0", "13.4")
for status in (0, 1)
(version, status) for version in ("13.0", "13.4") for status in (0, 1)
):
with self.subTest(version=version, conda_status=conda_status):
result = subprocess.run(
Expand Down
25 changes: 0 additions & 25 deletions .ci/scripts/wheel/cuda_arch_list.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,6 @@ _cuda_arch_aarch64_cu130="8.0 9.0 10.0 11.0 12.0"
_cuda_arch_aarch64_cu132="${_cuda_arch_aarch64_cu130}"
_cuda_arch_aarch64_cu134="${_cuda_arch_aarch64_cu130}"

# The older CUDA train.
#
# The two architectures do not carry identical lists, because each covers what the published PyTorch
# build for that architecture covers, and those differ. Matching them to each other instead would mean
# advertising a GPU on one architecture that PyTorch cannot serve there.
#
# The smaller embedded modules are deliberately absent, with one exception. An embedded-only
# architecture in a generic wheel would advertise a device the row cannot otherwise serve, since
# those devices also need the CUDA, TensorRT and PyTorch pinned by their own software release
# rather than the ones a generic wheel resolves.
#
# 8.7 is that exception. This is the only row whose CUDA major matches what that module's software
# release ships, and the wheel declares no PyTorch, so the user supplies the build that carries
# their architecture. Omitting it does not protect them from a bad pairing, it only removes the
# device code they need.
#
# The floor is 8.0 rather than the oldest architecture PyTorch still carries. One of these sources compiles
# an integer matrix-multiply path only at 8.0 and newer, so an older architecture would get a delegate that
# loads, runs most models, and fails on one that needs that operator. Claiming hardware the delegate only
# partly serves is the same problem the embedded modules have, so the row leaves it out for the same reason.
_cuda_arch_x86_64_cu126="8.0 8.6 8.9 9.0"
_cuda_arch_aarch64_cu126="8.0 8.7 9.0"

# A CUDA train with no architecture list would leave the build detecting the builder's GPU, which is
# the failure this file exists to prevent. Adding a train to the release matrix without adding its
# architectures should fail loudly rather than silently produce a single-GPU wheel.
Expand Down Expand Up @@ -103,7 +80,6 @@ executorch_cuda_arch_list() {
case "${machine}" in
aarch64 | arm64)
case "${train}" in
126) printf '%s' "${_cuda_arch_aarch64_cu126}" ;;
130) printf '%s' "${_cuda_arch_aarch64_cu130}" ;;
132) printf '%s' "${_cuda_arch_aarch64_cu132}" ;;
134) printf '%s' "${_cuda_arch_aarch64_cu134}" ;;
Expand All @@ -112,7 +88,6 @@ executorch_cuda_arch_list() {
;;
x86_64)
case "${train}" in
126) printf '%s' "${_cuda_arch_x86_64_cu126}" ;;
130) printf '%s' "${_cuda_arch_x86_64_cu130}" ;;
132) printf '%s' "${_cuda_arch_x86_64_cu132}" ;;
134) printf '%s' "${_cuda_arch_x86_64_cu134}" ;;
Expand Down
6 changes: 3 additions & 3 deletions .ci/scripts/wheel/test_shared_libraries.py
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ def _wheel_cuda_train() -> str:
"""The CUDA train the installed wheel was built for, or "" for a CPU wheel.
Read from the local version segment, which is the only place the wheel states what
it was built for. `1.5.0+cu126` gives "126".
it was built for. `1.5.0+cu132` gives "132".
"""
local = importlib.metadata.version("executorch").partition("+")[2]
return local[2:] if local.startswith("cu") else ""
Expand Down Expand Up @@ -1360,7 +1360,7 @@ def _resolve_required(required):
),
# The CUDA components. Required exactly when the wheel says it is a CUDA wheel,
# which is decided at check time rather than here: a fixed False meant a wheel
# tagged +cu126 carrying no CUDA library at all passed every check in this file,
# tagged +cu132 carrying no CUDA library at all passed every check in this file,
# while a fixed True would fail every CPU wheel. The marker is the string these
# rows are keyed on below.
(
Expand Down Expand Up @@ -1457,7 +1457,7 @@ def test_each_component_has_one_owner() -> None:
shipped = {path.name for path in _shipped_shared_objects(_installed_package_dir())}
for what, symbols, owner, required in _OWNED_COMPONENTS:
# Resolved here rather than in the table, because it depends on the installed
# wheel. A fixed False let a wheel tagged +cu126 ship with no CUDA library at
# wheel. A fixed False let a wheel tagged +cu132 ship with no CUDA library at
# all and still pass, which is the whole point of the conditional rows.
required = _resolve_required(required)
present = any(name.startswith(owner) for name in shipped)
Expand Down
11 changes: 2 additions & 9 deletions .github/scripts/filter_cuda_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,6 @@
# Skip wholly absent trains so an upstream removal cannot block the remaining releases.
# Offered trains must still cover every supported Python version.
#
# cu126 was the floor until PyTorch stopped offering it on the nightly channel. The generator
# still offers it when a release is cut, so keeping it here would publish a train that no
# nightly has built since, and a release is the wrong place to find out that it no longer
# builds. A machine on CUDA 12.6 can still build from source, where the pinned torch comes
# from a channel that carries 12.6.
#
# cu130 is not published. PyTorch keeps it on its nightly builds only as a temporary hold for
# other projects, and its release-candidate builds do not carry it, so a release would have
# no cu130 train even while nightlies do.
Expand Down Expand Up @@ -91,9 +85,8 @@
# version. Kept empty on purpose today, so no Jetson row is emitted.
#
# Published PyTorch stopped shipping sm_87 device code after 2.8.0, so a Jetson row today
# would produce a wheel whose PyTorch dependency cannot execute on the device. The aarch64
# CUDA 12.6 row, which was the one that compiled sm_87 device code for an embedded module,
# is no longer published either. Populate this when both change.
# would produce a wheel whose PyTorch dependency cannot execute on the device, and no
# published row compiles sm_87 device code. Populate this when both change.
#
# Because both lists are empty, asking for the JetPack rows can only produce an empty result.
# No workflow asks, and the request is rejected up front with that reason rather than left to
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/cuda.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Test ExecuTorch CUDA Build Compatibility
# This workflow tests whether ExecuTorch can be successfully built with CUDA support
# across different CUDA versions (12.6, 13.0, 13.4) using the command:
# across different CUDA versions (13.0, 13.4) using the command:
# ./install_executorch.sh
#
# It also runs model accuracy (e2e EXPECTED_OUTPUT checks) and, for the perf
Expand Down Expand Up @@ -142,7 +142,7 @@ jobs:
strategy:
fail-fast: false
matrix:
cuda-version: ["12.6", "13.0", "13.4"]
cuda-version: ["13.0", "13.4"]

name: test-executorch-cuda-build-${{ matrix.cuda-version }}
uses: pytorch/test-infra/.github/workflows/linux_job_v3.yml@main
Expand All @@ -159,8 +159,8 @@ jobs:
script: |
set -eux
# AOTI model libraries need a newer C++ runtime than the 12.6 image's
# system library; the 13.4 image also needs the thread-local cleanup fix.
# AOTI model libraries need a newer C++ runtime than the image's system
# library; the 13.4 image also needs the thread-local cleanup fix.
conda install -y -n base -c conda-forge 'libstdcxx-ng=16.2.0' 'libgcc-ng=16.2.0'
export LD_LIBRARY_PATH="/opt/conda/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
source .ci/scripts/test-cuda-build.sh "${{ matrix.cuda-version }}"
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/vulkan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ jobs:
timeout: 120
runner: mt-l-x86aavx2-11-41-a10g
gpu-arch-type: cuda
gpu-arch-version: "12.6"
gpu-arch-version: "13.2"
submodules: recursive
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
script: |
Expand Down Expand Up @@ -171,7 +171,7 @@ jobs:
timeout: 180
runner: mt-l-x86aavx2-11-41-a10g
gpu-arch-type: cuda
gpu-arch-version: "12.6"
gpu-arch-version: "13.2"
submodules: recursive
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
upload-artifact: vulkan-llm-e2e
Expand Down
2 changes: 1 addition & 1 deletion docs/source/backends/cuda/cuda-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Below are the requirements for running a CUDA-delegated ExecuTorch model:
- **Hardware**: NVIDIA GPU with compute capability 8.0 (Ampere) or newer. This is the floor the
prebuilt packages are built for.
- **CUDA**: 13 for the prebuilt packages. On Linux they bring the CUDA runtime with them. On
Windows it comes from a CUDA 13 toolkit install. A build from source also supports CUDA 12.6.
Windows it comes from a CUDA 13 toolkit install. A build from source also supports CUDA 13.0.
- **Operating System**: Linux, or Windows from C++ for programs exported on Linux (see
[CUDA on Windows](../../using-executorch-cpp.md#cuda-on-windows))
- **Drivers**: An NVIDIA driver that supports the CUDA version you use: CUDA 13 for the prebuilt
Expand Down
9 changes: 4 additions & 5 deletions install_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
# Supported CUDA versions - modify this to add/remove supported versions
# Format: tuple of (major, minor) version numbers
SUPPORTED_CUDA_VERSIONS = (
(12, 6),
(13, 0),
(13, 2),
(13, 4),
Expand Down Expand Up @@ -114,7 +113,7 @@ def _get_cuda_version():
_selected_nvcc(), capture_output=True, text=True, check=True
)
# Parse nvcc output for CUDA version
# Output contains line like "Cuda compilation tools, release 12.6, V12.6.68"
# Output contains line like "Cuda compilation tools, release 13.0, V13.0.88"
match = re.search(r"release (\d+)\.(\d+)", nvcc_result.stdout)
if match:
major, minor = int(match.group(1)), int(match.group(2))
Expand Down Expand Up @@ -301,11 +300,11 @@ def _cuda_version_to_pytorch_suffix(major, minor):
Generate PyTorch CUDA wheel suffix from CUDA version numbers.
Args:
major: CUDA major version (e.g., 12)
minor: CUDA minor version (e.g., 6)
major: CUDA major version (e.g., 13)
minor: CUDA minor version (e.g., 2)
Returns:
PyTorch wheel suffix string (e.g., "cu126")
PyTorch wheel suffix string (e.g., "cu132")
"""
return f"cu{major}{minor}"

Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,9 @@ def _cuda_train() -> str:
Raises when a release row names a train the installed toolkit does not provide. The
declared packages and the loader paths both come from this value, so disagreeing with
the toolkit that compiled the libraries produces a wheel that installs cleanly and then
cannot load: a cu126 row built against a 13.0 toolkit declares the CUDA 12 runtime for
binaries that need libcudart.so.13.
the toolkit that compiled the libraries produces a wheel that installs cleanly but
declares a train it was not compiled for, such as a cu134 row built against a 13.2
toolkit.
"""
# An explicit OFF first, ahead of the release field. A CPU row on a builder that has a
# toolkit installed sets both, so reading the row field first would declare a runtime
Expand Down
Loading