FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
log_transform_stage.h
Go to the documentation of this file.
1#pragma once
2
12#include "stage/stage.h"
13#include "fzm_format.h"
14#include "backend/types.h"
15#include <array>
16#include <cmath>
17#include <cstdint>
18#include <memory>
19#include <cstring>
20#include <stdexcept>
21#include <string>
22#include <type_traits>
23#include <unordered_map>
24#include <vector>
25
26namespace fz {
27
34 float threshold;
35 uint32_t num_elements;
36 uint32_t outlier_count;
38 uint8_t reserved[3];
39
41 : error_bound(1e-3f), threshold(0.0f), num_elements(0), outlier_count(0),
42 input_type(DataType::FLOAT32), reserved{0, 0, 0} {}
43};
44static_assert(sizeof(LogTransformConfig) == 20,
45 "LogTransformConfig must be 20 bytes");
46
150template<typename TInput = float>
151class LogTransformStage : public Stage {
152 static_assert(std::is_floating_point<TInput>::value,
153 "LogTransformStage: TInput must be a floating-point type.");
154
155public:
172 static constexpr float kLogRoundTripSlack = 1e-6f;
173
176 static constexpr size_t kMinOutlierSlots = 8;
177
179 struct Config {
181 float error_bound = 1e-3f;
185 float threshold = 0.0f;
187 float outlier_capacity = 0.05f;
188 Config() = default;
189 explicit Config(float eb, float thr = 0.0f, float cap = 0.05f)
190 : error_bound(eb), threshold(thr), outlier_capacity(cap) {}
191 };
192
193 LogTransformStage() = default;
194 explicit LogTransformStage(const Config& config) : config_(config) {}
195 ~LogTransformStage() override;
196
197 // ── Execution ────────────────────────────────────────────────────────────
198 void execute(cudaStream_t stream, MemoryPool* pool,
199 const std::vector<void*>& inputs,
200 const std::vector<void*>& outputs,
201 const std::vector<size_t>& sizes) override;
202
203 void postStreamSync(fz::stream_t stream) override;
204 void onFinalize(size_t estimated_inlen, MemoryPool* pool) override;
205
206 size_t estimateDeviceFootprintBytes(size_t /*estimated_inlen*/) const override {
207 return sizeof(uint32_t);
208 }
209
211 bool isGraphCompatible() const override { return true; }
212
213 // ── Metadata ─────────────────────────────────────────────────────────────
214 std::string getName() const override { return "LogTransform"; }
215
216 size_t getNumInputs() const override { return is_inverse_ ? 4 : 1; }
217 size_t getNumOutputs() const override { return is_inverse_ ? 1 : 4; }
218
219 std::vector<std::string> getOutputNames() const override {
220 if (is_inverse_) return {"reconstructed"};
221 return {"output", "signs", "outlier_vals", "outlier_idxs"};
222 }
223
224 std::vector<size_t> estimateOutputSizes(
225 const std::vector<size_t>& input_sizes) const override;
226
227 std::unordered_map<std::string, size_t>
228 getActualOutputSizesByName() const override {
229 auto names = getOutputNames();
230 std::unordered_map<std::string, size_t> result;
231 for (size_t i = 0; i < names.size() && i < actual_output_sizes_.size(); ++i)
232 result[names[i]] = actual_output_sizes_[i];
233 return result;
234 }
235 size_t getActualOutputSize(int index) const override {
236 return (index >= 0 && index < static_cast<int>(actual_output_sizes_.size()))
237 ? actual_output_sizes_[index] : 0;
238 }
239
240 void setInverse(bool inverse) override { is_inverse_ = inverse; }
241 bool isInverse() const override { return is_inverse_; }
242
243 uint16_t getStageTypeId() const override {
244 return static_cast<uint16_t>(StageType::LOG_TRANSFORM);
245 }
246
247 uint8_t getOutputDataType(size_t output_index) const override {
248 if (is_inverse_) return static_cast<uint8_t>(inputDataType());
249 switch (output_index) {
250 case 0: return static_cast<uint8_t>(inputDataType()); // log values
251 case 1: return static_cast<uint8_t>(DataType::UINT8); // sign bitmap
252 case 2: return static_cast<uint8_t>(inputDataType()); // outlier vals
253 case 3: return static_cast<uint8_t>(DataType::UINT32); // outlier idxs
254 default: return static_cast<uint8_t>(DataType::UINT8);
255 }
256 }
261 uint8_t getInputDataType(size_t input_index) const override {
262 if (!is_inverse_) return static_cast<uint8_t>(inputDataType());
263 switch (input_index) {
264 case 0: return static_cast<uint8_t>(inputDataType()); // log values
265 case 1: return static_cast<uint8_t>(DataType::UINT8); // sign bitmap
266 case 2: return static_cast<uint8_t>(inputDataType()); // outlier vals
267 case 3: return static_cast<uint8_t>(DataType::UINT32); // outlier idxs
268 default: return static_cast<uint8_t>(DataType::UINT8);
269 }
270 }
271
272 // ── Serialization ────────────────────────────────────────────────────────
273 size_t serializeHeader(size_t output_index, uint8_t* buf, size_t max_size) const override;
274 size_t getMaxHeaderSize(size_t) const override { return sizeof(LogTransformConfig); }
275 void deserializeHeader(const uint8_t* buf, size_t size) override;
276
277 void saveState() override {
278 saved_config_ = config_;
279 saved_num_elements_ = num_elements_;
280 saved_actual_outlier_count_ = actual_outlier_count_;
281 saved_actual_output_sizes_ = actual_output_sizes_;
282 }
283 void restoreState() override {
284 config_ = saved_config_;
285 num_elements_ = saved_num_elements_;
286 actual_outlier_count_ = saved_actual_outlier_count_;
287 actual_output_sizes_ = saved_actual_output_sizes_;
288 }
289
290 // ── Configuration ────────────────────────────────────────────────────────
292 void setErrorBound(float delta) { config_.error_bound = delta; }
294 void setThreshold(float t) { config_.threshold = t; }
295 void setOutlierCapacity(float c) { config_.outlier_capacity = c; }
296
297 float getErrorBound() const { return config_.error_bound; }
298 float getThreshold() const { return config_.threshold; }
299 float getOutlierCapacity() const { return config_.outlier_capacity; }
300 uint32_t getOutlierCount() const { return actual_outlier_count_; }
301
309 float quantizerErrorBound() const {
310 return quantizerErrorBoundFor(config_.error_bound);
311 }
312
315 static float quantizerErrorBoundFor(float delta) {
316 return std::log2(1.0f + delta) - kLogRoundTripSlack;
317 }
318
327 static float minimumErrorBound() {
328 return std::exp2(2.0f * kLogRoundTripSlack) - 1.0f;
329 }
330
331private:
332 Config config_;
333 Config saved_config_;
334 bool is_inverse_ = false;
335
336 std::vector<size_t> actual_output_sizes_{0, 0, 0, 0};
337 std::vector<size_t> saved_actual_output_sizes_{0, 0, 0, 0};
338
339 size_t num_elements_ = 0;
340 size_t saved_num_elements_ = 0;
341 uint32_t actual_outlier_count_ = 0;
342 uint32_t saved_actual_outlier_count_ = 0;
343
346 uint32_t* d_outlier_count_scratch_ = nullptr;
347 MemoryPool* persistent_pool_ = nullptr;
352 std::weak_ptr<const void> persistent_pool_alive_;
353
354
355 void initOutlierCountScratch(MemoryPool* pool);
356
368 size_t maxOutlierCount(size_t n) const {
369 const size_t scaled =
370 static_cast<size_t>(static_cast<double>(n) * config_.outlier_capacity);
371 const size_t floored = (scaled < kMinOutlierSlots) ? kMinOutlierSlots : scaled;
372 return (floored > n) ? n : floored;
373 }
374
375 static size_t signBytes(size_t n) { return (n + 7) / 8; }
376
377 static DataType inputDataType() {
378 return std::is_same<TInput, double>::value ? DataType::FLOAT64
379 : DataType::FLOAT32;
380 }
381};
382
383extern template class LogTransformStage<float>;
384
385} // namespace fz
Definition log_transform_stage.h:151
float quantizerErrorBound() const
Definition log_transform_stage.h:309
size_t getMaxHeaderSize(size_t) const override
Definition log_transform_stage.h:274
static constexpr float kLogRoundTripSlack
Definition log_transform_stage.h:172
static float minimumErrorBound()
Definition log_transform_stage.h:327
void deserializeHeader(const uint8_t *buf, size_t size) override
std::vector< std::string > getOutputNames() const override
Definition log_transform_stage.h:219
void setErrorBound(float delta)
Set delta, the target point-wise relative error bound.
Definition log_transform_stage.h:292
size_t estimateDeviceFootprintBytes(size_t) const override
Definition log_transform_stage.h:206
void execute(cudaStream_t stream, MemoryPool *pool, const std::vector< void * > &inputs, const std::vector< void * > &outputs, const std::vector< size_t > &sizes) override
void onFinalize(size_t estimated_inlen, MemoryPool *pool) override
void setInverse(bool inverse) override
Definition log_transform_stage.h:240
size_t serializeHeader(size_t output_index, uint8_t *buf, size_t max_size) const override
uint8_t getOutputDataType(size_t output_index) const override
Definition log_transform_stage.h:247
void saveState() override
Definition log_transform_stage.h:277
void setThreshold(float t)
|x| < threshold => lossless outlier; 0 disables (specials only).
Definition log_transform_stage.h:294
uint16_t getStageTypeId() const override
Definition log_transform_stage.h:243
static float quantizerErrorBoundFor(float delta)
Definition log_transform_stage.h:315
static constexpr size_t kMinOutlierSlots
Definition log_transform_stage.h:176
bool isGraphCompatible() const override
No mid-execute sync: the outlier-count D2H happens in postStreamSync().
Definition log_transform_stage.h:211
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition log_transform_stage.h:228
void postStreamSync(fz::stream_t stream) override
size_t getActualOutputSize(int index) const override
Definition log_transform_stage.h:235
uint8_t getInputDataType(size_t input_index) const override
Definition log_transform_stage.h:261
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
std::string getName() const override
Definition log_transform_stage.h:214
Definition mempool.h:82
Definition stage.h:30
FZM binary file format definitions — structs, enums, and helpers.
Definition algorithms.h:48
@ LOG_TRANSFORM
Log-space transform for point-wise relative bounds (Liang et al., CLUSTER'18)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:117
Base class interface for all compression stages.
Definition log_transform_stage.h:32
uint32_t num_elements
Total element count.
Definition log_transform_stage.h:35
float threshold
|x| < threshold => lossless outlier. 0 = only specials.
Definition log_transform_stage.h:34
DataType input_type
Original input type (1B).
Definition log_transform_stage.h:37
float error_bound
delta — the target point-wise relative bound.
Definition log_transform_stage.h:33
uint32_t outlier_count
Actual number of outliers written.
Definition log_transform_stage.h:36
uint8_t reserved[3]
Must be zero.
Definition log_transform_stage.h:38
Definition log_transform_stage.h:179
float error_bound
delta — the target point-wise relative error bound.
Definition log_transform_stage.h:181
float threshold
Definition log_transform_stage.h:185
float outlier_capacity
Fraction of the input element count reserved for outliers.
Definition log_transform_stage.h:187
Backend-neutral GPU type aliases.