FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
fzm_format.h
Go to the documentation of this file.
1#pragma once
2
20#include <cstdint>
21#include <cstring>
22#include <stdexcept>
23#include <string>
24
25namespace fz {
26
28constexpr uint32_t FZM_MAGIC = 0x464D5A32;
29
40constexpr uint8_t FZM_VERSION_MAJOR = 3;
41constexpr uint8_t FZM_VERSION_MINOR = 1;
42constexpr uint16_t FZM_VERSION = (static_cast<uint16_t>(FZM_VERSION_MAJOR) << 8)
43 | static_cast<uint16_t>(FZM_VERSION_MINOR);
44
46constexpr size_t FZM_LEGACY_HEADER_CORE_SIZE = 72;
47
48constexpr uint16_t FZM_FLAG_HAS_DATA_CHECKSUM = 0x0001u;
49constexpr uint16_t FZM_FLAG_HAS_HEADER_CHECKSUM = 0x0002u;
50
55constexpr uint8_t fzmVersionMajor(uint16_t v) {
56 return (v <= 0xFF) ? static_cast<uint8_t>(v) : static_cast<uint8_t>(v >> 8);
57}
59constexpr uint8_t fzmVersionMinor(uint16_t v) {
60 return (v <= 0xFF) ? 0u : static_cast<uint8_t>(v & 0xFF);
61}
62
63constexpr size_t FZM_MAX_BUFFERS = 32;
64constexpr size_t FZM_MAX_NAME_LEN = 64;
65constexpr size_t FZM_STAGE_CONFIG_SIZE = 128;
66constexpr size_t FZM_MAX_SOURCES = 4;
67
78constexpr uint16_t FZM_STAGE_FLAG_PRIMARY_SOURCE = 0x1;
79
80// ─────────────────────────────────────────────────────────────────────────────
81
88enum class StageType : uint16_t {
89 UNKNOWN = 0,
90 LORENZO_QUANT = 1,
91 DIFFERENCE = 2,
92 SCALE = 3,
93 PASSTHROUGH= 4,
94 RLE = 5,
95 HUFFMAN = 6,
96 BITPACK = 7,
97 SPLIT = 10,
98 MERGE = 11,
99 LORENZO = 12,
100 QUANTIZER = 14,
101 ZIGZAG = 15,
102 NEGABINARY = 16,
103 BITSHUFFLE = 17,
104 RZE = 18,
105 ANS = 20,
106 // 19 reserved (formerly a removed transform stage; do not reuse — old
107 // archives may still carry it in a serialized stage-type field).
108 G_INTERP = 22,
109 BITPLANE_RZE = 23,
110 ADAPTIVE_BITPACK = 24,
111 TILED_LORENZO = 25,
112 RRE = 26,
113 RARE = 27,
114 RAZE = 28,
115 CLOG = 29,
116 HCLOG = 30,
117 TUPL = 31,
118 GPULZ = 32,
119 LOG_TRANSFORM = 33,
120 ADAPTIVE_LORENZO = 34,
121 ROIBIN_SPLIT = 35,
122 SZX = 36,
123 SZP = 37,
124 // 38 (TEE, SPERR-branch-only) never shipped on main -- bindExternalInput()
125 // replaced the fan-out/duplicate-copy stage it would have been for before
126 // this branch merged. Not reused -- a future stage type reading an old
127 // archive that used it should fail loudly, not silently collide.
128 CDF97 = 39,
129 SPECK2D = 40,
131 GOLOMB_RICE = 42,
133};
134
142enum class DataType : uint8_t {
143 UINT8 = 0,
144 UINT16 = 1,
145 UINT32 = 2,
146 UINT64 = 3,
147 INT8 = 4,
148 INT16 = 5,
149 INT32 = 6,
150 INT64 = 7,
151 FLOAT32 = 8,
152 FLOAT64 = 9,
153 UNKNOWN = 0xFF,
154};
155
156// ─────────────────────────────────────────────────────────────────────────────
157
158constexpr size_t FZM_MAX_STAGE_INPUTS = 8;
159constexpr size_t FZM_MAX_STAGE_OUTPUTS = 8;
160
172 uint16_t stage_version;
173 uint8_t num_inputs;
174 uint8_t num_outputs;
175 uint16_t stage_flags;
176
177 uint16_t input_buffer_ids[FZM_MAX_STAGE_INPUTS];
178 uint16_t output_buffer_ids[FZM_MAX_STAGE_OUTPUTS];
179
181 uint32_t config_size;
182
183 uint8_t reserved2[84];
184 // Total: 2+2+1+1+2+16+16+128+4+84 = 256 bytes
185
186 FZMStageInfo() {
187 // Zero the WHOLE object, not just the named arrays. This struct is
188 // written to disk verbatim, and the compiler's implicit tail padding
189 // (fields end at 254, sizeof is 256) is not covered by the member-wise
190 // initialization below — so an .fzm archive carried a few bytes of stack
191 // garbage and was not byte-reproducible across runs. See FZMBufferEntry.
192 std::memset(this, 0, sizeof(*this));
193 stage_type = StageType::UNKNOWN;
194 stage_version = 0;
195 num_inputs = 0;
196 num_outputs = 0;
197 stage_flags = 0;
198 memset(input_buffer_ids, 0xFF, sizeof(input_buffer_ids));
199 memset(output_buffer_ids, 0xFF, sizeof(output_buffer_ids));
201 config_size = 0;
202 memset(reserved2, 0, 84);
203 }
204};
205static_assert(sizeof(FZMStageInfo) == 256, "FZMStageInfo must be 256 bytes");
206
217 uint16_t stage_version;
220 uint16_t dag_buffer_id;
222
223 uint64_t data_size;
224 uint64_t allocated_size;
226 uint64_t byte_offset;
227
229 uint32_t config_size;
230
231 uint8_t reserved2[14];
232
234 // Zero the WHOLE object before setting fields. The named members end at
235 // byte 250 but sizeof(FZMBufferEntry) is 256 (8-byte alignment), and
236 // those 6 padding bytes are written straight to disk with the rest of
237 // the struct. Left uninitialized they made compression non-deterministic:
238 // two runs over CESM-2D/CLDHGH through gpu_zstd_lossless.toml produced
239 // archives differing in exactly 12 bytes — 2 padding bytes in each of the
240 // 4 buffer entries, plus the 4-byte header_checksum computed over them.
241 // Round-trip was unaffected (the padding is never read back), which is
242 // why it survived; but it breaks byte-for-byte reproducibility, and
243 // benchkit records compressed_sha256 per row and compares baselines
244 // across machines on exactly that.
245 std::memset(this, 0, sizeof(*this));
246 stage_type = StageType::UNKNOWN;
247 stage_version = 0;
248 data_type = DataType::UINT8;
250 dag_buffer_id = 0xFFFF;
251 memset(name, 0, FZM_MAX_NAME_LEN);
252 data_size = 0;
253 allocated_size = 0;
255 byte_offset = 0;
257 config_size = 0;
258 memset(reserved2, 0, 14);
259 }
260};
261static_assert(sizeof(FZMBufferEntry) == 256, "FZMBufferEntry must be 256 bytes");
262
276 uint32_t magic;
277 uint16_t version;
278 uint16_t num_buffers;
279
282 uint64_t header_size;
283
284 uint32_t num_stages;
285 uint16_t num_sources;
286 uint16_t flags;
287
294
295 uint32_t data_checksum;
297
298 FZMHeaderCore() {
300 version = FZM_VERSION;
301 num_buffers = 0;
303 compressed_size = 0;
304 header_size = sizeof(FZMHeaderCore);
305 num_stages = 0;
306 num_sources = 0;
307 flags = 0;
309 data_checksum = 0;
310 header_checksum = 0;
311 }
312
314 uint64_t computeHeaderSize() const {
315 return sizeof(FZMHeaderCore)
316 + num_stages * sizeof(FZMStageInfo)
317 + num_buffers * sizeof(FZMBufferEntry);
318 }
319};
320static_assert(sizeof(FZMHeaderCore) == 80, "FZMHeaderCore must be 80 bytes");
321
322// ─────────────────────────────────────────────────────────────────────────────
323// Helper functions
324// ─────────────────────────────────────────────────────────────────────────────
325
327inline size_t getDataTypeSize(DataType type) {
328 switch (type) {
329 case DataType::UINT8: case DataType::INT8: return 1;
330 case DataType::UINT16: case DataType::INT16: return 2;
331 case DataType::UINT32: case DataType::INT32: case DataType::FLOAT32: return 4;
332 case DataType::UINT64: case DataType::INT64: case DataType::FLOAT64: return 8;
333 default: throw std::runtime_error("Unknown data type");
334 }
335}
336
338inline std::string dataTypeToString(DataType type) {
339 switch (type) {
340 case DataType::UINT8: return "uint8";
341 case DataType::UINT16: return "uint16";
342 case DataType::UINT32: return "uint32";
343 case DataType::UINT64: return "uint64";
344 case DataType::INT8: return "int8";
345 case DataType::INT16: return "int16";
346 case DataType::INT32: return "int32";
347 case DataType::INT64: return "int64";
348 case DataType::FLOAT32: return "float32";
349 case DataType::FLOAT64: return "float64";
350 default: return "unknown";
351 }
352}
353
355inline std::string stageTypeToString(StageType type) {
356 switch (type) {
357 case StageType::LORENZO_QUANT: return "LorenzoQuant";
358 case StageType::DIFFERENCE: return "Difference";
359 case StageType::SCALE: return "Scale";
360 case StageType::PASSTHROUGH: return "PassThrough";
361 case StageType::RLE: return "RLE";
362 case StageType::HUFFMAN: return "Huffman";
363 case StageType::BITPACK: return "BitPack";
364 case StageType::SPLIT: return "Split";
365 case StageType::MERGE: return "Merge";
366 case StageType::ROIBIN_SPLIT: return "ROIBinSplit";
367 case StageType::SZX: return "SZx";
368 case StageType::SZP: return "SZp";
369 case StageType::QUANTIZER: return "Quantizer";
370 case StageType::ZIGZAG: return "Zigzag";
371 case StageType::NEGABINARY: return "Negabinary";
372 case StageType::BITSHUFFLE: return "Bitshuffle";
373 case StageType::RZE: return "RZE";
374 case StageType::RRE: return "RRE";
375 case StageType::RARE: return "RARE";
376 case StageType::RAZE: return "RAZE";
377 case StageType::CLOG: return "CLOG";
378 case StageType::HCLOG: return "HCLOG";
379 case StageType::TUPL: return "TUPL";
380 case StageType::LORENZO: return "Lorenzo";
381 case StageType::ANS: return "ANS";
382 case StageType::G_INTERP: return "GInterp";
383 case StageType::BITPLANE_RZE: return "BitplaneRZE";
384 case StageType::ADAPTIVE_BITPACK: return "AdaptiveBitpack";
385 case StageType::TILED_LORENZO: return "TiledLorenzo";
386 case StageType::GPULZ: return "GPULZ";
387 case StageType::LOG_TRANSFORM: return "LogTransform";
388 case StageType::ADAPTIVE_LORENZO: return "AdaptiveLorenzo";
389 case StageType::FUSED_QUANT_ADAPTIVE_LORENZO: return "FusedQuantAdaptiveLorenzo";
390 case StageType::CDF97: return "CDF97";
391 case StageType::SPECK2D: return "SPECK2D";
392 case StageType::CDF97_OUTLIER_CORRECT: return "Cdf97OutlierCorrect";
393 case StageType::GOLOMB_RICE: return "GolombRice";
394 default: return "Unknown";
395 }
396}
397
398} // namespace fz
Definition dag.h:24
size_t getDataTypeSize(DataType type)
Definition fzm_format.h:327
constexpr uint8_t FZM_VERSION_MAJOR
Definition fzm_format.h:40
std::string dataTypeToString(DataType type)
Definition fzm_format.h:338
std::string stageTypeToString(StageType type)
Definition fzm_format.h:355
constexpr uint8_t fzmVersionMinor(uint16_t v)
Definition fzm_format.h:59
constexpr uint16_t FZM_STAGE_FLAG_PRIMARY_SOURCE
Definition fzm_format.h:78
constexpr size_t FZM_MAX_SOURCES
Maximum source stages per pipeline.
Definition fzm_format.h:66
constexpr size_t FZM_STAGE_CONFIG_SIZE
Per-stage serialized config slot (bytes)
Definition fzm_format.h:65
constexpr uint8_t fzmVersionMajor(uint16_t v)
Definition fzm_format.h:55
constexpr uint16_t FZM_FLAG_HAS_DATA_CHECKSUM
data_checksum field is valid
Definition fzm_format.h:48
constexpr uint32_t FZM_MAGIC
Definition fzm_format.h:28
StageType
Stage type identifiers written into the FZM header.
Definition fzm_format.h:88
@ TUPL
Tuple deinterleave (AoS -> SoA) transpose (LC framework lossless component)
@ SZP
SZp / fZ-light: quantize + 1-D Lorenzo delta + fixed-length bitpack. QUARANTINED experimental referen...
@ ADAPTIVE_BITPACK
Per-block adaptive fixed-rate bit-plane coder (cuSZp plain mode)
@ LOG_TRANSFORM
Log-space transform for point-wise relative bounds (Liang et al., CLUSTER'18)
@ ANS
rANS entropy coder (GPU, via dietGPU)
@ SPECK2D
GPU-parallel "wavefront" SPECK-like coder (2-D), decode-parallel format.
@ GPULZ
TODO: describe this stage.
@ RRE
Repeated-word bitmap reducer with recursive bitmap compression (LC component)
@ ROIBIN_SPLIT
Region-of-interest / binned-background split (ROIBIN-style dual-error-bound branching)
@ GOLOMB_RICE
Chunk-local Golomb-Rice entropy coder (exact per-chunk k, escape-bounded)
@ CLOG
Per-subchunk leading-zero compression and bit packing (LC framework component)
@ CDF97
CDF 9/7 biorthogonal wavelet transform (SPERR's DWT front-half)
@ TILED_LORENZO
Dimension-aware (tiled separable) Lorenzo predictor (cuSZp3 delta)
@ BITPLANE_RZE
Fused bitplane transpose + zero-group RZE (FZ-GPU lossless encoder)
@ RARE
Adaptive top-bit matching generalization of RRE (LC component)
@ SZX
SZx ultrafast EB compressor: per-block constant/non-constant classification + fixed-length residuals ...
@ ADAPTIVE_LORENZO
Per-tile adaptive multi-order Lorenzo + centering (FSZ prediction stage)
@ RAZE
Adaptive leading-zero-bit generalization of RZE (LC component)
@ CDF97_OUTLIER_CORRECT
Sparse outlier correction, guarantees the GPU SPERR pipeline's pointwise bound.
@ G_INTERP
Spline interpolation predictor + quantizer (cuSZ-Hi G-Interp)
@ FUSED_QUANT_ADAPTIVE_LORENZO
AdaptiveLorenzo with the upstream linear Quantizer fused into its forward kernel (FSZ "M1" partial fu...
@ HCLOG
CLOG bit packing with per-subchunk TCMS selection (LC framework component)
constexpr uint16_t FZM_FLAG_HAS_HEADER_CHECKSUM
header_checksum field is valid
Definition fzm_format.h:49
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:142
constexpr size_t FZM_LEGACY_HEADER_CORE_SIZE
Definition fzm_format.h:46
constexpr size_t FZM_MAX_NAME_LEN
Maximum output port name length (bytes, null-terminated)
Definition fzm_format.h:64
constexpr size_t FZM_MAX_BUFFERS
Maximum pipeline output buffers per file.
Definition fzm_format.h:63
Per-buffer metadata record written into the FZM header (256 bytes).
Definition fzm_format.h:215
StageType stage_type
Producer stage type (2B)
Definition fzm_format.h:216
uint64_t data_size
Actual compressed bytes in this segment (8B)
Definition fzm_format.h:223
uint8_t producer_output_idx
Which output port of the producer (1B)
Definition fzm_format.h:219
uint64_t uncompressed_size
Bytes after fully decompressing this stage's output (8B)
Definition fzm_format.h:225
uint8_t stage_config[FZM_STAGE_CONFIG_SIZE]
Producer stage config, see Stage::serializeHeader() (128B)
Definition fzm_format.h:228
char name[FZM_MAX_NAME_LEN]
Output port name, null-terminated (64B)
Definition fzm_format.h:221
DataType data_type
Element data type in this buffer (1B)
Definition fzm_format.h:218
uint64_t allocated_size
Buffer capacity required for decompression (8B)
Definition fzm_format.h:224
uint8_t reserved2[14]
Reserved for future use (14B)
Definition fzm_format.h:231
uint32_t config_size
Valid bytes in stage_config (4B)
Definition fzm_format.h:229
uint16_t dag_buffer_id
DAG buffer ID used for inverse routing; 0xFFFF = unassigned (2B)
Definition fzm_format.h:220
uint16_t stage_version
Producer stage config version (2B)
Definition fzm_format.h:217
uint64_t byte_offset
Byte offset of this segment within the compressed payload (8B)
Definition fzm_format.h:226
Fixed-size FZM file header core (80 bytes).
Definition fzm_format.h:275
uint64_t computeHeaderSize() const
Definition fzm_format.h:314
uint16_t num_buffers
Number of FZMBufferEntry records (2B)
Definition fzm_format.h:278
uint32_t header_checksum
CRC32 of header bytes (v3.1+; 0 if flag not set) (4B)
Definition fzm_format.h:296
uint16_t flags
Feature flags: FZM_FLAG_* constants (2B)
Definition fzm_format.h:286
uint32_t data_checksum
CRC32 of compressed payload (v3.1+; 0 if flag not set) (4B)
Definition fzm_format.h:295
uint32_t num_stages
Number of FZMStageInfo records (4B)
Definition fzm_format.h:284
uint64_t compressed_size
Total compressed payload size in bytes (8B)
Definition fzm_format.h:281
uint64_t source_uncompressed_sizes[FZM_MAX_SOURCES]
(32B)
Definition fzm_format.h:293
uint16_t version
FZM_VERSION (2B)
Definition fzm_format.h:277
uint64_t uncompressed_size
Sum of all source uncompressed sizes in bytes (8B)
Definition fzm_format.h:280
uint16_t num_sources
Number of source (input) stages in the pipeline (2B)
Definition fzm_format.h:285
uint32_t magic
Must equal FZM_MAGIC (4B)
Definition fzm_format.h:276
uint64_t header_size
Total header size; compressed payload starts at this offset (8B)
Definition fzm_format.h:282
Per-stage metadata record written into the FZM header (256 bytes).
Definition fzm_format.h:170
uint8_t stage_config[FZM_STAGE_CONFIG_SIZE]
Serialized stage config, see Stage::serializeHeader() (128B)
Definition fzm_format.h:180
uint8_t num_inputs
Number of input ports (1B)
Definition fzm_format.h:173
uint8_t num_outputs
Number of output ports (1B)
Definition fzm_format.h:174
StageType stage_type
Stage type (2B)
Definition fzm_format.h:171
uint8_t reserved2[84]
Reserved for future use (84B)
Definition fzm_format.h:183
uint16_t stage_flags
FZM_STAGE_FLAG_* bits; 0 on pre-flag archives (2B, was reserved1)
Definition fzm_format.h:175
uint16_t input_buffer_ids[FZM_MAX_STAGE_INPUTS]
Input buffer indices (16B); 0xFFFF = unused.
Definition fzm_format.h:177
uint16_t stage_version
Config format version (2B)
Definition fzm_format.h:172
uint32_t config_size
Valid bytes in stage_config (4B)
Definition fzm_format.h:181
uint16_t output_buffer_ids[FZM_MAX_STAGE_OUTPUTS]
Output buffer indices (16B); 0xFFFF = unused.
Definition fzm_format.h:178