Skip to content

fix(musa): backport torch.mm/bmm out_dtype semantics (torch_musa < 2.13.0) - #116

Merged
yeahdongcn merged 1 commit into
mainfrom
xd/musa-100046-mm-out-dtype-created
Sep 21, 2026
Merged

yeahdongcn merged 1 commit into
mainfrom
xd/musa-100046-mm-out-dtype-created

Conversation

@yeahdongcn

@yeahdongcn yeahdongcn commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

What / Why

torch.mm/torch.bmm with out_dtype= returned a correctly shaped fp32 tensor on MUSA whose contents were never written: mm silently all zeros, bmm non-zero wrong values. Measured on torch_musa 2.11.0.post1+musa5.2.0; CUDA accumulates in fp32, so MUSA silently disagreed with CUDA.

Change

  • Promotes the operands to fp32 and accumulates there, reusing the plain overloads, so the backport assumes nothing about the vendor kernel. Invalid dtype pairs are forwarded verbatim, keeping the vendor error text byte-identical.
  • Armed only below 2.13.0, the release torch_musa committed to fix the overloads in (a vendor commitment we have not verified); an unknown or unparsable __version__ ranks lowest and stays armed.
  • Correctness is decided per process by a three-valued lazy probe: first promoted call only, caches only deterministic verdicts, warns once when undecidable, and refuses to probe inside a graph capture.
  • Version gates compare against inline literals - no version constants, no helper.

Verification

Focused 307 passed / 4 skipped, full 544 passed / 19 skipped on S5000; gate table 2.10.0..2.12.0 armed, 2.13.0 / 2.13.0.post1 unarmed, not-a-version armed; two-tree branch diff PARITY_IDENTICAL; independent MUSA recheck in generated/MUSA-100046/verify-2026-09-20/, end-to-end A/B with byte-identical outputs.

Not covered / notes

  • Builds whose binding has no *_Dtype overload keep raising on out_dtype=; that is the binding's contract, not a defect this repairs.
  • The 2.13.0 commitment is unverified by us: if the fix does not land, a >= 2.13.0 stack installs no wrapper and the silent zeros can return. The compatibility table records this, and the shim is deleted once 2.13.0 is verified fixed.
  • Reviewers: please do not move the probe back to import time. Running it eagerly initialises the vendor libraries before the host's own warm-up; measured cost was +6.7-8.1% decode TPOT (KV budget 731,482 -> 746,446 tokens) with identical device kernels.

@yeahdongcn
yeahdongcn force-pushed the xd/musa-100046-mm-out-dtype-created branch from 42acb8d to 61bae3d Compare September 20, 2026 07:57
@yeahdongcn yeahdongcn changed the title fix(musa): backport torch.mm/bmm out_dtype semantics on the affected torch_musa stack fix(musa): backport torch.mm/bmm out_dtype semantics (torch_musa < 2.13.0) Sep 20, 2026
@yeahdongcn
yeahdongcn force-pushed the xd/musa-100046-mm-out-dtype-created branch from 61bae3d to e3f3cb5 Compare September 20, 2026 09:51
@yeahdongcn
yeahdongcn marked this pull request as ready for review September 20, 2026 09:51
@yeahdongcn
yeahdongcn force-pushed the xd/musa-100046-mm-out-dtype-created branch from e3f3cb5 to 04c06bb Compare September 20, 2026 10:03
@lijing-mt

Copy link
Copy Markdown

LGTM

…13.0)

On the affected torch_musa stack the vendored `aten::mm.dtype` / `aten::bmm.dtype`
overloads are registered but do not write their result: `torch.mm(..., out_dtype=)`
returns a correctly shaped fp32 tensor that is silently all zeros, and `bmm` returns
non-zero wrong values. Measured on 2.11.0.post1+musa5.2.0; plain and invalid
arguments behave correctly, so only the promoted path is affected.

The wrappers are armed below `2.13.0`, the release torch_musa committed to fix the
overloads in - a vendor commitment, not a measurement of ours - and nothing is
installed from 2.13.0 on. An unknown or unparsable __version__ ranks lowest in
version_of and therefore stays armed, so a stack we cannot read is never assumed
fixed. Once 2.13.0 is released and verified fixed here the shim is deleted; if the
fix slips the bound moves to the newly committed release.

The backport promotes the operands to fp32 and accumulates there, reusing the plain
overloads, so it assumes nothing about the vendor kernel; every gate compares
against an inline literal (no version constants), invalid dtype combinations are
forwarded verbatim so the vendor error text stays byte-identical, and
`_version.version_of` stays as the parse-failure-safe comparator.

Correctness is decided per process by a three-valued, lazy probe: it runs only on
the first promoted call, caches only deterministic verdicts, warns once when it
cannot decide, and refuses to probe inside a CUDA/MUSA graph capture (the verdict
then resolves on the next eager call, which is why a graph captured before the
first eager call must be re-captured on a fixed stack).

Verified on S5000: focused 307 passed/4 skipped, full 554 passed/19 skipped, gate
table 2.10.0..2.12.0 armed and 2.13.0+ unarmed, capture safety, a no-shim control
showing the all-zero/wrong-value defect, and the end-to-end A/B with byte-identical
outputs (COMPARABLE, +0.044 ms). See the ticket for the full evidence list.

Version unified on 0.1.89 as a true replace-all: every `0.1.x` literal in the tree
now reads 0.1.89, including the C++ mirror in csrc/ops.h (was 0.1.0), the recorded
benchmark history entry (was 0.1.86) and the example extension setup (was 0.1.0);
a tree-wide grep for any other `0.1.x` literal returns nothing.
@yeahdongcn
yeahdongcn force-pushed the xd/musa-100046-mm-out-dtype-created branch from 04c06bb to 62a32ec Compare September 21, 2026 02:08
@yeahdongcn
yeahdongcn merged commit 339a336 into main Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants