82template<
typename Holder>
85template<HolderPolicy Holder = SingleExpanderHolder>
88template<HolderPolicy Holder = SingleExpanderHolder>
97 bool expanded_any_ =
false;
103 auto expander = holder_.get_expander_for(node);
107 ctx(this->builder_, parent, child_idx, block, node, analysis_manager_.options());
109 auto outcome = expander->handle_expand(ctx, block, node);
133 holder_(holder), force_expand_(force_expand) {
137 bool may_contain_libnodes =
true;
145 size_t total_children = seq.
size();
146 if (total_children == 0) {
147 may_contain_libnodes =
false;
148 }
else if (i >= total_children) {
152 for (; i < total_children; ++i) {
153 auto& child = seq.
at(i);
157 if (outcome.block_removed) {
158 if (outcome.skip_count) {
159 i += outcome.skip_count;
162 }
else if (outcome.skip_count) {
163 i += outcome.skip_count;
170 }
while (may_contain_libnodes);
178 if constexpr (
requires { holder_.scope_enter(schedType); }) {
179 scope_id = holder_.scope_enter(schedType);
182 auto res = ActualStructuredSDFGVisitor::handleStructuredLoop(loop);
184 if constexpr (
requires { holder_.scope_exit(schedType); }) {
185 holder_.scope_exit(scope_id);
198 bool may_contain_lib_nodes =
true;
199 bool handled_any =
false;
201 const bool force_expand = force_expand_;
209 auto libnodes = dataflow.nodes() | std::views::transform([](
auto& n) {
212 std::views::filter([](
auto* n) {
215 std::views::filter([last_element_id, force_expand](
auto* n) {
216 return (force_expand ||
218 n->element_id() > last_element_id;
220 std::vector<const data_flow::LibraryNode*> sorted_nodes(libnodes.begin(), libnodes.end());
221 std::ranges::sort(sorted_nodes, std::less<>{}, [](
const auto* n) {
222 return n->element_id();
225 may_contain_lib_nodes = !libnodes.empty();
227 bool block_changed =
false;
228 for (
auto* library_node : sorted_nodes) {
229 last_element_id = library_node->element_id();
231 handled_any |= outcome.expanded;
233 if (outcome.block_removed) {
234 this->expanded_any_ =
true;
236 }
else if (outcome.expanded) {
238 block_changed =
true;
246 }
while (may_contain_lib_nodes);
249 this->expanded_any_ =
true;
260template<HolderPolicy Holder>
262 Holder::StorageType holder_options_;
265 static constexpr std::string_view
NAME{
"library_node_expansion"};
275 :
Pass(
options), holder_options_(std::move(holder)) {
279 return std::string(
NAME);
284 FORCE_EXPAND.spec(
false,
"Also lower all library nodes that already have an implementation type"),
287 "Expand softmax as the single-pass online (log-sum-exp monoid) form instead of the default "
288 "three-pass (max; exp+sum; normalize) form"
295 v(
builder, analysis_manager, Holder(holder_options_), this->
option(FORCE_EXPAND));
299 return v.expanded_any_;
static const Options & empty()
Definition options.h:84
Note: Even though the class references unique_ptr, it will never delete an SDFG it has a reference to...
Definition structured_sdfg_builder.h:44
Base class for all library nodes in the dataflow graph.
Definition library_node.h:106
Base class for mathematical library nodes with expansion support.
Definition math_node.h:68
Definition lib_node_expander.h:122
Definition lib_node_expander.h:8
Definition library_node_expansion_pass.h:89
expansion::BlockOutcome handle_block(structured_control_flow::Sequence &parent, size_t child_idx, sdfg::structured_control_flow::Block &block)
Definition library_node_expansion_pass.h:191
bool handleStructuredLoop(sdfg::structured_control_flow::StructuredLoop &loop) override
Definition library_node_expansion_pass.h:175
bool visit(sdfg::structured_control_flow::Sequence &seq) override
Definition library_node_expansion_pass.h:136
LibNodeExpansionVisitor(builder::StructuredSDFGBuilder &builder, analysis::AnalysisManager &analysis_manager, Holder holder, bool force_expand)
Construct the expansion visitor.
Definition library_node_expansion_pass.h:126
Looks for and expands library nodes in a single pass, potentially recursively.
Definition library_node_expansion_pass.h:261
std::string name() override
Definition library_node_expansion_pass.h:278
std::vector< OptionSpec > options() override
Definition library_node_expansion_pass.h:282
static constexpr OptionKey< bool > FORCE_EXPAND
Definition library_node_expansion_pass.h:266
LibraryNodeExpansionPass(const Options &options)
Definition library_node_expansion_pass.h:271
LibraryNodeExpansionPass(Holder::StorageType holder, const Options &options=Options::empty())
Definition library_node_expansion_pass.h:274
bool run_pass(builder::StructuredSDFGBuilder &builder, analysis::AnalysisManager &analysis_manager) override
Definition library_node_expansion_pass.h:293
static constexpr std::string_view NAME
Definition library_node_expansion_pass.h:265
LibraryNodeExpansionPass()
Definition library_node_expansion_pass.h:269
static constexpr OptionKey< bool > ONLINE_SOFTMAX
Definition library_node_expansion_pass.h:267
Definition library_node_expansion_pass.h:44
LibNodeExpander::ExpandOutcome handle_expand(ExpandContext &context, Block &block, math::MathNode &node) const override
T option(const OptionKey< T > &key, T fallback=T{}) const
Definition pass.h:41
Definition lib_node_expander.h:168
Definition lib_node_expansion_context.h:9
bool expanded() const
Definition lib_node_expansion_context.h:45
bool dropped_block() const
Definition lib_node_expansion_context.h:49
A control flow node representing a basic block with dataflow computations.
Definition block.h:42
const data_flow::DataFlowGraph & dataflow() const
Access the dataflow graph (const version).
A sequential container of control flow nodes.
Definition sequence.h:52
const ControlFlowNode & at(size_t i) const
Access a child by index (const version).
size_t size() const
Get the number of children in this sequence.
Base class for structured loop constructs.
Definition structured_loop.h:244
const ScheduleType & schedule_type() const
Get the scheduling strategy for this Map.
Visitor for Structured SDFG (not a builder).
Definition structured_sdfg_visitor.h:71
ActualStructuredSDFGVisitor()
bool dispatch(sdfg::structured_control_flow::ControlFlowNode &node)
Definition structured_sdfg_visitor.h:79
Definition library_node_expansion_pass.h:83
Mathematical library node base class with expansion support.
Definition function_builder.h:10
ImplementationType ImplementationType_NONE
Default implementation type indicating no specific implementation.
Definition library_node.h:84
Definition lib_node_expansion_context.h:5
expansion::NodeOutcome expand_single_node(builder::StructuredSDFGBuilder &builder, Block &block, data_flow::LibraryNode &node, const LibNodeExpander &expanders)
expansion::NodeOutcome expand_single_math_node(builder::StructuredSDFGBuilder &builder, Block &block, data_flow::LibraryNode &node)
Definition approximate_math.h:12
LibraryNodeExpansionPass(T) -> LibraryNodeExpansionPass< T >
Definition control_flow_node.h:16
element_cast_target_t< T > * dyn_cast(Element *element)
Efficient down-cast to T, or nullptr if element is not a T.
Definition element.h:246
size_t ElementId
Definition element.h:215
Definition lib_node_expander.h:12
SingleExpanderHolder(StorageType expander)
Definition library_node_expansion_pass.h:74
std::shared_ptr< LibNodeExpander > StorageType
Definition library_node_expansion_pass.h:69
const LibNodeExpander & expander_
Definition library_node_expansion_pass.h:70
SingleExpanderHolder(const LibNodeExpander &expander)
Definition library_node_expansion_pass.h:72
const LibNodeExpander * get_expander_for(const data_flow::LibraryNode &node) const
Definition library_node_expansion_pass.h:77
Definition library_node_expansion_pass.h:50
bool block_removed
Definition library_node_expansion_pass.h:51
int skip_count
Definition library_node_expansion_pass.h:52
BlockOutcome(bool block_removed=false, int skip_count=0)
Definition library_node_expansion_pass.h:54
Definition library_node_expansion_pass.h:59
NodeOutcome(bool expanded=false, bool block_removed=false, int skip_count=0)
Definition library_node_expansion_pass.h:62
bool expanded
Definition library_node_expansion_pass.h:60