FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
szp_stage.h
Go to the documentation of this file.
1#pragma once
2
29#include "stage/stage.h"
30#include "fzm_format.h"
31#include "backend/types.h"
32#include <cstdint>
33#include <cstring>
34#include <stdexcept>
35#include <string>
36#include <type_traits>
37#include <unordered_map>
38#include <vector>
39
40namespace fz {
41
42enum class SZpErrorMode : uint8_t { ABS = 0, NOA = 2 };
43
45struct SZpConfig {
47 uint8_t eb_mode;
48 uint8_t _pad[2];
49 uint32_t block_size;
50 uint64_t num_elements;
51 double error_bound;
52 double value_base;
53
54 SZpConfig()
55 : data_type(DataType::FLOAT32), eb_mode(0), _pad{},
56 block_size(128), num_elements(0), error_bound(0.0), value_base(0.0) {}
57};
58static_assert(sizeof(SZpConfig) <= FZM_STAGE_CONFIG_SIZE,
59 "SZpConfig must fit in FZM_STAGE_CONFIG_SIZE");
60
73template<typename T>
74class SZpStage : public Stage {
75 static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>,
76 "SZpStage: T must be float or double.");
77public:
78 SZpStage() = default;
79 ~SZpStage() override;
80
81 void setInverse(bool inv) override { is_inverse_ = inv; }
82 bool isInverse() const override { return is_inverse_; }
83 // ABS forward is graph-capturable (size readback deferred to
84 // postStreamSync()); NOA forward needs a range reduce + host read inside
85 // execute(), so it is not.
86 bool isGraphCompatible() const override {
87 return !is_inverse_ && eb_mode_ != SZpErrorMode::NOA;
88 }
89
90 void setBlockSize(uint32_t n) {
91 if (n == 0 || n > 4096)
92 throw std::invalid_argument("SZpStage::setBlockSize: n in [1,4096]");
93 block_size_ = n;
94 }
95 uint32_t getBlockSize() const { return block_size_; }
96 void setErrorBound(double eb) { user_eb_ = eb; }
97 double getErrorBound() const { return user_eb_; }
98 void setErrorMode(SZpErrorMode m) { eb_mode_ = m; }
99 SZpErrorMode getErrorMode() const { return eb_mode_; }
100
101 void execute(fz::stream_t stream, MemoryPool* pool,
102 const std::vector<void*>& inputs,
103 const std::vector<void*>& outputs,
104 const std::vector<size_t>& sizes) override;
105 void postStreamSync(fz::stream_t stream) override;
106
107private:
110 double resolveAbsEb(fz::stream_t stream, MemoryPool* pool, const T* d_in, size_t n);
111public:
112
113 std::string getName() const override { return "SZp"; }
114 size_t getNumInputs() const override { return 1; }
115 size_t getNumOutputs() const override { return 1; }
116
117 std::vector<size_t> estimateOutputSizes(
118 const std::vector<size_t>& input_sizes) const override;
120 const std::vector<size_t>& input_sizes) const override;
121
122 std::unordered_map<std::string, size_t>
123 getActualOutputSizesByName() const override {
124 return {{"output", actual_output_size_}};
125 }
126 size_t getActualOutputSize(int index) const override {
127 return (index == 0) ? actual_output_size_ : 0;
128 }
129
130 uint16_t getStageTypeId() const override {
131 return static_cast<uint16_t>(StageType::SZP);
132 }
133 uint8_t getOutputDataType(size_t) const override {
134 return static_cast<uint8_t>(is_inverse_ ? getElementDataType()
135 : DataType::UINT8);
136 }
137 uint8_t getInputDataType(size_t) const override {
138 return static_cast<uint8_t>(is_inverse_ ? DataType::UINT8
139 : getElementDataType());
140 }
141
142 size_t serializeHeader(size_t, uint8_t* buf, size_t max_size) const override {
143 if (max_size < sizeof(SZpConfig)) return 0;
144 SZpConfig cfg;
145 cfg.data_type = getElementDataType();
146 cfg.eb_mode = static_cast<uint8_t>(eb_mode_);
147 cfg.block_size = block_size_;
148 cfg.num_elements = static_cast<uint64_t>(num_elements_);
149 cfg.error_bound = abs_eb_;
150 cfg.value_base = value_base_;
151 std::memcpy(buf, &cfg, sizeof(cfg));
152 return sizeof(cfg);
153 }
154 void deserializeHeader(const uint8_t* buf, size_t size) override {
155 if (size < sizeof(SZpConfig))
156 throw std::runtime_error("SZpStage: header too small");
157 SZpConfig cfg; std::memcpy(&cfg, buf, sizeof(cfg));
158 block_size_ = cfg.block_size ? cfg.block_size : 128u;
159 num_elements_ = static_cast<size_t>(cfg.num_elements);
160 eb_mode_ = static_cast<SZpErrorMode>(cfg.eb_mode);
161 abs_eb_ = cfg.error_bound;
162 value_base_ = cfg.value_base;
163 }
164 size_t getMaxHeaderSize(size_t) const override { return sizeof(SZpConfig); }
165
166 void saveState() override {
167 saved_ = {block_size_, num_elements_, actual_output_size_, abs_eb_, value_base_};
168 }
169 void restoreState() override {
170 block_size_ = saved_.block_size; num_elements_ = saved_.num_elements;
171 actual_output_size_ = saved_.actual_size; abs_eb_ = saved_.abs_eb;
172 value_base_ = saved_.value_base;
173 }
174 size_t getNumElements() const { return num_elements_; }
175
176private:
177 bool is_inverse_ = false;
178 uint32_t block_size_ = 128;
179 SZpErrorMode eb_mode_ = SZpErrorMode::ABS;
180 double user_eb_ = 1e-3;
181 double abs_eb_ = 0.0;
182 double value_base_ = 0.0;
183 size_t num_elements_ = 0;
184 size_t actual_output_size_= 0;
185
186 uint32_t* d_block_cost_ = nullptr;
187 uint32_t* d_block_offset_ = nullptr;
188 size_t scratch_blocks_ = 0;
189 MemoryPool* scratch_pool_ = nullptr;
190 size_t fwd_num_blocks_ = 0;
191 size_t fwd_meta_bytes_ = 0;
192
193 struct Saved { uint32_t block_size; size_t num_elements; size_t actual_size;
194 double abs_eb; double value_base; };
195 Saved saved_{128, 0, 0, 0.0, 0.0};
196
197 static DataType getElementDataType() {
198 return std::is_same<T, float>::value ? DataType::FLOAT32 : DataType::FLOAT64;
199 }
200};
201
202extern template class SZpStage<float>;
203extern template class SZpStage<double>;
204
205} // namespace fz
Definition mempool.h:82
Definition szp_stage.h:74
bool isGraphCompatible() const override
Definition szp_stage.h:86
size_t getActualOutputSize(int index) const override
Definition szp_stage.h:126
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
void postStreamSync(fz::stream_t stream) override
uint8_t getOutputDataType(size_t) const override
Definition szp_stage.h:133
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition szp_stage.h:123
uint8_t getInputDataType(size_t) const override
Definition szp_stage.h:137
void saveState() override
Definition szp_stage.h:166
void setInverse(bool inv) override
Definition szp_stage.h:81
uint16_t getStageTypeId() const override
Definition szp_stage.h:130
size_t estimateScratchBytes(const std::vector< size_t > &input_sizes) const override
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition szp_stage.h:154
size_t serializeHeader(size_t, uint8_t *buf, size_t max_size) const override
Definition szp_stage.h:142
std::string getName() const override
Definition szp_stage.h:113
size_t getMaxHeaderSize(size_t) const override
Definition szp_stage.h:164
Definition stage.h:31
FZM binary file format definitions — structs, enums, and helpers.
Definition dag.h:24
@ NOA
Value-range relative bound (norm-of-absolute).
@ ABS
Absolute error bound.
constexpr size_t FZM_STAGE_CONFIG_SIZE
Per-stage serialized config slot (bytes)
Definition fzm_format.h:65
@ SZP
SZp / fZ-light: quantize + 1-D Lorenzo delta + fixed-length bitpack (fused, no entropy coder)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:139
Base class interface for all compression stages.
Definition szp_stage.h:45
double error_bound
Absolute bound after mode conversion (f64-safe).
Definition szp_stage.h:51
uint32_t block_size
Elements per block (SZp default 128).
Definition szp_stage.h:49
uint8_t eb_mode
SZpErrorMode.
Definition szp_stage.h:47
double value_base
value_range for NOA; else 0.
Definition szp_stage.h:52
DataType data_type
FLOAT32 / FLOAT64.
Definition szp_stage.h:46
Backend-neutral GPU type aliases.