FZGPUModules 2.0
GPU-accelerated modular compression pipelines
Loading...
Searching...
No Matches
dag.h
Go to the documentation of this file.
1
5#pragma once
6
7/*
8 * ADVANCED API — no source-compatibility promise. The types here (CompressionDAG,
9 * DAGNode, BufferInfo, the fusion planner/registry) are pipeline internals exposed
10 * for advanced/experimental use; they may change or be removed in any release.
11 * Most users only need <fzgpumodules.h> / pipeline/compressor.h. See the API tiers
12 * in docs/api_reference.md.
13 */
14
15#include "pipeline/perf.h"
16
17#include "backend/types.h"
18#include <memory>
19#include <string>
20#include <unordered_map>
21#include <unordered_set>
22#include <vector>
23
24namespace fz {
25
26// Forward declarations
27class Stage;
28class MemoryPool;
29struct FusedImpl;
30
32enum class MemoryStrategy {
33 MINIMAL,
35};
36
38struct BufferInfo {
39 size_t size;
40 size_t initial_size;
41 size_t allocated_size;
42 void* d_ptr;
43 std::string tag;
44
45 int remaining_consumers;
46 std::vector<int> consumer_stage_ids;
47 int producer_stage_id;
48 int producer_output_index;
49
50 bool is_allocated;
53
55 : size(0), initial_size(0), allocated_size(0), d_ptr(nullptr), tag(""),
56 remaining_consumers(0), producer_stage_id(-1), producer_output_index(0),
57 is_allocated(false), is_persistent(false), is_external(false) {}
58};
59
61struct DAGNode {
62 int id;
63 Stage* stage;
64 std::string name;
65
66 std::vector<int> input_buffer_ids;
67 std::vector<int> output_buffer_ids;
68 std::unordered_map<int, int> output_index_to_buffer_id;
69
70 std::vector<DAGNode*> dependencies;
71 std::vector<DAGNode*> dependents;
72
73 int level;
74 int execution_order;
75 fz::stream_t stream;
76
77 bool is_executed;
78 fz::event_t completion_event;
79 fz::event_t start_event;
80
81 // Pre-sized vectors for execute() — allocated at finalize(), reused every call
82 // to avoid per-call heap allocations of the input/output/sizes arrays.
83 std::vector<void*> exec_inputs;
84 std::vector<void*> exec_outputs;
85 std::vector<size_t> exec_sizes;
86
87 DAGNode(Stage* s = nullptr)
88 : id(-1), stage(s), level(-1), execution_order(-1),
89 stream(nullptr), is_executed(false), completion_event(nullptr), start_event(nullptr) {}
90};
91
102public:
105
106 // ── Construction ──────────────────────────────────────────────────────────
107
109 DAGNode* addStage(Stage* stage, std::string name = "");
110
119 int addDependency(DAGNode* dependent, DAGNode* dependency,
120 size_t buffer_size = 0, int output_index = 0);
121
122 void setInputBuffer(DAGNode* node, size_t size, const std::string& tag = "input");
123 void setOutputBuffer(DAGNode* node, size_t size, const std::string& tag = "output");
124
129 int addUnconnectedOutput(DAGNode* node, size_t size, int output_index, const std::string& tag);
130
135 bool connectExistingOutput(DAGNode* producer, DAGNode* consumer, int output_index);
136
137 void updateBufferTag(int buffer_id, const std::string& tag);
138 void setBufferPersistent(int buffer_id, bool persistent);
139
141 void finalize();
142
144 void configureStreams(int num_streams);
145
146 // ── Execution ─────────────────────────────────────────────────────────────
147
148 void execute(fz::stream_t stream);
149
154 void preallocateBuffers(fz::stream_t stream = 0);
155
157 void reset(fz::stream_t stream = 0);
158
159 // ── Buffer access ─────────────────────────────────────────────────────────
160
161 void* getBuffer(int buffer_id) const;
162
167 void setExternalPointer(int buffer_id, void* external_ptr);
168
169 void updateBufferSize(int buffer_id, size_t new_size);
170
171 // ── Query & debug ─────────────────────────────────────────────────────────
172
174 size_t getTotalBufferSize() const;
175
184 size_t computeTopoPoolSize() const;
185
186 size_t getPeakMemoryUsage() const { return peak_memory_usage_; }
187 size_t getCurrentMemoryUsage() const { return current_memory_usage_; }
188 size_t getBufferSize(int buffer_id) const;
189 const BufferInfo& getBufferInfo(int buffer_id) const;
190 const std::vector<std::vector<DAGNode*>>& getLevels() const { return levels_; }
191 const std::vector<DAGNode*>& getNodes() const { return nodes_; }
192
194 int getMaxParallelism() const;
195
197 size_t getStreamCount() const { return streams_.size(); }
198
205 DAGNode* head = nullptr;
206 DAGNode* tail = nullptr;
207 std::vector<DAGNode*> members;
208 std::vector<Stage*> stages;
209 const FusedImpl* impl = nullptr;
210 };
211
213 void setFusedGroups(std::vector<FusedGroupExec> groups);
214 size_t getFusedGroupCount() const { return fused_groups_.size(); }
215
216 void printDAG() const;
217 void printBufferLifetimes() const;
218
224 void enableBoundsCheck(bool enable) { bounds_check_enabled_ = enable; }
225 bool isBoundsCheckEnabled() const { return bounds_check_enabled_; }
226
232 void setColoringEnabled(bool enable) { coloring_disabled_ = !enable; }
233 bool isColoringEnabled() const { return coloring_applied_; }
234 size_t getColorRegionCount() const { return color_region_sizes_.size(); }
235
243 void setCaptureMode(bool capture);
244 bool isCaptureMode() const { return capture_mode_; }
245
246 // ── Profiling ─────────────────────────────────────────────────────────────
247
252 void enableProfiling(bool enable);
253 bool isProfilingEnabled() const { return profiling_enabled_; }
254
256 std::vector<StageTimingResult> collectTimings();
257
258private:
259 MemoryPool* mem_pool_;
260 MemoryStrategy strategy_;
261
262 std::vector<DAGNode*> nodes_;
263 std::unordered_map<int, BufferInfo> buffers_;
264
265 int next_buffer_id_;
266 bool is_finalized_;
267
268 std::vector<fz::stream_t> streams_;
269 bool owns_streams_;
270
271 std::vector<std::vector<DAGNode*>> levels_;
272 int max_level_;
273
274 size_t current_memory_usage_;
275 size_t peak_memory_usage_;
276
277 bool profiling_enabled_;
278 bool bounds_check_enabled_;
279 bool capture_mode_;
280
281 // Buffer coloring (PREALLOCATE only). Non-overlapping buffers share a color
282 // and are aliased into one pool region. color_region_ptrs_ owns the allocations.
283 bool coloring_disabled_;
284 bool coloring_applied_;
285 std::unordered_map<int, int> buffer_color_;
286 std::vector<size_t> color_region_sizes_;
287 std::vector<void*> color_region_ptrs_;
288
289 // Fusion: groups whose staged execute()s are replaced by one fused runner.
290 std::vector<FusedGroupExec> fused_groups_;
291 std::unordered_map<DAGNode*, size_t> fused_head_;
292 std::unordered_set<DAGNode*> fused_member_;
293
294 void assignLevels();
295 void assignStreams();
296 void allocateBuffer(int buffer_id, fz::stream_t stream);
297 void freeBuffer(int buffer_id, fz::stream_t stream);
298 void planPreallocation();
299 void colorBuffers();
300};
301
302} // namespace fz
Definition dag.h:101
DAGNode * addStage(Stage *stage, std::string name="")
void setCaptureMode(bool capture)
int addDependency(DAGNode *dependent, DAGNode *dependency, size_t buffer_size=0, int output_index=0)
void setColoringEnabled(bool enable)
Definition dag.h:232
size_t computeTopoPoolSize() const
size_t getTotalBufferSize() const
void preallocateBuffers(fz::stream_t stream=0)
int addUnconnectedOutput(DAGNode *node, size_t size, int output_index, const std::string &tag)
void setExternalPointer(int buffer_id, void *external_ptr)
size_t getStreamCount() const
Definition dag.h:197
void enableBoundsCheck(bool enable)
Definition dag.h:224
void setFusedGroups(std::vector< FusedGroupExec > groups)
void enableProfiling(bool enable)
void reset(fz::stream_t stream=0)
std::vector< StageTimingResult > collectTimings()
void configureStreams(int num_streams)
int getMaxParallelism() const
bool connectExistingOutput(DAGNode *producer, DAGNode *consumer, int output_index)
Definition mempool.h:82
Definition stage.h:31
Definition dag.h:24
MemoryStrategy
Definition dag.h:32
@ MINIMAL
Allocate on-demand, free at last consumer. Lowest peak memory.
@ PREALLOCATE
Allocate everything upfront at finalize(). Required for graph mode.
Pipeline and per-stage profiling result types.
Definition dag.h:38
bool is_external
If true, pointer is caller-owned — DAG never allocs or frees.
Definition dag.h:52
bool is_persistent
If true, survives reset() until DAG destruction.
Definition dag.h:51
std::vector< DAGNode * > members
all group nodes (skipped individually)
Definition dag.h:207
DAGNode * head
first node (fused kernel runs here)
Definition dag.h:205
const FusedImpl * impl
matched fused implementation
Definition dag.h:209
std::vector< Stage * > stages
group stages for the runner context
Definition dag.h:208
DAGNode * tail
last node; its output = the archive
Definition dag.h:206
Definition dag.h:61
fz::event_t start_event
Non-null only when profiling is enabled.
Definition dag.h:79
A registered fused implementation and its matcher.
Definition fusion_registry.h:67
Backend-neutral GPU type aliases.