19#include <unordered_map>
44 "LorenzoConfig must fit in FZM_STAGE_CONFIG_SIZE");
60 static_assert(std::is_integral<T>::value && std::is_signed<T>::value,
61 "LorenzoStage requires a signed integer type");
75 : block_size_(block_size), centering_(centering), order_(order) {
76 if (block_size > 1024)
77 throw std::invalid_argument(
78 "LorenzoStage: block_size must be in [0, 1024], got "
79 + std::to_string(block_size));
80 if (centering && block_size == 0)
81 throw std::invalid_argument(
82 "LorenzoStage: centering requires block_size > 0");
83 if (order != 1 && order != 2)
84 throw std::invalid_argument(
85 "LorenzoStage: order must be 1 or 2, got " + std::to_string(order));
86 if (order == 2 && block_size == 0)
87 throw std::invalid_argument(
88 "LorenzoStage: order 2 requires block_size > 0");
91 void setInverse(
bool inv)
override { is_inverse_ = inv; }
92 bool isInverse()
const override {
return is_inverse_; }
94 void setDims(
const std::array<size_t, 3>& dims)
override { dims_ = dims; }
95 void setDims(
size_t x,
size_t y = 1,
size_t z = 1) { dims_ = {x, y, z}; }
96 std::array<size_t, 3> getDims()
const {
return dims_; }
112 throw std::invalid_argument(
113 "LorenzoStage::setBlockSize: n must be in [0, 1024], got "
114 + std::to_string(n));
117 uint32_t getBlockSize()
const {
return block_size_; }
124 if (isInverse() || block_size_ == 0)
return {};
125 return FusionSpec{FusionAccess::BlockLocal, block_size_};
134 if (isInverse() || block_size_ != 32u)
return {};
136 d.strategy = FusionStrategy::WarpRegister;
137 d.
op_name =
"Lorenzo1DPredictor";
142 d.
params.resize(
sizeof(p));
143 std::memcpy(d.
params.data(), &p,
sizeof(p));
175 bool getCentering()
const {
return centering_; }
195 if (k != 1 && k != 2)
196 throw std::invalid_argument(
197 "LorenzoStage::setOrder: order must be 1 or 2, got " + std::to_string(k));
200 uint8_t getOrder()
const {
return order_; }
203 if (dims_[2] > 1)
return 3;
204 if (dims_[1] > 1)
return 2;
211 const std::vector<void*>& inputs,
212 const std::vector<void*>& outputs,
213 const std::vector<size_t>& sizes
216 std::string
getName()
const override {
return "Lorenzo"; }
220 return (is_inverse_ && centeringActive()) ? 2 : 1;
222 size_t getNumOutputs()
const override {
223 return (!is_inverse_ && centeringActive()) ? 2 : 1;
227 if (centeringActive())
return {
"output",
"means"};
232 const std::vector<size_t>& input_sizes
234 const size_t in = input_sizes.empty() ? 0 : input_sizes[0];
235 if (!centeringActive())
return {in};
236 return {in, numBlocks(in /
sizeof(T)) *
sizeof(T)};
239 std::unordered_map<std::string, size_t>
241 if (centeringActive())
242 return {{
"output", actual_output_size_}, {
"means", actual_means_size_}};
243 return {{
"output", actual_output_size_}};
247 if (index == 0)
return actual_output_size_;
248 if (index == 1 && centeringActive())
return actual_means_size_;
253 return static_cast<uint16_t
>(StageType::LORENZO);
257 return static_cast<uint8_t
>(getElementDataType());
261 return static_cast<uint8_t
>(getElementDataType());
266 throw std::runtime_error(
"LorenzoStage: header buffer too small");
269 cfg.
ndim =
static_cast<uint8_t
>(ndim());
270 cfg.
dim_x =
static_cast<uint32_t
>(dims_[0]);
271 cfg.
dim_y =
static_cast<uint32_t
>(dims_[1]);
272 cfg.
dim_z =
static_cast<uint32_t
>(dims_[2]);
274 cfg.
centering = centeringActive() ? 1u : 0u;
282 constexpr size_t kMinSize = 16;
284 throw std::runtime_error(
"LorenzoStage: header too small");
286 std::memcpy(&cfg, buf, std::min(size,
sizeof(
LorenzoConfig)));
287 int eff_ndim = (cfg.
ndim == 0) ? 1 :
static_cast<int>(cfg.
ndim);
288 dims_[0] = cfg.
dim_x;
289 dims_[1] = (eff_ndim >= 2) ? cfg.
dim_y : 1;
290 dims_[2] = (eff_ndim >= 3) ? cfg.
dim_z : 1;
297 order_ = (cfg.
order == 2) ? 2u : 1u;
305 bool is_inverse_ =
false;
306 size_t actual_output_size_ = 0;
307 size_t actual_means_size_ = 0;
308 std::array<size_t, 3> dims_ = {0, 1, 1};
309 uint32_t block_size_ = 0;
310 bool centering_ =
false;
316 bool centeringActive()
const {
return centering_ && block_size_ > 0; }
319 size_t numBlocks(
size_t n)
const {
320 return (block_size_ == 0) ? 0 : (n + block_size_ - 1) / block_size_;
323 static DataType getElementDataType() {
324 if (std::is_same<T, int8_t>::value)
return DataType::INT8;
325 if (std::is_same<T, int16_t>::value)
return DataType::INT16;
326 if (std::is_same<T, int32_t>::value)
return DataType::INT32;
327 if (std::is_same<T, int64_t>::value)
return DataType::INT64;
328 return DataType::INT32;
332extern template class LorenzoStage<int8_t>;
333extern template class LorenzoStage<int16_t>;
334extern template class LorenzoStage<int32_t>;
335extern template class LorenzoStage<int64_t>;
340void launchLorenzoDeltaKernel1D(
341 const T* d_input, T* d_output,
size_t n, fz::stream_t stream,
342 unsigned block_threads = 256);
345void launchLorenzoPrefixSumKernel1D(
346 const T* d_input, T* d_output,
size_t n, fz::stream_t stream,
347 unsigned block_threads = 256);
354 const T* d_input, T* d_output, T* d_means,
size_t n, fz::stream_t stream,
355 unsigned block_threads);
363 const T* d_input,
const T* d_means, T* d_output,
size_t n, fz::stream_t stream,
364 unsigned block_threads,
int passes);
370 const T* d_input, T* d_output, T* d_means,
size_t n, fz::stream_t stream,
371 unsigned block_threads);
374void launchLorenzoDeltaKernel2D(
375 const T* d_input, T* d_output,
size_t nx,
size_t ny, fz::stream_t stream);
378void launchLorenzoPrefixSumKernel2D(
379 const T* d_input, T* d_output,
size_t nx,
size_t ny, fz::stream_t stream);
382void launchLorenzoDeltaKernel3D(
383 const T* d_input, T* d_output,
size_t nx,
size_t ny,
size_t nz, fz::stream_t stream);
386void launchLorenzoPrefixSumKernel3D(
387 const T* d_input, T* d_output,
size_t nx,
size_t ny,
size_t nz, fz::stream_t stream);
Definition lorenzo_stage.h:59
void setBlockSize(uint32_t n)
Definition lorenzo_stage.h:110
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
Definition lorenzo_stage.h:231
size_t getMaxHeaderSize(size_t) const override
Definition lorenzo_stage.h:300
std::string getName() const override
Definition lorenzo_stage.h:216
FusedOpDecl getFusedOp() const override
Definition lorenzo_stage.h:133
size_t getActualOutputSize(int index) const override
Definition lorenzo_stage.h:246
uint16_t getStageTypeId() const override
Definition lorenzo_stage.h:252
void setInverse(bool inv) override
Definition lorenzo_stage.h:91
std::vector< std::string > getOutputNames() const override
Definition lorenzo_stage.h:226
void setCentering(bool enable)
Definition lorenzo_stage.h:174
size_t serializeHeader(size_t, uint8_t *buf, size_t max_size) const override
Definition lorenzo_stage.h:264
void setOrder(uint8_t k)
Definition lorenzo_stage.h:194
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition lorenzo_stage.h:240
uint8_t getInputDataType(size_t) const override
Definition lorenzo_stage.h:260
uint8_t getOutputDataType(size_t) const override
Definition lorenzo_stage.h:256
LorenzoStage(uint32_t block_size, bool centering=false, uint8_t order=1)
Definition lorenzo_stage.h:73
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
size_t getNumInputs() const override
Centering adds a "means" port: a second output forward, a second input inverse.
Definition lorenzo_stage.h:219
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition lorenzo_stage.h:280
FusionSpec getFusionSpec() const override
Definition lorenzo_stage.h:123
void setDims(const std::array< size_t, 3 > &dims) override
Definition lorenzo_stage.h:94
void launchLorenzoDeltaCentered1D(const T *d_input, T *d_output, T *d_means, size_t n, fz::stream_t stream, unsigned block_threads)
void launchLorenzoSegmentedScan(const T *d_input, const T *d_means, T *d_output, size_t n, fz::stream_t stream, unsigned block_threads, int passes)
void launchLorenzo2Delta1D(const T *d_input, T *d_output, T *d_means, size_t n, fz::stream_t stream, unsigned block_threads)
constexpr size_t FZM_STAGE_CONFIG_SIZE
Per-stage serialized config slot (bytes)
Definition fzm_format.h:65
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:139
Base class interface for all compression stages.
A stage's contribution to a generated fused kernel — the device-op it maps to, where its source lives...
Definition fusion.h:161
std::vector< uint8_t > params
POD Params bytes; empty for stateless ops.
Definition fusion.h:165
uint32_t elems_per_lane
Definition fusion.h:172
std::string op_name
device-op type name, e.g. "DiffNegabinary"
Definition fusion.h:163
std::string include_header
header used by the generated source
Definition fusion.h:164
A stage's fusion contract. Stages that can participate in a fused kernel override Stage::getFusionSpe...
Definition fusion.h:52
Definition lorenzo_stage.h:29
uint8_t centering
1 if per-block mean centering is enabled, else 0.
Definition lorenzo_stage.h:32
uint32_t dim_z
Z dimension (1 for 1-D/2-D).
Definition lorenzo_stage.h:36
DataType data_type
Signed integer element type (1B).
Definition lorenzo_stage.h:30
uint32_t dim_y
Y dimension (1 for 1-D).
Definition lorenzo_stage.h:35
uint8_t ndim
Spatial dimensionality 1/2/3 (0 treated as 1).
Definition lorenzo_stage.h:31
uint32_t dim_x
X (fast) dimension.
Definition lorenzo_stage.h:34
uint8_t order
Prediction order: 0/1 = first, 2 = second. 0 reads as 1.
Definition lorenzo_stage.h:33
uint32_t block_size
1-D block-local reset period; 0 = default N-D behavior.
Definition lorenzo_stage.h:37
cuSZp2: linear-ABS quant + 1-D Lorenzo. Only inv2eb (dims are implicit in n).
Definition warp_op_params.h:26
Backend-neutral GPU type aliases.
POD parameter blocks for the warp-register predictor policies.