docc 0.8.3 (0d44999b)
C++ API Reference
Loading...
Searching...
No Matches
gpu_offload_reduce_dispatcher.h
Go to the documentation of this file.
1#pragma once
2
3#include <map>
4
13#include "sdfg/types/type.h"
14
15
16namespace sdfg {
17namespace gpu {
18
20protected:
22
23 std::map<std::string, tiles::ReductionBufferInfo> reduction_buffers_;
24
26 codegen::NestedCodeSnippetFactory& kernel_snippet_factory,
27 codegen::PrettyPrinter& kernel_source_stream,
28 codegen::PrettyPrinter& kernel_header_stream,
29 codegen::LanguageExtension& kernel_lang_ext,
30 symbolic::Symbol indvar,
31 std::vector<std::string>& scope_variables,
32 symbolic::Expression& num_iterations
33 ) override;
34
35 void validate_before_dispatch(analysis::AnalysisManager& analysis_manager) override;
36
37 // Whether a WARP-level reduction nested below this node reduces @p container,
38 // in which case this (block) level combines per-warp partials instead of per-thread.
39 bool has_nested_warp_reduction(const std::string& container);
40
41 // Whether a BLOCK-level reduction nested below this node reduces @p container. When a
42 // grid reduce owns such a nested block reduce of the same container, its register is
43 // populated only by the block's axis leaders (via the block combine), so every other
44 // thread holds the operator identity and the grid commit must stay unguarded.
45 bool has_nested_block_reduction(const std::string& container);
46
47 // Whether a BLOCK-level reduction enclosing this node reduces @p container. A WARP
48 // reduce relies on such an enclosing block reduce to own the shared buffer its
49 // per-warp partials are published into; without one, the warp must flush directly
50 // to the global accumulator instead.
51 bool has_enclosing_block_reduction(const std::string& container);
52
53 // Whether a GRID-level reduction enclosing this node reduces @p container. When a
54 // block reduce is nested under such a grid reduce, its per-block result is folded
55 // into the grid's register accumulator, which persists across the grid coverage
56 // loop; the block level must therefore combine (accumulate) into that target rather
57 // than overwrite it, so partials from every coverage-loop iteration are retained.
58 bool has_enclosing_grid_reduction(const std::string& container);
59
60 // Whether this block reduce's per-block result written to @p index collides across the
61 // grid: true when an enclosing grid-level offloaded loop's induction variable does not
62 // appear in the accumulator index, so multiple grid blocks / coverage-loop iterations
63 // target the same global slot and must combine atomically rather than overwrite.
65
66 // Predicate (as a C expression) selecting the single thread that commits the folded
67 // result of @p container to global memory: the leader across every reduced block axis,
68 // i.e. this level's axis index and every nested block-reduce level's axis index are 0.
69 // Any remaining (mapped) block dimensions stay free so each of their slots is written.
70 std::string block_reduce_leader_condition(codegen::LanguageExtension& language_extension, const std::string& container);
71
72 // Linearized flat thread index within the block: threadIdx.x + threadIdx.y * blockDim.x
73 // + threadIdx.z * blockDim.x * blockDim.y. Used to address per-thread shared slots so
74 // that every thread of a multi-dimensional block owns a distinct accumulator entry.
76
77 // Element stride, in the flat shared layout, between consecutive threads along the
78 // reduce node's own axis: 1 for x, blockDim.x for y, blockDim.x * blockDim.y for z.
79 std::string reduce_axis_stride(codegen::LanguageExtension& language_extension, TargetLevel target_level);
80
81 // Static size of a single block dimension, taken from the corresponding block level's
82 // schedule parallel_size in the enclosing/nested loop nest (1 if that level is absent).
83 // The launched blockDim equals these constants, so using them instead of the dynamic
84 // blockDim.x/y/z keeps the flat thread-index layout a compile-time constant expression
85 // that matches the statically sized shared buffer.
87
88 // Compile-time product of all block-level parallel sizes enclosing/within this node
89 // (x * y * z). Sizes the per-thread shared buffer for a multi-dimensional block.
91
92 // Name of the shared partials buffer for @p container: the schedule's
93 // partial_container property when set, else the invented __daisy_reduce_smem_<c>.
94 std::string partials_buffer_name(const std::string& container);
95
96 // Whether @p container is a scalar accumulator addressed by name (no subscript), e.g.
97 // an in-place pooling handler. Such an accumulator is a single-slot, per-thread private
98 // reduction target: it is aliased (a C++ reference) onto this level's partial in the
99 // body and, after the block/warp combine, broadcast back to every thread's private
100 // scalar, rather than being addressed as a pointer container[index].
101 bool is_scalar_accumulator(const std::string& container);
102
103 // Flat shared-buffer slot with the reduced block axes (this level plus nested block
104 // reduces of @p container) zeroed, so every thread sharing a mapped slot reads the same
105 // combined value when a scalar accumulator's block result is broadcast after the tree.
106 std::string reduce_base_slot(codegen::LanguageExtension& language_extension, const std::string& container);
107
109 codegen::LanguageExtension& language_extension,
111 codegen::CodeSnippetFactory& library_snippet_factory,
112 TargetLevel target_level
113 );
114
115 std::string reduction_target(
116 codegen::LanguageExtension& language_extension, const std::string& container, symbolic::Expression index
117 );
118
120 codegen::LanguageExtension& language_extension,
122 codegen::CodeSnippetFactory& library_snippet_factory,
123 TargetLevel target_level
124 );
125
126 // Whether the body of a block-level shared reduction for @p container accumulates into
127 // a per-thread register partial (published to shared once after the coverage loop)
128 // instead of read-modify-writing shared each iteration. Applies only to a standalone
129 // block level that solely owns the body (no enclosing block reduce, no nested block
130 // reduce, no nested warp reduce). This keeps the hot accumulation in a register so the
131 // FMA chain is not serialized through shared memory; the existing shared tree/shuffle
132 // combine is unchanged.
133 bool uses_register_partial(TargetLevel target_level, const std::string& container);
134
135 // Lane-group width for combining a register partial with warp shuffles before the
136 // cross-warp step (X_BLOCK reduce, constant block width divisible by the power-of-two
137 // group), or 0 to fall back to the shared halving tree.
138 int64_t warp_combine_width(TargetLevel target_level, const std::string& container);
139
140 // Lane-group width of the X_BLOCK warp-shuffle combine for this node (0 if unavailable),
141 // independent of any particular accumulator.
142 int64_t lane_group_width(TargetLevel target_level);
143
144 // Whether @p container is the anchor or a dependent of a rescaled (max-anchored) group.
145 bool in_rescale_group(const std::string& container);
146
147 // Combine a rescale group (a Max anchor and the Adds rescaled by base^anchor) as a unit:
148 // shuffle within lane groups, fold the groups of a row through shared, then commit.
150 codegen::LanguageExtension& language_extension,
153 TargetLevel target_level
154 );
155
156 // Publish each register partial to its shared slot once, after the coverage loop and
157 // before the combine (a single st.shared per thread instead of one per element).
159 codegen::LanguageExtension& language_extension, codegen::PrettyPrinter& stream, TargetLevel target_level
160 );
161
162public:
164 codegen::LanguageExtension& language_extension,
166 analysis::AnalysisManager& analysis_manager,
168 codegen::InstrumentationPlan& instrumentation_plan,
169 codegen::ArgCapturePlan& arg_capture_plan,
170 std::unique_ptr<GPUOffloadDispatcherStrategy> strategy
171 );
172};
173
174} // namespace gpu
175} // namespace sdfg
Definition structured_sdfg.h:30
Definition analysis.h:53
Definition arg_capture_plan.h:36
Originally started out as a handler for additional source files, like hardware-accelerator kernels th...
Definition code_snippet_factory.h:69
Definition instrumentation_plan.h:26
Definition language_extension.h:39
Used when we need to dispatch main SDFG elements into a subset of files (like offloaded kernels).
Definition code_snippet_factory.h:150
Definition utils.h:16
GPUOffloadBaseDispatcher(codegen::LanguageExtension &language_extension, StructuredSDFG &sdfg, analysis::AnalysisManager &analysis_manager, structured_control_flow::StructuredLoop &node, codegen::InstrumentationPlan &instrumentation_plan, codegen::ArgCapturePlan &arg_capture_plan, std::unique_ptr< GPUOffloadDispatcherStrategy > strategy)
std::string reduce_base_slot(codegen::LanguageExtension &language_extension, const std::string &container)
void dispatch_rescale_group_combine(codegen::LanguageExtension &language_extension, codegen::PrettyPrinter &stream, const structured_control_flow::ReductionInfo &anchor, TargetLevel target_level)
int64_t lane_group_width(TargetLevel target_level)
structured_control_flow::Reduce & node_
Definition gpu_offload_reduce_dispatcher.h:21
std::map< std::string, tiles::ReductionBufferInfo > reduction_buffers_
Definition gpu_offload_reduce_dispatcher.h:23
std::string reduction_target(codegen::LanguageExtension &language_extension, const std::string &container, symbolic::Expression index)
void dispatch_reduction_publish(codegen::LanguageExtension &language_extension, codegen::PrettyPrinter &stream, TargetLevel target_level)
bool has_enclosing_grid_reduction(const std::string &container)
std::string partials_buffer_name(const std::string &container)
std::string block_reduce_leader_condition(codegen::LanguageExtension &language_extension, const std::string &container)
bool uses_register_partial(TargetLevel target_level, const std::string &container)
symbolic::Expression reduce_block_dim(TargetLevel block_level)
bool is_scalar_accumulator(const std::string &container)
std::string reduce_linear_thread_index(codegen::LanguageExtension &language_extension)
bool in_rescale_group(const std::string &container)
void dispatch_kernel_body(codegen::NestedCodeSnippetFactory &kernel_snippet_factory, codegen::PrettyPrinter &kernel_source_stream, codegen::PrettyPrinter &kernel_header_stream, codegen::LanguageExtension &kernel_lang_ext, symbolic::Symbol indvar, std::vector< std::string > &scope_variables, symbolic::Expression &num_iterations) override
bool has_nested_block_reduction(const std::string &container)
bool has_enclosing_block_reduction(const std::string &container)
void dispatch_reduction_declarations(codegen::LanguageExtension &language_extension, codegen::PrettyPrinter &stream, codegen::CodeSnippetFactory &library_snippet_factory, TargetLevel target_level)
int64_t warp_combine_width(TargetLevel target_level, const std::string &container)
bool has_nested_warp_reduction(const std::string &container)
std::string reduce_axis_stride(codegen::LanguageExtension &language_extension, TargetLevel target_level)
GPUOffloadReduceDispatcher(codegen::LanguageExtension &language_extension, StructuredSDFG &sdfg, analysis::AnalysisManager &analysis_manager, structured_control_flow::Reduce &node, codegen::InstrumentationPlan &instrumentation_plan, codegen::ArgCapturePlan &arg_capture_plan, std::unique_ptr< GPUOffloadDispatcherStrategy > strategy)
symbolic::Expression reduce_block_size_product()
bool block_result_collides_across_grid(const symbolic::Expression &index)
void dispatch_reduction_combine(codegen::LanguageExtension &language_extension, codegen::PrettyPrinter &stream, codegen::CodeSnippetFactory &library_snippet_factory, TargetLevel target_level)
void validate_before_dispatch(analysis::AnalysisManager &analysis_manager) override
Node-specific preconditions checked before any code is emitted (default: none).
Represents a loop with an associative/commutative reduction carried dependency.
Definition reduce.h:106
SymEngine::RCP< const SymEngine::Basic > Expression
Reference-counted pointer to a symbolic expression (SymEngine Basic).
Definition symbolic.h:83
SymEngine::RCP< const SymEngine::Symbol > Symbol
Reference-counted pointer to a SymEngine Symbol.
Definition symbolic.h:71
Definition cuda_arch.h:11
TargetLevel
Definition gpu_offload_schedule_type.h:13
Definition analysis.h:7
Dispatcher base class for code generation from control flow nodes.
A single reduction carried by a Reduce loop.
Definition reduce.h:73
Symbolic system for integer-based symbol analysis.
Core type system definitions for sdfglib.