Skip to content

Derive FFT twiddle phase type from scalar lanes - #5

Closed
PhysicistJohn wants to merge 1 commit into
draft/generic-metal-fftfrom
draft/derive-fft-phase-type
Closed

Derive FFT twiddle phase type from scalar lanes#5
PhysicistJohn wants to merge 1 commit into
draft/generic-metal-fftfrom
draft/derive-fft-phase-type

Conversation

@PhysicistJohn

@PhysicistJohn PhysicistJohn commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Context

This fork draft targets draft/generic-metal-fft, the source branch reviewed in ml-explore/mlx#3969. That work templates the Metal C2C FFT over its scalar lane type, but get_twiddle<T> still names float directly for phase evaluation.

This is the next narrow step toward generalizing FFT precision across all Metal planning paths.

Current MLX executes FFTs at one scalar precision: public transforms cast inputs to float32 or complex64, the Metal planner table instantiates only float/float2, and Bluestein's chirp and convolution constants are complex64. The restriction applies to Stockham, Rader, Bluestein, and four-step rather than Bluestein alone.

Change

Derive the twiddle phase type from the templated scalar lane and Metal's pi constant:

using phase_T = decltype(M_PI_F * T(0));

The phase expression then remains in phase_T until fast::sin and fast::cos; the resulting twiddle is converted to the FFT lane type at the existing boundary.

Deriving from the phase arithmetic is intentional. decltype(fast::sin(T(0))) is include-context dependent because MLX's BF16 math wrapper declares a BF16 result while evaluating through FP32. In a JIT kernel that form prematurely quantized the phase, reduced accuracy, and slowed every measured planner. The arithmetic-promotion form is stable across static and JIT compilation.

Scope

  • One file and one commit.
  • No public dtype, API, host dispatch, or kernel-instantiation changes.
  • No claim of reduced-precision FFT support in this patch.
  • Shared by Stockham, Rader, Bluestein, and four-step through get_twiddle<T>.

Validation

  • Native xcrun metal compilation of the production FFT planner table.
  • Compile-only half2 and bfloat2 C2C instantiations across all four planners.
  • Baseline and patched AIR are byte-identical for both production and reduced-precision compile sets.
  • Exported symbols unchanged: 75 production; 85 with the compile-only reduced planners.
  • Float, FP16, and BF16 correctness summaries exactly match baseline across Stockham, Rader, Bluestein, and four-step.
  • Sixteen paired timing rounds show no measurable performance change:
Planner Patched / baseline throughput
Stockham 1.003x
Rader 1.004x
Bluestein 1.001x
Four-step 0.995x
  • clang-format --dry-run --Werror and git diff --check pass.

Derive twiddle phase evaluation precision from the scalar lane and Metal's pi constant instead of naming float in generic FFT code.\n\nThis preserves current code generation while keeping phase precision under the template's usual arithmetic promotion.
@PhysicistJohn
PhysicistJohn marked this pull request as ready for review August 2, 2026 05:12
@PhysicistJohn

Copy link
Copy Markdown
Owner Author

Folded into ml-explore#3969 as part of its amended single commit (611e080). This fork PR remains the isolated review record.

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