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
151template<typename TInput = float>
152class LogTransformStage : public Stage {
153 static_assert(std::is_floating_point<TInput>::value,
154 "LogTransformStage: TInput must be a floating-point type.");
155
156public:
173 static constexpr float kLogRoundTripSlack = 1e-6f;
174
177 static constexpr size_t kMinOutlierSlots = 8;
178
180 struct Config {
182 float error_bound = 1e-3f;
186 float threshold = 0.0f;
188 float outlier_capacity = 0.05f;
189 Config() = default;
190 explicit Config(float eb, float thr = 0.0f, float cap = 0.05f)
191 : error_bound(eb), threshold(thr), outlier_capacity(cap) {}
192 };
193
194 LogTransformStage() = default;
195 explicit LogTransformStage(const Config& config) : config_(config) {}
196 ~LogTransformStage() override;
197
198 // ── Execution ────────────────────────────────────────────────────────────
199 void execute(cudaStream_t stream, MemoryPool* pool,
200 const std::vector<void*>& inputs,
201 const std::vector<void*>& outputs,
202 const std::vector<size_t>& sizes) override;
203
204 void postStreamSync(fz::stream_t stream) override;
205 void onFinalize(size_t estimated_inlen, MemoryPool* pool) override;
206
207 size_t estimateDeviceFootprintBytes(size_t /*estimated_inlen*/) const override {
208 return sizeof(uint32_t);
209 }
210
212 bool isGraphCompatible() const override { return true; }
213
214 // ── Metadata ─────────────────────────────────────────────────────────────
215 std::string getName() const override { return "LogTransform"; }
216
217 size_t getNumInputs() const override { return is_inverse_ ? 4 : 1; }
218 size_t getNumOutputs() const override { return is_inverse_ ? 1 : 4; }
219
220 std::vector<std::string> getOutputNames() const override {
221 if (is_inverse_) return {"reconstructed"};
222 return {"output", "signs", "outlier_vals", "outlier_idxs"};
223 }
224
225 std::vector<size_t> estimateOutputSizes(
226 const std::vector<size_t>& input_sizes) const override;
227
228 std::unordered_map<std::string, size_t>
229 getActualOutputSizesByName() const override {
230 auto names = getOutputNames();
231 std::unordered_map<std::string, size_t> result;
232 for (size_t i = 0; i < names.size() && i < actual_output_sizes_.size(); ++i)
233 result[names[i]] = actual_output_sizes_[i];
234 return result;
235 }
236 size_t getActualOutputSize(int index) const override {
237 return (index >= 0 && index < static_cast<int>(actual_output_sizes_.size()))
238 ? actual_output_sizes_[index] : 0;
239 }
240
241 void setInverse(bool inverse) override { is_inverse_ = inverse; }
242 bool isInverse() const override { return is_inverse_; }
243
244 uint16_t getStageTypeId() const override {
245 return static_cast<uint16_t>(StageType::LOG_TRANSFORM);
246 }
247
248 uint8_t getOutputDataType(size_t output_index) const override {
249 if (is_inverse_) return static_cast<uint8_t>(inputDataType());
250 switch (output_index) {
251 case 0: return static_cast<uint8_t>(inputDataType()); // log values
252 case 1: return static_cast<uint8_t>(DataType::UINT8); // sign bitmap
253 case 2: return static_cast<uint8_t>(inputDataType()); // outlier vals
254 case 3: return static_cast<uint8_t>(DataType::UINT32); // outlier idxs
255 default: return static_cast<uint8_t>(DataType::UINT8);
256 }
257 }
262 uint8_t getInputDataType(size_t input_index) const override {
263 if (!is_inverse_) return static_cast<uint8_t>(inputDataType());
264 switch (input_index) {
265 case 0: return static_cast<uint8_t>(inputDataType()); // log values
266 case 1: return static_cast<uint8_t>(DataType::UINT8); // sign bitmap
267 case 2: return static_cast<uint8_t>(inputDataType()); // outlier vals
268 case 3: return static_cast<uint8_t>(DataType::UINT32); // outlier idxs
269 default: return static_cast<uint8_t>(DataType::UINT8);
270 }
271 }
272
273 // ── Serialization ────────────────────────────────────────────────────────
274 size_t serializeHeader(size_t output_index, uint8_t* buf, size_t max_size) const override;
275 size_t getMaxHeaderSize(size_t) const override { return sizeof(LogTransformConfig); }
276 void deserializeHeader(const uint8_t* buf, size_t size) override;
277
278 void saveState() override {
279 saved_config_ = config_;
280 saved_num_elements_ = num_elements_;
281 saved_actual_outlier_count_ = actual_outlier_count_;
282 saved_actual_output_sizes_ = actual_output_sizes_;
283 }
284 void restoreState() override {
285 config_ = saved_config_;
286 num_elements_ = saved_num_elements_;
287 actual_outlier_count_ = saved_actual_outlier_count_;
288 actual_output_sizes_ = saved_actual_output_sizes_;
289 }
290
291 // ── Configuration ────────────────────────────────────────────────────────
293 void setErrorBound(float delta) { config_.error_bound = delta; }
295 void setThreshold(float t) { config_.threshold = t; }
296 void setOutlierCapacity(float c) { config_.outlier_capacity = c; }
297
298 float getErrorBound() const { return config_.error_bound; }
299 float getThreshold() const { return config_.threshold; }
300 float getOutlierCapacity() const { return config_.outlier_capacity; }
301 uint32_t getOutlierCount() const { return actual_outlier_count_; }
302
310 float quantizerErrorBound() const {
311 return quantizerErrorBoundFor(config_.error_bound);
312 }
313
316 static float quantizerErrorBoundFor(float delta) {
317 return std::log2(1.0f + delta) - kLogRoundTripSlack;
318 }
319
328 static float minimumErrorBound() {
329 return std::exp2(2.0f * kLogRoundTripSlack) - 1.0f;
330 }
331
332private:
333 Config config_;
334 Config saved_config_;
335 bool is_inverse_ = false;
336
337 std::vector<size_t> actual_output_sizes_{0, 0, 0, 0};
338 std::vector<size_t> saved_actual_output_sizes_{0, 0, 0, 0};
339
340 size_t num_elements_ = 0;
341 size_t saved_num_elements_ = 0;
342 uint32_t actual_outlier_count_ = 0;
343 uint32_t saved_actual_outlier_count_ = 0;
344
347 uint32_t* d_outlier_count_scratch_ = nullptr;
348 MemoryPool* persistent_pool_ = nullptr;
353 std::weak_ptr<const void> persistent_pool_alive_;
354
355
356 void initOutlierCountScratch(MemoryPool* pool);
357
369 size_t maxOutlierCount(size_t n) const {
370 const size_t scaled =
371 static_cast<size_t>(static_cast<double>(n) * config_.outlier_capacity);
372 const size_t floored = (scaled < kMinOutlierSlots) ? kMinOutlierSlots : scaled;
373 return (floored > n) ? n : floored;
374 }
375
376 static size_t signBytes(size_t n) { return (n + 7) / 8; }
377
378 static DataType inputDataType() {
379 return std::is_same<TInput, double>::value ? DataType::FLOAT64
380 : DataType::FLOAT32;
381 }
382};
383
384extern template class LogTransformStage<float>;
385
386} // namespace fz
Definition log_transform_stage.h:152
float quantizerErrorBound() const
Definition log_transform_stage.h:310
size_t getMaxHeaderSize(size_t) const override
Definition log_transform_stage.h:275
static constexpr float kLogRoundTripSlack
Definition log_transform_stage.h:173
static float minimumErrorBound()
Definition log_transform_stage.h:328
void deserializeHeader(const uint8_t *buf, size_t size) override
std::vector< std::string > getOutputNames() const override
Definition log_transform_stage.h:220
void setErrorBound(float delta)
Set delta, the target point-wise relative error bound.
Definition log_transform_stage.h:293
size_t estimateDeviceFootprintBytes(size_t) const override
Definition log_transform_stage.h:207
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:241
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:248
void saveState() override
Definition log_transform_stage.h:278
void setThreshold(float t)
|x| < threshold => lossless outlier; 0 disables (specials only).
Definition log_transform_stage.h:295
uint16_t getStageTypeId() const override
Definition log_transform_stage.h:244
static float quantizerErrorBoundFor(float delta)
Definition log_transform_stage.h:316
static constexpr size_t kMinOutlierSlots
Definition log_transform_stage.h:177
bool isGraphCompatible() const override
No mid-execute sync: the outlier-count D2H happens in postStreamSync().
Definition log_transform_stage.h:212
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition log_transform_stage.h:229
void postStreamSync(fz::stream_t stream) override
size_t getActualOutputSize(int index) const override
Definition log_transform_stage.h:236
uint8_t getInputDataType(size_t input_index) const override
Definition log_transform_stage.h:262
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
std::string getName() const override
Definition log_transform_stage.h:215
Definition mempool.h:82
Definition stage.h:31
FZM binary file format definitions — structs, enums, and helpers.
Definition dag.h:24
@ 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:139
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:180
float error_bound
delta — the target point-wise relative error bound.
Definition log_transform_stage.h:182
float threshold
Definition log_transform_stage.h:186
float outlier_capacity
Fraction of the input element count reserved for outliers.
Definition log_transform_stage.h:188
Backend-neutral GPU type aliases.