From d77cb2aea5c2a0fb161510e33b1e8821f0fc4e4d Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Thu, 22 Aug 2019 10:27:08 +0530 Subject: [PATCH 1/5] do not allow non integral array indices --- loopy/check.py | 27 +++++++++++++++++++++++++++ test/test_loopy.py | 13 +++++++++++++ 2 files changed, 40 insertions(+) diff --git a/loopy/check.py b/loopy/check.py index 5fb7a2fb9..aeec19c78 100644 --- a/loopy/check.py +++ b/loopy/check.py @@ -29,6 +29,9 @@ from islpy import dim_type import islpy as isl from loopy.symbolic import WalkMapper from loopy.diagnostic import LoopyError, WriteRaceConditionWarning, warn_with_kernel +from loopy.type_inference import TypeInferenceMapper +from loopy.kernel.instruction import (MultiAssignmentBase, CInstruction, + _DataObliviousInstruction) import logging logger = logging.getLogger(__name__) @@ -66,6 +69,29 @@ def check_identifiers_in_subst_rules(knl): VALID_NOSYNC_SCOPES = frozenset(["local", "global", "any"]) +class SubscriptIndicesIsIntChecker(TypeInferenceMapper): + def map_subscript(self, expr): + for idx in expr.index_tuple: + if not self.rec(idx)[0].is_integral(): + raise LoopyError("Non integral array indices obtained in" + " {}.".format(expr)) + + return self.rec(expr.aggregate) + + +def check_for_integer_subscript_indices(kernel): + idx_int_checker = SubscriptIndicesIsIntChecker(kernel) + for insn in kernel.instructions: + if isinstance(insn, MultiAssignmentBase): + idx_int_checker(insn.expression) + [idx_int_checker(assignee) for assignee in insn.assignees] + elif isinstance(insn, (CInstruction, _DataObliviousInstruction)): + pass + else: + raise NotImplementedError("Unknown insn type %s." % ( + type(insn).__name__)) + + def check_insn_attributes(kernel): all_insn_ids = set(insn.id for insn in kernel.instructions) @@ -620,6 +646,7 @@ def pre_schedule_checks(kernel): try: logger.debug("%s: pre-schedule check: start" % kernel.name) + check_for_integer_subscript_indices(kernel) check_for_duplicate_insn_ids(kernel) check_for_orphaned_user_hardware_axes(kernel) check_for_double_use_of_hw_axes(kernel) diff --git a/test/test_loopy.py b/test/test_loopy.py index 119d57adf..d506258c2 100644 --- a/test/test_loopy.py +++ b/test/test_loopy.py @@ -3015,6 +3015,19 @@ def test_array_arg_extra_kwargs_persis_hash(): assert key_builder(a) != key_builder(not_a) +def test_non_integral_array_idx_raises(): + knl = lp.make_kernel( + "{[i, j]: 0<=i<=4 and 0<=j<16}", + """ + out[j] = 0 {id=init} + out[i] = a[1.94**i-1] {dep=init} + """, [lp.GlobalArg('a', np.float64), '...']) + + from loopy.diagnostic import LoopyError + with pytest.raises(LoopyError): + print(lp.generate_code_v2(knl).device_code()) + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1]) -- GitLab From c81353e5b8f384155ab01f3eda574c2ee44fd69a Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Thu, 22 Aug 2019 11:31:34 +0530 Subject: [PATCH 2/5] handle return tuple correctly --- loopy/check.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/loopy/check.py b/loopy/check.py index aeec19c78..ad7717226 100644 --- a/loopy/check.py +++ b/loopy/check.py @@ -30,8 +30,8 @@ import islpy as isl from loopy.symbolic import WalkMapper from loopy.diagnostic import LoopyError, WriteRaceConditionWarning, warn_with_kernel from loopy.type_inference import TypeInferenceMapper -from loopy.kernel.instruction import (MultiAssignmentBase, CInstruction, - _DataObliviousInstruction) +from loopy.kernel.instruction import (MultiAssignmentBase, CallInstruction, + CInstruction, _DataObliviousInstruction) import logging logger = logging.getLogger(__name__) @@ -83,7 +83,8 @@ def check_for_integer_subscript_indices(kernel): idx_int_checker = SubscriptIndicesIsIntChecker(kernel) for insn in kernel.instructions: if isinstance(insn, MultiAssignmentBase): - idx_int_checker(insn.expression) + idx_int_checker(insn.expression, return_tuple=isinstance(insn, + CallInstruction), return_dtype_set=True) [idx_int_checker(assignee) for assignee in insn.assignees] elif isinstance(insn, (CInstruction, _DataObliviousInstruction)): pass -- GitLab From 70c1ca7430f58784266e4e2679592461145fc412 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Thu, 22 Aug 2019 11:54:20 +0530 Subject: [PATCH 3/5] check only for subscript assignees --- loopy/check.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/loopy/check.py b/loopy/check.py index ad7717226..e11aafab0 100644 --- a/loopy/check.py +++ b/loopy/check.py @@ -80,12 +80,14 @@ class SubscriptIndicesIsIntChecker(TypeInferenceMapper): def check_for_integer_subscript_indices(kernel): + from pymbolic.primitives import Subscript idx_int_checker = SubscriptIndicesIsIntChecker(kernel) for insn in kernel.instructions: if isinstance(insn, MultiAssignmentBase): idx_int_checker(insn.expression, return_tuple=isinstance(insn, CallInstruction), return_dtype_set=True) - [idx_int_checker(assignee) for assignee in insn.assignees] + [idx_int_checker(assignee) for assignee in insn.assignees if + isinstance(assignee, Subscript)] elif isinstance(insn, (CInstruction, _DataObliviousInstruction)): pass else: -- GitLab From 0b653d28804d07231bbde1c3567c30d373f4f438 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Thu, 22 Aug 2019 13:00:00 +0530 Subject: [PATCH 4/5] changes after https://gitlab.tiker.net/inducer/pymbolic/merge_requests/42 --- doc/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.rst b/doc/tutorial.rst index 3c85060da..aa75b0efd 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -1220,7 +1220,7 @@ should call :func:`loopy.get_one_scheduled_kernel`: 2: RETURN FROM KERNEL rotate_v2 3: ... gbarrier 4: CALL KERNEL rotate_v2_0(extra_args=[], extra_inames=[]) - 5: arr[((1 + i_inner + i_outer*16) % n)] = tmp {id=rotate} + 5: arr[(1 + i_inner + i_outer*16) % n] = tmp {id=rotate} 6: RETURN FROM KERNEL rotate_v2_0 --------------------------------------------------------------------------- -- GitLab From 5daa725c9917a9ad6875d797773883bead4a4fd8 Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Thu, 22 Aug 2019 14:43:47 +0530 Subject: [PATCH 5/5] some more changes from changes in pymbolic --- doc/tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tutorial.rst b/doc/tutorial.rst index aa75b0efd..8ca56619b 100644 --- a/doc/tutorial.rst +++ b/doc/tutorial.rst @@ -1260,7 +1260,7 @@ put those instructions into the schedule. 4: ... gbarrier 5: CALL KERNEL rotate_v2_0(extra_args=['tmp_save_slot'], extra_inames=[]) 6: tmp = tmp_save_slot[tmp_reload_hw_dim_0_rotate_v2_0, tmp_reload_hw_dim_1_rotate_v2_0] {id=tmp.reload} - 7: arr[((1 + i_inner + i_outer*16) % n)] = tmp {id=rotate} + 7: arr[(1 + i_inner + i_outer*16) % n] = tmp {id=rotate} 8: RETURN FROM KERNEL rotate_v2_0 --------------------------------------------------------------------------- -- GitLab