Skip to content

Commit 157a448

Browse files
authored
Remove torchaudio _check_cuda_version() call when repackaging cu130->cu132 (#8052)
## Summary torchaudio is now built against the PyTorch stable C++ ABI, so the runtime `_check_cuda_version()` guard in [`torchaudio/_extension/__init__.py`](https://github.com/pytorch/audio/blob/main/src/torchaudio/_extension/__init__.py) is no longer needed and would otherwise fail on cross-CUDA-version installs (e.g. a cu132-tagged torchaudio wheel running against `torch` built for a different CUDA minor version). Extends `release/repackage_torchaudio_cu130_to_cu132.py` (added in #8043) to also **strip the `_check_cuda_version()` call** from `torchaudio/_extension/__init__.py` inside each wheel during the same `auditwheel.wheeltools.InWheelCtx` pass that rewrites the `+cu130` -> `+cu132` local-version label, so the regenerated RECORD covers both edits. The function definition in `utils.py` is left intact so external callers (e.g. the [pytorch/builder smoke test](https://github.com/pytorch/builder/blob/e2e4542b8eb0bdf491214451a1a4128bd606cce2/test/smoke_test/smoke_test.py#L80)) keep working. The new repackaged cu132 wheels can be re-uploaded to: - AWS S3: `s3://pytorch/whl/test/cu132/<wheel>` - Cloudflare R2: `s3://pytorch-downloads/whl/test/cu132/<wheel>` via the existing upload paths in the same script (no flag changes). ## Test plan - [ ] `python release/repackage_torchaudio_cu130_to_cu132.py --version 2.11.0 --dry-run` lists the expected wheels and prints the planned uploads without making any S3/R2 calls; output includes a `+ Removed _check_cuda_version() call from torchaudio/_extension/__init__.py` line for each wheel. - [ ] After a real run, `unzip -p torchaudio-2.11.0+cu132-...whl torchaudio/_extension/__init__.py | grep _check_cuda_version` shows only the `from .utils import _check_cuda_version` import line, and no bare `_check_cuda_version()` call. - [ ] `python s3_management/manage_v2.py whl/test` regenerates the cu132 index and the new wheels appear at https://download.pytorch.org/whl/test/cu132/torchaudio. - [ ] `pip install --index-url https://download.pytorch.org/whl/test/cu132 torch torchaudio==2.11.0+cu132 && python -c "import torchaudio"` succeeds with no `RuntimeError` about CUDA version mismatch.
1 parent 35633f8 commit 157a448

1 file changed

Lines changed: 85 additions & 1 deletion

File tree

release/repackage_torchaudio_cu130_to_cu132.py

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,15 @@
99
3. Rewrites the wheel local-version label from ``+cu130`` to ``+cu132``
1010
(METADATA ``Version:`` field, ``.dist-info`` directory name, and the
1111
wheel filename). The RECORD file is regenerated by auditwheel.
12-
4. Uploads each repackaged wheel to:
12+
4. Removes the ``_check_cuda_version()`` runtime guard from
13+
``torchaudio/_extension/__init__.py`` inside the wheel. torchaudio is
14+
now built against the PyTorch stable C++ ABI, so the strict CUDA
15+
version match is no longer required and would otherwise fail when a
16+
cu132-tagged torchaudio wheel runs alongside a torch built for a
17+
different CUDA minor version. The function definition in ``utils.py``
18+
is preserved so external callers (e.g. the pytorch/builder smoke
19+
test) keep working.
20+
5. Uploads each repackaged wheel to:
1321
- AWS S3: s3://pytorch/whl/test/cu132/
1422
- Cloudflare R2: s3://pytorch-downloads/whl/test/cu132/
1523
Each upload sets ``x-amz-meta-checksum-sha256`` on the object so the
@@ -56,6 +64,18 @@
5664
R2_BUCKET_NAME_DEFAULT = "pytorch-downloads"
5765
R2_PREFIX = "whl/test/{cuda}"
5866

67+
EXTENSION_INIT_PATH = "torchaudio/_extension/__init__.py"
68+
EXTENSION_UTILS_PATH = "torchaudio/_extension/utils.py"
69+
CHECK_CUDA_CALL_RE = re.compile(r"^[ \t]*_check_cuda_version\(\)[ \t]*\n", re.MULTILINE)
70+
# Match the `if ta_version != t_version: raise RuntimeError(...)` block inside
71+
# _check_cuda_version() in utils.py. The raise spans multiple lines, so we
72+
# match the whole if-body by indent.
73+
CHECK_CUDA_RAISE_RE = re.compile(
74+
r"^(?P<indent>[ \t]+)if ta_version != t_version:[ \t]*\n"
75+
r"(?:(?P=indent)[ \t]+.*\n)+",
76+
re.MULTILINE,
77+
)
78+
5979

6080
def discover_wheels(package: str, version: str, cuda: str) -> List[str]:
6181
"""Return list of wheel filenames for ``package`` at ``version`` on the
@@ -177,6 +197,70 @@ def repackage_wheel(
177197
os.path.join(ctx.path, new_dist_info_dir),
178198
)
179199

200+
# torchaudio is now built against the PyTorch stable C++ ABI,
201+
# so the runtime _check_cuda_version() guard is no longer needed
202+
# and would otherwise fail on cross-CUDA-version installs (e.g.
203+
# a torchaudio cu132 wheel running against torch built for a
204+
# different CUDA minor). Two patches are required:
205+
# (a) strip the call site in __init__.py so importing the
206+
# package does not raise, and
207+
# (b) neutralize the version-mismatch raise in utils.py so
208+
# external callers (e.g. the pytorch smoke test, which
209+
# calls torchaudio._extension._check_cuda_version()
210+
# directly) do not raise either.
211+
init_file = os.path.join(ctx.path, EXTENSION_INIT_PATH)
212+
if not os.path.exists(init_file):
213+
raise RuntimeError(f"{EXTENSION_INIT_PATH} not found in {wheel_path}")
214+
with open(init_file, "r", encoding="utf-8") as f:
215+
init_src = f.read()
216+
patched_src, count = CHECK_CUDA_CALL_RE.subn("", init_src)
217+
if count == 0:
218+
raise RuntimeError(
219+
f"No _check_cuda_version() call found in "
220+
f"{EXTENSION_INIT_PATH} of {wheel_path.name}"
221+
)
222+
if count > 1:
223+
print(
224+
f"- WARNING: removed {count} _check_cuda_version() "
225+
f"calls from {wheel_path.name} (expected 1)"
226+
)
227+
with open(init_file, "w", encoding="utf-8") as f:
228+
f.write(patched_src)
229+
print(
230+
f"+ Removed _check_cuda_version() call from "
231+
f"{EXTENSION_INIT_PATH} ({wheel_path.name})"
232+
)
233+
234+
utils_file = os.path.join(ctx.path, EXTENSION_UTILS_PATH)
235+
if not os.path.exists(utils_file):
236+
raise RuntimeError(f"{EXTENSION_UTILS_PATH} not found in {wheel_path}")
237+
with open(utils_file, "r", encoding="utf-8") as f:
238+
utils_src = f.read()
239+
patched_utils, utils_count = CHECK_CUDA_RAISE_RE.subn(
240+
lambda m: (
241+
f"{m.group('indent')}pass "
242+
f"# CUDA version mismatch check disabled by "
243+
f"repackage_torchaudio_cu130_to_cu132.py\n"
244+
),
245+
utils_src,
246+
)
247+
if utils_count == 0:
248+
raise RuntimeError(
249+
f"No `if ta_version != t_version:` block found in "
250+
f"{EXTENSION_UTILS_PATH} of {wheel_path.name}"
251+
)
252+
if utils_count > 1:
253+
print(
254+
f"- WARNING: replaced {utils_count} CUDA-mismatch "
255+
f"raise blocks in {wheel_path.name} (expected 1)"
256+
)
257+
with open(utils_file, "w", encoding="utf-8") as f:
258+
f.write(patched_utils)
259+
print(
260+
f"+ Disabled CUDA version mismatch raise in "
261+
f"{EXTENSION_UTILS_PATH} ({wheel_path.name})"
262+
)
263+
180264
new_filename = wheel_path.name.replace(old_label, new_label)
181265
out_path = output_dir / new_filename
182266
if not tmp_whl.exists():

0 commit comments

Comments
 (0)