From 3eee0f4fd2ce6c76fc47ca8297c6a51966146e13 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 11 Dec 2023 15:02:44 +0100 Subject: [PATCH 1/7] WIP --- dace/sdfg/state.py | 7 +++++++ tests/sdfg/cfg_block_conditions_test.py | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/sdfg/cfg_block_conditions_test.py diff --git a/dace/sdfg/state.py b/dace/sdfg/state.py index becebd1c28..d990a211a4 100644 --- a/dace/sdfg/state.py +++ b/dace/sdfg/state.py @@ -1074,6 +1074,10 @@ class ControlFlowBlock(BlockGraphView, abc.ABC): is_collapsed = Property(dtype=bool, desc='Show this block as collapsed', default=False) + pre_conditions = DictProperty(key_type=str, value_type=list, desc='Pre-conditions for this block') + post_conditions = DictProperty(key_type=str, value_type=list, desc='Post-conditions for this block') + invariant_conditions = DictProperty(key_type=str, value_type=list, desc='Invariant conditions for this block') + _label: str def __init__(self, @@ -1086,6 +1090,9 @@ def __init__(self, self._sdfg = sdfg self._parent_graph = parent self.is_collapsed = False + self.pre_conditions = {} + self.post_conditions = {} + self.invariant_conditions = {} def set_default_lineinfo(self, lineinfo: dace.dtypes.DebugInfo): """ diff --git a/tests/sdfg/cfg_block_conditions_test.py b/tests/sdfg/cfg_block_conditions_test.py new file mode 100644 index 0000000000..120eeb39f0 --- /dev/null +++ b/tests/sdfg/cfg_block_conditions_test.py @@ -0,0 +1,13 @@ +# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. +import dace + +def test_broken_symbol_pre_condition(): + N = dace.symbol('N') + + @dace.program + def simple_matmul(A: dace.float64[N, N], B: dace.float64[N, N]): + return A @ B + + sdfg = simple_matmul.to_sdfg(simplify=True) + + sdfg.pre_conditions['N'] = 'N > 30' From 5ea68068424c2d48ef821f7bea9074c6e7945124 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 11 Dec 2023 20:14:04 +0100 Subject: [PATCH 2/7] Add size constraint derivation --- dace/transformation/passes/analysis.py | 37 +++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/dace/transformation/passes/analysis.py b/dace/transformation/passes/analysis.py index 86e1cde062..353853cfb4 100644 --- a/dace/transformation/passes/analysis.py +++ b/dace/transformation/passes/analysis.py @@ -2,7 +2,7 @@ from collections import defaultdict from dace.transformation import pass_pipeline as ppl -from dace import SDFG, SDFGState, properties, InterstateEdge +from dace import SDFG, SDFGState, properties, InterstateEdge, symbolic from dace.sdfg.graph import Edge from dace.sdfg import nodes as nd from dace.sdfg.analysis import cfg @@ -505,3 +505,38 @@ def apply_pass(self, top_sdfg: SDFG, pipeline_results: Dict[str, Any]) -> Dict[i del result[desc][write] top_result[sdfg.sdfg_id] = result return top_result + + +@properties.make_properties +class DeriveSDFGConstraints(ppl.Pass): + + CATEGORY: str = 'Analysis' + + assume_max_data_size = properties.Property(dtype=int, default=None, allow_none=True, + desc='Assume that all data containers have no dimension larger than ' + + 'this value. If None, no assumption is made.') + + def modifies(self) -> ppl.Modifies: + return ppl.Modifies.Nothing + + def should_reapply(self, modified: ppl.Modifies) -> bool: + # If anything was modified, reapply + return modified & ppl.Modifies.Everything + + def _derive_parameter_datasize_constraints(self, sdfg: SDFG, invariants: Dict[str, Set[str]]) -> None: + handled = set() + for arr in sdfg.arrays.values(): + for dim in arr.shape: + if isinstance(dim, symbolic.symbol) and not dim in handled: + ds = str(dim) + if ds not in invariants: + invariants[ds] = set() + invariants[ds].add(f'{ds} > 0') + if self.assume_max_data_size is not None: + invariants[ds].add(f'{ds} <= {self.assume_max_data_size}') + handled.add(ds) + + def apply_pass(self, sdfg: SDFG, _) -> Tuple[Dict[str, Set[str]], Dict[str, Set[str]], Dict[str, Set[str]]]: + invariants: Dict[str, Set[str]] = {} + self._derive_parameter_datasize_constraints(sdfg, invariants) + return {}, invariants, {} From 4521bebc4e4ff8c524dca1947bc11d598b41c440 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 11 Dec 2023 20:19:33 +0100 Subject: [PATCH 3/7] Add test --- .../passes/sdfg_constraint_derivation_test.py | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/passes/sdfg_constraint_derivation_test.py diff --git a/tests/passes/sdfg_constraint_derivation_test.py b/tests/passes/sdfg_constraint_derivation_test.py new file mode 100644 index 0000000000..62257f7e3c --- /dev/null +++ b/tests/passes/sdfg_constraint_derivation_test.py @@ -0,0 +1,49 @@ +# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. + +import dace +from dace.transformation.passes.analysis import DeriveSDFGConstraints + + +def test_infer_data_dim_constraints_nomax(): + N = dace.symbol('N') + + @dace.program + def matmul(A: dace.float64[N, N], B: dace.float64[N, N], C: dace.float64[N, N]): + for i in range(N): + for j in range(N): + for k in range(N): + C[i, j] += A[i, k] * B[k, j] + + sdfg = matmul.to_sdfg() + + derive_pass = DeriveSDFGConstraints() + _, inv, _ = derive_pass.apply_pass(sdfg, {}) + + assert 'N' in inv + assert 'N > 0' in inv['N'] + + +def test_infer_data_dim_constraints_withmax(): + N = dace.symbol('N') + + @dace.program + def matmul(A: dace.float64[N, N], B: dace.float64[N, N], C: dace.float64[N, N]): + for i in range(N): + for j in range(N): + for k in range(N): + C[i, j] += A[i, k] * B[k, j] + + sdfg = matmul.to_sdfg() + + derive_pass = DeriveSDFGConstraints() + derive_pass.assume_max_data_size = 128 + _, inv, _ = derive_pass.apply_pass(sdfg, {}) + + assert 'N' in inv + assert 'N > 0' in inv['N'] + assert 'N <= 128' in inv['N'] + + +if __name__ == "__main__": + test_infer_data_dim_constraints_nomax() + test_infer_data_dim_constraints_withmax() From 9388ae4b00919bb021060c153a0627f49acd3871 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Mon, 11 Dec 2023 20:25:24 +0100 Subject: [PATCH 4/7] Remove unused test --- tests/sdfg/cfg_block_conditions_test.py | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 tests/sdfg/cfg_block_conditions_test.py diff --git a/tests/sdfg/cfg_block_conditions_test.py b/tests/sdfg/cfg_block_conditions_test.py deleted file mode 100644 index 120eeb39f0..0000000000 --- a/tests/sdfg/cfg_block_conditions_test.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. -import dace - -def test_broken_symbol_pre_condition(): - N = dace.symbol('N') - - @dace.program - def simple_matmul(A: dace.float64[N, N], B: dace.float64[N, N]): - return A @ B - - sdfg = simple_matmul.to_sdfg(simplify=True) - - sdfg.pre_conditions['N'] = 'N > 30' From 70612a7ab1e4ec5b76d900fcf0d06df89073c899 Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Thu, 16 May 2024 14:19:44 +0200 Subject: [PATCH 5/7] Fix copyright year --- dace/viewer/webclient | 2 +- tests/passes/sdfg_constraint_derivation_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dace/viewer/webclient b/dace/viewer/webclient index 2128d61489..dd34948875 160000 --- a/dace/viewer/webclient +++ b/dace/viewer/webclient @@ -1 +1 @@ -Subproject commit 2128d61489ff249db5a0f92587ef4d55eefc8add +Subproject commit dd34948875d01f63749faee5dd0fd34a198aaaa6 diff --git a/tests/passes/sdfg_constraint_derivation_test.py b/tests/passes/sdfg_constraint_derivation_test.py index 62257f7e3c..868548da7f 100644 --- a/tests/passes/sdfg_constraint_derivation_test.py +++ b/tests/passes/sdfg_constraint_derivation_test.py @@ -1,4 +1,4 @@ -# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. +# Copyright 2019-2024 ETH Zurich and the DaCe authors. All rights reserved. import dace from dace.transformation.passes.analysis import DeriveSDFGConstraints From b2c046da83885a44ee8578dd681b9299188cef8d Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Thu, 16 May 2024 14:26:34 +0200 Subject: [PATCH 6/7] Revert "Fix copyright year" This reverts commit 70612a7ab1e4ec5b76d900fcf0d06df89073c899. --- dace/viewer/webclient | 2 +- tests/passes/sdfg_constraint_derivation_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dace/viewer/webclient b/dace/viewer/webclient index dd34948875..2128d61489 160000 --- a/dace/viewer/webclient +++ b/dace/viewer/webclient @@ -1 +1 @@ -Subproject commit dd34948875d01f63749faee5dd0fd34a198aaaa6 +Subproject commit 2128d61489ff249db5a0f92587ef4d55eefc8add diff --git a/tests/passes/sdfg_constraint_derivation_test.py b/tests/passes/sdfg_constraint_derivation_test.py index 868548da7f..62257f7e3c 100644 --- a/tests/passes/sdfg_constraint_derivation_test.py +++ b/tests/passes/sdfg_constraint_derivation_test.py @@ -1,4 +1,4 @@ -# Copyright 2019-2024 ETH Zurich and the DaCe authors. All rights reserved. +# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. import dace from dace.transformation.passes.analysis import DeriveSDFGConstraints From ae93e40bcbcbdfc4b73ca60bdaa34c98ddca8f9c Mon Sep 17 00:00:00 2001 From: Philipp Schaad Date: Thu, 16 May 2024 14:27:15 +0200 Subject: [PATCH 7/7] Fix copyright year --- tests/passes/sdfg_constraint_derivation_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/passes/sdfg_constraint_derivation_test.py b/tests/passes/sdfg_constraint_derivation_test.py index 62257f7e3c..868548da7f 100644 --- a/tests/passes/sdfg_constraint_derivation_test.py +++ b/tests/passes/sdfg_constraint_derivation_test.py @@ -1,4 +1,4 @@ -# Copyright 2019-2023 ETH Zurich and the DaCe authors. All rights reserved. +# Copyright 2019-2024 ETH Zurich and the DaCe authors. All rights reserved. import dace from dace.transformation.passes.analysis import DeriveSDFGConstraints