FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
stage_factory.h
Go to the documentation of this file.
1#pragma once
2
8#include "stage/stage.h"
9#include "fzm_format.h"
11#include "coders/rle/rle.h"
28
29#include <memory>
30#include <stdexcept>
31#include <cstring>
32
33namespace fz {
34
44inline Stage* createStage(StageType type, const uint8_t* config, size_t config_size) {
45 Stage* stage = nullptr;
46
47 switch (type) {
48 case StageType::LORENZO_QUANT: {
49 // Dims are restored by deserializeHeader(); template types come from stored fields.
50 if (config_size >= sizeof(LorenzoQuantConfig)) {
52 std::memcpy(&lc, config, sizeof(LorenzoQuantConfig));
53 if (lc.input_type == DataType::FLOAT32 && lc.code_type == DataType::UINT16) {
55 s->deserializeHeader(config, config_size);
56 stage = s;
57 } else if (lc.input_type == DataType::FLOAT64 && lc.code_type == DataType::UINT16) {
59 s->deserializeHeader(config, config_size);
60 stage = s;
61 } else {
62 throw std::runtime_error(
63 "Unsupported Lorenzo template instantiation: input_type="
64 + std::to_string(static_cast<int>(lc.input_type))
65 + " code_type=" + std::to_string(static_cast<int>(lc.code_type)));
66 }
67 } else {
68 throw std::runtime_error("Lorenzo config too small: " + std::to_string(config_size));
69 }
70 break;
71 }
72
73 case StageType::DIFFERENCE: {
74 // Header: [0] TIn DataType, [1] TOut DataType, [2..5] chunk_size.
75 // TIn == TOut → same-type (legacy); TIn signed + TOut unsigned → negabinary-fused.
76 if (config_size >= 2) {
77 DataType tin_dt = static_cast<DataType>(config[0]);
78 DataType tout_dt = static_cast<DataType>(config[1]);
79 // Negabinary-fused instantiations
80 if (tin_dt == DataType::INT8 && tout_dt == DataType::UINT8)
82 else if (tin_dt == DataType::INT16 && tout_dt == DataType::UINT16)
84 else if (tin_dt == DataType::INT32 && tout_dt == DataType::UINT32)
86 else if (tin_dt == DataType::INT64 && tout_dt == DataType::UINT64)
88 // Same-type instantiations
89 else if (tin_dt == DataType::FLOAT32) stage = new DifferenceStage<float>();
90 else if (tin_dt == DataType::FLOAT64) stage = new DifferenceStage<double>();
91 else if (tin_dt == DataType::UINT8) stage = new DifferenceStage<uint8_t>();
92 else if (tin_dt == DataType::UINT16) stage = new DifferenceStage<uint16_t>();
93 else if (tin_dt == DataType::UINT32) stage = new DifferenceStage<uint32_t>();
94 else if (tin_dt == DataType::INT32) stage = new DifferenceStage<int32_t>();
95 else if (tin_dt == DataType::INT64) stage = new DifferenceStage<int64_t>();
96 else
97 throw std::runtime_error("Unsupported Difference data type: "
98 + std::to_string(static_cast<int>(tin_dt)));
99 stage->deserializeHeader(config, config_size);
100 } else if (config_size >= 1) {
101 // Legacy 1-byte header (same-type only)
102 DataType dt = static_cast<DataType>(config[0]);
103 switch (dt) {
104 case DataType::FLOAT32: stage = new DifferenceStage<float>(); break;
105 case DataType::FLOAT64: stage = new DifferenceStage<double>(); break;
106 case DataType::UINT8: stage = new DifferenceStage<uint8_t>(); break;
107 case DataType::UINT16: stage = new DifferenceStage<uint16_t>(); break;
108 case DataType::UINT32: stage = new DifferenceStage<uint32_t>(); break;
109 case DataType::INT32: stage = new DifferenceStage<int32_t>(); break;
110 case DataType::INT64: stage = new DifferenceStage<int64_t>(); break;
111 default:
112 throw std::runtime_error("Unsupported Difference data type: "
113 + std::to_string(static_cast<int>(dt)));
114 }
115 } else {
116 stage = new DifferenceStage<float>();
117 }
118 break;
119 }
120
121 case StageType::RLE: {
122 if (config_size >= 1) {
123 DataType dt;
124 std::memcpy(&dt, config, sizeof(DataType));
125 switch (dt) {
126 case DataType::UINT8: stage = new RLEStage<uint8_t>(); break;
127 case DataType::UINT16: stage = new RLEStage<uint16_t>(); break;
128 case DataType::UINT32: stage = new RLEStage<uint32_t>(); break;
129 case DataType::INT32: stage = new RLEStage<int32_t>(); break;
130 default:
131 throw std::runtime_error("Unsupported RLE data type: "
132 + std::to_string(static_cast<int>(dt)));
133 }
134 stage->deserializeHeader(config, config_size);
135 } else {
136 // No config — default to uint16_t
137 stage = new RLEStage<uint16_t>();
138 }
139 break;
140 }
141
142 case StageType::ZIGZAG: {
143 if (config_size >= 2) {
144 DataType tin_dt = static_cast<DataType>(config[0]);
145 DataType tout_dt = static_cast<DataType>(config[1]);
146 if (tin_dt == DataType::INT8 && tout_dt == DataType::UINT8)
147 stage = new ZigzagStage<int8_t, uint8_t>();
148 else if (tin_dt == DataType::INT16 && tout_dt == DataType::UINT16)
149 stage = new ZigzagStage<int16_t, uint16_t>();
150 else if (tin_dt == DataType::INT32 && tout_dt == DataType::UINT32)
151 stage = new ZigzagStage<int32_t, uint32_t>();
152 else if (tin_dt == DataType::INT64 && tout_dt == DataType::UINT64)
153 stage = new ZigzagStage<int64_t, uint64_t>();
154 else
155 throw std::runtime_error(
156 "Unsupported ZigzagStage type pair: TIn="
157 + std::to_string(static_cast<int>(tin_dt))
158 + " TOut=" + std::to_string(static_cast<int>(tout_dt)));
159 } else {
160 // Default: int32_t → uint32_t
161 stage = new ZigzagStage<int32_t, uint32_t>();
162 }
163 stage->deserializeHeader(config, config_size);
164 break;
165 }
166
167 case StageType::NEGABINARY: {
168 if (config_size >= 2) {
169 DataType tin_dt = static_cast<DataType>(config[0]);
170 DataType tout_dt = static_cast<DataType>(config[1]);
171 if (tin_dt == DataType::INT8 && tout_dt == DataType::UINT8)
173 else if (tin_dt == DataType::INT16 && tout_dt == DataType::UINT16)
175 else if (tin_dt == DataType::INT32 && tout_dt == DataType::UINT32)
177 else if (tin_dt == DataType::INT64 && tout_dt == DataType::UINT64)
179 else
180 throw std::runtime_error(
181 "Unsupported NegabinaryStage type pair: TIn="
182 + std::to_string(static_cast<int>(tin_dt))
183 + " TOut=" + std::to_string(static_cast<int>(tout_dt)));
184 } else {
186 }
187 stage->deserializeHeader(config, config_size);
188 break;
189 }
190
191 case StageType::BITSHUFFLE: {
192 auto* s = new BitshuffleStage();
193 s->deserializeHeader(config, config_size);
194 stage = s;
195 break;
196 }
197
198 case StageType::BITPACK: {
199 // config[0] holds the DataType of T; use it to pick the instantiation.
200 DataType dt = (config_size > 0)
201 ? static_cast<DataType>(config[0])
202 : DataType::UINT16;
203 if (dt == DataType::UINT8) stage = new BitpackStage<uint8_t>();
204 else if (dt == DataType::UINT16) stage = new BitpackStage<uint16_t>();
205 else if (dt == DataType::UINT32) stage = new BitpackStage<uint32_t>();
206 else throw std::runtime_error(
207 "Unsupported BitpackStage DataType: "
208 + std::to_string(static_cast<int>(dt)));
209 stage->deserializeHeader(config, config_size);
210 break;
211 }
212
213 case StageType::RZE: {
214 auto* s = new RZEStage();
215 s->deserializeHeader(config, config_size);
216 stage = s;
217 break;
218 }
219
220 case StageType::RRE: {
221 auto* s = new RREStage();
222 s->deserializeHeader(config, config_size);
223 stage = s;
224 break;
225 }
226
227 case StageType::MERGE: {
228 auto* s = new MergeStage();
229 s->deserializeHeader(config, config_size);
230 stage = s;
231 break;
232 }
233
234 case StageType::HUFFMAN: {
235 // config[0] holds the DataType of T; use it to pick the instantiation.
236 DataType dt = (config_size > 0)
237 ? static_cast<DataType>(config[0])
238 : DataType::UINT16;
239 if (dt == DataType::UINT8) stage = new HuffmanStage<uint8_t>();
240 else if (dt == DataType::UINT16) stage = new HuffmanStage<uint16_t>();
241 else if (dt == DataType::UINT32) stage = new HuffmanStage<uint32_t>();
242 else throw std::runtime_error(
243 "Unsupported HuffmanStage DataType: "
244 + std::to_string(static_cast<int>(dt)));
245 stage->deserializeHeader(config, config_size);
246 break;
247 }
248
249 case StageType::LORENZO: {
250 DataType dt = (config_size >= sizeof(LorenzoConfig))
251 ? static_cast<DataType>(config[0])
252 : DataType::INT32;
253 if (dt == DataType::INT8) stage = new LorenzoStage<int8_t>();
254 else if (dt == DataType::INT16) stage = new LorenzoStage<int16_t>();
255 else if (dt == DataType::INT32) stage = new LorenzoStage<int32_t>();
256 else if (dt == DataType::INT64) stage = new LorenzoStage<int64_t>();
257 else throw std::runtime_error(
258 "Unsupported LorenzoStage DataType: "
259 + std::to_string(static_cast<int>(dt)));
260 stage->deserializeHeader(config, config_size);
261 break;
262 }
263
264 case StageType::ANS: {
265 auto* s = new ANSStage();
266 s->deserializeHeader(config, config_size);
267 stage = s;
268 break;
269 }
270
271 case StageType::ADM: {
272 auto* s = new ADMStage();
273 s->deserializeHeader(config, config_size);
274 stage = s;
275 break;
276 }
277
278 case StageType::G_INTERP: {
279 // Code type stored in config[5] (DataType code_type in GInterpConfig).
280 if (config_size < sizeof(GInterpConfig)) {
281 throw std::runtime_error(
282 "GInterp config too small: " + std::to_string(config_size));
283 }
284 GInterpConfig gc;
285 std::memcpy(&gc, config, sizeof(GInterpConfig));
286 auto make_ginterp = [&](auto input_tag) {
287 using TInput = decltype(input_tag);
288 if (gc.code_type == DataType::UINT8) {
289 auto* s = new GInterpStage<TInput, uint8_t>();
290 s->deserializeHeader(config, config_size);
291 stage = s;
292 } else if (gc.code_type == DataType::UINT16) {
293 auto* s = new GInterpStage<TInput, uint16_t>();
294 s->deserializeHeader(config, config_size);
295 stage = s;
296 } else if (gc.code_type == DataType::UINT32) {
297 auto* s = new GInterpStage<TInput, uint32_t>();
298 s->deserializeHeader(config, config_size);
299 stage = s;
300 } else {
301 throw std::runtime_error(
302 "Unsupported GInterp code_type: "
303 + std::to_string(static_cast<int>(gc.code_type)));
304 }
305 };
306 if (gc.input_type == DataType::FLOAT32) {
307 make_ginterp(float{});
308 } else if (gc.input_type == DataType::FLOAT64) {
309 make_ginterp(double{});
310 } else {
311 throw std::runtime_error(
312 "Unsupported GInterp input_type: "
313 + std::to_string(static_cast<int>(gc.input_type)));
314 }
315 break;
316 }
317
319 auto* s = new BitplaneRZEStage();
320 s->deserializeHeader(config, config_size);
321 stage = s;
322 break;
323 }
324
326 // config[0] holds the DataType of T (INT16 / INT32).
327 DataType dt = (config_size > 0)
328 ? static_cast<DataType>(config[0])
329 : DataType::INT32;
330 if (dt == DataType::INT16) stage = new AdaptiveBitpackStage<int16_t>();
331 else if (dt == DataType::INT32) stage = new AdaptiveBitpackStage<int32_t>();
332 else throw std::runtime_error(
333 "Unsupported AdaptiveBitpackStage DataType: "
334 + std::to_string(static_cast<int>(dt)));
335 stage->deserializeHeader(config, config_size);
336 break;
337 }
338
340 // config[0] holds the DataType of T (INT16 / INT32).
341 DataType dt = (config_size > 0)
342 ? static_cast<DataType>(config[0])
343 : DataType::INT32;
344 if (dt == DataType::INT16) stage = new TiledLorenzoStage<int16_t>();
345 else if (dt == DataType::INT32) stage = new TiledLorenzoStage<int32_t>();
346 else throw std::runtime_error(
347 "Unsupported TiledLorenzoStage DataType: "
348 + std::to_string(static_cast<int>(dt)));
349 stage->deserializeHeader(config, config_size);
350 break;
351 }
352
353 default:
354 throw std::runtime_error("Unknown stage type: "
355 + std::to_string(static_cast<uint16_t>(type)));
356 }
357
358 return stage;
359}
360
361} // namespace fz
Per-block adaptive fixed-rate bit-plane coder (cuSZp-style plain mode).
Adaptive Data Mapping (ADM) stage — remaps u16/u32 integer streams into a compact 8-bit symbol domain...
rANS entropy coding stage (GPU, via vendored dietGPU kernel templates).
Bit-packing stage: packs N-bit integers into a dense byte stream.
Fused bitplane-transpose + zero-group RZE stage — the FZ-GPU lossless encoder, ported as a single-ker...
GPU bit-matrix transpose stage (W × N bit shuffle over fixed-size chunks).
Definition adaptive_bitpack_stage.h:75
Definition bitpack_stage.h:47
Definition bitplane_rze_stage.h:60
Definition bitshuffle_stage.h:43
Definition diff.h:51
Definition ginterp_stage.h:204
Definition huffman_stage.h:68
Definition lorenzo_quant.h:96
Definition lorenzo_stage.h:53
Definition merge_stage.h:68
Definition negabinary_stage.h:34
Definition rle.h:31
Definition rre_stage.h:54
Definition rze_stage.h:55
Definition stage.h:30
virtual void deserializeHeader(const uint8_t *header_buffer, size_t size)
Definition stage.h:149
Definition tiled_lorenzo_stage.h:70
Definition zigzag_stage.h:30
First-order difference coding stage with optional negabinary fusion.
FZM binary file format definitions — structs, enums, and helpers.
G-Interp spline-interpolation predictor + quantizer (cuSZ-Hi port).
Huffman entropy coding stage with selectable encode mode.
Fused Lorenzo predictor and quantizer stage.
Plain integer Lorenzo predictor (delta coding / prefix sum). Lossless.
MergeStage — concatenate N input buffers into one, split back to N.
Definition fzm_format.h:25
Stage * createStage(StageType type, const uint8_t *config, size_t config_size)
Definition stage_factory.h:44
StageType
Stage type identifiers written into the FZM header.
Definition fzm_format.h:76
@ ADAPTIVE_BITPACK
Per-block adaptive fixed-rate bit-plane coder (cuSZp plain mode)
@ ANS
rANS entropy coder (GPU, via dietGPU)
@ RRE
Repetition-Reduction Encoding (LC framework lossless component)
@ ADM
Adaptive Data Mapping transform (MANS)
@ TILED_LORENZO
Dimension-aware (tiled separable) Lorenzo predictor (cuSZp3 delta)
@ BITPLANE_RZE
Fused bitplane transpose + zero-group RZE (FZ-GPU lossless encoder)
@ G_INTERP
Spline interpolation predictor + quantizer (cuSZ-Hi G-Interp)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:109
Element-wise negabinary encode/decode stage (TIn[] ↔ TOut[]).
Run-Length Encoding stage (lossless, stream-ordered).
Repetition-Reduction Encoding stage — lossless byte-stream compressor.
Zero-Elimination Encoding stage — lossless byte-stream compressor.
Base class interface for all compression stages.
Definition ginterp_stage.h:39
DataType code_type
Quant code type (1 B).
Definition ginterp_stage.h:47
DataType input_type
Float input type (1 B).
Definition ginterp_stage.h:46
Definition lorenzo_stage.h:28
Definition lorenzo_quant.h:43
DataType input_type
Original input type (1B).
Definition lorenzo_quant.h:48
DataType code_type
Quantization code type (1B).
Definition lorenzo_quant.h:49
Dimension-aware (tiled separable) Lorenzo predictor — cuSZp3 delta. Lossless.
Element-wise zigzag encode/decode stage (TIn[] ↔ TOut[]).