Native Direct Ptycho preparation, 2026-11-05#

The complete five-second native-app target is not yet established. These measurements concern Swift/Metal; they do not qualify the Python MPS or CUDA implementations.

Workload and reference#

Apple M5 Max, 128 GiB unified memory, AC power. Full 512 × 512 scan positions and 192 × 192 detector pixels, original integer counts, 200 search trials, both estimated-rotation branches, fifth-order refinement and the existing half-band consistency check. Source calibration, BF selection, precision, search settings and fallback rules remain fixed within each comparison.

The private experiment ID is live4dstem-rc2-optimization-20261105. Its frozen backend control is 99bf9026, based on 373725d8 with the preceding native integration changes preserved. Raw source identities, command receipts, patches, arrays and app screenshots remain in that private archive.

Verified preparation improvements#

  • Fuse the final FFT transpose with the Hermitian-cache write, retaining exactly the original Fourier values.

  • Fuse the integer conversion with the first 512-point FFT stage. Threadgroup staging preserves the original arithmetic for uint8, uint16 and uint32. A register-only alternative failed exact parity and was rejected.

  • Gather cached spectra in larger batches and traverse the existing power buffer contiguously. Each frequency retains its original Double summation order. Partly cached and fully streamed cases retain bounded batches.

  • Decode QEM columns with contiguous stores through a bounded shared tile. Specialize native-width output to avoid unnecessary row-padding indexing. Padded scans use the same exact count decoder with the original layout.

Matched warm Fourier preparation with the first fusion already enabled fell from 0.59–0.63 s to 0.54–0.56 s across three acquisitions. Model preparation fell from approximately 0.26–0.33 s to 0.15–0.24 s. These are isolated stages, not total interaction times.

For two QEM acquisitions with 9,081 and 9,110 selected detector columns, interleaved column-decoder measurements gave:

Selected-column GPU decoding

Original

Coalesced stores

Native-width

Parallel chunks

Acquisition A

1.88–1.90 s

1.45 s

1.25 s

0.331 s

Acquisition B

1.89–1.91 s

1.47 s

1.28 s

0.333 s

All returned column hashes match the frozen original. The reusable runner is metal-qem-detector-update-benchmark --columns acquisition.qem pixels.json 3; the JSON pixel list contains detector indices in the requested order. It hashes all returned counts outside synchronized GPU timing and checks original diffraction samples independently. The parallel-chunk comparison uses three repetitions per condition, interleaved serial/parallel/serial. Independent chunks write disjoint positions of the existing bounded 32-plane output buffer; the ANS stream order and integer counts are unchanged. An argument table adds 32 bytes per chunk (1 KiB for these acquisitions, bounded at 4 KiB), included in resident accounting. The Metal allocator reports the same allocation totals; this is not a claim of zero extra metadata bytes or a 16 GiB working set.

Synthetic tests additionally cover partial restart blocks, multiple chunks starting inside a scan row, flagged pixels, repeated indices, scan padding, and zero, constant, sparse, entropy and literal count streams.

Correctness and acceptance boundaries#

QEM stored moments include flagged counts, whereas ordinary selected-column reads mask them. includeFlaggedPixels: true explicitly retrieves original counts for exact moment replacement; the default still masks them. Neither the source nor its validity mask is changed. Native app rotation now uses the original flagged values and verifies the remaining independent valid total.

Full 200-trial, fifth-order benchmark results on three acquisitions match the frozen fitted parameters, branch decisions, objectives and consistency checks exactly. Independent count tests and native direct/Phase/Complex image comparisons are separate gates. Format-specific BF estimation differences must be recorded; matched comparisons use explicit session-only geometry, without modifying source calibration.

Small-batch and eight-candidate layouts, paired Double normalization, additional zero-support culling and several decoder layouts preserved values but failed to establish a speed improvement; they are archived, not retained as production tuning choices. GPU and host timings drift under normal desktop conditions. Report first observations separately from repeated timings, and do not call a warm minimum a cold result.

The first cleaned default passed 17 focused backend tests and seven native reconstruction journeys plus three native binding-driven slider journeys. The registered final candidate passed 15 uninterrupted native journeys (three repetitions for five acquisition/format combinations), with exact initial/final fits, exact initial-method images and positive first/final drawable receipts. The first repetition of each combination also checked all three reconstruction methods. Two injected memory-pressure recovery journeys passed.

Matched serial/parallel/serial native Fourier preparation was 1.801/0.639/1.828 s for acquisition A and 1.920/0.688/1.920 s for acquisition B. All fits and method images matched. This supports a roughly 2.8-fold preparation improvement; it is not a whole-pipeline speedup. Lazy compilation now builds only the requested column layout and the separately requested totals pipeline.

The final three-repeat native measurements are:

Acquisition/source

Run to checked image, median (range)

Launch to checked image, median (range)

A / HDF5

7.85 (5.11–9.18) s

10.27 (7.84–11.81) s

A / QEM

7.09 (4.93–8.94) s

8.62 (7.42–10.33) s

B / HDF5

11.26 (6.61–13.35) s

14.06 (9.26–15.90) s

B / QEM

11.17 (9.18–13.75) s

12.57 (10.79–15.15) s

C / HDF5

8.96 (5.22–9.37) s

11.31 (7.79–11.83) s

Native test hooks request Run and Refine in separate immediately consecutive actions. Their action gap and consistency checks are included; screenshots occur after timed work. The source page-cache state is unspecified. The macOS thermal state moved from nominal to fair during the run, coincident with increased fit time. GPU clocks were not measured, so this does not establish the sole cause of timing drift. Fourier preparation remained comparatively stable. These are native-window tests, not physical mouse or trackpad acceptance.

Acquisitions A and B retain the original standard-range fallback and untrusted higher-order flag; C retains the wide-range result. Exact parity includes these decisions. A completed check is not the same as trusted physical coefficients.

The full Swift backend suite passed 311 tests with 31 fixture-dependent skips and zero failures. Frozen CUDA image references and native full-count audits are separate acceptance gates; their completion is recorded in the private archive. Loading, first image, checked fifth-order result, cache interactions and positive drawable presentation must be reported separately. An active-stage sum that excludes loading or the Run-to-Refine action gap is not open-to-final latency. No release, cross-device speed claim or 16 GiB memory guarantee follows from these measurements.