quantem.gpu migration status#

Reusable numerical math and GPU kernels are being moved from quantem.widget to quantem.gpu. This is an incremental ownership migration, not a rewrite of the widgets and not a blanket claim that every widget path is complete.

Ownership boundary#

quantem.gpu owns mathematics or kernels only when at least two real widget call sites use the same scientific semantics. quantem.widget continues to own React components, viewer state, interaction policy, caches, workflow orchestration, exports, and widget-specific scientific controls and defaults.

The browser sources copied into js/.generated/engine/ are generated build inputs. Edit their canonical source in quantem.gpu, then run:

QUANTEM_GPU_SRC=/path/to/quantem.gpu/src npm run sync:webgpu

Thin modules in quantem.widget/js/ may re-export canonical functions so existing imports remain stable during the migration. They must not grow a second implementation.

Browser execution rule#

For migrated scientific operations, the production browser path requires a hardware WebGPU adapter. Missing WebGPU, a software adapter, shader failure, or device loss is reported as unavailable; it must not silently run the same numerical operation in JavaScript. Scalar TypeScript, NumPy, and SciPy versions remain only as independent parity references and test oracles.

This rule applies to the migrated FFT, histogram/colorization, display filter, frequency filter, ROI crop/mask, line profile, FFT-peak, detector reduction, CoM-magnitude, and iCoM paths. It does not claim that every legacy or widget-specific browser calculation has already migrated.

Current coverage#

Area

Shared consumers

Status

finite extrema, histograms, normalization, signed-log transforms, and LUT colorization

Show2D, Show3D, Show3DSlices, Show4DSTEM, ShowEDS, ShowPtycho

migrated candidate

FFT, shift, magnitude, peak localization, quality metrics, and reciprocal-coordinate math

Show2D, Show3D, Show3DSlices, Show4DSTEM, ShowPtycho, as applicable

migrated candidate; widget-specific FFT display policies remain local

Gaussian/Anscombe display filtering and bin/resample stages

Show2D, Show3D

migrated candidate; active production path requires WebGPU

Smooth radial frequency filtering

Show2D, Show3D

migrated candidate; padded odd/nonsquare FFT domain is preserved through the inverse

ROI masked crops and bilinear line profiles

Show2D, Show3D, Show4DSTEM, Browse

migrated candidate; active production path requires WebGPU

FFT local-peak refinement

Show2D, Show3D, Show3DSlices, Show4DSTEM, ShowPtycho

migrated candidate; active production path requires WebGPU

disk and annulus detector masks

Show4DSTEM detector compute and local browser compute

migrated candidate

masked DPC magnitude and iCoM integration

Show4DSTEM and local Browse

migrated candidate; GPU reduction and post-processing

block binning, affine transforms, correlation, and subpixel alignment

varies

under audit; not migrated where semantics differ

iterative ptychography reconstruction

none in this migration

explicitly out of scope

“Migrated candidate” means canonical ownership and call sites have moved. It is not a release claim until the acceptance gates below pass on the final commits.

Acceptance gates#

A primitive is complete only when all applicable gates pass:

  1. Freeze a NumPy or other independent reference result before changing the implementation, including zeros, constants, negative values, extreme finite values, NaN/Inf, odd and nonsquare shapes, and dtype boundaries.

  2. Compare every backend that actually implements the primitive: CPU, CUDA, Metal, and WebGPU. An unavailable backend is recorded as unavailable, not as passing.

  3. Prove at least two real widget consumers and retain focused call-site tests.

  4. Build all affected widget bundles and verify that generated engine sources and package artifacts contain the canonical implementation.

  5. Drive affected standalone HTML or notebook widgets after the final code change: validate every marked scientific output for nonzero pixels, dynamic range, and multiple colors or tones; exercise the relevant controls, inspect browser errors, and save screenshots. Hardware signoff must pass --require-hardware-webgpu. Use scripts/widget_local_signoff.sh --quick --browser for the repeatable HTML matrix and Agent signoff for human-driven review.

  6. Record limitations and semantic rejections. Reduced precision, resolution, or evidence cannot be used to claim parity or performance.

Known limitations#

  • Auto-contrast percentages, sampling, linked-panel behavior, and display defaults intentionally remain widget policy.

  • ShowPtycho’s padded/cropped FFT coordinates are not yet represented by the shared reciprocal-coordinate helper.

  • ShowPtycho’s optional complex-HSV display does not yet have a WebGPU shader; it now reports the unavailable view instead of silently CPU-rendering it.

  • ShowEDS sparse stream map, preview, and spectrum paths require WebGPU. Its dense prefix-plane representation remains separate because it is an I/O representation with different semantics, not the same reusable sparse kernel.

  • Show3D registration, quantized kymograph sampling, export encoders, and several widget-specific display policies remain local. They are not evidence that the shared migrated operations have a CPU fallback.

  • Some similarly named operations have different scientific definitions—for example positive-only versus signed logarithms, detector annuli versus FFT crop circles, and different alignment algorithms—and are intentionally not unified.

  • The ordinary headless standalone matrix does not expose hardware WebGPU and therefore cannot sign off these migrated production paths. Hardware WebGPU numerical parity and the full-widget macOS interaction matrix must remain separate release gates.

  • Browser WebGPU parity is verified over the supported finite test range. The full positive/negative float32 extrema remain a documented browser-driver limitation until hardware WebGPU produces stable histogram evidence there.

Update this page when ownership, consumers, or evidence changes. Do not replace the per-run test and signoff reports with this status summary.

Candidate evidence (2026-08-17)#

The tested local branches are named webgpu-required-widget-compute in both repositories. No branch was pushed and no PR or release was created.

Repository

Tested code head

Parent

Starting main

quantem.gpu

5cd285250911974c738e9c911bd00a170873bf45

94c59e22754e1a49779e9270b36308d8051652c2

bfdfa7e0ebefd2b8a86655dbd162368dbc2fa6c3

quantem.widget

de3dc3989561c767c36547298df2b6cc8ee9cd22

a830ea6d5bc22be3ad588227d936afcd5cf7505a

9211cac4dcd6fc7b87157246bbffda4bf725f173

The final candidate was installed from tracked Git archives into a fresh, isolated environment on Phil. This caught missing candidate-version, pandas, ipykernel, macOS Chrome-launch, and test-fixture dependencies before signoff.

Numerical and build gates#

  • Linux quantem.gpu: 293 passed, 55 skipped; real CUDA display parity: 4 passed.

  • Phil/macOS quantem.gpu: 262 passed, 77 skipped with the MPS extra.

  • Phil/macOS quantem.widget: 1134 passed, 33 skipped, 47 warnings; no test failures. Warnings are recorded deprecations/runtime guidance, not numerical mismatches.

  • TypeScript/Vitest: 26 files and 154 passed; TypeScript typecheck passed.

  • Headed Chrome hardware-WebGPU parity: 7 passed on adapter apple metal-3, with softwareAdapter=false. This covers NumPy-referenced histogram/LUT/FFT evidence plus detector masked sum, center of mass, DPC, odd/nonsquare filters, ROI crop/mask, line profile, and FFT peak paths.

  • Swift/Metal: 27 passed (16 Metal4DSTEM and 11 MetalDisplay tests) on arm64e macOS.

  • npm run build built all widget bundles; web/npm run build built the Browse application. A fresh npm ci and npm audit --json reported zero vulnerabilities.

End-to-end browser gates#

The fresh standalone matrix generated 19 exports and passed 38/38 across desktop and 390x844 touch layouts in headed Phil Chrome. This includes Show1D, five Show2D layouts, six Show3D layouts, Show3DSlices, Show4DSTEM single and compare, a ShowPtycho WebGPU folder, ShowEDS, ShowDiffraction, and ShowFolder. Every page acquired apple / metal-3; all 38 adapter records reported is_fallback_adapter=false and software=false.

The browser captured and tested every visible element marked data-quantem-scientific-output, rather than accepting the largest canvas as a proxy for the page. All 126/126 output regions passed: at least eight colors or tones, channel span at least 8, nonblack-pixel fraction at least 0.5%, and mean luminance greater than 1. The observed worst cases were 303 colors or tones, channel span 64, nonblack fraction 90.1%, and mean luminance 4.162. Grayscale scientific data are valid when they have tonal range; chromatic saturation is not required. Every page was interactive, above the 20 browser-rAF FPS gate, and free of page, console-error, and HTTP failures. The lowest measured browser-rAF rate was 119.89. Browser-rAF is an event-loop health signal, not interaction latency.

  • Show2D native stress: 40 exact 4096x4096 uint8 panels; linked contrast changed six visible panels, linked zoom/pan changed six, keyboard selection/hide/restore passed, and every sampled canvas was nonblank. The final linked pan-to-paint measurement was 8.7 ms; a separate single wheel batch was 149.9 ms and is not hidden by the rAF number.

  • Show3D real-data stress: 24 real 2048x2048 drift frames passed desktop, wide, and narrow viewports with apple metal-3, nonblank composited-pixel checks, histogram Auto-to-manual contrast, slider and keyboard scrub, playback, FFT toggle, and zoom/pan. Final interaction latency was 1.3-1.8 ms in the widget debug evidence.

  • Show3DSlices: a real-derived odd/nonsquare 17x511x769 volume; slice playback, oblique-angle, FFT, and contrast interactions changed visible pixels.

  • Show4DSTEM: actual single-tilt and seven-tilt command launchers; all 28 seven-tilt HDF5 family requests completed, and detector-radius drag changed the virtual-image canvas while the pointer remained held.

  • ShowEDS: a 96x128x512 spectrum image with deterministic Au-like peaks; band, ROI, log-scale, Save Band, and Save ROI paths passed, and both map and spectrum reported webgpu as their producing backend.

  • ShowPtycho: non-iterative SSB review only, using a real 128x128 crop from a 512x512 HDF5 source prepared on MPS and reopened through the actual WebGPU folder launcher. Exported BF columns matched probed raw source coordinates; BF count and C10 changed nonblank phase/FFT evidence, amplitude was GPU-native, and complex HSV reported unavailable instead of using a CPU fallback.

The stress pass corrected three false-negative test-driver assumptions: MUI range inputs use an implicit slider role, visible-panel hashes must follow the viewport, and WebGPU canvas pixels must be checked from the browser’s composited output. Show3D’s existing WebGPU-to-retained-2D zoom fallback is accepted only when the destination remains readable and nonblank; the dangerous 2D-to-WebGPU swap remains a failing continuity condition. This presentation fallback is not a CPU implementation of the migrated numerical kernels.

The hardware pass found and fixed two product blockers before this evidence was recorded: native uint8 Show2D galleries could paint black at 4096x4096, and a cropped ShowPtycho export wrote the full source scan plane while declaring the crop shape. The final matrix had no application console errors; one existing ShowDiffraction passive-listener warning remains recorded.

These are candidate-branch results, not a public release signoff. CUDA and Metal are recorded only for primitives with real implementations; a WebGPU-only display primitive is not presented as CUDA/Metal parity. Iterative ptychography remains explicitly outside this migration.