FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
zigzag_stage.h
Go to the documentation of this file.
1#pragma once
2
12#include "stage/stage.h"
13#include "fzm_format.h"
15#include "backend/types.h"
16#include <cstdint>
17#include <cstring>
18#include <stdexcept>
19#include <type_traits>
20
21namespace fz {
22
29template<typename TIn, typename TOut = typename std::make_unsigned<TIn>::type>
30class ZigzagStage : public Stage {
31 static_assert(std::is_integral<TIn>::value && std::is_signed<TIn>::value,
32 "ZigzagStage: TIn must be a signed integer type "
33 "(int8_t, int16_t, int32_t, or int64_t).");
34 static_assert(std::is_integral<TOut>::value && std::is_unsigned<TOut>::value,
35 "ZigzagStage: TOut must be an unsigned integer type.");
36 static_assert(sizeof(TIn) == sizeof(TOut),
37 "ZigzagStage: TIn and TOut must have the same byte width.");
38
39public:
40 ZigzagStage() : is_inverse_(false), actual_output_size_(0) {}
41
42 // ── Stage control ──────────────────────────────────────────────────────
43 void setInverse(bool inv) override { is_inverse_ = inv; }
44 bool isInverse() const override { return is_inverse_; }
45
58 void setByteTransparent(bool on) { byte_transparent_ = on; }
59 bool isByteTransparent() const { return byte_transparent_; }
60
61 // ── Fusion (warp-register transform) ─────────────────────────────────────
62 // Element-wise TCMS is a Map — composes anywhere. As a warp-register op it slots
63 // between a predictor and the coder (the register→register `ZigzagTransform`).
64 // Restricted to the 32-bit signed form the device op implements; a chunk group
65 // won't pick it up (its op declares the WarpRegister strategy, not chunk).
66 FusionSpec getFusionSpec() const override {
67 if (is_inverse_ || !std::is_same<TIn, int32_t>::value) return {};
68 return FusionSpec{FusionAccess::Map, 0};
69 }
70 FusedOpDecl getFusedOp() const override {
71 if (is_inverse_ || !std::is_same<TIn, int32_t>::value) return {};
73 d.strategy = FusionStrategy::WarpRegister;
74 d.op_name = "ZigzagTransform";
75 d.include_header = "fused/fused_block/warp_fusion.cuh";
76 return d;
77 }
78
79 // ── Execution ──────────────────────────────────────────────────────────
80 void execute(
81 fz::stream_t stream,
82 MemoryPool* pool,
83 const std::vector<void*>& inputs,
84 const std::vector<void*>& outputs,
85 const std::vector<size_t>& sizes
86 ) override;
87
88 // ── Metadata ───────────────────────────────────────────────────────────
89 std::string getName() const override { return "Zigzag"; }
90 size_t getNumInputs() const override { return 1; }
91 size_t getNumOutputs() const override { return 1; }
92
93 std::vector<size_t> estimateOutputSizes(
94 const std::vector<size_t>& input_sizes
95 ) const override {
96 return {input_sizes[0]};
97 }
98
99 std::unordered_map<std::string, size_t>
100 getActualOutputSizesByName() const override {
101 return {{"output", actual_output_size_}};
102 }
103 size_t getActualOutputSize(int index) const override {
104 return (index == 0) ? actual_output_size_ : 0;
105 }
106
107 uint16_t getStageTypeId() const override {
108 return static_cast<uint16_t>(StageType::ZIGZAG);
109 }
110
111 uint8_t getOutputDataType(size_t output_index) const override {
112 (void)output_index;
113 if (byte_transparent_) return static_cast<uint8_t>(DataType::UNKNOWN);
114 // Forward output is TOut (unsigned); inverse output is TIn (signed).
115 return is_inverse_
116 ? static_cast<uint8_t>(dataTypeOf<TIn>())
117 : static_cast<uint8_t>(dataTypeOf<TOut>());
118 }
119
120 uint8_t getInputDataType(size_t /*input_index*/) const override {
121 if (byte_transparent_) return static_cast<uint8_t>(DataType::UNKNOWN);
122 // Forward input is TIn (signed); inverse input is TOut (unsigned).
123 return is_inverse_
124 ? static_cast<uint8_t>(dataTypeOf<TOut>())
125 : static_cast<uint8_t>(dataTypeOf<TIn>());
126 }
127
128 // ── Serialization ──────────────────────────────────────────────────────
130 size_t output_index, uint8_t* buf, size_t max_size
131 ) const override {
132 (void)output_index;
133 if (max_size < 3) return 0;
134 buf[0] = static_cast<uint8_t>(dataTypeOf<TIn>());
135 buf[1] = static_cast<uint8_t>(dataTypeOf<TOut>());
136 buf[2] = byte_transparent_ ? 1 : 0; // LC TCMS mode
137 return 3;
138 }
139
140 void deserializeHeader(const uint8_t* buf, size_t size) override {
141 // TIn/TOut are baked into the template (factory selects the right
142 // instantiation before calling this); byte 2 carries byte-transparent.
143 if (size >= 3) byte_transparent_ = (buf[2] != 0);
144 }
145
146 size_t getMaxHeaderSize(size_t) const override { return 3; }
147
148private:
149 bool is_inverse_;
150 bool byte_transparent_ = false; // LC TCMS mode: opt out of type checking
151 size_t actual_output_size_;
152
153 template<typename U>
154 static constexpr DataType dataTypeOf() {
155 if (std::is_same<U, int8_t>::value) return DataType::INT8;
156 if (std::is_same<U, int16_t>::value) return DataType::INT16;
157 if (std::is_same<U, int32_t>::value) return DataType::INT32;
158 if (std::is_same<U, int64_t>::value) return DataType::INT64;
159 if (std::is_same<U, uint8_t>::value) return DataType::UINT8;
160 if (std::is_same<U, uint16_t>::value) return DataType::UINT16;
161 if (std::is_same<U, uint32_t>::value) return DataType::UINT32;
162 if (std::is_same<U, uint64_t>::value) return DataType::UINT64;
163 return DataType::UINT8; // unreachable
164 }
165};
166
167extern template class ZigzagStage<int8_t, uint8_t>;
168extern template class ZigzagStage<int16_t, uint16_t>;
169extern template class ZigzagStage<int32_t, uint32_t>;
170extern template class ZigzagStage<int64_t, uint64_t>;
171
172} // namespace fz
Definition mempool.h:82
Definition stage.h:31
Definition zigzag_stage.h:30
uint8_t getInputDataType(size_t) const override
Definition zigzag_stage.h:120
std::unordered_map< std::string, size_t > getActualOutputSizesByName() const override
Definition zigzag_stage.h:100
std::string getName() const override
Definition zigzag_stage.h:89
void setInverse(bool inv) override
Definition zigzag_stage.h:43
void deserializeHeader(const uint8_t *buf, size_t size) override
Definition zigzag_stage.h:140
FusedOpDecl getFusedOp() const override
Definition zigzag_stage.h:70
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
uint16_t getStageTypeId() const override
Definition zigzag_stage.h:107
uint8_t getOutputDataType(size_t output_index) const override
Definition zigzag_stage.h:111
std::vector< size_t > estimateOutputSizes(const std::vector< size_t > &input_sizes) const override
Definition zigzag_stage.h:93
size_t serializeHeader(size_t output_index, uint8_t *buf, size_t max_size) const override
Definition zigzag_stage.h:129
size_t getMaxHeaderSize(size_t) const override
Definition zigzag_stage.h:146
void setByteTransparent(bool on)
Definition zigzag_stage.h:58
FusionSpec getFusionSpec() const override
Definition zigzag_stage.h:66
size_t getActualOutputSize(int index) const override
Definition zigzag_stage.h:103
FZM binary file format definitions — structs, enums, and helpers.
Definition dag.h:24
DataType
Element data type identifiers used in buffer and stage descriptors.
Definition fzm_format.h:139
@ UNKNOWN
Byte-transparent stages: skip type checking at finalize()
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::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
Backend-neutral GPU type aliases.
Zigzag (two's complement to magnitude-sign) encoding helpers.