From 7343f55e2dca5c06721c7b9bf3448b2ca0f1637e Mon Sep 17 00:00:00 2001 From: Samuel Martin Date: Thu, 20 Jul 2023 13:00:02 +0200 Subject: [PATCH 1/5] state.read_and_write_sets() take into account when read happens directly after write --- dace/sdfg/state.py | 16 +++++++++++++--- tests/sdfg/state_test.py | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 tests/sdfg/state_test.py diff --git a/dace/sdfg/state.py b/dace/sdfg/state.py index 0796bf00d0..0354dd107b 100644 --- a/dace/sdfg/state.py +++ b/dace/sdfg/state.py @@ -298,10 +298,11 @@ def scope_tree(self) -> 'dace.sdfg.scope.ScopeTree': # Get scopes for node, scopenodes in sdc.items(): + scope_exit_nodes = [v for v in scopenodes if isinstance(v, nd.ExitNode)] if node is None: exit_node = None else: - exit_node = next(v for v in scopenodes if isinstance(v, nd.ExitNode)) + exit_node = next(iter(scope_exit_nodes)) scope = ScopeTree(node, exit_node) result[node] = scope @@ -502,13 +503,22 @@ def _read_and_write_sets(self) -> Tuple[Dict[AnyStr, List[Subset]], Dict[AnyStr, # is read is not counted in the read set for n in utils.dfs_topological_sort(sg, sources=sg.source_nodes()): if isinstance(n, nd.AccessNode): - for e in sg.in_edges(n): + in_edges = sg.in_edges(n) + out_edges = sg.out_edges(n) + # Filter out memlets which go out but the same data is written to the AccessNode by another memlet + for out_edge in out_edges: + for in_edge in in_edges: + if in_edge.data.data == out_edge.data.data and \ + in_edge.data.dst_subset.covers(out_edge.data.src_subset): + out_edges.remove(out_edge) + + for e in in_edges: # skip empty memlets if e.data.is_empty(): continue # Store all subsets that have been written ws[n.data].append(e.data.subset) - for e in sg.out_edges(n): + for e in out_edges: # skip empty memlets if e.data.is_empty(): continue diff --git a/tests/sdfg/state_test.py b/tests/sdfg/state_test.py new file mode 100644 index 0000000000..07e2e8c4c7 --- /dev/null +++ b/tests/sdfg/state_test.py @@ -0,0 +1,23 @@ +import dace + + +def test_read_write_set(): + sdfg = dace.SDFG('graph') + A = sdfg.add_array('A', [10], dace.float64) + B = sdfg.add_array('B', [10], dace.float64) + C = sdfg.add_array('C', [10], dace.float64) + state = sdfg.add_state('state') + task1 = state.add_tasklet('work1', {'A'}, {'B'}, 'B = A + 1') + task2 = state.add_tasklet('work2', {'B'}, {'C'}, 'C = B + 1') + read_a = state.add_access('A') + rw_b = state.add_access('B') + write_c = state.add_access('C') + state.add_memlet_path(read_a, task1, dst_conn='A', memlet=dace.Memlet('A[2]')) + state.add_memlet_path(task1, rw_b, src_conn='B', memlet=dace.Memlet('B[2]')) + state.add_memlet_path(rw_b, task2, dst_conn='B', memlet=dace.Memlet('B[2]')) + state.add_memlet_path(task2, write_c, src_conn='C', memlet=dace.Memlet('C[2]')) + + assert 'B' not in state.read_and_write_sets()[0] + +if __name__ == '__main__': + test_read_write_set() From bb00fea35013b66c153d89c5ba31ede70c0120d2 Mon Sep 17 00:00:00 2001 From: Samuel Martin Date: Thu, 20 Jul 2023 14:07:48 +0200 Subject: [PATCH 2/5] Change RefineNestedAccess to only look at memlets which are in the read and write set --- dace/transformation/interstate/sdfg_nesting.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dace/transformation/interstate/sdfg_nesting.py b/dace/transformation/interstate/sdfg_nesting.py index 1b9324546a..71d9e22aca 100644 --- a/dace/transformation/interstate/sdfg_nesting.py +++ b/dace/transformation/interstate/sdfg_nesting.py @@ -925,7 +925,12 @@ def _candidates( continue # For now we only detect one element + read_set, write_set = nstate.read_and_write_sets() for e in nstate.in_edges(dnode): + if e.data.data not in write_set: + # Skip data which is not in the read and write set of the state -> there also won't be a + # connector + continue # If more than one unique element detected, remove from # candidates if e.data.data in out_candidates: @@ -941,6 +946,10 @@ def _candidates( continue out_candidates[e.data.data] = (e.data, nstate, set(range(len(e.data.subset)))) for e in nstate.out_edges(dnode): + if e.data.data not in read_set: + # Skip data which is not in the read and write set of the state -> there also won't be a + # connector + continue # If more than one unique element detected, remove from # candidates if e.data.data in in_candidates: From 08aac34a8fdd6cd38860d5907e7bca925248a20a Mon Sep 17 00:00:00 2001 From: Samuel Martin Date: Fri, 21 Jul 2023 08:47:39 +0200 Subject: [PATCH 3/5] Add review changes --- dace/sdfg/state.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dace/sdfg/state.py b/dace/sdfg/state.py index 0354dd107b..8059609c36 100644 --- a/dace/sdfg/state.py +++ b/dace/sdfg/state.py @@ -298,11 +298,10 @@ def scope_tree(self) -> 'dace.sdfg.scope.ScopeTree': # Get scopes for node, scopenodes in sdc.items(): - scope_exit_nodes = [v for v in scopenodes if isinstance(v, nd.ExitNode)] if node is None: exit_node = None else: - exit_node = next(iter(scope_exit_nodes)) + exit_node = next(v for v in scopenodes if isinstance(v, nd.ExitNode)) scope = ScopeTree(node, exit_node) result[node] = scope @@ -506,10 +505,10 @@ def _read_and_write_sets(self) -> Tuple[Dict[AnyStr, List[Subset]], Dict[AnyStr, in_edges = sg.in_edges(n) out_edges = sg.out_edges(n) # Filter out memlets which go out but the same data is written to the AccessNode by another memlet - for out_edge in out_edges: - for in_edge in in_edges: - if in_edge.data.data == out_edge.data.data and \ - in_edge.data.dst_subset.covers(out_edge.data.src_subset): + for out_edge in list(out_edges): + for in_edge in list(in_edges): + if (in_edge.data.data == out_edge.data.data and + in_edge.data.dst_subset.covers(out_edge.data.src_subset)): out_edges.remove(out_edge) for e in in_edges: From 851f1fa4f7041c4c3e1be564ae7c92929bb2dbc3 Mon Sep 17 00:00:00 2001 From: Samuel Martin Date: Fri, 21 Jul 2023 08:48:05 +0200 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: alexnick83 <31545860+alexnick83@users.noreply.github.com> --- tests/sdfg/state_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/sdfg/state_test.py b/tests/sdfg/state_test.py index 07e2e8c4c7..c5cb953c4d 100644 --- a/tests/sdfg/state_test.py +++ b/tests/sdfg/state_test.py @@ -1,3 +1,4 @@ +# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. import dace From 9a1db886905fb037e92b96b0fbefa5c5074ba73d Mon Sep 17 00:00:00 2001 From: Samuel Martin Date: Fri, 21 Jul 2023 08:49:45 +0200 Subject: [PATCH 5/5] Added myself to AUTHORS file --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 573f142cf9..48cb4c05ec 100644 --- a/AUTHORS +++ b/AUTHORS @@ -36,5 +36,6 @@ Reid Wahl Yihang Luo Alexandru Calotoiu Phillip Lane +Samuel Martin and other contributors listed in https://github.com/spcl/dace/graphs/contributors