Experimental lossless resident ANS#
ANS means asymmetric numeral systems. Supported original acquisitions now
default to ANS on CUDA/MPS through io.load(path). This page retains experimental
browser/archive integrations; their qualification is distinct from that default.
See the current IO guide for supported formats and the
acceptance gate for runtime coverage.
Source integration does not mean these changes have been released on PyPI.
Compatibility safeguards#
The loader detects encoded sources. Explicit reference inputs retain their separate contract. Encoding writes a new container atomically and refuses to overwrite an existing file; original acquisitions remain intact. Source ownership and cancellation are covered by regression tests. These are specific safeguards, not a guarantee that every experimental hardware path is qualified. The performance and validation limits below remain part of the feature.
One implementation owner#
quantem.gpu owns the count encoder, validated container reader, CUDA decoders,
WebGPU decoders, detector reductions, pattern gathering, and shared GPU display
math. Show4DSTEM owns browser permission prompts, progressive panel display,
selection, gestures, and scheduling. Its build copies the package’s TypeScript
sources into the ignored js/.generated/engine directory and bundles them;
those generated files are not an independently maintained codec.
Input |
Package implementation |
Client route |
|---|---|---|
K3 saved copies, |
CUDA and Metal encoding, checksummed reopening, spatial queries |
Python CUDA/MPS and native Live4DSTEM macOS |
Saved |
|
CUDA/MPS resident queries; native Live4DSTEM macOS |
Retained detector-rANS manifest |
WebGPU |
Show4DSTEM WebGPU export |
These are explicitly identified formats, not interchangeable byte streams. The canonical writer is shared; compatibility readers retain older experiments without rewriting source data. Full-series conversion of every retained archive to the canonical container is not a completed acceptance gate.
Encode and query canonical counts#
from quantem.gpu import detector, io
# resident: an encoded acquisition from io.load, native uint8/uint16 counts,
# (scan_row, scan_col, detector_row, detector_col)
io.save("acquisition.qem", resident)
with io.load("acquisition.qem", backend="cuda", device=0) as loaded:
session = detector.prepare(loaded)
pattern = session.frame(0, output="native")
image = session.masked_sum_exact(binary_detector_mask, output="native")
device=0 means the first CUDA-visible device; select the intended physical GPU
before launching Python. Saving copies the resident’s encoded bytes without
re-encoding; it is not a claim of real-time full-acquisition compression. CUDA
residency retains encoded buffers and produces device results without
constructing a full dense acquisition. See the container contract for dtype, checksums,
invalid pixels, conversion, and lifetime rules.
Compatible ANS acquisitions can be retained independently on MPS and queried as one detector session without dense stacking:
from quantem.gpu import detector, io
loaded = io.load(paths, backend="mps", stack=False)
session = detector.prepare(loaded)
patterns = session.frame(scan_row * scan_columns + scan_column)
images = session.masked_sums_exact(masks) # (mask, acquisition, scan_row, scan_column)
All files must declare the same complete scan and detector geometry. The series
adapter runs each query on each acquisition in turn and stacks the results along
the acquisition axis, so every value equals the result of preparing that
acquisition alone; it returns only the requested point patterns or detector
products. Each Dataset4dstemGPU owner remains caller-owned and must be closed
after the session is finished. This is the supported
multi-file ANS API, not a claim that arbitrary HDF5 folders are encoded as ANS
automatically.
Show4DSTEM WebGPU#
The widget package supplies the browser export, using the same package reader:
from quantem.widget.show4dstem_webgpu_export import export_show4dstem_rans_viewer
html = export_show4dstem_rans_viewer(
["acquisition.qem", "next-acquisition.qem"],
"ans-viewer",
frame_labels=["First", "Second"],
)
Open the generated launcher/viewer and use Open QEM files to grant access
to the linked .qem files in ans-viewer/rans. Export preserves native shape
and dtype, links the .qem files, and does not decode or duplicate the full
acquisition. Keep the source files available.
The canonical-file workflow above is the browser export integration.
Raw hardware sentinel counts are preserved. The established detector validity mask is applied only to displayed scientific products. Integer native patterns and detector sums require exact reference equality. Count means use explicitly rounded float32 division; native sums remain exact for the validated series.
Qualification and limits#
Releasing the resident owner or closing the viewer releases its encoded source and display buffers. Failed/cancelled admissions must release owned allocations. Do not delete original acquisitions, canonical containers, or retained archive payloads as part of branch or benchmark cleanup.
Maintainer checks#
Build Show4DSTEM with
QUANTEM_GPU_SRCpointing to this package’ssrctree.Run count-ANS integer round trips and browser-export tests for native dtypes.
Run
tests/webgpu/display-readback-lifecycle.tsfor ownership failures.On an identified real adapter, run native source parity and
tests/webgpu/resident-pattern-mean-parity.ts.Drive selected and averaged scan drags with the button held, then verify the endpoint against original counts. Separately check detector drags, contrast, zoom, copy, progressive loading, cancellation, and device loss.
Count fresh scientific output, not animation callbacks or repeated paints.