Skip to content

MUFU.SIN / COS reduce their turns exactly; MUFU.TANH is translated - #1412

Open
Copak731 wants to merge 1 commit into
seedds:mainfrom
Copak731:mufu-fixes
Open

Copak731 wants to merge 1 commit into
seedds:mainfrom
Copak731:mufu-fixes

Conversation

@Copak731

@Copak731 Copak731 commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

What and why

  • MUFU.SIN / COS argument reduction. Since sm_70 they take turns, which NVIDIA reduces exactly. 2pi x in 32 bits loses x's fraction as it grows (errors up to 7e-4 at a few thousand turns: an animation's sin(time * speed) drifts with play time). ATurns takes the angle from x - floor(x), exact in 32 bits; an infinity gives inf - inf = NaN.
  • MUFU.TANH (op 9, nvdisasm) was refused (MUFU op 9), so a shader using it (an activation in a neural upscaler, for instance) failed to translate. ATanh computes 1 - 2 / (e^2x + 1), which gives +-1 at either end and keeps a NaN, and x itself below 2^-10 (PTX documents tanh.approx.f32 to about 2^-11 relative error).

Reference entry: docs/reference/shaders.md, "MUFU.SIN / COS argument reduction, and MUFU.TANH".

Checked

  • Tests: DMSH_TEST_XLATE=<translator> python3 dm/gfx/tests/test_dmsh_ampere_alu.py, new MufuTurns (3, all fail on main). All test_dmsh_*.py pass.
  • GPU cross-check (The cross-checks translate real sm_86 encodings (an nvdisasm 13.5-validated corpus) with dmsh_xlate using the production options (debug and reduced on, as dmsh_build.py), convert with spirv-cross 1.4.363.0 at MSL 2.3, run them on the GPU and compare every bit with a reference written from the oracle, PTX's documentation and Mesa NAK where it applies. MUFU is approximate on NVIDIA, so the comparison uses tolerances from PTX's .approx error bounds, with special values compared exactly): 1,000 MUFU, 92.6 % on main (29 sine / cosine precision mismatches, 45 TANH refusals), 99.5 % with the change. Left: the sine / cosine of an infinity (0 instead of NaN under Metal's fast math) and EX2 results below 2^-126 (flushed by the GPU).
  • Devices and OS: MacBook, Apple M5, macOS 26.6.2, Xcode 27.2.
  • Games run: none (no game files were used).

Docs

  • The finding is in its docs/reference/shaders.md entry, and python3 dm/tools/docs_symptoms.py was run (the symptom index)
  • No game files, keys or data extracted from a game in the change or the attachments

🤖 Generated with Claude Code

Since sm_70 MUFU.SIN and COS take turns, which NVIDIA reduces exactly; 2pi x
in 32 bits lost x's fraction as it grew (errors up to 7e-4 at a few thousand
turns). ATurns takes the angle from x - floor(x). Op 9 is MUFU.TANH
(nvdisasm), refused until now: ATanh computes 1 - 2 / (e^2x + 1), x itself
below 2^-10.

New MufuTurns tests in test_dmsh_ampere_alu.py (three fail on main). A GPU
cross-check of 1,500 MUFU with PTX .approx tolerances: 42 mismatches and 69
refusals to 7-11 (sine of an infinity under Metal's fast math, EX2 below
2^-126).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests) docs Documentation labels Nov 5, 2026
fpedrolucas95 pushed a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
fpedrolucas95 pushed a commit to fpedrolucas95/nxnative that referenced this pull request Nov 6, 2026
…, seedds#1410, seedds#1411, seedds#1412, seedds#1413, seedds#1414, seedds#1329 on top of main's translator fixes): chain c9cf9613657e

Publishes Ryujinx.Graphics.Shader, Ryujinx.Common, Spv.Generator and dmsh_xlate (osx-arm64, framework-dependent, the universal launcher kept) from the merged source; the
PRs' own binaries were built without this tree's translator changes (float atomic adds, F2IP, the growing raw pool table). The lock and dmsh_chain.h are written again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
javierdv7 pushed a commit to javierdv7/nxnative that referenced this pull request Nov 6, 2026
…#1462's CAS, seedds#1487, seedds#1329, seedds#1410, seedds#1411, seedds#1412, seedds#1357): lock and chain header; conflict leftovers removed from shaders.md and test_dmsh_ampere_alu.py
@Know-It-All-Brother

Copy link
Copy Markdown
Contributor

Thanks for this! I ran it against the Jetson Orin suite from #2041, both on its own base and applied on top of current main, and nothing that matched the Orin before differs now.

Sin / cos. On the branch's own base, the reduction is a clear step closer to the Orin (sin 897 → 798 lanes off out of 1,024, cos 735 → 625). Since this branch was cut, though, main got its own reduction from #1234, x - rint(x), and it lands a little closer than x - floor(x) does (sin 780 vs 798, cos 606 vs 625). That's because rint is exact for every float and keeps a small negative angle small, while floor turns -3.7e-8 turns into 1 - 3.7e-8, which rounds to 1, so sin gives 1.7e-7 where the Orin gives -0. What's left at large arguments comes from the FMUL.RZ x, 1/(2π) that ptxas puts in front of every MUFU.SIN / COS. #2051 deliberately keeps that one multiply rounded to nearest, since emulating it would cost every sin and cos for an error far below Metal's own sin and cos.

TANH. This overlaps #2058, which also translates MUFU.TANH:

f32 lanes off (of 1,024) f32 max ULP f16 lanes off (of 2,048)
this PR 498 323 632 (all 1 ULP)
#2058 496 116 3 (1 ULP)

The NaN-payload lanes are left out, since they're the same for both. For f32 the two are close, and the formula's cancellation between 2^-10 and 0.5 is where the larger misses come from. For f16 the Orin rounds tanh toward zero, which #2058 copies.

What I'd suggest is that we land TANH through #2058 and keep main's sin/cos reduction, so this PR would come down to your MufuTurns tests. They'd need to check for main's reduction instead of floor(, and for #2058's tanh instead of exp2(. Happy to help rebase it if that's useful.

To rerun this yourself, check out #2041's branch, set DMSH_TEST_XLATE to your translator, and run python3 dm/gfx/tests/test_dmsh_ampere_orin.py. Setting AMPERE_ORIN_ONLY=mufu_sin,mufu_cos,mufu_tanh,mufu_tanh_f16x2 limits it to these ops, and AMPERE_ORIN_REPORT=<file> writes a JSON report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation nvn NVN on Metal and its tests (dm/gfx/nvn, dm/gfx/tests)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants