-
Notifications
You must be signed in to change notification settings - Fork 129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conditional Blocks #1666
Conditional Blocks #1666
Conversation
…e end state if not used in inline
…ks when encountering breaks and contiunes
…y ConditionalRegions
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See minor comments
dace/frontend/python/newast.py
Outdated
for node, parent in loop_region.all_nodes_recursive(lambda n, _: not isinstance(n, (LoopRegion, SDFGState))): | ||
if isinstance(node, BreakBlock): | ||
for in_edge in parent.in_edges(node): | ||
in_edge.data.assignments["did_break_" + loop_region.label] = "1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should add a __dace_
prefix to avoid name clashes. This is also true in the _generate_orelse code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, agree - done.
dead_blocks = [succ for succ in parent.successors(self) if parent.in_degree(succ) == 1] | ||
while dead_blocks: | ||
layer = list(dead_blocks) | ||
dead_blocks.clear() | ||
for u in layer: | ||
dead_blocks.extend([succ for succ in parent.successors(u) if parent.in_degree(succ) == 1]) | ||
parent.remove_node(u) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not be part of a transformation / pass like dead state elimination? I am ok with this here now but I still would want a TODO note or TODO(later)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point - I am placing a TODO and will adjust this in the PR that adapts the passes to these changes.
This is a continuation of #1617 (superseded and closed by this PR), with a lot of the work being done by @luca-patrignani.
Conditional Blocks
This PR implements Conditional Blocks, which are a native way of semantically expressing conditional branching in an SDFG. This replaces the traditional "state machine only" way of expressing conditional branching, with two main goals:
goto
statements for each state transition. However, just as in the above issue, this process is error prone and often leads to invalid code being generated for complex control flow constructs (e.g., conditionals inside of loops with conditional break, continue, return, etc.). By exposing all regular control flow (i.e., loops and conditional branching) with native SDFG constructs, this step can be skipped in code generation.Anatomy of Conditional Blocks
ConditionalBlock
s are a type ofControlFlowBlock
which contains a series of branches. Each branch is represented by a fullControlFlowRegion
and has a condition in the form of aCodeBlock
attached to it. When aConditionalBlock
is executed, the conditions are checked in the insertion order of the branches, and if a matching condition was found, that branch (and only that branch) is executed. When the executed branch finishes executing, theConditionalBlock
's successor is next. If no condition matches, no branch is executed.The condition for a single branch at a time may be
None
, which represents a wildcard orelse
case that is executed if no conditions match.Code Generation Changes
Code generation (when using this feature) is drastically simplified with respect to control flow: no more control flow detection is performed. Instead, regular control flow constructs are only generated from the new native SDFG constructs (
LoopRegion
s andConditionalBlock
s), and any other state transition is either only used for sequential ordering (unconditional transitions to a single, direct successor), or leads to agoto
. This makes code generation significantly less error prone and simpler to work with.Compatibility
This feature is implemented minimally invasive and with full backwards compatibility for now.
Just as with
LoopRegion
s, this feature is only used if an explicituse_experimental_cfg_blocks
flag is set toTrue
in compatible frontends (currently only Python frontend, Fortran frontend integration is coming soon).If an SDFG makes use of these experimental blocks, some passes and transformations will no longer be applied automatically in pipelines. Transformations that handle these blocks correctly can be explicitly marked with
@transformation.experimental_cfg_block_compatible
to apply them on SDFGs with experimental blocks.Inlining
Conditional blocks can be inlined through a utility function to traditional SDFG state machines. This is automatically done by compatible frontends if the experimental CFG blocks feature is turned off.
Visualization Components
The visualization components are being worked on separately in spcl/dace-webclient#173. This PR does not depend on the visualization components to be merged.