Native Metal image endpoints#
These Swift package products are the reusable Apple-GPU endpoints for native clients. They own mathematics and GPU residency. They do not own SwiftUI, gestures, cache policy, or Python.
Native clients should call these APIs instead of copying Metal source or launching a local Python backend.
Products#
Product |
Endpoint |
Use |
|---|---|---|
|
|
Browser FFT of an already-transferred 2D product |
|
|
Histogram windows, range, and display contracts |
|
LUT / histogram / render shaders |
Colormap and display kernels |
|
decode / detector / CoM / iDPC kernels |
Raw-data science on Apple GPU |
|
catalog, QH5 index, EMD calibration |
Native HDF5/EMD discovery |
Import the products from the repository-root Swift package. Do not copy
.metal files into an application.
Browser FFT#
The display contract is fftshift(log1p(abs(fft2(source)))) in row-major
Float32. Forward transforms are unnormalized. Reciprocal-space labels come
from the caller’s scan calibration, not from FFT amplitude.
import Metal
import MetalImageFFT
let fft = try MetalImageFFT(device: device)
try fft.prewarm(rows: scanRows, columns: scanCols)
let result = try fft.logMagnitude(
source: brightField.values,
rows: scanRows,
columns: scanCols,
scalarType: .uint32,
output: existingFFT.values
)
source is a GPU-resident MTLBuffer. Typical Browser products:
Product |
|
Typical scan |
|---|---|---|
BF / ABF / ADF / custom |
|
|
CoM / DPC / iDPC |
|
same scan shape |
output is the in-place destination. Pass the already-displayed FFT buffer so
warm updates do not allocate. result.minimum is 0; result.maximum is the
GPU-reduced log-magnitude peak.
Call prewarm(rows:columns:) once after the scan shape is known, during load,
so the first visible FFT is not an MPSGraph compile hitch.
512×512 performance gate#
Browser BF/ADF images are commonly 512×512. After prewarming, the FFT gate is
completion within 8.33 ms for a 120 Hz frame. This is an acceptance budget,
not a copied benchmark result. Current measurements, device identity, revision,
distribution, and parity live in Verified benchmark results.
Release checks:
swift test --filter MetalImageFFTTests
swift run metal-image-fft-benchmark 512 512 12
python native/swift/Benchmarks/MetalImageFFTBenchmark/compare_torch_fft.py 512 512 12
testWarm512UInt32BrightFieldFFTStaysInside120Hz is the BF/ADF gate. Do not
treat CPU fft2, software adapters, a first-compile hitch, or a historical
table copied into an API contract as 120 Hz evidence.
Histogram and contrast#
import MetalImageRuntime
let statistics = try MetalDisplayStatistics(device: device)
let analyzed = try statistics.analyzeUInt32(
values: brightField.values,
rows: scanRows,
columns: scanCols,
scale: .linear
)
let window = MetalHistogramContrast.percentileWindow(
bins: analyzed.bins,
lowerPercentile: 0.01,
upperPercentile: 0.99
)
Contrast, colormap, pan, and zoom stay in the client. They must not recompute the FFT or request raw 4D data.
Client rules#
Local macOS/iOS Explore is Swift + Metal + native HDF5 only.
Do not bundle or launch Python, NumPy, or h5py in the app.
Linux CUDA hosts may use Python
quantem.gpu; that stays on the service host.The app owns cache, latest-wins scheduling, and SwiftUI. This package owns the buffer-to-buffer math.