From ac88bd0fb3ac47cce4ff79f5a130e8efb1b999b9 Mon Sep 17 00:00:00 2001 From: Sergi Siso Date: Thu, 30 Jan 2025 16:33:49 +0000 Subject: [PATCH] #1010 Improve tests and documentation --- src/psyclone/domain/lfric/lfric_invoke.py | 12 ++-- src/psyclone/domain/lfric/lfric_kern.py | 5 +- src/psyclone/domain/lfric/lfric_psy.py | 2 +- src/psyclone/domain/lfric/lfric_stencils.py | 8 +-- src/psyclone/dynamo0p3.py | 72 ++++++++++++++----- src/psyclone/gen_kernel_stub.py | 10 +-- src/psyclone/gocean1p0.py | 18 ++--- src/psyclone/psyGen.py | 24 ++++--- src/psyclone/psyir/nodes/schedule.py | 11 --- .../tests/domain/gocean/goloop_test.py | 36 ---------- .../tests/domain/lfric/lfric_kern_test.py | 13 ++++ src/psyclone/tests/dynamo0p3_cma_test.py | 22 +++--- src/psyclone/tests/psyGen_test.py | 9 +++ 13 files changed, 122 insertions(+), 120 deletions(-) diff --git a/src/psyclone/domain/lfric/lfric_invoke.py b/src/psyclone/domain/lfric/lfric_invoke.py index 86aaf901ac..639245a423 100644 --- a/src/psyclone/domain/lfric/lfric_invoke.py +++ b/src/psyclone/domain/lfric/lfric_invoke.py @@ -271,16 +271,11 @@ def field_on_space(self, func_space): return field return None - def declare(self): - ''' Declare and initialise all symbols associated this Invoke. - Generates LFRic-specific invocation code (the subroutine - called by the associated Invoke call in the algorithm - layer). This consists of the PSy invocation subroutine and the - declaration of its arguments. + def setup_psy_layer_symbols(self): + ''' Declare, initialise and deallocate all symbols required by the + PSy-layer Invoke subroutine. ''' - cursor = 0 - # Declare all quantities required by this PSy routine (Invoke) for entities in [self.scalar_args, self.fields, self.lma_ops, self.stencil, self.meshes, @@ -293,6 +288,7 @@ def declare(self): self.run_time_checks]: entities.invoke_declarations() + cursor = 0 for entities in [self.proxies, self.run_time_checks, self.cell_iterators, self.meshes, self.stencil, self.dofmaps, diff --git a/src/psyclone/domain/lfric/lfric_kern.py b/src/psyclone/domain/lfric/lfric_kern.py index 45cb976733..67ab577c03 100644 --- a/src/psyclone/domain/lfric/lfric_kern.py +++ b/src/psyclone/domain/lfric/lfric_kern.py @@ -543,9 +543,8 @@ def ncolours_var(self): f"coloured loop.") if self.is_intergrid: ncols_sym = self._intergrid_ref.ncolours_var_symbol - if not ncols_sym: - return None - return ncols_sym.name + if ncols_sym is not None: + return ncols_sym.name return self.scope.symbol_table.lookup_with_tag("ncolour").name diff --git a/src/psyclone/domain/lfric/lfric_psy.py b/src/psyclone/domain/lfric/lfric_psy.py index 1f48fefc93..e120c42b65 100644 --- a/src/psyclone/domain/lfric/lfric_psy.py +++ b/src/psyclone/domain/lfric/lfric_psy.py @@ -122,7 +122,7 @@ def gen(self) -> str: # Now do the declarations/initialisation on the copied tree for invoke in self.invokes.invoke_list: - invoke.declare() + invoke.setup_psy_layer_symbols() # Use the PSyIR Fortran backend to generate Fortran code of the # supplied PSyIR tree. diff --git a/src/psyclone/domain/lfric/lfric_stencils.py b/src/psyclone/domain/lfric/lfric_stencils.py index 5ad53b07fc..b45438f2e4 100644 --- a/src/psyclone/domain/lfric/lfric_stencils.py +++ b/src/psyclone/domain/lfric/lfric_stencils.py @@ -303,9 +303,7 @@ def _unique_extent_vars(self): def _declare_unique_extent_vars(self): ''' - Declare all unique extent arguments as integers with intent 'in' and - add the declaration as a child of the parent argument passed - in. + Declare all unique extent arguments as integers with intent 'in'. ''' if self._unique_extent_vars: @@ -356,9 +354,7 @@ def _unique_direction_vars(self): def _declare_unique_direction_vars(self): ''' - Declare all unique direction arguments as integers with intent 'in' - and add the declaration as a child of the parent argument - passed in. + Declare all unique direction arguments as integers with intent 'in'. ''' for var in self._unique_direction_vars: diff --git a/src/psyclone/dynamo0p3.py b/src/psyclone/dynamo0p3.py index 72d2d17bf0..ed9a595030 100644 --- a/src/psyclone/dynamo0p3.py +++ b/src/psyclone/dynamo0p3.py @@ -415,7 +415,10 @@ def __init__(self, node): name_lower, symbol_type=DataSymbol, datatype=UnsupportedFortranType( "integer(kind=i_def), pointer :: adjacent_face(:,:) " - "=> null()" + "=> null()", + partial_datatype=ArrayType( + LFRicTypes("LFRicIntegerScalarDataType")(), + [ArrayType.Extent.DEFERRED]*2) ), tag=name_lower) else: @@ -566,6 +569,7 @@ def stub_declarations(self): ''' Creates the necessary declarations for the variables needed in order to provide properties of the mesh in a kernel stub. + Note that argument order is redefined later by ArgOrdering. :raises InternalError: if an unsupported mesh property is encountered. @@ -935,8 +939,8 @@ def invoke_declarations(self): def stub_declarations(self): ''' Create the necessary declarations for the variables needed in order - to provide properties of the reference element in a Kernel stub. Note - that argument order is redefined later by ArgOrdering. + to provide properties of the reference element in a Kernel stub. + Note that argument order is redefined later by ArgOrdering. ''' super().stub_declarations() @@ -1123,6 +1127,7 @@ def __init__(self, kern_or_invoke): def stub_declarations(self): ''' Add function-space-related declarations to a Kernel stub. + Note that argument order is redefined later by ArgOrdering. ''' super().stub_declarations() @@ -1780,6 +1785,7 @@ def stub_declarations(self): ''' Generate all necessary declarations for CMA operators being passed to a Kernel stub. + Note that argument order is redefined later by ArgOrdering. ''' super().stub_declarations() @@ -1838,7 +1844,7 @@ def stub_declarations(self): op = symtab.find_or_create( op_name, symbol_type=DataSymbol, datatype=ArrayType( - LFRicTypes("LFRicIntegerScalarDataType")(), + LFRicTypes("LFRicRealScalarDataType")(), [Reference(bandwidth), Reference(nrow), Reference(symtab.lookup("ncell_2d"))])) op.interface = ArgumentInterface( @@ -2023,12 +2029,16 @@ def colourmap_init(self): carg_name = call._intergrid_ref.coarse.name # Colour map base_name = "cmap_" + carg_name + array_type = ArrayType( + LFRicTypes("LFRicRealScalarDataType")(), + [ArrayType.Extent.DEFERRED]*2) colour_map = self.symtab.find_or_create( base_name, symbol_type=DataSymbol, datatype=UnsupportedFortranType( f"integer(kind=i_def), pointer, dimension(:,:) :: " - f"{base_name} => null()"), + f"{base_name} => null()", + partial_datatype=array_type), tag=base_name) # No. of colours base_name = "ncolour_" + carg_name @@ -2338,8 +2348,9 @@ def initialise(self, cursor: int) -> int: coarse_mesh, [name]))) self._invoke.schedule.addchild(assignment, cursor) cursor += 1 - self._invoke.schedule[comment_cursor].preceding_comment = ( - "Look-up mesh objects and loop limits for inter-grid kernels") + if cursor != comment_cursor: + self._invoke.schedule[comment_cursor].preceding_comment = ( + "Look-up mesh objects and loop limits for inter-grid kernels") return cursor @@ -2409,12 +2420,19 @@ def __init__(self, fine_arg, coarse_arg): ).name # Name for cell map base_name = "cell_map_" + coarse_arg.name + ArrayType( + LFRicTypes("LFRicRealScalarDataType")(), + [ArrayType.Extent.DEFERRED]*2) sym = symtab.find_or_create( base_name, symbol_type=DataSymbol, datatype=UnsupportedFortranType( f"integer(kind=i_def), pointer :: {base_name}" - f"(:,:,:) => null()")) + f"(:,:,:) => null()", + partial_datatype=ArrayType( + LFRicTypes("LFRicRealScalarDataType")(), + [ArrayType.Extent.DEFERRED]*3) + )) self.cell_map = sym.name @@ -2713,6 +2731,7 @@ def stub_declarations(self): ''' Insert the variable declarations required by the basis functions into the Kernel stub. + Note that argument order is redefined later by ArgOrdering. :raises InternalError: if an unsupported quadrature shape is found. @@ -2736,6 +2755,8 @@ def stub_declarations(self): arg.interface = ArgumentInterface( ArgumentInterface.Access.READ) self.symtab.append_argument(arg) + + # Allocate basis arrays for basis in basis_arrays: dims = [] for value in basis_arrays[basis]: @@ -3263,12 +3284,16 @@ def _initialise_face_or_edge_qr(self, cursor, qr_type): symbol_type=DataSymbol, datatype=LFRicTypes("LFRicIntegerScalarDataType")()) + array_type = ArrayType( + LFRicTypes("LFRicRealScalarDataType")(), + [ArrayType.Extent.DEFERRED]*2) for name in self.qr_weight_vars[qr_type]: self.symtab.find_or_create( f"{name}_{qr_arg_name}", symbol_type=DataSymbol, datatype=UnsupportedFortranType( f"real(kind=r_def), pointer, dimension(:,:) :: " - f"{name}_{qr_arg_name} => null()\n" + f"{name}_{qr_arg_name} => null()\n", + partial_datatype=array_type ), tag=f"{name}_{qr_arg_name}") const = LFRicConstants() @@ -3553,7 +3578,11 @@ def invoke_declarations(self): kind = api_config.default_kind["integer"] dtype = UnsupportedFortranType( f"integer(kind={kind}), pointer " - f":: {name}(:,:) => null()") + f":: {name}(:,:) => null()", + partial_datatype=ArrayType( + LFRicTypes("LFRicIntegerScalarDataType")(), + [ArrayType.Extent.DEFERRED]*2) + ) self.symtab.new_symbol( name, symbol_type=DataSymbol, @@ -3562,6 +3591,7 @@ def invoke_declarations(self): def stub_declarations(self): ''' Add declarations for any boundary-dofs arrays required by a kernel. + Note that argument order is redefined later by ArgOrdering. ''' super().stub_declarations() @@ -4353,6 +4383,8 @@ class HaloDepth(): access that is represented. :type parent: :py:class:`psyclone.psyir.nodes.Node` + :raises TypeError: if the parent argument is not a Node. + ''' def __init__(self, parent): # var_depth is used to store the PSyIR of the expression holding @@ -5420,9 +5452,10 @@ def generate_method_call(self, method, function_space=None, ''' Generate a PSyIR call to the given method of this object. - :param str method: name of the method to generate. + :param str method: name of the method to generate a call to. :param Optional[str] function_space: name of the function space. - :param bool: if we generate the call by using the proxy as the base. + :param bool use_proxy: if we generate the call by using the proxy + as the base. :returns: the generated call. :rtype: :py:class:`psyclone.psyir.nodes.Call` @@ -5437,16 +5470,17 @@ def generate_method_call(self, method, function_space=None, symbol = symtab.lookup(self.name) if self._vector_size > 1: + # For a field vector, just call the specified method on the first + # element return Call.create(ArrayOfStructuresReference.create( symbol, [Literal('1', INTEGER_TYPE)], [self.ref_name(function_space), method])) - else: - return Call.create(StructureReference.create( - symbol, [self.ref_name(function_space), method])) + return Call.create(StructureReference.create( + symbol, [self.ref_name(function_space), method])) def generate_accessor(self, function_space=None): ''' - Generate a Reference accessing this object data. + Generate a Reference accessing this object's data. :param Optional[str] function_space: name of the function space. @@ -5460,12 +5494,12 @@ def generate_accessor(self, function_space=None): symbol = symtab.lookup(self.proxy_name) if self._vector_size > 1: + # For a field vector, access the first element return ArrayOfStructuresReference.create( symbol, [Literal('1', INTEGER_TYPE)], [self.ref_name(function_space)]) - else: - return StructureReference.create( - symbol, [self.ref_name(function_space)]) + return StructureReference.create( + symbol, [self.ref_name(function_space)]) def ref_name(self, function_space=None): ''' diff --git a/src/psyclone/gen_kernel_stub.py b/src/psyclone/gen_kernel_stub.py index fe5aa4e3d0..76593d7f4b 100644 --- a/src/psyclone/gen_kernel_stub.py +++ b/src/psyclone/gen_kernel_stub.py @@ -61,12 +61,12 @@ def generate(filename, api=""): Kernel Metadata must be presented in the standard Kernel format. - :param str filename: the name of the file for which to create a \ - kernel stub for. - :param str api: the name of the API for which to create a kernel \ - stub. Must be one of the supported stub APIs. + :param str filename: the name of the file for which to create a + kernel stub for. + :param str api: the name of the API for which to create a kernel + stub. Must be one of the supported stub APIs. - :returns: the kernel stub of the given kernel file. + :returns: the kernel stub of the metadata in the given kernel file. :rtype: str :raises GenerationError: if an invalid stub API is specified. diff --git a/src/psyclone/gocean1p0.py b/src/psyclone/gocean1p0.py index 36d7427d66..c13d8ad535 100644 --- a/src/psyclone/gocean1p0.py +++ b/src/psyclone/gocean1p0.py @@ -914,18 +914,18 @@ def _validate_loop(self): f" '{kernel.index_offset}' which does " f"not match '{index_offset}'.") - def gen_code(self, parent): - ''' Create the f2pygen AST for this loop (and update the PSyIR - representing the loop bounds if necessary). + # def gen_code(self, parent): + # ''' Create the f2pygen AST for this loop (and update the PSyIR + # representing the loop bounds if necessary). - :param parent: the node in the f2pygen AST to which to add content. - :type parent: :py:class:`psyclone.f2pygen.SubroutineGen` + # :param parent: the node in the f2pygen AST to which to add content. + # :type parent: :py:class:`psyclone.f2pygen.SubroutineGen` - ''' - # Check that it is a properly formed GOLoop - self._validate_loop() + # ''' + # # Check that it is a properly formed GOLoop + # self._validate_loop() - super().gen_code(parent) + # super().gen_code(parent) # pylint: disable=too-few-public-methods diff --git a/src/psyclone/psyGen.py b/src/psyclone/psyGen.py index d4461b2cf7..e3b6831f07 100644 --- a/src/psyclone/psyGen.py +++ b/src/psyclone/psyGen.py @@ -1035,13 +1035,19 @@ def zero_reduction_variable(self): reduction variable if one exists. The latter is used for reproducible reductions, if specified. + TODO #514: This is only used by LFRic, but should be generalised, + ideally in psyir.nodes.omp/acc_directives + :raises GenerationError: if the variable to zero is not a scalar. - :raises GenerationError: if the reprod_pad_size (read from the \ - configuration file) is less than 1. - :raises GenerationError: for a reduction into a scalar that is \ - neither 'real' nor 'integer'. + :raises GenerationError: if the reprod_pad_size (read from the + configuration file) is less than 1. + :raises GenerationError: for a reduction into a scalar that is + neither 'real' nor 'integer'. ''' + # pylint: disable-next=import-outside-toplevel + from psyclone.domain.common.psylayer import PSyLoop + variable_name = self._reduction_arg.name local_var_name = self.local_reduction_name var_arg = self._reduction_arg @@ -1053,10 +1059,8 @@ def zero_reduction_variable(self): # Generate the reduction variable var_data_type = var_arg.intrinsic_type if var_data_type == "real": - data_value = "0.0" data_type = REAL_TYPE elif var_data_type == "integer": - data_value = "0" data_type = INTEGER_TYPE else: raise GenerationError( @@ -1064,13 +1068,12 @@ def zero_reduction_variable(self): f"an 'integer' scalar but found scalar of type " f"'{var_arg.intrinsic_type}'.") # Retrieve the precision information (if set) and append it - # to the initial reduction value + # to the reduction variable if var_arg.precision: kind_type = var_arg.precision else: kind_type = "" variable = self.scope.symbol_table.lookup(variable_name) - from psyclone.domain.common.psylayer import PSyLoop insert_loc = self.ancestor(PSyLoop) # If it has ancestor directive keep going up while isinstance(insert_loc.parent.parent, Directive): @@ -1079,7 +1082,7 @@ def zero_reduction_variable(self): insert_loc = insert_loc.parent new_node = Assignment.create( lhs=Reference(variable), - rhs=Literal(data_value, data_type)) + rhs=Literal("0", data_type)) insert_loc.addchild(new_node, cursor) cursor += 1 @@ -1107,7 +1110,7 @@ def zero_reduction_variable(self): assign = Assignment.create( lhs=Reference(local_var), - rhs=Literal(data_value, data_type) + rhs=Literal("0", data_type) ) insert_loc.addchild(assign, cursor) return new_node @@ -1687,7 +1690,6 @@ def _rename_psyir(self, suffix): sym._datatype = UnsupportedFortranType( new_declaration, partial_datatype=sym.datatype.partial_datatype) - # pylint: enable=protected-access break # There is only one such statement per type @property diff --git a/src/psyclone/psyir/nodes/schedule.py b/src/psyclone/psyir/nodes/schedule.py index 28dc49774d..04fc0f2a31 100644 --- a/src/psyclone/psyir/nodes/schedule.py +++ b/src/psyclone/psyir/nodes/schedule.py @@ -84,17 +84,6 @@ def __str__(self): result += "End " + self.coloured_name(False) return result - def gen_code(self, parent): - ''' - A Schedule does not have any direct Fortran representation. We just - call gen_code() for all of its children. - - :param parent: node in the f2pygen AST to which to add content. - :type parent: :py:class:`psyclone.f2pygen.BaseGen` - ''' - for child in self.children: - child.gen_code(parent) - # For AutoAPI documentation generation __all__ = ['Schedule'] diff --git a/src/psyclone/tests/domain/gocean/goloop_test.py b/src/psyclone/tests/domain/gocean/goloop_test.py index 25336674cd..ca9465cee2 100644 --- a/src/psyclone/tests/domain/gocean/goloop_test.py +++ b/src/psyclone/tests/domain/gocean/goloop_test.py @@ -55,42 +55,6 @@ API = "gocean" -def test_goloop_no_parent(): - ''' Attempt to generate code for a loop that has no GOInvokeSchedule - as a parent ''' - # Attempt to create a GOLoop within a generic Schedule - schedule = Schedule() - with pytest.raises(GenerationError) as err: - goloop = GOLoop(loop_type="inner", parent=schedule) - assert ("GOLoops must always be constructed with a parent which is inside " - "(directly or indirectly) of a GOInvokeSchedule" in str(err.value)) - - # Now create it in a GOInvokeSchedule but then detach it - schedule = GOInvokeSchedule.create('name') - goloop = GOLoop(loop_type="inner", parent=schedule) - schedule.children = [goloop] - # Now remove parent and children - goloop.detach() - - # Try and generate the code for this loop even though it - # has no parent schedule and no children - with pytest.raises(GenerationError): - goloop.gen_code(None) - - -def test_goloop_no_children(): - ''' Attempt to generate code for a loop that has no child - kernel calls ''' - gosched = GOInvokeSchedule.create('name') - goloop = GOLoop(parent=gosched, loop_type="outer") - # Try and generate the code for this loop even though it - # has no children - with pytest.raises(GenerationError) as err: - goloop.gen_code(None) - assert "Cannot find the GOcean Kernel enclosed by this loop" \ - in str(err.value) - - def test_goloop_create(monkeypatch): ''' Test that the GOLoop create method populates the relevant attributes and creates the loop children. ''' diff --git a/src/psyclone/tests/domain/lfric/lfric_kern_test.py b/src/psyclone/tests/domain/lfric/lfric_kern_test.py index 366f72e08e..c3c2237924 100644 --- a/src/psyclone/tests/domain/lfric/lfric_kern_test.py +++ b/src/psyclone/tests/domain/lfric/lfric_kern_test.py @@ -470,3 +470,16 @@ def test_undf_name(): kern = sched.walk(LFRicKern)[0] assert kern.undf_name == "undf_w1" + + +def test_argument_kinds(): + ''' Test the LFRicKern.argument_kinds property. ''' + _, invoke_info = parse(os.path.join(BASE_PATH, "1_single_invoke.f90"), + api=TEST_API) + psy = PSyFactory(TEST_API, distributed_memory=True).create(invoke_info) + sched = psy.invokes.invoke_list[0].schedule + kern = sched.walk(LFRicKern)[0] + + assert len(kern.argument_kinds) == 2 + assert "i_def" in kern.argument_kinds + assert "r_def" in kern.argument_kinds diff --git a/src/psyclone/tests/dynamo0p3_cma_test.py b/src/psyclone/tests/dynamo0p3_cma_test.py index 90b5ea4f21..bb3a61558c 100644 --- a/src/psyclone/tests/dynamo0p3_cma_test.py +++ b/src/psyclone/tests/dynamo0p3_cma_test.py @@ -1346,7 +1346,7 @@ def test_cma_asm_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_2_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_2_bandwidth,cma_op_2_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_2_bandwidth,cma_op_2_nrow,ncell_2d)\ , intent(in) :: cma_op_2 integer(kind=i_def), intent(in) :: op_1_ncell_3d real(kind=r_def), dimension(op_1_ncell_3d,ndf_adspc1_op_1,ndf_adspc2_op_1)\ @@ -1403,7 +1403,7 @@ def test_cma_asm_with_field_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_3_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ , intent(in) :: cma_op_3 real(kind=r_def), dimension(undf_aspc1_field_1), intent(in) :: \ field_1_aspc1_field_1 @@ -1458,7 +1458,7 @@ def test_cma_asm_same_fs_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_3_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ , intent(in) :: cma_op_3 real(kind=r_def), dimension(undf_aspc1_op_1), intent(in) :: \ field_2_aspc1_op_1 @@ -1519,7 +1519,7 @@ def test_cma_app_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_3_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow_1,\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow_1,\ ncell_2d), intent(in) :: cma_op_3 real(kind=r_def), dimension(undf_aspc1_field_1), intent(inout) :: \ field_1_aspc1_field_1 @@ -1575,7 +1575,7 @@ def test_cma_app_same_space_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_3_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow_1,\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow_1,\ ncell_2d), intent(in) :: cma_op_3 real(kind=r_def), dimension(undf_aspc2_field_1), intent(inout) :: \ field_1_aspc2_field_1 @@ -1637,11 +1637,11 @@ def test_cma_mul_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_3_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_1_bandwidth,cma_op_1_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_1_bandwidth,cma_op_1_nrow,ncell_2d)\ , intent(in) :: cma_op_1 - integer(kind=i_def), dimension(cma_op_2_bandwidth,cma_op_2_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_2_bandwidth,cma_op_2_nrow,ncell_2d)\ , intent(in) :: cma_op_2 - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ , intent(in) :: cma_op_3 integer(kind=i_def) :: nlayers real(kind=r_solver), pointer, dimension(:,:,:) :: cma_op_1_cma_matrix \ @@ -1703,11 +1703,11 @@ def test_cma_mul_with_scalars_stub_gen(): integer(kind=i_def), intent(in) :: cma_op_5_gamma_p integer(kind=i_def), intent(in) :: cell integer(kind=i_def), intent(in) :: ncell_2d - integer(kind=i_def), dimension(cma_op_1_bandwidth,cma_op_1_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_1_bandwidth,cma_op_1_nrow,ncell_2d)\ , intent(in) :: cma_op_1 - integer(kind=i_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_3_bandwidth,cma_op_3_nrow,ncell_2d)\ , intent(in) :: cma_op_3 - integer(kind=i_def), dimension(cma_op_5_bandwidth,cma_op_5_nrow,ncell_2d)\ + real(kind=r_def), dimension(cma_op_5_bandwidth,cma_op_5_nrow,ncell_2d)\ , intent(in) :: cma_op_5 real(kind=r_def), intent(in) :: rscalar_2 real(kind=r_def), intent(in) :: rscalar_4 diff --git a/src/psyclone/tests/psyGen_test.py b/src/psyclone/tests/psyGen_test.py index 594234a48c..8510586e63 100644 --- a/src/psyclone/tests/psyGen_test.py +++ b/src/psyclone/tests/psyGen_test.py @@ -953,6 +953,7 @@ def test_reduction_var_invalid_scalar_error(dist_mem): schedule = psy.invokes.invoke_list[0].schedule call = schedule.kernels()[0] # args[5] is a scalar of data type gh_logical + assert call.arguments.args[5].intrinsic_type == 'logical' call._reduction_arg = call.arguments.args[5] with pytest.raises(GenerationError) as err: call.zero_reduction_variable() @@ -960,6 +961,14 @@ def test_reduction_var_invalid_scalar_error(dist_mem): "or an 'integer' scalar but found scalar of type 'logical'." in str(err.value)) + # REALs and INTEGERs are fine + assert call.arguments.args[0].intrinsic_type == 'real' + call._reduction_arg = call.arguments.args[0] + call.zero_reduction_variable() + assert call.arguments.args[6].intrinsic_type == 'integer' + call._reduction_arg = call.arguments.args[6] + call.zero_reduction_variable() + def test_reduction_sum_error(dist_mem): ''' Check that we raise an exception if the reduction_sum_loop()