diff --git a/changelog b/changelog index 89082c45dd..07de3af556 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,5 @@ +release 3.0.0 6th of December 2024 + 1) PR #2477 for #2463. Add support for Fortran Namelist statements. 2) PR #2367 for #2296. Extends ModuleInfo so that it can be queried @@ -225,8 +227,8 @@ 77) PR #2708 for #2663. Add LFRic OpenACC in the integration tests. - 78) PR #2678 for #2636. Alter LFRic PSy-layer to lookup nlevels for - each kernel + 78) PR #2678 for #2636. Alter LFRic PSy-layer to lookup nlayers for + each kernel. 79) PR #2687 for #2684. Add support for WHERE constructs that contain references without range-notation (and prevent some incorrect cases). @@ -326,6 +328,15 @@ dependencies so that Sphinx markup is able to make use of the typehints that we are starting to add to the code base. + 123) PR #2809 for #2737. Updates documentation on OpenMP to point to + examples of tranformations for CPU and GPU. + + 124) PR #2815 for #2636. Get nlayers from first field or operator + argument to each kernel in LFRic. + + 125) PR #2817 for #2816. Fix index type in initialisation of arrays + of fields in PSyAD test harness construction. + release 2.5.0 14th of February 2024 1) PR #2199 for #2189. Fix bugs with missing maps in enter data diff --git a/doc/reference_guide/doxygen.config b/doc/reference_guide/doxygen.config index 565e6a85c1..6331c7a82b 100644 --- a/doc/reference_guide/doxygen.config +++ b/doc/reference_guide/doxygen.config @@ -38,7 +38,7 @@ PROJECT_NAME = "Reference Guide" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 2.5.0 +PROJECT_NUMBER = 3.0.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doc/user_guide/conf.py b/doc/user_guide/conf.py index 5a3d347029..fc493aab11 100644 --- a/doc/user_guide/conf.py +++ b/doc/user_guide/conf.py @@ -246,9 +246,10 @@ # (source start file, target name, title, author, # documentclass [howto/manual]). latex_documents = [ - ('index', 'psyclone.tex', 'PSyclone Documentation', - 'Andrew Coughtrie, Rupert Ford, Joerg Henrichs, Iva Kavcic,\\\\ ' - 'Andrew Porter, Sergi Siso and Joseph Wallwork', 'manual'), + ('index', 'psyclone.tex', 'PSyclone User Guide', + 'Oakley Brunt, Andrew Coughtrie, Rupert Ford, \\\\ ' + 'Joerg Henrichs, Iva Kavcic, Andrew Porter, Sergi Siso \\\ ' + 'and Joseph Wallwork', 'manual'), ] # Set maximum depth for the nested lists to prevent LaTeX diff --git a/doc/user_guide/dynamo0p3.rst b/doc/user_guide/dynamo0p3.rst index 70139caa60..4e8775b6cb 100644 --- a/doc/user_guide/dynamo0p3.rst +++ b/doc/user_guide/dynamo0p3.rst @@ -1938,7 +1938,7 @@ conventions, are: 2) Include ``nlayers``, the number of layers in a column. ``nlayers`` is an ``integer`` of kind ``i_def`` and has intent ``in``. PSyclone will obtain the value of ``nlayers`` to use for a particular kernel - from the first field (in the argument list) that is written to. + from the first field or operator in the argument list. 3) For each scalar/field/vector_field/operator in the order specified by the meta_args metadata: diff --git a/doc/user_guide/transformations.rst b/doc/user_guide/transformations.rst index f068be7443..adc0865b99 100644 --- a/doc/user_guide/transformations.rst +++ b/doc/user_guide/transformations.rst @@ -148,11 +148,6 @@ can be found in the API-specific sections). :members: apply :noindex: -.. warning:: This transformation assumes that the ABS Intrinsic acts on - PSyIR Real scalar data and does not check that this is - not the case. Once issue #658 is on master then this - limitation can be fixed. - #### .. autoclass:: psyclone.transformations.ACCDataTrans @@ -461,11 +456,6 @@ can be found in the API-specific sections). :members: apply :noindex: -.. warning:: This transformation assumes that the SIGN Intrinsic acts - on PSyIR Real scalar data and does not check whether or not - this is the case. Once issue #658 is on master then this - limitation can be fixed. - #### .. autoclass:: psyclone.psyir.transformations.Sum2LoopTrans @@ -844,9 +834,13 @@ transformations currently supported allow the addition of: The generic versions of these transformations (i.e. ones that theoretically work for all APIs) were given in the -:ref:`sec_transformations_available` section. The API-specific versions -of these transformations are described in the API-specific sections of -this document. +:ref:`sec_transformations_available` section. Examples of their use, +for both CPU and offload to GPU, may be found in the +``PSyclone/examples/nemo/scripts/omp_?pu_trans.py`` transformation scripts. + +The API-specific versions of these transformations are described in the +API-specific sections of this document. Examples for the LFRic API may +be found in ``PSyclone/examples/lfric/scripts``. .. _openmp-reductions: diff --git a/psyclone.pdf b/psyclone.pdf index 52bd098e3a..3fa4af129f 100644 Binary files a/psyclone.pdf and b/psyclone.pdf differ diff --git a/src/psyclone/domain/lfric/kern_call_arg_list.py b/src/psyclone/domain/lfric/kern_call_arg_list.py index 26c8729bc1..dbde419901 100644 --- a/src/psyclone/domain/lfric/kern_call_arg_list.py +++ b/src/psyclone/domain/lfric/kern_call_arg_list.py @@ -236,7 +236,7 @@ def mesh_height(self, var_accesses=None): ''' if self._kern.iterates_over == "dof": return - name = f"nlayers_{self._kern.arguments.iteration_space_arg().name}" + name = f"nlayers_{self._kern.arguments.first_field_or_operator.name}" nlayers_symbol = self.append_integer_reference(name, tag=name) self.append(nlayers_symbol.name, var_accesses) self._nlayers_positions.append(self.num_args) diff --git a/src/psyclone/domain/lfric/lfric_cell_iterators.py b/src/psyclone/domain/lfric/lfric_cell_iterators.py index b7d1b37c98..bc0a46b6fb 100644 --- a/src/psyclone/domain/lfric/lfric_cell_iterators.py +++ b/src/psyclone/domain/lfric/lfric_cell_iterators.py @@ -77,13 +77,14 @@ def __init__(self, kern_or_invoke): return # Each kernel that operates on either the domain or cell-columns needs - # an 'nlayers' obtained from the first written field/operator argument. + # an 'nlayers' obtained from the first field/operator argument. for kern in self._invoke.schedule.walk(LFRicKern): if kern.iterates_over != "dof": - arg = kern.arguments.iteration_space_arg() - self._nlayers_names[self._symbol_table.find_or_create_tag( + arg = kern.arguments.first_field_or_operator + sym = self._symbol_table.find_or_create_tag( f"nlayers_{arg.name}", - symbol_type=LFRicTypes("MeshHeightDataSymbol")).name] = arg + symbol_type=LFRicTypes("MeshHeightDataSymbol")) + self._nlayers_names[sym.name] = arg first_var = None for var in self._invoke.psy_unique_vars: diff --git a/src/psyclone/dynamo0p3.py b/src/psyclone/dynamo0p3.py index c1df8df527..5625d2d789 100644 --- a/src/psyclone/dynamo0p3.py +++ b/src/psyclone/dynamo0p3.py @@ -4993,6 +4993,24 @@ def unique_fs_names(self): specified in the kernel metadata) ''' return self._unique_fs_names + @property + def first_field_or_operator(self): + ''' + :returns: the first field or operator argument in the list. + :rtype: :py:class:`psyclone.dynamo0p3.DynKernelArgument` + + :raises InternalError: if no field or operator argument is found. + + ''' + for arg in self._args: + arg: DynKernelArgument + if arg.is_field or arg.is_operator: + return arg + + raise InternalError( + f"Invalid LFRic kernel: failed to find a DynKernelArgument that is" + f" a field or operator in '{self.names}'.") + def iteration_space_arg(self): ''' Returns an argument we can use to dereference the iteration diff --git a/src/psyclone/psyad/domain/lfric/lfric_adjoint_harness.py b/src/psyclone/psyad/domain/lfric/lfric_adjoint_harness.py index 744ddec470..41541f3bef 100644 --- a/src/psyclone/psyad/domain/lfric/lfric_adjoint_harness.py +++ b/src/psyclone/psyad/domain/lfric/lfric_adjoint_harness.py @@ -266,7 +266,7 @@ def _init_fields_random(fields, input_symbols, table): ''' idef_sym = table.add_lfric_precision_symbol("i_def") - idef_type = ScalarType(ScalarType.Intrinsic.REAL, idef_sym) + idef_type = ScalarType(ScalarType.Intrinsic.INTEGER, idef_sym) # We use the setval_random builtin to initialise all fields. kernel_list = [] builtin_factory = LFRicBuiltinFunctorFactory.get() diff --git a/src/psyclone/tests/domain/lfric/arg_ordering_test.py b/src/psyclone/tests/domain/lfric/arg_ordering_test.py index 8af75fd1bf..cb97f46479 100644 --- a/src/psyclone/tests/domain/lfric/arg_ordering_test.py +++ b/src/psyclone/tests/domain/lfric/arg_ordering_test.py @@ -280,7 +280,7 @@ def test_arg_ordering_generate_cma_kernel(dist_mem, fortran_writer): assert not create_arg_list._arglist create_arg_list.generate() assert create_arg_list._arglist == [ - 'cell', 'nlayers_cma_op1', 'ncell_2d', 'lma_op1_proxy%ncell_3d', + 'cell', 'nlayers_lma_op1', 'ncell_2d', 'lma_op1_proxy%ncell_3d', 'lma_op1_local_stencil', 'cma_op1_cma_matrix', 'cma_op1_nrow', 'cma_op1_ncol', 'cma_op1_bandwidth', 'cma_op1_alpha', 'cma_op1_beta', 'cma_op1_gamma_m', 'cma_op1_gamma_p', 'ndf_adspc1_lma_op1', diff --git a/src/psyclone/tests/domain/lfric/kern_call_arg_list_test.py b/src/psyclone/tests/domain/lfric/kern_call_arg_list_test.py index 1e2607b26c..d217d0e1fc 100644 --- a/src/psyclone/tests/domain/lfric/kern_call_arg_list_test.py +++ b/src/psyclone/tests/domain/lfric/kern_call_arg_list_test.py @@ -110,7 +110,7 @@ def test_cellmap_intergrid(dist_mem, fortran_writer): assert Signature("cell_map_field2") in vai assert create_arg_list._arglist == [ - 'nlayers_field2', 'cell_map_field2(:,:,cell)', 'ncpc_field1_field2_x', + 'nlayers_field1', 'cell_map_field2(:,:,cell)', 'ncpc_field1_field2_x', 'ncpc_field1_field2_y', 'ncell_field1', 'field1_data', 'field2_data', 'ndf_w1', 'undf_w1', 'map_w1', 'undf_w2', 'map_w2(:,cell)'] diff --git a/src/psyclone/tests/domain/lfric/lfric_domain_kernels_test.py b/src/psyclone/tests/domain/lfric/lfric_domain_kernels_test.py index bfaa17ad61..f2cc56934e 100644 --- a/src/psyclone/tests/domain/lfric/lfric_domain_kernels_test.py +++ b/src/psyclone/tests/domain/lfric/lfric_domain_kernels_test.py @@ -441,7 +441,7 @@ def test_domain_plus_cma_kernels(dist_mem, tmpdir): assert "ncell_2d_no_halos = mesh%get_last_edge_cell()" in gen_code assert ("call testkern_domain_code(nlayers_f1, ncell_2d_no_halos, b, " "f1_data, ndf_w3, undf_w3, map_w3)" in gen_code) - assert ("call columnwise_op_asm_kernel_code(cell, nlayers_cma_op1, " + assert ("call columnwise_op_asm_kernel_code(cell, nlayers_lma_op1, " "ncell_2d, lma_op1_proxy%ncell_3d," in gen_code) assert LFRicBuild(tmpdir).code_compiles(psy) diff --git a/src/psyclone/tests/domain/lfric/lfric_field_codegen_test.py b/src/psyclone/tests/domain/lfric/lfric_field_codegen_test.py index 8cbe0219c3..962e915590 100644 --- a/src/psyclone/tests/domain/lfric/lfric_field_codegen_test.py +++ b/src/psyclone/tests/domain/lfric/lfric_field_codegen_test.py @@ -612,7 +612,7 @@ def test_int_field_fs(tmpdir): "f4, m3, m4, f5, f6, m5, m6, f7, f8, m7\n" " INTEGER(KIND=i_def) cell\n" " INTEGER(KIND=i_def) loop0_start, loop0_stop\n" - " INTEGER(KIND=i_def) nlayers_f2\n" + " INTEGER(KIND=i_def) nlayers_f1\n" " INTEGER(KIND=i_def), pointer, dimension(:) :: m7_data => " "null()\n" " INTEGER(KIND=i_def), pointer, dimension(:) :: f8_data => " @@ -699,7 +699,7 @@ def test_int_field_fs(tmpdir): " !\n" " ! Initialise number of layers\n" " !\n" - " nlayers_f2 = f2_proxy%vspace%get_nlayers()\n" + " nlayers_f1 = f1_proxy%vspace%get_nlayers()\n" " !\n" " ! Create a mesh object\n" " !\n" @@ -849,7 +849,7 @@ def test_int_field_fs(tmpdir): " CALL m7_proxy%halo_exchange(depth=1)\n" " END IF\n" " DO cell = loop0_start, loop0_stop, 1\n" - " CALL testkern_fs_int_field_code(nlayers_f2, f1_data, " + " CALL testkern_fs_int_field_code(nlayers_f1, f1_data, " "f2_data, m1_data, m2_data, f3_data, " "f4_data, m3_data, m4_data, f5_data, " "f6_data, m5_data, m6_data, f7_data, " @@ -993,7 +993,7 @@ def test_int_real_field_fs(dist_mem, tmpdir): " INTEGER(KIND=i_def) cell\n" " INTEGER(KIND=i_def) loop1_start, loop1_stop\n" " INTEGER(KIND=i_def) loop0_start, loop0_stop\n" - " INTEGER(KIND=i_def) nlayers_f1, nlayers_i2\n" + " INTEGER(KIND=i_def) nlayers_f1, nlayers_i1\n" " INTEGER(KIND=i_def), pointer, dimension(:) :: n7_data => " "null()\n" " INTEGER(KIND=i_def), pointer, dimension(:) :: i8_data => " @@ -1051,7 +1051,7 @@ def test_int_real_field_fs(dist_mem, tmpdir): " ! Initialise number of layers\n" " !\n" " nlayers_f1 = f1_proxy%vspace%get_nlayers()\n" - " nlayers_i2 = i2_proxy%vspace%get_nlayers()\n" + " nlayers_i1 = i1_proxy%vspace%get_nlayers()\n" " !\n") if dist_mem: output += ( @@ -1081,7 +1081,7 @@ def test_int_real_field_fs(dist_mem, tmpdir): assert output in generated_code # Kernel calls are the same regardless of distributed memory kern1_call = ( - " CALL testkern_fs_int_field_code(nlayers_i2, i1_data, " + " CALL testkern_fs_int_field_code(nlayers_i1, i1_data, " "i2_data, n1_data, n2_data, i3_data, " "i4_data, n3_data, n4_data, i5_data, " "i6_data, n5_data, n6_data, i7_data, " diff --git a/src/psyclone/tests/domain/lfric/transformations/dynamo0p3_transformations_test.py b/src/psyclone/tests/domain/lfric/transformations/dynamo0p3_transformations_test.py index f320b545f0..95ffb68460 100644 --- a/src/psyclone/tests/domain/lfric/transformations/dynamo0p3_transformations_test.py +++ b/src/psyclone/tests/domain/lfric/transformations/dynamo0p3_transformations_test.py @@ -312,7 +312,7 @@ def test_colour_trans_cma_operator(tmpdir, dist_mem): assert ( " CALL columnwise_op_asm_field_kernel_code(cmap(colour," - "cell), nlayers_cma_op1, ncell_2d, afield_data, " + "cell), nlayers_afield, ncell_2d, afield_data, " "lma_op1_proxy%ncell_3d, lma_op1_local_stencil, " "cma_op1_cma_matrix(:,:,:), cma_op1_nrow, " "cma_op1_ncol, cma_op1_bandwidth, " @@ -1380,7 +1380,7 @@ def test_loop_fuse_cma(tmpdir, dist_mem): " cma_op1_gamma_p = cma_op1_proxy%gamma_p\n" ) in code assert ( - "CALL columnwise_op_asm_field_kernel_code(cell, nlayers_cma_op1, " + "CALL columnwise_op_asm_field_kernel_code(cell, nlayers_afield, " "ncell_2d, afield_data, lma_op1_proxy%ncell_3d, " "lma_op1_local_stencil, cma_op1_cma_matrix(:,:,:), cma_op1_nrow, " "cma_op1_ncol, cma_op1_bandwidth, cma_op1_alpha, cma_op1_beta, " @@ -6364,7 +6364,7 @@ def test_intergrid_colour(dist_mem, trans_class, tmpdir): "(colour), 1\n") assert expected in gen expected = ( - " call prolong_test_kernel_code(nlayers_fld_m, cell_map_fld_m" + " call prolong_test_kernel_code(nlayers_fld_f, cell_map_fld_m" "(:,:,cmap_fld_m(colour,cell)), ncpc_fld_f_fld_m_x, " "ncpc_fld_f_fld_m_y, ncell_fld_f, fld_f_data, fld_m_data, " "ndf_w1, undf_w1, map_w1, undf_w2, " @@ -6478,7 +6478,7 @@ def test_intergrid_omp_para_region1(dist_mem, tmpdir): f" !$omp parallel default(shared), private(cell)\n" f" !$omp do schedule(static)\n" f" DO cell = loop1_start, {upper_bound}, 1\n" - f" CALL prolong_test_kernel_code(nlayers_cmap_fld_c, " + f" CALL prolong_test_kernel_code(nlayers_fld_m, " f"cell_map_cmap_fld_c(:,:,cmap_cmap_fld_c(colour,cell)), " f"ncpc_fld_m_cmap_fld_c_x, ncpc_fld_m_cmap_fld_c_y, ncell_fld_m, " f"fld_m_data, cmap_fld_c_data, ndf_w1, undf_w1, " diff --git a/src/psyclone/tests/dynamo0p3_basis_test.py b/src/psyclone/tests/dynamo0p3_basis_test.py index 3c03449d79..9a75940370 100644 --- a/src/psyclone/tests/dynamo0p3_basis_test.py +++ b/src/psyclone/tests/dynamo0p3_basis_test.py @@ -1096,7 +1096,7 @@ def test_two_eval_op_to_space(tmpdir): "ndf_w1, undf_w1, map_w1(:,cell), diff_basis_w1_on_w0)\n" " END DO\n" " DO cell = loop1_start, loop1_stop, 1\n" - " CALL testkern_eval_op_to_code(cell, nlayers_f2, " + " CALL testkern_eval_op_to_code(cell, nlayers_op1, " "op1_proxy%ncell_3d, op1_local_stencil, f2_data, " "ndf_w2, basis_w2_on_w3, diff_basis_w2_on_w3, ndf_w0, ndf_w3, " "undf_w3, map_w3(:,cell), diff_basis_w3_on_w3)\n" @@ -1189,13 +1189,13 @@ def test_eval_diff_nodal_space(tmpdir): expected_kern_call = ( " DO cell = loop0_start, loop0_stop, 1\n" - " CALL testkern_eval_op_to_code(cell, nlayers_f1, " + " CALL testkern_eval_op_to_code(cell, nlayers_op2, " "op2_proxy%ncell_3d, op2_local_stencil, f1_data, " "ndf_w2, basis_w2_on_w3, diff_basis_w2_on_w3, ndf_w0, ndf_w3, " "undf_w3, map_w3(:,cell), diff_basis_w3_on_w3)\n" " END DO\n" " DO cell = loop1_start, loop1_stop, 1\n" - " CALL testkern_eval_op_to_w0_code(cell, nlayers_f2, " + " CALL testkern_eval_op_to_w0_code(cell, nlayers_op1, " "op1_proxy%ncell_3d, op1_local_stencil, f0_data, " "f2_data, ndf_w2, basis_w2_on_w0, diff_basis_w2_on_w0, " "ndf_w0, undf_w0, map_w0(:,cell), ndf_w3, undf_w3, map_w3(:,cell), " diff --git a/src/psyclone/tests/dynamo0p3_cma_test.py b/src/psyclone/tests/dynamo0p3_cma_test.py index 6c0fa0af85..ce2a3b3e41 100644 --- a/src/psyclone/tests/dynamo0p3_cma_test.py +++ b/src/psyclone/tests/dynamo0p3_cma_test.py @@ -838,7 +838,7 @@ def test_cma_asm(tmpdir, dist_mem): "=> null(), cbanded_map_adspc2_lma_op1(:,:) => null()") in code assert "ncell_2d = mesh%get_ncells_2d" in code assert "cma_op1_proxy = cma_op1%get_proxy()" in code - assert ("CALL columnwise_op_asm_kernel_code(cell, nlayers_cma_op1, " + assert ("CALL columnwise_op_asm_kernel_code(cell, nlayers_lma_op1, " "ncell_2d, lma_op1_proxy%ncell_3d, lma_op1_local_stencil, " "cma_op1_cma_matrix(:,:,:), cma_op1_nrow, cma_op1_ncol, " "cma_op1_bandwidth, cma_op1_alpha, cma_op1_beta, cma_op1_gamma_m, " @@ -877,7 +877,7 @@ def test_cma_asm_field(tmpdir, dist_mem): assert "ncell_2d = mesh%get_ncells_2d()" in code assert "cma_op1_proxy = cma_op1%get_proxy()" in code expected = ( - "CALL columnwise_op_asm_field_kernel_code(cell, nlayers_cma_op1, " + "CALL columnwise_op_asm_field_kernel_code(cell, nlayers_afield, " "ncell_2d, afield_data, lma_op1_proxy%ncell_3d, " "lma_op1_local_stencil, cma_op1_cma_matrix(:,:,:), cma_op1_nrow, " "cma_op1_ncol, cma_op1_bandwidth, cma_op1_alpha, cma_op1_beta, " @@ -920,7 +920,7 @@ def test_cma_asm_scalar(dist_mem, tmpdir): assert "ncell_2d = mesh%get_ncells_2d()" in code assert "cma_op1_proxy = cma_op1%get_proxy()" in code expected = ("CALL columnwise_op_asm_kernel_scalar_code(cell, " - "nlayers_cma_op1, ncell_2d, lma_op1_proxy%ncell_3d, " + "nlayers_lma_op1, ncell_2d, lma_op1_proxy%ncell_3d, " "lma_op1_local_stencil, cma_op1_cma_matrix(:,:,:), " "cma_op1_nrow, cma_op1_ncol, cma_op1_bandwidth, " "cma_op1_alpha_1, cma_op1_beta, cma_op1_gamma_m, " @@ -971,7 +971,7 @@ def test_cma_asm_field_same_fs(dist_mem, tmpdir): assert "loop0_stop = cma_op1_proxy%fs_from%get_ncell()\n" in code assert "DO cell = loop0_start, loop0_stop, 1\n" in code expected = ("CALL columnwise_op_asm_same_fs_kernel_code(cell, " - "nlayers_cma_op1, ncell_2d, lma_op1_proxy%ncell_3d, " + "nlayers_lma_op1, ncell_2d, lma_op1_proxy%ncell_3d, " "lma_op1_local_stencil, afield_data, " "cma_op1_cma_matrix(:,:,:), cma_op1_nrow, cma_op1_bandwidth, " "cma_op1_alpha, cma_op1_beta, cma_op1_gamma_m, " @@ -1274,7 +1274,7 @@ def test_cma_multi_kernel(tmpdir, dist_mem): " loop2_stop = cma_opc_proxy%fs_from%get_ncell()\n" in code) - assert ("CALL columnwise_op_asm_field_kernel_code(cell, nlayers_cma_op1, " + assert ("CALL columnwise_op_asm_field_kernel_code(cell, nlayers_afield, " "ncell_2d, afield_data, lma_op1_proxy%ncell_3d, " "lma_op1_local_stencil, cma_op1_cma_matrix(:,:,:), cma_op1_nrow, " "cma_op1_ncol, cma_op1_bandwidth, cma_op1_alpha, cma_op1_beta, " diff --git a/src/psyclone/tests/dynamo0p3_multigrid_test.py b/src/psyclone/tests/dynamo0p3_multigrid_test.py index efc25cb0d8..3d5d490c9f 100644 --- a/src/psyclone/tests/dynamo0p3_multigrid_test.py +++ b/src/psyclone/tests/dynamo0p3_multigrid_test.py @@ -355,7 +355,7 @@ def test_field_prolong(tmpdir, dist_mem): assert "loop0_stop = field2_proxy%vspace%get_ncell()\n" in gen_code expected = ( - " CALL prolong_test_kernel_code(nlayers_field2, " + " CALL prolong_test_kernel_code(nlayers_field1, " "cell_map_field2(:,:,cell), ncpc_field1_field2_x, " "ncpc_field1_field2_y, ncell_field1, field1_data, " "field2_data, ndf_w1, undf_w1, map_w1, undf_w2, " @@ -662,14 +662,14 @@ def test_restrict_prolong_chain(tmpdir, dist_mem): assert "loop3_stop = cmap_fld_c_proxy%vspace%get_ncell()\n" in output expected = ( " DO cell = loop0_start, loop0_stop, 1\n" - " CALL prolong_test_kernel_code(nlayers_cmap_fld_c, " + " CALL prolong_test_kernel_code(nlayers_fld_m, " "cell_map_cmap_fld_c(:,:,cell), ncpc_fld_m_cmap_fld_c_x, " "ncpc_fld_m_cmap_fld_c_y, ncell_fld_m, fld_m_data, " "cmap_fld_c_data, ndf_w1, undf_w1, map_w1, undf_w2, " "map_w2(:,cell))\n" " END DO\n" " DO cell = loop1_start, loop1_stop, 1\n" - " CALL prolong_test_kernel_code(nlayers_fld_m, " + " CALL prolong_test_kernel_code(nlayers_fld_f, " "cell_map_fld_m(:,:,cell), ncpc_fld_f_fld_m_x, ncpc_fld_f_fld_m_y," " ncell_fld_f, fld_f_data, fld_m_data, ndf_w1, undf_w1, map_w1, " "undf_w2, map_w2(:,cell))\n" diff --git a/src/psyclone/tests/dynamo0p3_test.py b/src/psyclone/tests/dynamo0p3_test.py index 76721031e2..01000ca360 100644 --- a/src/psyclone/tests/dynamo0p3_test.py +++ b/src/psyclone/tests/dynamo0p3_test.py @@ -53,7 +53,8 @@ from psyclone.domain.lfric.transformations import LFRicLoopFuseTrans from psyclone.dynamo0p3 import ( DynACCEnterDataDirective, DynBoundaryConditions, DynGlobalSum, - DynKernelArguments, DynProxies, HaloReadAccess, KernCallArgList) + DynKernelArgument, DynKernelArguments, DynProxies, HaloReadAccess, + KernCallArgList) from psyclone.errors import FieldNotFoundError, GenerationError, InternalError from psyclone.f2pygen import ModuleGen from psyclone.gen_kernel_stub import generate @@ -464,7 +465,7 @@ def test_op_any_discontinuous_space_1(tmpdir): assert "ndf_adspc3_op4 = op4_proxy%fs_to%get_ndf()" in generated_code assert "ndf_adspc7_op4 = op4_proxy%fs_from%get_ndf()" in generated_code assert ("CALL testkern_any_discontinuous_space_op_1_code(cell, " - "nlayers_op4, f1_1_data, f1_2_data, f1_3_data, " + "nlayers_f1, f1_1_data, f1_2_data, f1_3_data, " "f2_data, op3_proxy%ncell_3d, op3_local_stencil, " "op4_proxy%ncell_3d, op4_local_stencil, rdt, " "ndf_adspc1_f1, undf_adspc1_f1, map_adspc1_f1(:,cell), " @@ -3058,6 +3059,25 @@ def test_kernel_args_has_op(): assert "'op_type' must be a valid operator type" in str(excinfo.value) +def test_dynkernelargs_first_field_or_op(monkeypatch): + '''Test the first_field_or_operator property of DynKernelArguments.''' + _, invoke_info = parse( + os.path.join(BASE_PATH, "19.1_single_stencil.f90"), + api=TEST_API) + # Find the parsed code's Call class + call = invoke_info.calls[0].kcalls[0] + dka = DynKernelArguments(call, None) + arg = dka.first_field_or_operator + assert isinstance(arg, DynKernelArgument) + assert arg.is_field + # Monkeypatch the argument list to make it invalid. + monkeypatch.setattr(dka, "_args", []) + with pytest.raises(InternalError) as err: + dka.first_field_or_operator + assert ("Invalid LFRic kernel: failed to find a DynKernelArgument that is " + "a field or operator in ''" in str(err.value)) + + def test_kerncallarglist_quad_rule_error(dist_mem, tmpdir): ''' Check that we raise the expected exception if we encounter an unsupported quadrature shape in the quad_rule() method. ''' diff --git a/src/psyclone/tests/generator_test.py b/src/psyclone/tests/generator_test.py index 8511945aae..cb9da93c8b 100644 --- a/src/psyclone/tests/generator_test.py +++ b/src/psyclone/tests/generator_test.py @@ -701,7 +701,10 @@ def test_main_profile(capsys): main(options+["--profile", filename]) _, outerr = capsys.readouterr() - correct_re = "invalid choice.*choose from 'invokes', 'routines', 'kernels'" + # regex is slightly complicated to allow for changes in the formatting + # of the message between versions of argparse. + correct_re = ("invalid choice[.:].*choose from '?invokes'?, " + "'?routines'?, '?kernels'?") assert re.search(correct_re, outerr) is not None # Check for invalid parameter diff --git a/src/psyclone/tests/psyad/domain/lfric/test_lfric_adjoint_harness.py b/src/psyclone/tests/psyad/domain/lfric/test_lfric_adjoint_harness.py index f85b0193d7..6361797a09 100644 --- a/src/psyclone/tests/psyad/domain/lfric/test_lfric_adjoint_harness.py +++ b/src/psyclone/tests/psyad/domain/lfric/test_lfric_adjoint_harness.py @@ -249,7 +249,7 @@ def test_init_fields_random_vector(type_map): ''' table = LFRicSymbolTable() idef_sym = table.add_lfric_precision_symbol("i_def") - idef_type = ScalarType(ScalarType.Intrinsic.REAL, idef_sym) + idef_type = ScalarType(ScalarType.Intrinsic.INTEGER, idef_sym) fld_type = DataTypeSymbol(type_map["field"]["type"], datatype=UnresolvedType()) diff --git a/src/psyclone/version.py b/src/psyclone/version.py index aec663cd67..ecc254c3f9 100644 --- a/src/psyclone/version.py +++ b/src/psyclone/version.py @@ -33,14 +33,15 @@ # ----------------------------------------------------------------------------- # Author: A. R. Porter, STFC Daresbury Laboratory # Modified by R. W. Ford and N. Nobre, STFC Daresbury Lab +# Modified by J. Henrichs, Bureau of Meteorology ''' Single location for the current version number of PSyclone. This is used in setup.py and doc/{user_guide,developer_guide,reference_guide/source}/conf.py ''' -__MAJOR__ = 2 -__MINOR__ = 5 -__MICRO__ = 0 +__MAJOR__ = 3 +__MINOR__ = 0 +__MICRO__ = 1 -__SHORT_VERSION__ = f"{__MAJOR__:d}.{__MINOR__:d}" -__VERSION__ = f"{__MAJOR__:d}.{__MINOR__:d}.{__MICRO__:d}" +__SHORT_VERSION__ = f"{__MAJOR__:d}.{__MINOR__:d}-dev" +__VERSION__ = f"{__MAJOR__:d}.{__MINOR__:d}.{__MICRO__:d}-dev"