diff --git a/loopy/check.py b/loopy/check.py index 8e1709b71ae9e849fae4726b84407f504a082f4d..0390618181b70129ba0395218f9dd40f2cad803a 100644 --- a/loopy/check.py +++ b/loopy/check.py @@ -525,6 +525,27 @@ def check_that_temporaries_are_defined_in_subkernels_where_used(kernel): # }}} +# {{{ check that all instructions are scheduled + +def check_that_all_insns_are_scheduled(kernel): + all_insns = set(insn.id for insn in kernel.instructions) + from loopy.schedule import sched_item_to_insn_id + scheduled_insns = set( + insn_id + for sched_item in kernel.schedule + for insn_id in sched_item_to_insn_id(sched_item)) + + assert scheduled_insns <= all_insns + + if scheduled_insns < all_insns: + from loopy.diagnostic import UnscheduledInstructionError + raise UnscheduledInstructionError( + "unscheduled instructions: '%s'" + % ', '.join(all_insns - scheduled_insns)) + +# }}} + + # {{{ check that shapes and strides are arguments def check_that_shapes_and_strides_are_arguments(kernel): @@ -576,6 +597,7 @@ def pre_codegen_checks(kernel): check_for_unused_hw_axes_in_insns(kernel) check_that_atomic_ops_are_used_exactly_on_atomic_arrays(kernel) check_that_temporaries_are_defined_in_subkernels_where_used(kernel) + check_that_all_insns_are_scheduled(kernel) kernel.target.pre_codegen_check(kernel) check_that_shapes_and_strides_are_arguments(kernel) diff --git a/loopy/diagnostic.py b/loopy/diagnostic.py index e76279c27e5fab5d01b3039d0e5dcc08c2fa749e..15ab8a1ee13df440926e51e676223bc6a398df57 100644 --- a/loopy/diagnostic.py +++ b/loopy/diagnostic.py @@ -99,6 +99,10 @@ class MissingBarrierError(LoopyError): class MissingDefinitionError(LoopyError): pass + +class UnscheduledInstructionError(LoopyError): + pass + # }}} diff --git a/test/test_loopy.py b/test/test_loopy.py index 81fe49cb42ad2dcc3c7dd69e54b758f3278a4517..30408b26e5b6ce02cb8a0b709bc8a3e7fd4f9ceb 100644 --- a/test/test_loopy.py +++ b/test/test_loopy.py @@ -1817,6 +1817,23 @@ def test_tight_loop_bounds_codegen(): assert for_loop in cgr.device_code() +def test_unscheduled_insn_detection(): + knl = lp.make_kernel( + "{ [i]: 0 <= i < 10 }", + """ + out[i] = i {id=insn1} + """, + "...") + + knl = lp.get_one_scheduled_kernel(lp.preprocess_kernel(knl)) + insn1, = lp.find_instructions(knl, "id:insn1") + knl.instructions.append(insn1.copy(id="insn2")) + + from loopy.diagnostic import UnscheduledInstructionError + with pytest.raises(UnscheduledInstructionError): + lp.generate_code(knl) + + if __name__ == "__main__": if len(sys.argv) > 1: exec(sys.argv[1])