diff --git a/src/psyclone/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans.py b/src/psyclone/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans.py index 8da23ad036..e15327e58d 100644 --- a/src/psyclone/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans.py +++ b/src/psyclone/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans.py @@ -109,13 +109,6 @@ def validate(self, node, options=None): f"can only be applied to 'GOKern' nodes, but found " f"'{type(node).__name__}'.") - _, kschedules = node.get_kernel_schedule() - if len(kschedules) > 1: - raise TransformationError( - f"Error in {self.name} transformation. Polymorphic kernels " - f"are not supported but kernel '{node.name}' has " - f"implementations: {[sched.name for sched in kschedules]}") - def apply(self, node, options=None): '''Apply this transformation to the supplied node. @@ -188,7 +181,7 @@ def apply(self, node, options=None): # Update Kernel _, kschedules = node.get_kernel_schedule() - # validate() has checked that this kernel is not polymorphic. + # GOcean Kernels must have a single implementation. kschedule = kschedules[0] kernel_st = kschedule.symbol_table iteration_indices = kernel_st.iteration_indices diff --git a/src/psyclone/domain/gocean/transformations/gocean_opencl_trans.py b/src/psyclone/domain/gocean/transformations/gocean_opencl_trans.py index 4d84aeeb34..eab964cdda 100644 --- a/src/psyclone/domain/gocean/transformations/gocean_opencl_trans.py +++ b/src/psyclone/domain/gocean/transformations/gocean_opencl_trans.py @@ -147,17 +147,19 @@ def validate(self, node, options=None): # Validate options map valid_options = ['end_barrier', 'enable_profiling', 'out_of_order'] - for key, value in options.items(): - if key in valid_options: - # All current options should contain boolean values - if not isinstance(value, bool): + if options: + for key, value in options.items(): + if key in valid_options: + # All current options should contain boolean values + if not isinstance(value, bool): + raise TransformationError( + f"InvokeSchedule OpenCL option '{key}' should be " + f"a boolean.") + else: raise TransformationError( - f"InvokeSchedule OpenCL option '{key}' should be a " - f"boolean.") - else: - raise TransformationError( - f"InvokeSchedule does not support the OpenCL option " - f"'{key}'. The supported options are: {valid_options}.") + f"InvokeSchedule does not support the OpenCL option " + f"'{key}'. The supported options are: " + f"{valid_options}.") # Validate that the options are valid with previously generated OpenCL if self._transformed_invokes > 0: @@ -193,8 +195,7 @@ def validate(self, node, options=None): for kern in node.kernels(): KernelModuleInlineTrans().validate(kern) _, kschedules = kern.get_kernel_schedule() - if len(kschedules) > 1: - raise TransformationError("TODO") + # GOcean Kernels must have a single implementation. ksched = kschedules[0] global_variables = ksched.symbol_table.imported_symbols if global_variables: diff --git a/src/psyclone/gocean1p0.py b/src/psyclone/gocean1p0.py index 4100c251ae..4a456e5f37 100644 --- a/src/psyclone/gocean1p0.py +++ b/src/psyclone/gocean1p0.py @@ -1235,8 +1235,15 @@ def index_offset(self): def get_kernel_schedule(self): ''' + Obtains and returns the PSyIR Schedule representing the kernel code. + + For consistency with LFRic kernels (which may be polymorphic), this + method actually returns a tuple with the second element containing a + list comprising just one Schedule. + :returns: a schedule representing the GOcean kernel code. - :rtype: :py:class:`psyclone.gocean1p0.GOKernelSchedule` + :rtype: tuple[NoneType, + list[:py:class:`psyclone.gocean1p0.GOKernelSchedule`]] :raises GenerationError: if there is a problem raising the language- level PSyIR of this kernel to GOcean PSyIR. diff --git a/src/psyclone/tests/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans_test.py b/src/psyclone/tests/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans_test.py index 0e167c861e..2d72b8951f 100644 --- a/src/psyclone/tests/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans_test.py +++ b/src/psyclone/tests/domain/gocean/transformations/gocean_move_iteration_boundaries_inside_kernel_trans_test.py @@ -43,9 +43,9 @@ from psyclone.domain.gocean.transformations import ( GOMoveIterationBoundariesInsideKernelTrans) from psyclone.psyir.nodes import ( - Assignment, Container, IfBlock, Return, Routine) + Assignment, Container, IfBlock, Return) from psyclone.psyir.symbols import ArgumentInterface -from psyclone.gocean1p0 import GOKern, GOLoop +from psyclone.gocean1p0 import GOLoop from psyclone.psyir.transformations import TransformationError API = "gocean" @@ -60,29 +60,13 @@ def test_description(): def test_validation(monkeypatch): - ''' Check that the transformation can only be applied to routine nodes and - that polymorphic kernels are rejected. - - ''' + '''Check that the transformation can only be applied to routine nodes.''' trans = GOMoveIterationBoundariesInsideKernelTrans() with pytest.raises(TransformationError) as info: trans.validate(None) assert ("Error in GOMoveIterationBoundariesInsideKernelTrans " "transformation. This transformation can only be applied to " "'GOKern' nodes, but found 'NoneType'." in str(info.value)) - # Test that a polymorphic kernel is rejected. GOcean doesn't actually - # support these so we use monkeypatch. - psy, _ = get_invoke("single_invoke.f90", API, idx=0, dist_mem=False) - sched = psy.invokes.invoke_list[0].schedule - kern = sched.walk(GOKern)[0] - sched1 = Routine.create("kern_32") - sched2 = Routine.create("kern_64") - monkeypatch.setattr(kern, "get_kernel_schedule", - lambda: (None, [sched1, sched2])) - with pytest.raises(TransformationError) as err: - trans.validate(kern) - assert ("but kernel 'compute_cu_code' has implementations: ['kern_32', " - "'kern_64']" in str(err.value)) def test_go_move_iteration_boundaries_inside_kernel_trans():