Skip to content
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

Enhance rendering SCFGs #144

Merged
merged 1 commit into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 43 additions & 49 deletions numba_rvsdg/rendering/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
from graphviz import Digraph


node_style_kwargs = {"shape": "rect", "style": "rounded"}


class BaseRenderer:
"""Base Renderer class.
Expand Down Expand Up @@ -252,89 +255,80 @@ def render_region_block(
color = "purple"
if regionblock.kind == "head":
color = "red"
label = (
regionblock.name
+ "\njump targets: "
+ str(regionblock.jump_targets)
+ "\nback edges: "
+ str(regionblock.backedges)
)

subg.attr(color=color, label=label)
label = [regionblock.name, r"\n"]
if regionblock.jump_targets:
label.append(
f"\njump targets: {str(regionblock.jump_targets)}"
)
if regionblock.backedges:
label.append(f"\nback edges: {str(regionblock.backedges)}")

subg.attr(color=color, label="".join(label), **node_style_kwargs)
assert regionblock.subregion is not None
for name, block in regionblock.subregion.graph.items():
self.render_block(subg, name, block)

def render_basic_block(
self, digraph: "Digraph", name: str, block: BasicBlock
) -> None:
body = (
name
+ r"\l"
+ "\njump targets: "
+ str(block.jump_targets)
+ "\nback edges: "
+ str(block.backedges)
)
label = [name, r"\n"]
if block.jump_targets:
label.append(f"\njump targets: {str(block.jump_targets)}")
if block.backedges:
label.append(f"\nback edges: {str(block.backedges)}")

digraph.node(str(name), shape="rect", label=body)
digraph.node(str(name), label="".join(label), **node_style_kwargs)

def render_python_ast_block(
self, digraph: "Digraph", name: str, block: BasicBlock
) -> None:
code = r"\l".join(
ast.unparse(n) for n in block.get_tree() # type: ignore
)
body = (
name
+ "\n\n"
+ code
+ r"\l\ljump targets: "
+ str(block.jump_targets)
+ r"\lback edges: "
+ str(block.backedges)
)
label = [name, r"\n\l", code, r"\l"]
if block.jump_targets:
label.append(f"\njump targets: {str(block.jump_targets)}")
if block.backedges:
label.append(f"\nback edges: {str(block.backedges)}")

digraph.node(str(name), shape="rect", label=body)
digraph.node(str(name), label="".join(label), **node_style_kwargs)

def render_control_variable_block(
self, digraph: "Digraph", name: str, block: SyntheticAssignment
) -> None:
if isinstance(name, str):
body = name + r"\l"
body += r"\l".join(
(f"{k} = {v}" for k, v in block.variable_assignment.items())
)
body += (
"\njump targets: "
+ str(block.jump_targets)
+ "\nback edges: "
+ str(block.backedges)
assignments = r"\l".join(
(
f"{k} = {v}"
for k, v in sorted(block.variable_assignment.items())
)
)
label = [name, r"\n\l", assignments, r"\l"]
if block.jump_targets:
label.append(f"\njump targets: {str(block.jump_targets)}")
if block.backedges:
label.append(f"\nback edges: {str(block.backedges)}")

else:
raise Exception("Unknown name type: " + name)
digraph.node(str(name), shape="rect", label=body)
digraph.node(str(name), label="".join(label), **node_style_kwargs)

def render_branching_block(
self, digraph: "Digraph", name: str, block: SyntheticBranch
) -> None:
if isinstance(name, str):
body = name + r"\l"
body += rf"variable: {block.variable}\l"
body += r"\l".join(
(f"{k}=>{v}" for k, v in block.branch_value_table.items())
)
body += (
"\njump targets: "
+ str(block.jump_targets)
+ "\nback edges: "
+ str(block.backedges)
branches = rf"variable: {block.variable}\l" + r"\l".join(
(f"{k}{v}" for k, v in block.branch_value_table.items())
)
label = [name, r"\n\l", branches, r"\l"]
if block.jump_targets:
label.append(f"\njump targets: {str(block.jump_targets)}")
if block.backedges:
label.append(f"\nback edges: {str(block.backedges)}")

else:
raise Exception("Unknown name type: " + name)
digraph.node(str(name), shape="rect", label=body)
digraph.node(str(name), label="".join(label), **node_style_kwargs)

def render_scfg(self) -> "Digraph":
"""Return the graphviz Digraph that contains the rendered SCFG."""
Expand Down
161 changes: 63 additions & 98 deletions numba_rvsdg/tests/test_rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@
from numba_rvsdg.rendering.rendering import SCFGRenderer

expected_original = r"""digraph {
0 [label="0\l
jump targets: ('1', '2')
back edges: ()" shape=rect]
1 [label="1\l
jump targets: ('3',)
back edges: ()" shape=rect]
2 [label="2\l
jump targets: ('4',)
back edges: ()" shape=rect]
3 [label="3\l
jump targets: ('2', '5')
back edges: ()" shape=rect]
4 [label="4\l
jump targets: ('1',)
back edges: ()" shape=rect]
5 [label="5\l
jump targets: ()
back edges: ()" shape=rect]
0 [label="0\n
jump targets: ('1', '2')" shape=rect style=rounded]
1 [label="1\n
jump targets: ('3',)" shape=rect style=rounded]
2 [label="2\n
jump targets: ('4',)" shape=rect style=rounded]
3 [label="3\n
jump targets: ('2', '5')" shape=rect style=rounded]
4 [label="4\n
jump targets: ('1',)" shape=rect style=rounded]
5 [label="5\n" shape=rect style=rounded]
0 -> 1
0 -> 2
1 -> 3
Expand All @@ -37,109 +30,81 @@

expected_restructured = r"""digraph {
subgraph cluster_head_region_0 {
color=red label="head_region_0
jump targets: ('branch_region_0', 'branch_region_1')
back edges: ()"
0 [label="0\l
jump targets: ('branch_region_0', 'branch_region_1')
back edges: ()" shape=rect]
color=red label="head_region_0\n
jump targets: ('branch_region_0', 'branch_region_1')" shape=rect style=rounded
0 [label="0\n
jump targets: ('branch_region_0', 'branch_region_1')" shape=rect style=rounded]
}
subgraph cluster_branch_region_0 {
color=green label="branch_region_0
jump targets: ('tail_region_0',)
back edges: ()"
synth_asign_block_0 [label="synth_asign_block_0\l__scfg_control_var_0__ = 0
jump targets: ('tail_region_0',)
back edges: ()" shape=rect]
color=green label="branch_region_0\n
jump targets: ('tail_region_0',)" shape=rect style=rounded
synth_asign_block_0 [label="synth_asign_block_0\n\l__scfg_control_var_0__ = 0\l
jump targets: ('tail_region_0',)" shape=rect style=rounded]
}
subgraph cluster_branch_region_1 {
color=green label="branch_region_1
jump targets: ('tail_region_0',)
back edges: ()"
synth_asign_block_1 [label="synth_asign_block_1\l__scfg_control_var_0__ = 1
jump targets: ('tail_region_0',)
back edges: ()" shape=rect]
color=green label="branch_region_1\n
jump targets: ('tail_region_0',)" shape=rect style=rounded
synth_asign_block_1 [label="synth_asign_block_1\n\l__scfg_control_var_0__ = 1\l
jump targets: ('tail_region_0',)" shape=rect style=rounded]
}
subgraph cluster_tail_region_0 {
color=purple label="tail_region_0
jump targets: ()
back edges: ()"
5 [label="5\l
jump targets: ()
back edges: ()" shape=rect]
color=purple label="tail_region_0\n" shape=rect style=rounded
5 [label="5\n" shape=rect style=rounded]
subgraph cluster_loop_region_0 {
color=blue label="loop_region_0
jump targets: ('5',)
back edges: ()"
color=blue label="loop_region_0\n
jump targets: ('5',)" shape=rect style=rounded
subgraph cluster_head_region_1 {
color=red label="head_region_1
jump targets: ('branch_region_2', 'branch_region_3')
back edges: ()"
synth_head_block_0 [label="synth_head_block_0\lvariable: __scfg_control_var_0__\l0=>branch_region_2\l1=>branch_region_3
jump targets: ('branch_region_2', 'branch_region_3')
back edges: ()" shape=rect]
color=red label="head_region_1\n
jump targets: ('branch_region_2', 'branch_region_3')" shape=rect style=rounded
synth_head_block_0 [label="synth_head_block_0\n\lvariable: __scfg_control_var_0__\l0 → branch_region_2\l1 → branch_region_3\l
jump targets: ('branch_region_2', 'branch_region_3')" shape=rect style=rounded]
}
subgraph cluster_branch_region_2 {
color=green label="branch_region_2
jump targets: ('tail_region_1',)
back edges: ()"
color=green label="branch_region_2\n
jump targets: ('tail_region_1',)" shape=rect style=rounded
subgraph cluster_head_region_2 {
color=red label="head_region_2
jump targets: ('branch_region_4', 'branch_region_5')
back edges: ()"
1 [label="1\l
jump targets: ('3',)
back edges: ()" shape=rect]
3 [label="3\l
jump targets: ('branch_region_4', 'branch_region_5')
back edges: ()" shape=rect]
color=red label="head_region_2\n
jump targets: ('branch_region_4', 'branch_region_5')" shape=rect style=rounded
1 [label="1\n
jump targets: ('3',)" shape=rect style=rounded]
3 [label="3\n
jump targets: ('branch_region_4', 'branch_region_5')" shape=rect style=rounded]
}
subgraph cluster_branch_region_4 {
color=green label="branch_region_4
jump targets: ('tail_region_2',)
back edges: ()"
synth_asign_block_2 [label="synth_asign_block_2\l__scfg_backedge_var_0__ = 0\l__scfg_control_var_0__ = 1
jump targets: ('tail_region_2',)
back edges: ()" shape=rect]
color=green label="branch_region_4\n
jump targets: ('tail_region_2',)" shape=rect style=rounded
synth_asign_block_2 [label="synth_asign_block_2\n\l__scfg_backedge_var_0__ = 0\l__scfg_control_var_0__ = 1\l
jump targets: ('tail_region_2',)" shape=rect style=rounded]
}
subgraph cluster_branch_region_5 {
color=green label="branch_region_5
jump targets: ('tail_region_2',)
back edges: ()"
synth_asign_block_3 [label="synth_asign_block_3\l__scfg_backedge_var_0__ = 1
jump targets: ('tail_region_2',)
back edges: ()" shape=rect]
color=green label="branch_region_5\n
jump targets: ('tail_region_2',)" shape=rect style=rounded
synth_asign_block_3 [label="synth_asign_block_3\n\l__scfg_backedge_var_0__ = 1\l
jump targets: ('tail_region_2',)" shape=rect style=rounded]
}
subgraph cluster_tail_region_2 {
color=purple label="tail_region_2
jump targets: ('tail_region_1',)
back edges: ()"
synth_tail_block_0 [label="synth_tail_block_0\l
jump targets: ('tail_region_1',)
back edges: ()" shape=rect]
color=purple label="tail_region_2\n
jump targets: ('tail_region_1',)" shape=rect style=rounded
synth_tail_block_0 [label="synth_tail_block_0\n
jump targets: ('tail_region_1',)" shape=rect style=rounded]
}
}
subgraph cluster_branch_region_3 {
color=green label="branch_region_3
jump targets: ('tail_region_1',)
back edges: ()"
2 [label="2\l
jump targets: ('4',)
back edges: ()" shape=rect]
4 [label="4\l
jump targets: ('synth_asign_block_4',)
back edges: ()" shape=rect]
synth_asign_block_4 [label="synth_asign_block_4\l__scfg_backedge_var_0__ = 0\l__scfg_control_var_0__ = 0
jump targets: ('tail_region_1',)
back edges: ()" shape=rect]
color=green label="branch_region_3\n
jump targets: ('tail_region_1',)" shape=rect style=rounded
2 [label="2\n
jump targets: ('4',)" shape=rect style=rounded]
4 [label="4\n
jump targets: ('synth_asign_block_4',)" shape=rect style=rounded]
synth_asign_block_4 [label="synth_asign_block_4\n\l__scfg_backedge_var_0__ = 0\l__scfg_control_var_0__ = 0\l
jump targets: ('tail_region_1',)" shape=rect style=rounded]
}
subgraph cluster_tail_region_1 {
color=purple label="tail_region_1
jump targets: ('5',)
back edges: ()"
synth_exit_latch_block_0 [label="synth_exit_latch_block_0\lvariable: __scfg_backedge_var_0__\l1=>5\l0=>head_region_1
color=purple label="tail_region_1\n
jump targets: ('5',)" shape=rect style=rounded
synth_exit_latch_block_0 [label="synth_exit_latch_block_0\n\lvariable: __scfg_backedge_var_0__\l1 → 5\l0 → head_region_1\l
jump targets: ('5',)
back edges: ('head_region_1',)" shape=rect]
back edges: ('head_region_1',)" shape=rect style=rounded]
}
}
}
Expand Down