Optimization of stitching, inference, added (optional) low-precision compute - #3
Open
cophus wants to merge 5 commits into
Open
Optimization of stitching, inference, added (optional) low-precision compute#3cophus wants to merge 5 commits into
cophus wants to merge 5 commits into
Conversation
Identical results; multithreads the cross-correlation FFTs in masked_correlation_patch_stitching for a free speedup on multi-core CPUs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
When a shift-vector direction has no edges (degenerate/poorly-connected graph), np.array([]) is float64, which broke the concatenated integer indexing in the direct position solve. Force intp dtype so these cases behave like the original torch path (which coerced via LongTensor). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Convolutions can run in bfloat16/float16 on the GPU tensor cores while batch-norm statistics stay in float32 for stability. Params stay float32 (same pickled weights). Default float32 is bitwise-identical to before. Measured vs float32 on Model10: float16 ~0.1% max / 0.008% mean rel error (tensor-core accelerated, best accuracy); bfloat16 ~1.5% max but full fp32 range (safe fallback if fp16 activations overflow on real data). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
learn_stitch(..., backend='jax') runs the array-heavy phases (FFT cross-correlations, peak finding, upsampled-DFT shift refinement, and the windowed patch shift+accumulate) on the GPU, keeping the networkx graph prune and the sparse position solve on the CPU. Selected in the eval script via PTYRAN_STITCH_BACKEND=jax. Default numpy path is unchanged. Runs in float32; matches the float64 numpy stitched image to ~3e-7 relative (NaN masks and output shape identical) on 20/50/124 grids. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Speeds up the experimental 4D-STEM reconstruction pipeline ~2.5× end-to-end on an NVIDIA L4 (233 s → 93 s over the 4-dataset benchmark; 49 s → 19 s per single reconstruction) while keeping results essentially identical. The gains come from three independent areas — position-corrected stitching, network-inference data movement, and optional low-precision compute. The default numerical path is unchanged; every new behavior is opt-in.
Results (NVIDIA L4, 4 experimental datasets)
The middle column is the bitwise-safe tier (stitching rewrite + inference data movement); the right column adds opt-in float16 inference. (For single reconstructions, fp16 + the numpy stitch backend is marginally faster still — it avoids the one-time GPU-stitch compile — for ~2.7×.)
What changed
1. Position-corrected stitching (
learn_stitch): 118 s → 45 s (2.6×)Replaced three per-item Python loops with vectorized equivalents:
torchdependency.)einsum(factored kernel → shared GEMM).scipy.ndimage.shiftloop → batched bilinear shift + scatter.maximum_filter; cross-correlation FFTs multithreaded (workers=-1).Output differs from the old Adam result only by a smooth sub-0.1% global gauge term (exact optimum vs. under-converged iterate); the output array size can differ by ≤1 px at the masked border.
2. Inference data movement (bitwise identical)
3. Optional mixed-precision inference (
PTYRAN_PRECISION)Convolutions can run on the tensor cores in
float16/bfloat16(batch-norm stays float32; weights stay float32). Defaultfloat32is bitwise-unchanged. On the L4: float16 = 2.3× faster inference at 0.23% max output difference; bfloat16 = 2.4× at 2.3%. float16 is the recommended fast path; bfloat16 is the fallback if a dataset overflows fp16's range.4. Optional GPU stitching backend (
PTYRAN_STITCH_BACKEND=jax)Runs the stitching FFTs / peak-finding / refinement / accumulate on the GPU (graph-prune + position solve stay on CPU); matches the numpy result to ~3e-7 (identical shapes and NaN masks). On the L4 this is roughly break-even with the already-vectorized CPU stitching for these sizes, so the numpy backend remains the default; the GPU backend mainly helps CPU-constrained runtimes.
Accuracy & compatibility
float32, numpy stitch, and the original host gather all still available) is unchanged. New behavior is entirely opt-in.PTYRAN_PRECISION=float32|bfloat16|float16;PTYRAN_STITCH_BACKEND=numpy|jax.learn_stitch(..., backend=),loop_batch_exp(..., on_device_gather=),Autoencoder(..., compute_dtype=).torchdependency from stitching; addedscipy.sparse. Also fixed a degenerate-graph crash (empty shift-vector directions).Colab testing notebooks