Skip to main content

Non-uniform FFTs (types 1/2/3, dims 1/2/3) on Apple GPUs via Metal/MLX

Project description

mlx-nufft — non-uniform FFTs on Apple GPUs (Metal/MLX)

tests PyPI License: Apache 2.0 Python Platform Backend: MLX

mlx-nufft computes non-uniform fast Fourier transforms — types 1, 2 and 3, in dimensions 1, 2 and 3 — on Apple-silicon GPUs via Metal/MLX, with a drop-in mirror of the finufft Python API. It runs an fp32 GPU pipeline with the precision-critical coordinate setup performed in double precision at plan time ("crit64"), so it reaches fp64-grade accuracy on hardware that has no native double precision.

Paper: mlx-nufft.pdf — a technical report describing the method, accuracy, and performance (types 1/2/3 in 1/2/3D, the crit64 precision mechanism, and M1 / M5 Max benchmarks). Pin a tagged release rather than tracking main.

Install

Requires an Apple-silicon Mac (Metal/MLX).

pip install mlx-nufft

Or pin a tagged release straight from GitHub:

pip install "git+https://github.com/martinlachaine/mlx-nufft.git@v0.1.2"

then import mlx_nufft. Dependencies are pinned (notably mlx==0.31.2).

For development — running the test/benchmark harness, which uses CPU finufft and scipy as references:

git clone https://github.com/martinlachaine/mlx-nufft && cd mlx-nufft
uv venv --python 3.13 .venv
uv pip install -p .venv/bin/python -e ".[dev]"

Verify the install — run the full correctness suite (each test compares against CPU finufft and/or an exact direct-summation oracle):

.venv/bin/python harness/run_tests.py

It prints a per-test pass/fail summary and exits non-zero on any failure. The optional VkFFT backend test reports SKIP unless the bridge in vkfft_bridge/ is built.

Quickstart

A complete, copy-paste-runnable 2-D type-1 transform (M nonuniform points → N1 × N2 uniform Fourier modes):

import numpy as np
import mlx_nufft as finufft

rng = np.random.default_rng(0)
M, N1, N2 = 100_000, 256, 256
x = rng.uniform(-np.pi, np.pi, M)                          # coords in [-pi, pi)
y = rng.uniform(-np.pi, np.pi, M)
c = rng.standard_normal(M) + 1j * rng.standard_normal(M)   # source strengths

fk = finufft.nufft2d1(x, y, c, (N1, N2), eps=1e-6)         # -> (256, 256) complex

A fuller runnable script (basic call, plan reuse, and a self-check against an exact direct DFT — no finufft install needed) is in examples/quickstart.py:

python examples/quickstart.py

Usage

Drop-in finufft API (same call surface):

import mlx_nufft as finufft

fk = finufft.nufft2d1(x, y, c, (N1, N2), eps=1e-6)   # all nufft{1,2,3}d{1,2,3}
plan = finufft.Plan(1, (N1, N2), n_trans=8, eps=1e-6)
plan.setpts(x, y)
fk = plan.execute(c)

Native plan classes — Type3Plan (type-3 engine) and Type1PlanND / Type2PlanND (dims 1–3):

from mlx_nufft import Type3Plan

# plan once (geometry-dependent setup cached), execute per call
plan = Type3Plan((x1, x2, x3), (s1, s2, s3), eps=1e-5, isign=+1)
f = plan.execute(c)            # f[k] = sum_j c[j] exp(i*isign * s_k . x_j)

Type1PlanND also offers a batched multi-strength execute over one shared point spread, and a cheap re-point of a fixed-mode-box plan to new coordinates:

from mlx_nufft import Type1PlanND

plan = Type1PlanND((x, y), (N1, N2), eps=1e-5, isign=+1)
fk = plan.execute_batch(cs)               # cs: (B, P) over the same points -> (B, N1, N2)
plan.set_sources((x2, y2), backend="gpu") # re-point without recompiling kernels
fk2 = plan.execute(c2)

The double-single phase primitive is also exposed standalone, for callers with a large-magnitude fp64 phase that cannot be reduced mod 2π in fp32 but want the cos/sin on the GPU:

from mlx_nufft import expi, EXPI_MAX_PHASE

z = expi(phi)                    # device complex64 e^{i*phi}, phi an fp64 array
z = expi([a, b, c], isign=-1)    # phase summed in double-single: e^{-i*(a+b+c)}

An optional VkFFT-Metal FFT backend is selectable for the type-3 slab path (Type3Plan(..., fft_backend="vkfft"), requires building the bridge in vkfft_bridge/); MLX's FFT is the default. vkfft_available() reports whether the bridge is built.

Documented differences from finufft

  • Computation is fp32-grade (crit64): eps below 1e-6 clamps with a warning; complex128 inputs are accepted and returned but transformed at fp32 grade.
  • modeord=1 (FFT ordering) is not implemented.
  • 1D/2D type 3 run as degenerate slices of the 3D type-3 kernel.
  • Plans hold points as plan state (setpts); out= and multi-vector (n_trans, ...) shapes mirror finufft, and Plan.execute_adjoint (finufft 2.5) is supported for all three types.

Layout

  • mlx_nufft/ — the library: gpu_t3.py (type-3 engine), nd.py (Type1PlanND/Type2PlanND), types12.py, dfmath.py (the expi / double-single primitive), sizing.py (kernel/grid sizing), api.py (the finufft-compatible surface), vkfft_backend.py.
  • examples/ — runnable, dependency-light usage examples (quickstart.py).
  • harness/ — correctness tests (test_*.py), the suite runner (run_tests.py), the acceptance/benchmark runner, and the CPU-reference oracle.
  • vkfft_bridge/ — optional VkFFT-Metal backend build.

Development and validation

mlx-nufft is AI-assisted, human-directed research software. Its scope, numerical requirements, validation strategy, acceptance criteria, and release decisions are the author's; generative AI tools accelerated implementation, refactoring, test scaffolding, and documentation.

Generated code was not trusted by default. Every component was validated against independent references — CPU FINUFFT, exact direct-summation oracles on small problems, transform-convention and adjoint checks, full dimension/type coverage, dtype/device behavior, and API-parity tests (see harness/).

The author is responsible for the released software — its design, limitations, and maintenance. Known limitations and hardware assumptions are documented; corrections are welcome via the issue tracker.

License & citation

Apache-2.0 (see LICENSE). mlx-nufft is an independent implementation that follows the FINUFFT/cuFINUFFT algorithms and was validated against FINUFFT; see NOTICE for attribution and the methods papers to cite, and CITATION.cff to cite mlx-nufft itself.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mlx_nufft-0.1.2.tar.gz (53.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mlx_nufft-0.1.2-py3-none-any.whl (55.5 kB view details)

Uploaded Python 3

File details

Details for the file mlx_nufft-0.1.2.tar.gz.

File metadata

  • Download URL: mlx_nufft-0.1.2.tar.gz
  • Upload date:
  • Size: 53.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mlx_nufft-0.1.2.tar.gz
Algorithm Hash digest
SHA256 5137a7e4c1c21bd272d3c32743329b6fc5fdc68373f2d67cdd54ac67f2a76ffc
MD5 7246e6cd489795c9abb49d06629cce98
BLAKE2b-256 eaed695dc8c7cb0885c98eac355061f18ec6511d0d0adb359a1b599edc26cc8f

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_nufft-0.1.2.tar.gz:

Publisher: publish.yml on martinlachaine/mlx-nufft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mlx_nufft-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: mlx_nufft-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 55.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mlx_nufft-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 423eccb9b02e278d7b916e0be345b81eeb5c639749a71201d8a94eea40536a67
MD5 37d1d79c9c3bec433dd11d88636a94ae
BLAKE2b-256 f768c42a9cedb1d3921c6cf64a15dd4836570fb59c4364d2a514424bf59689f6

See more details on using hashes here.

Provenance

The following attestation bundles were made for mlx_nufft-0.1.2-py3-none-any.whl:

Publisher: publish.yml on martinlachaine/mlx-nufft

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page