diff --git a/.github/workflows/build-wheel.yml b/.github/workflows/build-wheel.yml
index b3fd248539f..e2729dc2752 100644
--- a/.github/workflows/build-wheel.yml
+++ b/.github/workflows/build-wheel.yml
@@ -223,7 +223,7 @@ jobs:
- name: Build cuda.bindings wheel
if: ${{ env.BUILD_BINDINGS == 'true' }}
- uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
+ uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae # v4.2.1
with:
package-dir: ./cuda_bindings/
output-dir: ${{ env.CUDA_BINDINGS_ARTIFACTS_DIR }}
@@ -231,11 +231,6 @@ jobs:
CIBW_BUILD: ${{ env.CIBW_BUILD }}
CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"'
CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel'
- # TODO: remove cpython-prerelease once 3.15 is officially supported
- # Allow CPython pre-release builds (currently 3.15 / 3.15t). This is a
- # no-op for stable Python versions because CIBW_BUILD still filters
- # the target version.
- CIBW_ENABLE: cpython-prerelease
# CIBW mounts the host filesystem under /host
CIBW_ENVIRONMENT_LINUX: >
CUDA_PATH=/host/${{ env.CUDA_PATH }}
@@ -330,7 +325,7 @@ jobs:
- name: Build cuda.core wheel
if: ${{ env.BUILD_CORE == 'true' }}
- uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
+ uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae # v4.2.1
with:
package-dir: ./cuda_core/
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
@@ -338,11 +333,6 @@ jobs:
CIBW_BUILD: ${{ env.CIBW_BUILD }}
CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"'
CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel'
- # TODO: remove cpython-prerelease once 3.15 is officially supported
- # Allow CPython pre-release builds (currently 3.15 / 3.15t). This is a
- # no-op for stable Python versions because CIBW_BUILD still filters
- # the target version.
- CIBW_ENABLE: cpython-prerelease
# CIBW mounts the host filesystem under /host
CIBW_ENVIRONMENT_LINUX: >
CUDA_PATH=/host/${{ env.CUDA_PATH }}
@@ -459,8 +449,6 @@ jobs:
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
- # TODO: remove allow-prereleases once 3.15 is officially supported
- allow-prereleases: ${{ startsWith(matrix.python-version, '3.15') }}
- name: Enable Scientific Python Nightly Wheels for Python 3.15
if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true') && startsWith(matrix.python-version, '3.15') }}
@@ -624,7 +612,7 @@ jobs:
- name: Build cuda.core wheel
if: ${{ !inputs.single-cuda-major && env.BUILD_CORE == 'true' }}
- uses: pypa/cibuildwheel@4726cd35bb13f7bde50cf2761f2499ac7b3aa32c # v4.1.1
+ uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae # v4.2.1
with:
package-dir: ./cuda_core/
output-dir: ${{ env.CUDA_CORE_ARTIFACTS_DIR }}
@@ -632,11 +620,6 @@ jobs:
CIBW_BUILD: ${{ env.CIBW_BUILD }}
CIBW_BEFORE_BUILD_LINUX: 'python -m pip install --upgrade "pip>=25.3"'
CIBW_BEFORE_BUILD_WINDOWS: 'python -m pip install --upgrade "pip>=25.3" delvewheel'
- # TODO: remove cpython-prerelease once 3.15 is officially supported
- # Allow CPython pre-release builds (currently 3.15 / 3.15t). This is a
- # no-op for stable Python versions because CIBW_BUILD still filters
- # the target version.
- CIBW_ENABLE: cpython-prerelease
# CIBW mounts the host filesystem under /host
CIBW_ENVIRONMENT_LINUX: >
CUDA_PATH=/host/${{ env.CUDA_PATH }}
diff --git a/.github/workflows/test-wheel-linux.yml b/.github/workflows/test-wheel-linux.yml
index a44279cc27f..8561579916c 100644
--- a/.github/workflows/test-wheel-linux.yml
+++ b/.github/workflows/test-wheel-linux.yml
@@ -110,8 +110,6 @@ jobs:
fail-fast: false
matrix: ${{ fromJSON(needs.compute-matrix.outputs.MATRIX) }}
runs-on: "${{ matrix.FLAVOR || 'linux' }}-${{ matrix.ARCH }}-gpu-${{ matrix.GPU }}-${{ matrix.RUNNER_DRIVER }}-${{ matrix.GPU_COUNT }}"
- # TODO: remove continue-on-error once 3.15 is officially supported
- continue-on-error: ${{ startsWith(matrix.PY_VER, '3.15') }}
# The build stage could fail but we want the CI to keep moving.
if: ${{ github.repository_owner == 'nvidia' && !cancelled() }}
# Our self-hosted runners require a container
@@ -324,8 +322,6 @@ jobs:
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.PY_VER }}
- # TODO: remove allow-prereleases once 3.15 is officially supported
- allow-prereleases: ${{ startsWith(matrix.PY_VER, '3.15') }}
env:
# we use self-hosted runners on which setup-python behaves weirdly (Python include can't be found)...
AGENT_TOOLSDIRECTORY: "/opt/hostedtoolcache"
diff --git a/.github/workflows/test-wheel-windows.yml b/.github/workflows/test-wheel-windows.yml
index 93cfaef81e1..bb9f6099404 100644
--- a/.github/workflows/test-wheel-windows.yml
+++ b/.github/workflows/test-wheel-windows.yml
@@ -101,8 +101,6 @@ jobs:
fail-fast: false
matrix: ${{ fromJSON(needs.compute-matrix.outputs.MATRIX) }}
if: ${{ github.repository_owner == 'nvidia' && !cancelled() }}
- # TODO: remove continue-on-error once 3.15 is officially supported
- continue-on-error: ${{ startsWith(matrix.PY_VER, '3.15') }}
runs-on: "windows-${{ matrix.ARCH }}-gpu-${{ matrix.GPU }}-${{ matrix.RUNNER_DRIVER }}-${{ matrix.GPU_COUNT }}"
steps:
- name: Checkout ${{ github.event.repository.name }}
@@ -304,8 +302,6 @@ jobs:
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.PY_VER }}
- # TODO: remove allow-prereleases once 3.15 is officially supported
- allow-prereleases: ${{ startsWith(matrix.PY_VER, '3.15') }}
- name: Enable Scientific Python Nightly Wheels for Python 3.15
if: ${{ (env.TEST_BINDINGS == 'true' || env.TEST_CORE == 'true' || env.TEST_PYTHON == 'true') &&
diff --git a/ci/test-matrix.yml b/ci/test-matrix.yml
index 6da0a99bc5e..bf4c77760a8 100644
--- a/ci/test-matrix.yml
+++ b/ci/test-matrix.yml
@@ -59,9 +59,14 @@ linux:
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '1', DRIVER: 'latest' }
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.3.0', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
- # No Python 3.15 test jobs on this release branch: the build uses CUDA 13.4.2
- # while these jobs test on 13.3.0, so they install published cuda-bindings
- # 13.3.x, which has no cp315 wheels. 1.2.1 ships no 3.15 wheels either.
+ # Python 3.15 jobs test against published cuda-bindings, like every other
+ # job on this branch. cuda-bindings 13.4.4 is the first release with cp315
+ # wheels. A test CUDA version of 13.4 matches the build version, so env-vars
+ # would select the bindings built in this run; the ENV values below select
+ # the published 13.4.* release instead, with the settings that env-vars uses
+ # for published bindings.
+ - { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', ENV: { BINDINGS_SOURCE: 'published', SKIP_CUDA_BINDINGS_TEST: '1', SKIP_CYTHON_TEST: '1' } }
+ - { ARCH: 'amd64', PY_VER: '3.15t', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', ENV: { BINDINGS_SOURCE: 'published', SKIP_CUDA_BINDINGS_TEST: '1', SKIP_CYTHON_TEST: '1' } }
# linux-aarch64
- { ARCH: 'arm64', PY_VER: '3.10', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest' }
- { ARCH: 'arm64', PY_VER: '3.10', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest' }
@@ -135,7 +140,8 @@ windows:
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '12.9.1', LOCAL_CTK: '1', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'TCC' }
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.0.2', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
- { ARCH: 'amd64', PY_VER: '3.14t', CUDA_VER: '13.3.0', LOCAL_CTK: '0', GPU: 'a100', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
- # No Python 3.15 test job here either; see the linux-64 note above.
+ # Python 3.15 tests against published cuda-bindings; see the linux-64 note above.
+ - { ARCH: 'amd64', PY_VER: '3.15', CUDA_VER: '13.4.2', LOCAL_CTK: '0', GPU: 'l4', GPU_COUNT: '1', DRIVER: 'latest', DRIVER_MODE: 'MCDM', ENV: { BINDINGS_SOURCE: 'published', SKIP_CUDA_BINDINGS_TEST: '1', SKIP_CYTHON_TEST: '1' } }
# special runners
- { ARCH: 'amd64', PY_VER: '3.14', CUDA_VER: '13.3.0', LOCAL_CTK: '1', GPU: 't4', GPU_COUNT: '2', DRIVER: 'latest', DRIVER_MODE: 'TCC' }
- { ARCH: 'amd64', PY_VER: '3.14', CUDA_VER: '13.3.0', LOCAL_CTK: '0', GPU: 'h100', GPU_COUNT: '2', DRIVER: 'latest', DRIVER_MODE: 'MCDM' }
diff --git a/ci/tools/download-wheels b/ci/tools/download-wheels
index 20f31fb73d5..58e8a213226 100755
--- a/ci/tools/download-wheels
+++ b/ci/tools/download-wheels
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
-# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
@@ -56,13 +56,6 @@ do
continue
fi
- # TODO: remove the Python 3.15 exclusion once 3.15 is officially supported
- # exclude pre-release Python (3.15) wheels from releasing
- if [[ "${p}" == *python315* ]]; then
- echo "Skipping pre-release Python artifact: $p"
- continue
- fi
-
# If we're not downloading "all", only process matching component
if [[ "$COMPONENT" != "all" && "$p" != ${COMPONENT}* ]]; then
continue
diff --git a/cuda_core/docs/source/install.rst b/cuda_core/docs/source/install.rst
index ee7a3838e64..ac73ebef169 100644
--- a/cuda_core/docs/source/install.rst
+++ b/cuda_core/docs/source/install.rst
@@ -26,7 +26,7 @@ dependencies are as follows:
.. [#f1] Including ``cuda-python``.
-``cuda.core`` supports Python 3.10 - 3.14, on Linux (x86-64, arm64) and Windows (x86-64, arm64). Windows on ARM (arm64) wheels are provided for CUDA 13 only and for Python 3.11 and newer, and require ``cuda.bindings`` 13.4.1 or newer. **Experimental** free-threaded builds for Python 3.14 are also provided.
+``cuda.core`` supports Python 3.10 - 3.15, on Linux (x86-64, arm64) and Windows (x86-64, arm64). Windows on ARM (arm64) wheels are provided for CUDA 13 only and for Python 3.11 and newer, and require ``cuda.bindings`` 13.4.1 or newer. Python 3.15 requires ``cuda.bindings`` 13.4.4 or newer, the first release with Python 3.15 wheels, so Python 3.15 is supported with CUDA 13 only. **Experimental** free-threaded builds for Python 3.14 and 3.15 are also provided.
Free-threading Build Support
diff --git a/cuda_core/docs/source/release/1.2.2-notes.rst b/cuda_core/docs/source/release/1.2.2-notes.rst
new file mode 100644
index 00000000000..ab0c2d81f65
--- /dev/null
+++ b/cuda_core/docs/source/release/1.2.2-notes.rst
@@ -0,0 +1,15 @@
+.. SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+.. SPDX-License-Identifier: Apache-2.0
+
+.. currentmodule:: cuda.core
+
+``cuda.core`` 1.2.2 Release Notes
+=================================
+
+New features
+------------
+
+- Added wheels for Python 3.15, including the experimental free-threaded
+ build. On Python 3.15, ``cuda.core`` requires ``cuda.bindings`` 13.4.4 or
+ newer, the first release with Python 3.15 wheels, so Python 3.15 is
+ supported with CUDA 13 only. Python 3.10 remains supported.
diff --git a/cuda_core/docs/source/support.rst b/cuda_core/docs/source/support.rst
index 3a6548ce204..9f450adec92 100644
--- a/cuda_core/docs/source/support.rst
+++ b/cuda_core/docs/source/support.rst
@@ -66,7 +66,7 @@ Python Version Support
----------------------
``cuda.core`` supports all Python versions following the `CPython EOL schedule
-`_. As of writing, Python 3.10 – 3.14 are supported.
+`_. As of writing, Python 3.10 – 3.15 are supported.
When a new Python feature version is released and the oldest supported version reaches EOL,
``cuda.core`` will bump its minor version accordingly.
diff --git a/cuda_core/pyproject.toml b/cuda_core/pyproject.toml
index a29aff70ef1..be4bec19e1a 100644
--- a/cuda_core/pyproject.toml
+++ b/cuda_core/pyproject.toml
@@ -42,6 +42,7 @@ classifiers = [
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
+ "Programming Language :: Python :: 3.15",
"Programming Language :: Python :: Implementation :: CPython",
"Environment :: GPU :: NVIDIA CUDA",
"Environment :: GPU :: NVIDIA CUDA :: 12",
diff --git a/cuda_pathfinder/cuda/pathfinder/_dynamic_libs/descriptor_catalog.py b/cuda_pathfinder/cuda/pathfinder/_dynamic_libs/descriptor_catalog.py
index 3b51f486278..9e6f6673466 100644
--- a/cuda_pathfinder/cuda/pathfinder/_dynamic_libs/descriptor_catalog.py
+++ b/cuda_pathfinder/cuda/pathfinder/_dynamic_libs/descriptor_catalog.py
@@ -362,6 +362,7 @@ class DescriptorSpec:
packaged_with="ctk",
linux_sonames=("libcupti.so.13", "libcupti.so.12"),
windows_dlls=(
+ "cupti64_2026.3.1.dll",
"cupti64_2026.3.0.dll",
"cupti64_2026.2.1.dll",
"cupti64_2026.2.0.dll",
@@ -480,7 +481,7 @@ class DescriptorSpec:
name="cusparseLt",
packaged_with="other",
linux_sonames=("libcusparseLt.so.0",),
- windows_dlls=("cusparseLt.dll",),
+ windows_dlls=("cusparseLt_13.dll", "cusparseLt.dll"),
supported_windows_arch=("x64", "arm64"),
site_packages_linux=("nvidia/cu13/lib", "nvidia/cusparselt/lib"),
site_packages_windows=WindowsSearchDirs(