FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
compressor.h
Go to the documentation of this file.
1
5#pragma once
6
7#include "backend/types.h"
8#include "advanced/dag.h"
10#include "pipeline/perf.h"
11#include "pipeline/config.h"
12#include "stage/stage.h"
13#include "stage/stage_factory.h"
14#include "mem/mempool.h"
15#include "fzm_format.h"
16
17#include <array>
18#include <memory>
19#include <stdexcept>
20#include <string>
21#include <unordered_map>
22#include <vector>
23
24namespace fz {
25
63enum class SpecializationPolicy { Off, Auto, Force };
64
68
71 std::string implementation;
72 std::vector<std::string> stages;
73 std::string execution_path;
74};
76
79 SpecializationPolicy policy = SpecializationPolicy::Off;
80 size_t legal_group_count = 0;
81 std::vector<SpecializationGroupInfo> installed_groups;
83 std::vector<SpecializationGroupInfo> installed_inverse_groups;
85 std::string fallback_reason;
86};
88
89class Pipeline {
90public:
96 explicit Pipeline(
97 size_t input_data_size = 0,
99 float pool_multiplier = 3.0f
100 );
101
109 explicit Pipeline(const std::string& config_path);
110
111 ~Pipeline();
112
113 // ── Configuration ─────────────────────────────────────────────────────────
114
116 void setMemoryStrategy(MemoryStrategy strategy);
117
119 void setSpecializationPolicy(SpecializationPolicy mode) { fusion_policy_ = mode; }
120 SpecializationPolicy getSpecializationPolicy() const { return fusion_policy_; }
122 size_t getSpecializedGroupCount() const { return dag_ ? dag_->getFusedGroupCount() : 0; }
124 const SpecializationInfo& getSpecializationInfo() const { return fusion_info_; }
125
127 void setFusionPolicy(SpecializationPolicy mode) { setSpecializationPolicy(mode); }
128 SpecializationPolicy getFusionPolicy() const { return getSpecializationPolicy(); }
129 size_t getFusedGroupCount() const { return getSpecializedGroupCount(); }
130 const SpecializationInfo& getFusionInfo() const { return fusion_info_; }
131
133 void setNumStreams(int num_streams);
134
141 void setDims(size_t x, size_t y = 1, size_t z = 1) { dims_ = {x, y, z}; }
142 void setDims(std::array<size_t, 3> dims) { dims_ = dims; }
143 std::array<size_t, 3> getDims() const { return dims_; }
144
145 // ── Builder API ───────────────────────────────────────────────────────────
146
151 template<typename StageT, typename... Args>
152 StageT* addStage(Args&&... args);
153
161 int connect(Stage* dependent, Stage* producer, const std::string& output_name = "output");
162
164 int connect(Stage* dependent, const std::vector<Stage*>& producers);
165
189 void bindExternalInput(Stage* stage);
190
196 void finalize();
197
203 void warmup(fz::stream_t stream = 0);
204
206 void setWarmupOnFinalize(bool enable) { warmup_on_finalize_ = enable; }
207 bool isWarmupOnFinalizeEnabled() const { return warmup_on_finalize_; }
208
215 void setPoolManagedDecompOutput(bool enable) { pool_managed_decomp_ = enable; }
216 bool isPoolManagedDecompOutput() const { return pool_managed_decomp_; }
217
250 void setPrimarySource(Stage* stage) { primary_source_stage_ = stage; }
251
265 size_t getMaxCompressedSize(size_t input_bytes) const;
266
286 size_t getLastUncompressedSize() const {
287 return original_input_size_ > 0 ? original_input_size_ : input_size_;
288 }
289
290 // ── Execution ─────────────────────────────────────────────────────────────
291
303 void compress(
304 const void* d_input,
305 size_t input_size,
306 void** d_output,
307 size_t* output_size,
308 fz::stream_t stream = 0
309 );
310
337 void compress(
338 const void* d_input,
339 size_t input_size,
340 void* d_output_buf,
341 size_t output_buf_capacity,
342 size_t* actual_output_size,
343 fz::stream_t stream = 0
344 );
345
360 void decompress(
361 const void* d_input,
362 size_t input_size,
363 void** d_output,
364 size_t* output_size,
365 fz::stream_t stream = 0
366 );
367
388 void decompress(
389 const void* d_input,
390 size_t input_size,
391 void* d_output_buf,
392 size_t output_buf_capacity,
393 size_t* actual_output_size,
394 fz::stream_t stream = 0
395 );
396
434 void decompressInto(
435 const void* d_input,
436 size_t input_size,
437 void* d_output_buf,
438 size_t output_buf_capacity,
439 size_t* actual_output_size,
440 fz::stream_t stream = 0
441 );
442
443 // ── Explicit-ownership execution API ──────────────────────────────────────
444 //
445 // Span-based wrappers over the pointer overloads above. Behavior is
446 // identical — these exist so ownership is visible in the signature instead
447 // of depending on `void**` vs `void*` and on setPoolManagedDecompOutput().
448 // Prefer these in new code; the pointer overloads remain supported.
449
455 BorrowedDeviceBuffer compress(ConstDeviceSpan input, fz::stream_t stream = 0);
456
462 size_t compressInto(ConstDeviceSpan input, DeviceSpan output, fz::stream_t stream = 0);
463
472 BorrowedDeviceBuffer decompressBorrowed(ConstDeviceSpan input, fz::stream_t stream = 0);
473
479 OwnedDeviceBuffer decompressOwned(ConstDeviceSpan input, fz::stream_t stream = 0);
480
486 size_t decompressInto(ConstDeviceSpan input, DeviceSpan output, fz::stream_t stream = 0);
487
494 size_t decompressIntoAsync(ConstDeviceSpan input, DeviceSpan output, fz::stream_t stream = 0);
495
520 void prepareInverse(size_t uncompressed_size);
521
523 void reset(fz::stream_t stream = 0);
524
525 // ── Profiling ─────────────────────────────────────────────────────────────
526
531 void enableProfiling(bool enable);
532 bool isProfilingEnabled() const { return profiling_enabled_; }
533
535 const PipelinePerfResult& getLastPerfResult() const { return last_perf_result_; }
536
538 CompressionDAG* getDAG() { return dag_.get(); }
539
541 size_t getPoolThreshold() const;
542
552 bool isMemPoolFallbackMode() const;
553
559 void enableBoundsCheck(bool enable) { dag_->enableBoundsCheck(enable); }
560 bool isBoundsCheckEnabled() const { return dag_->isBoundsCheckEnabled(); }
561
567 void setColoringEnabled(bool enable) {
568 coloring_enabled_ = enable; // survives a setMemoryStrategy() DAG swap
569 dag_->setColoringEnabled(enable);
570 }
571 bool isColoringEnabled() const { return dag_->isColoringEnabled(); }
572 size_t getColorRegionCount() const { return dag_->getColorRegionCount(); }
573
581 bool isColoringRequested() const { return coloring_enabled_; }
582
592 std::unordered_map<std::string, std::vector<std::string>> collectRunNotes() const {
593 std::unordered_map<std::string, std::vector<std::string>> notes;
594 for (const auto& s : stages_) {
595 if (!s) continue;
596 auto n = s->getRunNotes();
597 if (!n.empty()) notes.emplace(s->getName(), std::move(n));
598 }
599 return notes;
600 }
601
602 // ── CUDA Graph Capture (compression-only) ─────────────────────────────────
603
611 void enableGraphMode(bool enable);
612 bool isGraphModeEnabled() const { return graph_mode_enabled_; }
613
624 void captureGraph(fz::stream_t stream = 0);
625 bool isGraphCaptured() const { return graph_captured_; }
626
627 size_t getPeakMemoryUsage() const;
628 size_t getCurrentMemoryUsage() const;
629 void printPipeline() const;
630
631 // ── File Serialization ────────────────────────────────────────────────────
632
635 FZMHeaderCore core;
636 std::vector<FZMStageInfo> stages;
637 std::vector<FZMBufferEntry> buffers;
638 };
639
641 void writeToFile(const std::string& filename, fz::stream_t stream = 0);
642
644 static FZMFileHeader readHeader(const std::string& filename);
645
647 FZMFileHeader buildHeader() const;
648
649 // ── In-memory metadata header (decode without a prior compress) ────────────
650
665 std::vector<uint8_t> serializeHeaderToMemory() const;
666
686 void primeInverseFromHeader(const void* header_bytes, size_t header_size);
687
702 static void decompressFromFile(
703 const std::string& filename,
704 void** d_output,
705 size_t* output_size,
706 fz::stream_t stream = 0,
707 PipelinePerfResult* perf_out = nullptr,
708 size_t pool_override_bytes = 0
709 );
710
728 void decompressFromFileInstance(
729 const std::string& filename,
730 void** d_output,
731 size_t* output_size,
732 fz::stream_t stream = 0,
733 PipelinePerfResult* perf_out = nullptr
734 );
735
760 void decompressFromMemory(
761 const void* header_bytes,
762 size_t header_size,
763 const void* d_blob,
764 size_t blob_size,
765 void** d_output,
766 size_t* output_size,
767 fz::stream_t stream = 0
768 );
769
770 // ── Config File ───────────────────────────────────────────────────────────
771
785 void loadConfig(const std::string& path);
786
795 void saveConfig(const std::string& path) const;
796
797private:
798 // ── RAII buffer wrappers (private implementation detail) ─────────────────
799
800 // Pool-allocated persistent device buffer.
801 struct PoolBuffer {
802 void* ptr = nullptr;
803 size_t capacity = 0;
804 MemoryPool* pool = nullptr;
805
806 ~PoolBuffer() { free(0); }
807 PoolBuffer() = default;
808 PoolBuffer(const PoolBuffer&) = delete;
809 PoolBuffer& operator=(const PoolBuffer&) = delete;
810
811 void free(fz::stream_t s) {
812 if (ptr && pool) { pool->free(ptr, s); ptr = nullptr; capacity = 0; }
813 }
814 bool allocate(MemoryPool* p, size_t bytes, fz::stream_t s,
815 const char* tag, bool persistent = false) {
816 free(s);
817 pool = p;
818 ptr = pool->allocate(bytes, s, tag, persistent);
819 if (ptr) capacity = bytes;
820 return ptr != nullptr;
821 }
822 };
823
824 // cudaHostAlloc pinned host buffer — grows on demand, never shrinks.
825 struct PinnedBuffer {
826 void* ptr = nullptr;
827 size_t capacity = 0;
828
829 ~PinnedBuffer() { if (ptr) cudaFreeHost(ptr); }
830 PinnedBuffer() = default;
831 PinnedBuffer(const PinnedBuffer&) = delete;
832 PinnedBuffer& operator=(const PinnedBuffer&) = delete;
833
834 // Returns false on CUDA allocation failure.
835 bool ensureCapacity(size_t bytes) {
836 if (capacity >= bytes) return true;
837 if (ptr) { cudaFreeHost(ptr); ptr = nullptr; capacity = 0; }
838 if (cudaHostAlloc(&ptr, bytes, cudaHostAllocDefault) != cudaSuccess) return false;
839 capacity = bytes;
840 return true;
841 }
842 };
843
844 // cudaMalloc device buffer — grows on demand, never shrinks.
845 struct DeviceBuffer {
846 void* ptr = nullptr;
847 size_t capacity = 0;
848
849 ~DeviceBuffer() { if (ptr) cudaFree(ptr); }
850 DeviceBuffer() = default;
851 DeviceBuffer(const DeviceBuffer&) = delete;
852 DeviceBuffer& operator=(const DeviceBuffer&) = delete;
853
854 // Returns false on CUDA allocation failure.
855 bool ensureCapacity(size_t bytes) {
856 if (capacity >= bytes) return true;
857 if (ptr) { cudaFree(ptr); ptr = nullptr; capacity = 0; }
858 if (cudaMalloc(&ptr, bytes) != cudaSuccess) return false;
859 capacity = bytes;
860 return true;
861 }
862 };
863
864 // ── Internal helpers ──────────────────────────────────────────────────────
865
866 Stage* addRawStage(Stage* stage);
867
868 struct OutputBuffer {
869 void* d_ptr;
870 size_t actual_size;
871 size_t allocated_size;
872 std::string name;
873 int buffer_id;
874 };
875 std::vector<OutputBuffer> getOutputBuffers() const;
876
877 static void* loadCompressedData(
878 const std::string& filename,
879 const FZMFileHeader& header,
880 fz::stream_t stream = 0,
881 MemoryPool* pool = nullptr
882 );
883
884 void validate();
885 std::pair<std::vector<Stage*>, std::vector<Stage*>> identifyTopology();
886 void setupInputBuffers(const std::vector<Stage*>& sources);
887 int autoDetectUnconnectedOutputs();
888 void detectMultiOutputScenario(int pipeline_outputs);
889 void configureStreamsIfNeeded();
890
891 // finalize() sub-steps
892 void typeCheckConnections();
893 void computeInputAlignment();
896 void bindSemanticContracts();
900 void planAndInstallFusion();
901 void notifyStagesFinalizeHooks();
902 void refinePoolSize();
903 void setupGraphModeInput();
904 void preallocatePadBuffer();
905 void preallocateConcatBuffers();
906
907 // compress() helper: handles graph-mode copy or alignment padding.
908 // Returns the effective source pointer and padded source size.
909 std::pair<const void*, size_t> prepareInputSource(
910 const void* d_input, size_t input_size, fz::stream_t stream);
911
917 void propagateBufferSizes(bool force_from_current_inputs = false);
918
919 std::vector<Stage*> getSourceStages() const;
920 std::vector<Stage*> getSinkStages() const;
921
922 // ── Inverse DAG helpers ───────────────────────────────────────────────────
923
925 struct FwdStageDesc {
926 Stage* stage;
927 std::vector<int> output_buf_ids;
928 std::vector<int> input_buf_ids;
929 };
930
932 using PipelineOutputMap = std::unordered_map<int, std::pair<void*, size_t>>;
933
934 // decompress() helper: builds or reuses the inverse DAG cache.
935 void buildOrReuseInvCache(
936 const PipelineOutputMap& po_map,
937 Stage* src_stage,
938 size_t src_sz,
939 fz::stream_t stream);
940
949 std::vector<size_t> resolveDecompressSegmentSizes(
950 const void* d_input, size_t input_size, fz::stream_t stream) const;
951
958 PipelineOutputMap mapCompressedBufferPointers(
959 const void* d_input, const std::vector<size_t>& seg_sizes) const;
960
967 std::pair<Stage*, size_t> resolvePrimarySource() const;
968
976 void* allocateDecompressOutput(
977 size_t actual_size, void* caller_output, size_t caller_capacity,
978 fz::stream_t stream);
979
992 void decompressCore(
993 const void* d_input,
994 size_t input_size,
995 void* caller_output,
996 size_t caller_capacity,
997 bool synchronize,
998 void** d_output,
999 size_t* output_size,
1000 fz::stream_t stream);
1001
1009 void buildStaticBufferMetadata();
1010
1016 std::vector<size_t> readConcatSegmentSizes(
1017 const void* d_blob, size_t n, fz::stream_t stream) const;
1018
1019 // decompressFromFile() helpers.
1021 static FZMFileHeader parseHeaderFromMemory(const void* data, size_t size);
1022 static size_t computeFilePoolSize(const FZMFileHeader& fh, size_t pool_override_bytes);
1023 static std::pair<std::vector<std::unique_ptr<Stage>>, std::vector<FwdStageDesc>>
1024 reconstructForwardTopology(const FZMFileHeader& fh);
1025 static std::unordered_map<Stage*, size_t> buildSourceSizesFromHeader(
1026 const FZMFileHeader& fh, const std::vector<FwdStageDesc>& fwd_topology);
1027
1033 static std::pair<std::unique_ptr<CompressionDAG>,
1034 std::unordered_map<Stage*, int>>
1035 buildInverseDAG(
1036 const std::vector<FwdStageDesc>& fwd_stages,
1037 const PipelineOutputMap& pipeline_outputs,
1038 MemoryPool* pool,
1039 MemoryStrategy strategy,
1040 const std::unordered_map<Stage*, size_t>& source_sizes,
1041 bool enable_profiling,
1042 bool enable_inverse_fusion = false,
1045 bool caller_supplies_results = false
1046 );
1047
1048 // ── Concat helpers ────────────────────────────────────────────────────────
1049
1050 struct OutputBufferInfo {
1051 int buffer_id;
1052 void* d_ptr;
1053 size_t actual_size;
1054 std::string stage_name;
1055 std::string output_name;
1056 };
1057
1058 std::vector<OutputBufferInfo> collectOutputBuffers() const;
1059
1061 size_t calculateConcatSize(const std::vector<OutputBufferInfo>& outputs) const;
1062
1063 size_t writeConcatBuffer(
1064 const std::vector<OutputBufferInfo>& outputs,
1065 uint8_t* d_concat_bytes,
1066 fz::stream_t stream
1067 ) const;
1068
1069 void concatOutputs(void** d_output, size_t* output_size, fz::stream_t stream);
1070
1071 // ── Member variables ──────────────────────────────────────────────────────
1072
1073 std::unique_ptr<MemoryPool> mem_pool_;
1074 std::unique_ptr<CompressionDAG> dag_;
1075 MemoryStrategy strategy_;
1076
1077 std::vector<std::unique_ptr<Stage>> stages_;
1078 std::unordered_map<Stage*, DAGNode*> stage_to_node_;
1079
1080 struct ConnectionInfo {
1081 Stage* dependent;
1082 Stage* producer;
1083 std::string output_name;
1084 int output_index;
1085 };
1086 std::vector<ConnectionInfo> connections_;
1087
1088 int num_streams_;
1089 bool is_finalized_;
1090 bool warmup_on_finalize_;
1091 bool pool_managed_decomp_;
1092
1093 // is_compressed_: true after the first successful compress() (gates writeToFile).
1094 // was_compressed_: true between compress() and the next reset() (gates captureGraph).
1095 bool is_compressed_;
1096 bool was_compressed_;
1097
1098 bool profiling_enabled_;
1101 bool coloring_enabled_ = true;
1102 PipelinePerfResult last_perf_result_;
1103
1104 std::vector<DAGNode*> input_nodes_;
1105 // Explicit choice of which input_nodes_ entry decompress() returns, for
1106 // pipelines with more than one source stage. Null = default to
1107 // input_nodes_[0]. Set via setPrimarySource(); resolved to an index lazily
1108 // (source stages aren't wired into input_nodes_ until finalize()).
1109 Stage* primary_source_stage_ = nullptr;
1110 // (node, buffer_id) pairs registered by bindExternalInput(), captured
1111 // immediately (before any later connect() calls add more buffer ids to
1112 // the same node). setupInputBuffers() appends these to input_nodes_/
1113 // input_buffer_ids_ after its own auto-discovery pass, since it clears
1114 // both first and auto-discovery alone would miss any stage that also
1115 // has real dependencies (getSourceStages() requires dependencies.empty()).
1116 std::vector<std::pair<DAGNode*, int>> explicit_external_bindings_;
1117 std::vector<DAGNode*> output_nodes_;
1118 std::vector<int> input_buffer_ids_;
1119 std::vector<int> output_buffer_ids_;
1120
1121 PoolBuffer d_concat_buffer_;
1122 bool needs_concat_;
1123
1124 // Pool-persistent decompress output buffers (one per source stage).
1125 // Only used when pool_managed_decomp_ == true.
1126 std::vector<void*> d_decomp_outputs_;
1127
1128 // Pinned host buffer for concat header (one H2D copy instead of N).
1129 PinnedBuffer h_concat_header_;
1130 // Persistent pinned host + device descriptor buffers for the gather kernel.
1131 PinnedBuffer h_copy_descs_;
1132 DeviceBuffer d_copy_descs_;
1133
1134 size_t input_size_;
1135
1136 // Per-source input sizes from the most recent compress(), ordered to match
1137 // input_nodes_. Used by decompress() to size each inverse result buffer.
1138 std::vector<size_t> source_input_sizes_;
1139
1140 // Input alignment in bytes — LCM of all stage getRequiredInputAlignment() values.
1141 // compress() zero-pads to this boundary transparently.
1142 size_t input_alignment_bytes_;
1143 PoolBuffer d_pad_buf_;
1147 bool fused_source_unpadded_ = false;
1148
1149 // Original (pre-padding) input size. decompress() uses this to trim the
1150 // reported output back to what the caller provided. 0 when no padding.
1151 size_t original_input_size_;
1152
1153 size_t input_size_hint_;
1154 float pool_multiplier_;
1155
1156 // Dataset dimensions (x=fast, y, z). Pushed to each stage on addStage() and
1157 // again at finalize(). Default {0,1,1} = 1-D, infer x from input size.
1158 std::array<size_t, 3> dims_;
1159
1168 struct InvDAGCache {
1169 std::unique_ptr<CompressionDAG> inv_dag;
1170 std::unordered_map<Stage*, int> inv_result_map;
1171 std::unordered_map<int, int> fwd_to_inv_ext_buf;
1172 std::unordered_map<Stage*, size_t> source_sizes;
1177 std::vector<size_t> fwd_size_signature;
1178 };
1179 std::unique_ptr<InvDAGCache> inv_cache_;
1181 std::vector<size_t> forwardSizeSignature() const;
1182
1183 struct BufferMetadata {
1184 int buffer_id;
1185 size_t actual_size;
1186 size_t allocated_size;
1187 std::string name;
1188 DAGNode* producer;
1189 int output_index;
1190 };
1191 std::vector<BufferMetadata> buffer_metadata_;
1192
1193 bool graph_mode_enabled_;
1194 bool graph_captured_;
1195 FusionPolicy fusion_policy_ = FusionPolicy::Off;
1196 FusionInfo fusion_info_;
1197
1198 // Fixed device input buffer whose address is baked into the captured graph.
1199 // compress() copies user input here before cudaGraphLaunch().
1200 PoolBuffer d_graph_input_;
1201 size_t d_graph_input_size_;
1202
1203 fz::graph_t captured_graph_;
1204 fz::graph_exec_t graph_exec_;
1205};
1206
1207// ── Template implementation ───────────────────────────────────────────────────
1208
1209template<typename StageT, typename... Args>
1210StageT* Pipeline::addStage(Args&&... args) {
1211 if (is_finalized_) {
1212 throw std::runtime_error("Cannot add stages after finalization");
1213 }
1214
1215 // if constexpr, not a runtime check: on an unsupported backend, StageT's
1216 // constructor may not exist in the build at all (its .cu translation
1217 // unit excluded — see Stage::isSupportedOnBackend()'s doc comment), so
1218 // every line below that references `new StageT()` must never be
1219 // instantiated at all, not merely never executed — hence the whole rest
1220 // of the function lives in the `if constexpr` branch rather than after
1221 // a standalone early-throw.
1222 if constexpr (!StageT::isSupportedOnBackend()) {
1223 throw std::runtime_error(
1224 "addStage(): this stage type is not supported on the current "
1225 "GPU backend (FZGMOD_BACKEND) this library was built for");
1226 } else {
1227 auto stage_ptr = std::make_unique<StageT>(std::forward<Args>(args)...);
1228 StageT* stage = stage_ptr.get();
1229
1230 stage->setDims(dims_);
1231
1232 DAGNode* node = dag_->addStage(stage, stage->getName());
1233 size_t num_outputs = stage->getNumOutputs();
1234 auto output_names = stage->getOutputNames();
1235
1236 // Pre-allocate all output slots as unconnected (size=1 placeholder).
1237 // connect() will promote any that get wired to downstream stages.
1238 for (size_t i = 0; i < num_outputs; i++) {
1239 std::string out_name = i < output_names.size() ? output_names[i] : std::to_string(i);
1240 dag_->addUnconnectedOutput(node, 1, i, stage->getName() + "." + out_name + "_unconnected");
1241 }
1242
1243 stage_to_node_[stage] = node;
1244 stages_.push_back(std::move(stage_ptr));
1245 return stage;
1246 }
1247}
1248
1249} // namespace fz
Definition device_buffer.h:54
Definition dag.h:104
Definition mempool.h:82
void free(void *ptr, fz::stream_t stream)
void * allocate(size_t size, fz::stream_t stream, const std::string &tag="", bool persistent=false)
Definition device_buffer.h:84
Definition stage.h:31
virtual void setDims(const std::array< size_t, 3 > &dims)
Definition stage.h:207
TOML-based pipeline configuration file support.
Compression DAG wiring, execution, and memory strategy types.
Backend-neutral device span and buffer value types.
FZM binary file format definitions — structs, enums, and helpers.
Stream-ordered CUDA memory pool for pipeline buffer management.
Definition dag.h:24
SpecializationPolicy
Pipeline Specialization policy.
Definition compressor.h:63
MemoryStrategy
Definition dag.h:32
@ MINIMAL
Allocate on-demand, free at last consumer. Lowest peak memory.
SpecializationInfo FusionInfo
Definition compressor.h:87
SpecializationPolicy FusionPolicy
Definition compressor.h:67
Pipeline and per-stage profiling result types.
Base class interface for all compression stages.
Backward-compatible shim.
Definition device_buffer.h:35
Definition device_buffer.h:24
Fixed-size FZM file header core (80 bytes).
Definition fzm_format.h:275
Definition perf.h:78
Definition compressor.h:634
One finalize-time specialization selected for execution (compress or inverse).
Definition compressor.h:70
std::vector< std::string > stages
the stages it replaced
Definition compressor.h:72
std::string execution_path
last runtime subpath; empty if not applicable
Definition compressor.h:73
std::string implementation
strategy impl name, e.g. "warp-register"
Definition compressor.h:71
Resolved specialization decision for diagnostics and benchmark provenance.
Definition compressor.h:78
std::string fallback_reason
policy_off, no_legal_group, or legacy no_profitable_implementation; empty on a hit.
Definition compressor.h:85
std::vector< SpecializationGroupInfo > installed_inverse_groups
Lazily populated after the first decompress builds its inverse DAG.
Definition compressor.h:83
Backend-neutral GPU type aliases.