FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
cdf97_stage.h
Go to the documentation of this file.
1#pragma once
2
3// Lifting constants, boundary handling, and level-count rule ported from the
4// SPERR project (Li, Lindstrom, Clyne — NCAR), Apache License 2.0 — see
5// THIRD_PARTY.md. Original: include/CDF97.h, src/CDF97.cpp in
6// https://github.com/NCAR/SPERR. GPU kernels are FZGPUModules' own.
7
43#include "stage/stage.h"
44#include "fzm_format.h"
45#include "backend/types.h"
46#include <array>
47#include <cstdint>
48#include <cstring>
49#include <stdexcept>
50#include <string>
51#include <type_traits>
52#include <unordered_map>
53#include <vector>
54
55namespace fz {
56
62 uint8_t ndim;
63 uint8_t reserved[2];
64 uint32_t dim_x;
65 uint32_t dim_y;
66 uint32_t dim_z;
67
69 : data_type(DataType::FLOAT64), ndim(1), reserved{0, 0},
70 dim_x(0), dim_y(1), dim_z(1) {}
71};
72static_assert(sizeof(Cdf97Config) <= FZM_STAGE_CONFIG_SIZE,
73 "Cdf97Config must fit in FZM_STAGE_CONFIG_SIZE");
74
81template <typename TInput = double>
82class Cdf97Stage : public Stage {
83 static_assert(std::is_floating_point<TInput>::value,
84 "Cdf97Stage: TInput must be a floating-point type.");
85
86public:
88 static constexpr size_t kMaxLineElems = (48u * 1024u) / sizeof(TInput);
89
90 Cdf97Stage() = default;
91
92 // ── Stage control ─────────────────────────────────────────────────────────
93 void setInverse(bool inv) override { is_inverse_ = inv; }
94 bool isInverse() const override { return is_inverse_; }
95
96 void setDims(const std::array<size_t, 3>& dims) override { dims_ = dims; }
97 void setDims(size_t x, size_t y = 1, size_t z = 1) { dims_ = {x, y, z}; }
98 std::array<size_t, 3> getDims() const { return dims_; }
99
100 // ── Execution ─────────────────────────────────────────────────────────────
101 void execute(cudaStream_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
107 bool isGraphCompatible() const override { return true; }
108
109 // ── Metadata ──────────────────────────────────────────────────────────────
110 std::string getName() const override { return "CDF97"; }
111 size_t getNumInputs() const override { return 1; }
112 size_t getNumOutputs() const override { return 1; }
113
114 std::vector<size_t> estimateOutputSizes(
115 const std::vector<size_t>& input_sizes) const override {
116 return { input_sizes.empty() ? 0 : input_sizes[0] }; // size-preserving
117 }
118
119 std::unordered_map<std::string, size_t>
120 getActualOutputSizesByName() const override {
121 return {{"output", actual_output_size_}};
122 }
123 size_t getActualOutputSize(int index) const override {
124 return index == 0 ? actual_output_size_ : 0;
125 }
126
127 // ── Type system ───────────────────────────────────────────────────────────
128 uint16_t getStageTypeId() const override {
129 return static_cast<uint16_t>(StageType::CDF97);
130 }
131 uint8_t getOutputDataType(size_t /*output_index*/) const override {
132 return static_cast<uint8_t>(elementDataType());
133 }
134 uint8_t getInputDataType(size_t /*input_index*/) const override {
135 return static_cast<uint8_t>(elementDataType());
136 }
137
138 // ── Serialization ─────────────────────────────────────────────────────────
139 size_t serializeHeader(size_t /*output_index*/, uint8_t* buf, size_t max_size) const override {
140 if (max_size < sizeof(Cdf97Config))
141 throw std::runtime_error("Cdf97Stage: header buffer too small");
142 Cdf97Config cfg;
143 cfg.data_type = elementDataType();
144 cfg.ndim = static_cast<uint8_t>(ndim());
145 cfg.dim_x = static_cast<uint32_t>(dims_[0]);
146 cfg.dim_y = static_cast<uint32_t>(dims_[1]);
147 cfg.dim_z = static_cast<uint32_t>(dims_[2]);
148 std::memcpy(buf, &cfg, sizeof(cfg));
149 return sizeof(cfg);
150 }
151 void deserializeHeader(const uint8_t* buf, size_t size) override {
152 if (size < sizeof(Cdf97Config))
153 throw std::runtime_error("Cdf97Stage: header too small");
154 Cdf97Config cfg;
155 std::memcpy(&cfg, buf, sizeof(cfg));
156 const int eff = (cfg.ndim == 0) ? 1 : static_cast<int>(cfg.ndim);
157 dims_[0] = cfg.dim_x;
158 dims_[1] = (eff >= 2) ? cfg.dim_y : 1;
159 dims_[2] = (eff >= 3) ? cfg.dim_z : 1;
160 }
161 size_t getMaxHeaderSize(size_t /*output_index*/) const override {
162 return sizeof(Cdf97Config);
163 }
164
165 void saveState() override { saved_dims_ = dims_; }
166 void restoreState() override { dims_ = saved_dims_; }
167
168private:
169 bool is_inverse_ = false;
170 size_t actual_output_size_ = 0;
171 std::array<size_t, 3> dims_ = {0, 1, 1};
172 std::array<size_t, 3> saved_dims_ = {0, 1, 1};
173
174 int ndim() const {
175 if (dims_[2] > 1) return 3;
176 if (dims_[1] > 1) return 2;
177 return 1;
178 }
179 static DataType elementDataType() {
180 return std::is_same<TInput, double>::value ? DataType::FLOAT64
181 : DataType::FLOAT32;
182 }
183};
184
185extern template class Cdf97Stage<float>;
186extern template class Cdf97Stage<double>;
187
188} // namespace fz
Definition cdf97_stage.h:82
bool isGraphCompatible() const override
No mid-execute sync or D2H: every kernel is enqueued on stream.
Definition cdf97_stage.h:107
static constexpr size_t kMaxLineElems
Largest transform line that fits the shared-memory scheme, in elements.
Definition cdf97_stage.h:88
void setDims(const std::array< size_t, 3 > &dims) override
Definition cdf97_stage.h:96
void setInverse(bool inv) override
Definition cdf97_stage.h:93
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
Definition cdf97_stage.h:114
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition cdf97_stage.h:151
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition cdf97_stage.h:120
void saveState() override
Definition cdf97_stage.h:165
uint8_t getOutputDataType(size_t) const override
Definition cdf97_stage.h:131
size_t serializeHeader(size_t, uint8_t *buf, size_t max_size) const override
Definition cdf97_stage.h:139
uint16_t getStageTypeId() const override
Definition cdf97_stage.h:128
void execute(cudaStream_t stream, MemoryPool *pool, const std::vector< void * > &inputs, const std::vector< void * > &outputs, const std::vector< size_t > &sizes) override
size_t getActualOutputSize(int index) const override
Definition cdf97_stage.h:123
uint8_t getInputDataType(size_t) const override
Definition cdf97_stage.h:134
size_t getMaxHeaderSize(size_t) const override
Definition cdf97_stage.h:161
std::string getName() const override
Definition cdf97_stage.h:110
Definition mempool.h:82
Definition stage.h:31
FZM binary file format definitions — structs, enums, and helpers.
Definition dag.h:24
constexpr size_t FZM_STAGE_CONFIG_SIZE
Per-stage serialized config slot (bytes)
Definition fzm_format.h:65
@ CDF97
CDF 9/7 biorthogonal wavelet transform (SPERR's DWT front-half)
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:139
Base class interface for all compression stages.
Definition cdf97_stage.h:60
DataType data_type
Floating-point element type (1B): FLOAT32 or FLOAT64.
Definition cdf97_stage.h:61
uint32_t dim_y
Y dimension (1 for 1-D).
Definition cdf97_stage.h:65
uint32_t dim_z
Z dimension (1 for 1-D/2-D).
Definition cdf97_stage.h:66
uint8_t reserved[2]
Must be zero.
Definition cdf97_stage.h:63
uint8_t ndim
Spatial dimensionality 1/2/3 (0 treated as 1).
Definition cdf97_stage.h:62
uint32_t dim_x
X (fast) dimension.
Definition cdf97_stage.h:64
Backend-neutral GPU type aliases.