Skip to content

Native CPU transforms by shape and one forward pack (#584, #587, #595) - #598

Draft
jtravs wants to merge 10 commits into
mainfrom
perf/native-fft-batching
Draft

jtravs wants to merge 10 commits into
mainfrom
perf/native-fft-batching

Conversation

@jtravs

@jtravs jtravs commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Native CPU FFT optimisation, for #584, #587 and #595. Draft until reviewed; ADR-075 is proposed for the maintainer.

What changes

  • Transforms thread by shape (Native CPU: transforms' width by rows and row length, not element count #587). A batch of transforms took its width from its element count. Now, from fft_threshold, it takes a thread per fft_thread_elements samples, at most one per row, or up to the medium width when its rows are at least fft_long_row long. fft_full is a backstop.
    • Linux and Windows: 8192, 4096 and 16384. macOS: 32768, 32768 and 65536, a sixteenth of those on a spinning top tier.
    • These values come from timing batched real transforms alone at 1–36 threads on an Intel Xeon Gold 6240, 16 cores of an AMD EPYC 7763 and an Apple M5 Max (table in benchmarks.md).
    • The sizing record now carries each batch's row length.
  • One forward pack on a host (Native CPU: a stage's forward transforms as one batched region (#560 item 4) #584). A modal stage's forward rows go through one batched plan, as on a device: the projection's fine and coarse rows, the in-stage absorber's, and the held plasma currents'.
    • The host puts the coarse rows after the fine ones, so a deferred quadrature's stages transform the fine block alone and its finish takes the coarse block in one call.
    • Compact (one-column) problems keep their separate transforms.
    • SOLPROP_NATIVE_FORWARD_PACK=0 turns the pack off (documented in the tuning guide).
  • The FFT grain is calibrated again. "fft" is back in grain.TIMED, last in the order, with its threshold and fft_thread_elements halved and doubled.
  • Calibration: why measured and patient FFT plans chosen alone rarely win in the step #595, plans alone against in the step. Each captured plan is timed alone (_core.time_fft_plan) and its ratio is stored beside its verdict. The thorough level no longer plans at patient. The calibration version is now 2.

Results

Against main: 5 % windows, three rounds, fields within 1e-12, with SOLPROP_CALIBRATION=off on both arms.

case Xeon Gold 6240, 18 36 EPYC 7763, 16 M5 Max, 6 (contended)
argon_blueshift 0.87 0.80 0.86 0.92
ctc 0.89 0.91 0.92 0.98
rdw 0.91 0.95 0.95 0.95
line 0.93 0.87 0.88 1.00
others (8 cases) 0.94–1.04 0.93–1.04 0.98–1.01 0.99–1.01
geometric mean, including the one-thread rows 0.977 0.981 0.993

On #595, measured plans for threaded rows (SOLPROP_FFTW_PLAN=measure) win in the step:

  • Xeon: 0.94 (kerr_beam_192 0.54–0.79).
  • EPYC: 0.96 (grin_nonlinear 0.83).
  • M5 Max: 0.97.

But planning them adds up to 12 s of construction (ctc on the EPYC: 13.8 s against 1.6 s), so the default stays at estimate.

The calibration's planning candidates "rarely won" because they were rarely timed. On all three machines the patient capture never finished, and the timing in the step ran out of rounds before a verdict. main does the same on the EPYC: no verdict at thorough, and nothing planned at standard. Giving the FFT stage enough time is a decision on the levels' budgets; see ADR-075.

The thorough and standard calibrations on the EPYC 7763 conclude as on main, admitting the copy threshold. The transforms' thread grain kept 4096 (2048: 0.976, not admitted; 8192: 1.13).

Not done here

🤖 Generated with Claude Code

jtravs and others added 6 commits November 9, 2026 09:06
…a probe switch

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s timed again

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hape rule

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jtravs added a commit that referenced this pull request Nov 9, 2026
John Travers accepted SEP 47 with five decisions taken before implementation:
device capabilities keep their per-vendor status (CUDA low-storage is the only
new qualification); every periodic statistic is computed natively; the native
session owns the monitor's decision state and records, with exact identity on
scalar decision logic; the reference session is built independently in phase
2; and #584 is delivered separately by PR #598.

Part I also now specifies running checkpoint contents, monitor restoration,
the calibration timing probe, groups as sequences of member problems and the
A/B/C attribution. The roadmap entry moves to Accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XGENPwVEY6NQKGaDDptaj9
@read-the-docs-community

read-the-docs-community Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

jtravs and others added 4 commits November 9, 2026 14:17
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jtravs jtravs changed the title WIP: native CPU transforms by shape and one forward pack (#584, #587, #595) Native CPU transforms by shape and one forward pack (#584, #587, #595) Nov 9, 2026

This branch has not been deployed

No deployments
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.

1 participant