FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
tiled_lorenzo_stage.h
Go to the documentation of this file.
1#pragma once
2
19#include "stage/stage.h"
20#include "fzm_format.h"
21#include "backend/types.h"
22#include <algorithm>
23#include <array>
24#include <cstdint>
25#include <cstring>
26#include <stdexcept>
27#include <string>
28#include <type_traits>
29#include <unordered_map>
30#include <vector>
31
32namespace fz {
33
40 uint8_t ndim;
41 uint8_t tile_x;
42 uint8_t tile_y;
43 uint8_t tile_z;
44 uint8_t reserved[3];
45 uint32_t dim_x;
46 uint32_t dim_y;
47 uint32_t dim_z;
48
50 : data_type(DataType::INT32), ndim(2),
51 tile_x(8), tile_y(8), tile_z(1), reserved{0, 0, 0},
52 dim_x(0), dim_y(1), dim_z(1) {}
53};
54static_assert(sizeof(TiledLorenzoConfig) <= FZM_STAGE_CONFIG_SIZE,
55 "TiledLorenzoConfig must fit in FZM_STAGE_CONFIG_SIZE");
56
69template<typename T>
70class TiledLorenzoStage : public Stage {
71 static_assert(std::is_same_v<T, int16_t> || std::is_same_v<T, int32_t>,
72 "TiledLorenzoStage: T must be int16_t or int32_t.");
73public:
74 TiledLorenzoStage() = default;
75 ~TiledLorenzoStage() override = default;
76
77 void setInverse(bool inv) override { is_inverse_ = inv; }
78 bool isInverse() const override { return is_inverse_; }
79
82 void setDims(const std::array<size_t, 3>& dims) override {
83 if (!dims_pinned_) dims_ = dims;
84 }
85 void setDims(size_t x, size_t y = 1, size_t z = 1) {
86 if (!dims_pinned_) dims_ = {x, y, z};
87 }
88 std::array<size_t, 3> getDims() const { return dims_; }
89 bool hasDimsOverride() const { return dims_pinned_; }
90
104 void setDimsOverride(size_t x, size_t y, size_t z) {
105 dims_ = {x, y, z};
106 dims_pinned_ = true;
107 }
108
115 void setTileShape(uint32_t tx, uint32_t ty = 1, uint32_t tz = 1) {
116 auto chk = [](uint32_t v, const char* nm) {
117 if (v > 255)
118 throw std::invalid_argument(
119 std::string("TiledLorenzoStage::setTileShape: ") + nm
120 + " must be in [0, 255], got " + std::to_string(v));
121 };
122 chk(tx, "tx"); chk(ty, "ty"); chk(tz, "tz");
123 const uint32_t prod = (tx ? tx : 1) * (ty ? ty : 1) * (tz ? tz : 1);
124 if (prod > 1024)
125 throw std::invalid_argument(
126 "TiledLorenzoStage::setTileShape: tx*ty*tz must be in [1, 1024], got "
127 + std::to_string(prod));
128 tile_ = {tx, ty, tz};
129 tile_set_ = true;
130 }
131 std::array<uint32_t, 3> getTileShape() const { return effectiveTile(); }
132
134 uint32_t getTileElems() const {
135 auto t = effectiveTile();
136 return t[0] * t[1] * t[2];
137 }
138
139 int ndim() const {
140 if (dims_[2] > 1) return 3;
141 if (dims_[1] > 1) return 2;
142 return 1;
143 }
144
146 fz::stream_t stream,
147 MemoryPool* pool,
148 const std::vector<void*>& inputs,
149 const std::vector<void*>& outputs,
150 const std::vector<size_t>& sizes
151 ) override;
152
153 std::string getName() const override { return "TiledLorenzo"; }
154 size_t getNumInputs() const override { return 1; }
155 size_t getNumOutputs() const override { return 1; }
156
157 std::vector<size_t> estimateOutputSizes(
158 const std::vector<size_t>& input_sizes
159 ) const override {
160 // Forward: natural n -> padded tile-major (num_tiles * tile_elems).
161 // Inverse: padded tile-major -> natural n.
162 const size_t n = naturalElems(input_sizes);
163 const size_t out_elems = is_inverse_ ? n : paddedElems();
164 return {out_elems * sizeof(T)};
165 }
166
167 std::unordered_map<std::string, size_t>
168 getActualOutputSizesByName() const override {
169 return {{"output", actual_output_size_}};
170 }
171 size_t getActualOutputSize(int index) const override {
172 return (index == 0) ? actual_output_size_ : 0;
173 }
174
175 uint16_t getStageTypeId() const override {
176 return static_cast<uint16_t>(StageType::TILED_LORENZO);
177 }
178
179 uint8_t getOutputDataType(size_t /*output_index*/) const override {
180 return static_cast<uint8_t>(getElementDataType());
181 }
182 uint8_t getInputDataType(size_t /*input_index*/) const override {
183 return static_cast<uint8_t>(getElementDataType());
184 }
185
186 size_t serializeHeader(size_t /*output_index*/, uint8_t* buf, size_t max_size) const override {
187 if (max_size < sizeof(TiledLorenzoConfig))
188 throw std::runtime_error("TiledLorenzoStage: header buffer too small");
189 auto t = effectiveTile();
191 cfg.data_type = getElementDataType();
192 cfg.ndim = static_cast<uint8_t>(ndim());
193 cfg.tile_x = static_cast<uint8_t>(t[0]);
194 cfg.tile_y = static_cast<uint8_t>(t[1]);
195 cfg.tile_z = static_cast<uint8_t>(t[2]);
196 cfg.dim_x = static_cast<uint32_t>(dims_[0]);
197 cfg.dim_y = static_cast<uint32_t>(dims_[1]);
198 cfg.dim_z = static_cast<uint32_t>(dims_[2]);
199 std::memcpy(buf, &cfg, sizeof(cfg));
200 return sizeof(cfg);
201 }
202
203 void deserializeHeader(const uint8_t* buf, size_t size) override {
204 if (size < sizeof(TiledLorenzoConfig))
205 throw std::runtime_error("TiledLorenzoStage: header too small");
207 std::memcpy(&cfg, buf, sizeof(cfg));
208 int eff_ndim = (cfg.ndim == 0) ? 1 : static_cast<int>(cfg.ndim);
209 dims_[0] = cfg.dim_x;
210 dims_[1] = (eff_ndim >= 2) ? cfg.dim_y : 1;
211 dims_[2] = (eff_ndim >= 3) ? cfg.dim_z : 1;
212 tile_ = {cfg.tile_x, cfg.tile_y, cfg.tile_z};
213 tile_set_ = (cfg.tile_x != 0);
214 }
215
216 size_t getMaxHeaderSize(size_t /*output_index*/) const override {
217 return sizeof(TiledLorenzoConfig);
218 }
219
220private:
221 bool is_inverse_ = false;
222 bool dims_pinned_ = false;
223 size_t actual_output_size_ = 0;
224 std::array<size_t, 3> dims_ = {0, 1, 1};
225 std::array<uint32_t, 3> tile_ = {8, 8, 1};
226 bool tile_set_ = false;
227
229 std::array<uint32_t, 3> effectiveTile() const {
230 if (tile_set_) {
231 return {tile_[0] ? tile_[0] : 1u,
232 tile_[1] ? tile_[1] : 1u,
233 tile_[2] ? tile_[2] : 1u};
234 }
235 switch (ndim()) {
236 case 3: return {4, 4, 4};
237 case 2: return {8, 8, 1};
238 default: return {64, 1, 1};
239 }
240 }
241
243 size_t naturalElems(const std::vector<size_t>& input_sizes) const {
244 if (dims_[0] > 0) return dims_[0] * dims_[1] * dims_[2];
245 return input_sizes.empty() ? 0 : input_sizes[0] / sizeof(T);
246 }
247
249 size_t paddedElems() const {
250 auto t = effectiveTile();
251 const size_t dx = (dims_[0] > 0) ? dims_[0] : 0;
252 const size_t dy = dims_[1], dz = dims_[2];
253 if (dx == 0) return 0;
254 const size_t ntx = (dx + t[0] - 1) / t[0];
255 const size_t nty = (dy + t[1] - 1) / t[1];
256 const size_t ntz = (dz + t[2] - 1) / t[2];
257 return ntx * nty * ntz * (size_t)t[0] * t[1] * t[2];
258 }
259
260 static DataType getElementDataType() {
261 if (std::is_same<T, int16_t>::value) return DataType::INT16;
262 return DataType::INT32;
263 }
264};
265
266extern template class TiledLorenzoStage<int16_t>;
267extern template class TiledLorenzoStage<int32_t>;
268
269} // namespace fz
Definition mempool.h:82
Definition stage.h:30
Definition tiled_lorenzo_stage.h:70
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition tiled_lorenzo_stage.h:203
std::string getName() const override
Definition tiled_lorenzo_stage.h:153
uint16_t getStageTypeId() const override
Definition tiled_lorenzo_stage.h:175
uint32_t getTileElems() const
Elements per tile = the AdaptiveBitpack block_size that aligns blocks to tiles.
Definition tiled_lorenzo_stage.h:134
size_t getActualOutputSize(int index) const override
Definition tiled_lorenzo_stage.h:171
void execute(fz::stream_t stream, MemoryPool *pool, const std::vector< void * > &inputs, const std::vector< void * > &outputs, const std::vector< size_t > &sizes) override
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
Definition tiled_lorenzo_stage.h:157
void setDims(const std::array< size_t, 3 > &dims) override
Definition tiled_lorenzo_stage.h:82
uint8_t getInputDataType(size_t) const override
Definition tiled_lorenzo_stage.h:182
void setDimsOverride(size_t x, size_t y, size_t z)
Definition tiled_lorenzo_stage.h:104
uint8_t getOutputDataType(size_t) const override
Definition tiled_lorenzo_stage.h:179
void setTileShape(uint32_t tx, uint32_t ty=1, uint32_t tz=1)
Definition tiled_lorenzo_stage.h:115
void setInverse(bool inv) override
Definition tiled_lorenzo_stage.h:77
size_t getMaxHeaderSize(size_t) const override
Definition tiled_lorenzo_stage.h:216
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition tiled_lorenzo_stage.h:168
size_t serializeHeader(size_t, uint8_t *buf, size_t max_size) const override
Definition tiled_lorenzo_stage.h:186
FZM binary file format definitions — structs, enums, and helpers.
Definition algorithms.h:48
constexpr size_t FZM_STAGE_CONFIG_SIZE
Per-stage serialized config slot (bytes)
Definition fzm_format.h:65
@ TILED_LORENZO
Dimension-aware (tiled separable) Lorenzo predictor (cuSZp3 delta)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:118
Base class interface for all compression stages.
Definition tiled_lorenzo_stage.h:38
uint32_t dim_z
Z dimension (1 for 1-D/2-D).
Definition tiled_lorenzo_stage.h:47
uint8_t reserved[3]
Must be zero.
Definition tiled_lorenzo_stage.h:44
uint8_t tile_z
Tile extent in z (1 for 1-D/2-D).
Definition tiled_lorenzo_stage.h:43
DataType data_type
Signed integer element type (1B): INT16 / INT32.
Definition tiled_lorenzo_stage.h:39
uint8_t tile_y
Tile extent in y (1 for 1-D).
Definition tiled_lorenzo_stage.h:42
uint8_t tile_x
Tile extent in x (fast dim).
Definition tiled_lorenzo_stage.h:41
uint32_t dim_y
Y dimension (1 for 1-D).
Definition tiled_lorenzo_stage.h:46
uint8_t ndim
Spatial dimensionality 1/2/3.
Definition tiled_lorenzo_stage.h:40
uint32_t dim_x
X (fast) dimension.
Definition tiled_lorenzo_stage.h:45
Backend-neutral GPU type aliases.