FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
Developing new stages: design & optimization decisions

STATUS: WORK IN PROGRESS — outline only. This page is a scaffold for a future deep-dive. The mechanical "how to add a stage" steps already live in how_to_add_a_stage.md; the specialization declaration contract lives in pipeline_specialization_internals.md. This page is meant to capture the judgment those two don't: how to decide a stage's shape, ports, access pattern, and how it connects to and is optimized by the rest of the pipeline. Sections below are stubs — fill them in with worked examples and measured evidence as the design stabilizes. Do not treat unfilled sections as authoritative.


1. Before you write a stage: is it a stage at all?

  • [ ] When a new capability is a composition of existing stages vs. a genuinely new primitive. (Case study: SZp was retired to a composed Quantizer → Lorenzo → AdaptiveBitpack chain rather than kept as a monolithic stage; SZx could not be, because of its per-block conditional representation. Cross-link: docs/experimental/szp.md.)
  • [ ] Stage vs. structural node vs. policy-on-an-existing-stage (e.g. a coder variant is often a setX() flag, not a new class).
  • [ ] The "whole compressor as a stage" anti-pattern and when it's justified (reference/experimental only).

2. Choosing the stage's shape

  • [ ] Ports: number of inputs/outputs, named ports, why ("codes" vs "output").
  • [ ] Data types in/out; templating over element type; when to specialize.
  • [ ] Size behavior: size-preserving vs. expanding vs. compacting; the bidirectional estimateOutputSizes contract and its worst-case bound.
  • [ ] Dimension awareness (setDims) and when a stage needs it before addStage.
  • [ ] Multi-output stages and escaping side outputs (outlier lists, means).

3. The access pattern decision (this is the load-bearing one)

  • [ ] Mapping the algorithm to a FusionAccess role (Elementwise / RegionLocal / SegmentCodec / TileSelector / Unfusable) — and why that choice determines everything downstream about how (and whether) the stage can be optimized.
  • [ ] Block geometry: choosing a reset period / block size; alignment to warps (32·EPL) vs. chunks (16 KB); how the choice interacts with occupancy.
  • [ ] What makes a stage a genuine fusion barrier (global codebook, whole-array scan) vs. a chain member.
  • [ ] TODO: a decision flowchart from "what does my kernel read per output element" → role.

4. Connections & the DAG

  • [ ] How a stage's ports become DAG edges; the connect(down, up, port) model.
  • [ ] Buffer lifetime, coloring/aliasing, and why fused stages disable coloring.
  • [ ] External input binding (bindExternalInput, multi-source pipelines).
  • [ ] Inverse DAG construction: how forward ports map to inverse edges; what a stage must expose so its inverse can be rebuilt from the FZM header alone.

5. Optimization decisions

  • [ ] Staged first, always: the staged kernel is the correctness oracle and the throughput baseline. Never optimize before it round-trips.
  • [ ] Per-kernel optimization before fusion (coalescing, barrier removal, warp cooperation) — with the profiling method (ncu sectors/request, pipe analysis). Cross-link: docs/decompress_kernel_optimizations.md.
  • [ ] A future "should I specialize?" cost model: predict the specialized ceiling from per-stage traffic, launch removal, scans, and occupancy. The current Auto policy uses an evidence-gated registry rather than a per-input predictor. Explain why optimizing a bottleneck can raise the specialization ceiling (bitshuffle case study).
  • [ ] Specialization declaration: forward + inverse ops, priming, the shared POD params contract. Cross-link: pipeline_specialization_internals.md.
  • [ ] Strategy selection: warp-register (≤64–128 elem blocks, registers) vs. chunk-cooperative (16 KB, shared memory) vs. thread-independent — the measured crossovers and when each wins.
  • [ ] When NOT to add a fused backend (unprofitable; the FSZ tile-execution prototype was built, measured below staged, and removed — keep the semantic declarations, drop the kernel).

6. Correctness & attribution obligations

  • [ ] The validation matrix: byte-identical archive, byte-exact round-trip, compute-sanitizer (memcheck + racecheck + synccheck for shuffles), partial final blocks, f32/f64, ABS/NOA/REL, full-corpus samples.
  • [ ] Where longform evidence goes (docs/codebase_notes.md, CN-* IDs) vs. inline contracts. Cross-link: AGENTS.md "Longform notes vs. inline comments".
  • [ ] Prior-work attribution (THIRD_PARTY.md, acknowledgements, module cards).

7. Worked examples (to be written)

  • [ ] An Elementwise stage from scratch (e.g. a transform), staged → declared → fused.
  • [ ] A RegionLocal predictor, including its forward+inverse device policy.
  • [ ] A SegmentCodec coder, including the exact encoded-size oracle contract.
  • [ ] A structural stage (no compression op) and why it exists.