Skip to content

[pull] main from pytorch:main - #173

Merged
pull[bot] merged 6 commits into
dumko2001:mainfrom
pytorch:main
Aug 28, 2026
Merged

[pull] main from pytorch:main#173
pull[bot] merged 6 commits into
dumko2001:mainfrom
pytorch:main

Conversation

@pull

@pull pull Bot commented Aug 28, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

georgehong and others added 6 commits August 28, 2026 08:00
periodic.yml still asked for pytorch-linux-jammy-py3.10-clang18, which #191108 retired on 2026-07-27. docker-builds.yml never builds that name, so the tag is absent from ECR, the pod hangs in ImagePullBackOff, and ARC surfaces it as the generic "pod failed to come online". 0 pass / 16 fail on main. clang21 is the 1:1 successor and still sets GCC_VERSION=11, so the gcc11 debug build is unchanged.

The 8 distributed shards have never executed on any branch, so this needs a ciflow/periodic run for real signal.

Authored with AI assistance.
Pull Request resolved: #195067
Approved by: https://github.com/pytorchgreenlight
Fixes #194442.

`baddbmm`/`addbmm`/`addmm` [document](https://docs.pytorch.org/docs/stable/generated/torch.addmm.html) that when `beta == 0` the `input`/bias is ignored, so nan/inf in it must not propagate. On MPS, real dtypes already honor this (the MPSGraph path drops the bias node when `beta == 0`, and the bfloat16 case from the issue was already fixed on main after 2.13.0), but complex and integral types take the Metal-kernel path, which unconditionally adds `beta*bias`, so a nan/inf `input` poisons the whole output even though `beta == 0`.

When `beta == 0` the bias must be dropped entirely:
- baddbmm lowers to a plain `bmm` and addmm to a plain `mm`, scaling in place only for the uncommon `alpha != 1`
- addbmm has no bias-free "batched matmul + reduce" kernel, so it stays on its own kernel but is handed a broadcast scalar-zero bias

It also fixes complex `addmm` more broadly: the MPSGraph addmm path applied `alpha`/`beta` via `toDouble()`, which throws for a complex scalar and silently drops the imaginary part (and a pure-imaginary `beta` was mis-detected as zero, wrongly dropping the bias). Complex `addmm` is now routed through the Metal kernel like `bmm`/`baddbmm`. Integral types cannot carry nan, so nothing changes for them.

For complex baddbmm with `beta=0` and a nan `input`, the poisoned-output count goes from `256 / 256` on main to `0 / 256`, matching CPU; same for addbmm/addmm. Complex `alpha`/`beta` addmm now matches CPU instead of raising.

Authored with the assistance of an AI agent (Claude Code).

Co-authored-by: Achraf Bayi <achrafbayi@icloud.com>

Pull Request resolved: #194474
Approved by: https://github.com/malfet

Co-authored-by: Nikita Shulga <nikita.shulga@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Previously, out-of-place `nn.Dropout` or `F.dropout` on MPS went through  non fused path, while we have the fused path available which just needed to be enabled.

<details>
<summary> Perf </summary>

| dtype | Shape | Layout | Before (us) | After (us) | Speedup |
|---|---:|---|---:|---:|---:|
| bf16 | 256 x 1024 | contiguous | 19.0 | 10.6 | 1.79x |
| bf16 | 8 x 512 x 1024 | contiguous | 202.5 | 52.8 | 3.84x |
| bf16 | 4096 x 4096 | contiguous | 953.1 | 313.3 | 3.04x |
| bf16 | 2048 x 4096 | transposed dense | 791.2 | 154.5 | 5.12x |
| bf16 | 16 x 128 x 64 x 64 | channels-last | 792.7 | 153.3 | 5.17x |
| bf16 | 4 x 32 x 32 x 32 x 32 | channels-last-3d | 361.7 | 53.1 | 6.82x |
| fp16 | 4096 x 4096 | contiguous | 947.3 | 322.0 | 2.94x |
| fp32 | 4096 x 4096 | contiguous | 1518.0 | 585.0 | 2.59x |
| fp32 | 16 x 128 x 64 x 64 | channels-last | 880.9 | 285.9 | 3.08x |

</details>
Pull Request resolved: #195011
Approved by: https://github.com/Skylion007
…#192496)

## Summary
add hw_classification attribute (TestDispatch, TestPythonDispatcher as GENERIC classes), enabling hardware-based test classification and filtering.

## Changes
test/test_dispatch.py : import HardwareClassification, and add hw_classification to TestDispatch, TestPythonDispatcher classes.

## Motivation
These tests are hardware-agnostic and should be classified as GENERIC so they can be properly selected and filtered when running on different hardware backends.

## Test Plan
CI: python -m pytest -q test/test_dispatch.py

## Notes
This is part of the test case refactoring initiative tracked in #185590.
Pull Request resolved: #192496
Approved by: https://github.com/Skylion007, https://github.com/FuDdd, https://github.com/KarhouTam, https://github.com/fffrog
…d suffix (#189388)

## Summary

Since #180243 the `torch._C` extension is built by CMake via
`Python_add_library(_C MODULE WITH_SOABI ...)`. `WITH_SOABI` names the module
using `Python_SOABI`, which CMake's FindPython only computes by running the
interpreter **when not cross-compiling**: under `CMAKE_CROSSCOMPILING` the query
is skipped unless `CMAKE_CROSSCOMPILING_EMULATOR` is set (policy `CMP0190`), so
`Python_SOABI` is left empty and `WITH_SOABI` silently emits an untagged `_C.so`.

That breaks cross builds: the extension is installed under a name the target
interpreter will not import, so `import torch._C` fails. This is the conda-forge
linux-aarch64 failure in
[pytorch-cpu-feedstock#526](conda-forge/pytorch-cpu-feedstock#526).

When this was first diagnosed the symptom was different: `setup.py` collected the
extension via `package_data = f"_C{sysconfig.get_config_var('EXT_SUFFIX')}"`, the
untagged name did not match, and `_C` was dropped from the wheel entirely.
#180248 has since removed `setup.py`, and `_C` is now collected by
`install(TARGETS _C ...)`, so it ships under the wrong name rather than going
missing. Either way the target cannot import it.

#190003 has since widened which builds hit this. It forwards `CMAKE_SYSTEM_NAME`
and `CMAKE_SYSTEM_PROCESSOR` from the environment before `project()`, which is
exactly what puts CMake into cross-compile mode, so a cross setup that passes
them that way now takes the empty-`Python_SOABI` path too. Such a build
previously stayed in native mode -- `CMAKE_CROSSCOMPILING` false, `Python_SOABI`
computed normally -- and so never produced an untagged module. That makes this
the completion of #190003 rather than a conda-forge-only concern.

CMake's sanctioned cross path (`CMP0190` + an emulator) assumes the target
interpreter is run under qemu/wine. That does not fit conda-forge's crossenv,
where the interpreter is a build-native binary that reports the target's config
and is directly runnable -- no emulator. So when `Python_SOABI` is empty while
cross-compiling, we query `SOABI` from the interpreter (which crossenv answers
with the target's value) and set it once, right where FindPython resolves the
`Development.Module` component. Every downstream `WITH_SOABI` consumer (`_C`, and
the CUDA-only `_nccl_ep`) then gets the correct suffix, and `WITH_SOABI` still
composes the platform-specific filename.

The override deliberately only fills an **empty** `Python_SOABI`. A non-empty
value is authoritative and left untouched: with an emulator FindPython ran the
target interpreter to compute it, whereas this bare invocation would run the
wrong interpreter (or fail to exec the target binary), so it must not
second-guess a value FindPython already produced.

It sets `Python_SOABI` centrally rather than overriding each target's `SUFFIX`
because FindPython recomputes `Python_SOABI` on every `find_package(Python)`, so
a manual value only survives if nothing re-finds Python afterwards. That now
holds unconditionally: since #189386 replaced the libnvrtc shorthash with
`file(SHA256)`, no `find_package(Python)` runs after this one at all.

An alternative considered was passing `-DPython_SOABI=...`; FindPython unsets and
recomputes the variable on each find, so a command-line value is not honored.

This PR was authored with the assistance of an AI coding assistant.

## Test Plan

### Cross-build validation (real linux-aarch64 crossenv)

Validated against a genuine conda-forge-style cross environment: cross compilers
plus a `linux-aarch64` target prefix, joined by `crossenv`, so `Python_EXECUTABLE`
is an interpreter that **runs on x86_64 but reports the target's config**
(SOABI `cpython-312-aarch64-linux-gnu`, platform `linux-aarch64`) -- the setup
this fix is written for.

```
mamba create -p $ROOT/build-env -c conda-forge python=3.12 crossenv cmake ninja \
      gcc_linux-aarch64 gxx_linux-aarch64 sysroot_linux-aarch64
conda create -p $ROOT/target-env --platform linux-aarch64 -c conda-forge python=3.12 numpy
export PATH="$ROOT/build-env/bin:$PATH"
$ROOT/build-env/bin/python -m crossenv \
  --sysconfigdata-file $ROOT/target-env/lib/python3.12/_sysconfigdata_aarch64_conda_linux_gnu.py \
  --cc aarch64-conda-linux-gnu-gcc --cxx aarch64-conda-linux-gnu-c++ \
  --ar aarch64-conda-linux-gnu-ar \
  --sysroot $ROOT/build-env/aarch64-conda-linux-gnu/sysroot \
  $ROOT/target-env/bin/python $ROOT/cross-venv
```

PyTorch itself was then configured twice with that interpreter, the two runs
differing **only** in `cmake/Dependencies.cmake`:

```
cmake -S . -B $B -G Ninja \
  -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64 \
  -DCMAKE_C_COMPILER=aarch64-conda-linux-gnu-gcc \
  -DCMAKE_CXX_COMPILER=aarch64-conda-linux-gnu-c++ \
  -DCMAKE_SYSROOT=$ROOT/build-env/aarch64-conda-linux-gnu/sysroot \
  -DPython_EXECUTABLE=$ROOT/cross-venv/cross/bin/python \
  -DPython_INCLUDE_DIR=$ROOT/target-env/include/python3.12 \
  -DUSE_CUDA=0 -DUSE_DISTRIBUTED=0 -DBUILD_TEST=0 -DUSE_MKLDNN=0 \
  -DUSE_NUMPY=0 -DUSE_OPENMP=0 -DUSE_KINETO=0 -DBLAS=Eigen
```

Both configures succeed; the resulting `_C` target in the generated build system:

| | `_C` output in `build.ninja` |
| --- | --- |
| without this patch (current `viable/strict`) | `torch/_C.so` -- untagged, the reported bug |
| with this patch | `torch/_C.cpython-312-aarch64-linux-gnu.so` |

The configure log shows the override firing with
`cpython-312-aarch64-linux-gnu`. This also exercises the central-override design
end to end: the value survives from the override in `Dependencies.cmake` all the
way to target generation, with no later `find_package(Python)` resetting it.

Scope: this covers configure and the generated build system, where the module
name is decided. A full aarch64 compile was not run, and the box has no
`qemu-user`, so importing an aarch64 artifact there was not possible; end-to-end
execution remains the conda-forge build below.

### Supporting checks

In a standalone FindPython project: (a) a non-empty `Python_SOABI` is preserved
and only an empty one takes the override path, and (b) setting `Python_SOABI`
before the `Python_add_library` calls (no intervening `find_package`) drives the
suffix of every `WITH_SOABI` module:

```cmake
set(Python_SOABI "cpython-312-aarch64-linux-gnu")
Python_add_library(_C MODULE WITH_SOABI stub.c)        # -> _C.cpython-312-aarch64-linux-gnu.so
Python_add_library(_nccl_ep MODULE WITH_SOABI stub.c)  # -> _nccl_ep.cpython-312-aarch64-linux-gnu.so
```

Native builds are unchanged: the `CMAKE_CROSSCOMPILING` guard is not taken and
FindPython's `Python_SOABI` already equals `EXT_SUFFIX` there.

The #190003 interaction was checked separately (cmake 3.28.3), since it governs
*which* builds reach the empty-`SOABI` condition in the first place:

```
# native, no toolchain vars
cmake -S . -B b1
# -> CMAKE_CROSSCOMPILING=FALSE  Python_SOABI=cpython-310-x86_64-linux-gnu

# toolchain vars in the environment, WITHOUT #190003's forwarding block
CMAKE_SYSTEM_NAME=Linux CMAKE_SYSTEM_PROCESSOR=aarch64 cmake -S . -B b4
# -> CMAKE_CROSSCOMPILING=FALSE  Python_SOABI=cpython-310-x86_64-linux-gnu

# same, WITH the forwarding block (current main)
CMAKE_SYSTEM_NAME=Linux CMAKE_SYSTEM_PROCESSOR=aarch64 cmake -S . -B b2
# -> CMAKE_CROSSCOMPILING=TRUE   Python_SOABI=''

# -D flags (the conda-forge CMAKE_ARGS path)
cmake -S . -B b3 -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=aarch64
# -> CMAKE_CROSSCOMPILING=TRUE   Python_SOABI=''
```

macOS is unaffected: `CMAKE_OSX_ARCHITECTURES=x86_64` on an arm64 host leaves
`CMAKE_CROSSCOMPILING` false, and macOS SOABI (`cpython-3XY-darwin`) carries no
architecture component, so no arch-mismatched module name can arise there.

End-to-end validation is a conda-forge linux-aarch64 build
([pytorch-cpu-feedstock#526](conda-forge/pytorch-cpu-feedstock#526))
confirming `_C.cpython-3XY-aarch64-linux-gnu.so` is installed and
`import torch._C` succeeds.

Pull Request resolved: #189388
Approved by: https://github.com/isuruf, https://github.com/jeffdaily
## Issue

Fixes #193933

## Summary

Dynamo models a tensor subclass without `__torch_dispatch__` as a `TensorWithTFOverrideVariable` holding the Python type in `class_type`, while the fake tensor behind the proxy stays a plain `FakeTensor`. When an inplace op bumps the fake version, `synchronize_attributes` re-derives every specialized property from that fake tensor, and `get_specialized_props` resolves `class_type` back to `torch.Tensor` (`torch/_dynamo/variables/builder.py:4334`); codegen then loads `__subclass_Tensor_<id>_c0`, a global `install_global` never installed. This excludes `class_type` from the resync, since the version-bump resync cannot change the Python type of the object being modelled. That resync fires for every inplace op since #187890 removed the `has_tensor_arg` gate.

The same cause reaches a second path with no inplace op involved. A subclass that sets `__torch_function__ = _disabled_torch_function_impl` -- every `nn.Parameter` subclass does -- does not intercept `__gt__`, so the comparison lands in `TensorVariable.tp_richcompare_impl`, which wrapped the result with `type(self)` and rebuilt the same broken `TensorWithTFOverrideVariable`. It now wraps with `TensorVariable`, matching eager, which returns a plain tensor there. On `main`, `torch.compile(lambda x: x > 0, backend="eager")` on an `nn.Parameter` subclass raises the same `NameError`.

## Checklist

- [x] Passes lint (`spin fixlint`)
- [x] Added/updated tests
- [ ] Updated documentation (if applicable)
- [ ] Included benchmark results (for PRs impacting perf)

## BC-breaking?

No.

---
AI assistance was used in developing this change: investigation, validation, and additional testing

Pull Request resolved: #193969
Approved by: https://github.com/aorenste
@pull pull Bot locked and limited conversation to collaborators Aug 28, 2026
@pull pull Bot added the ⤵️ pull label Aug 28, 2026
@pull
pull Bot merged commit 4687d34 into dumko2001:main Aug 28, 2026
2 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants