diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml index 296e259e04..36fa1b4b67 100644 --- a/.github/workflows/linkcheck.yml +++ b/.github/workflows/linkcheck.yml @@ -4,7 +4,8 @@ jobs: check-links: if: ${{ github.repository != 'stfc/PSyclone-mirror' }} name: Run linkspector - runs-on: ubuntu-latest + # TODO 2838: linkspector doesn't support ubuntu-latest at the moment. + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Run linkspector diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 6ebc56ae5a..f893e99ea9 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -1,7 +1,7 @@ # ----------------------------------------------------------------------------- # BSD 3-Clause License # -# Copyright (c) 2020-2024, Science and Technology Facilities Council. +# Copyright (c) 2020-2025, Science and Technology Facilities Council. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ # Modified by A. J. Voysey, Met Office # Modified by J. Henrichs, Bureau of Meteorology # Modified by N. Nobre, STFC Daresbury Lab +# Modified by A. B. G. Chalk, STFC Daresbury Lab # This workflow will install Python dependencies, run tests and lint with a # variety of Python versions. @@ -103,7 +104,8 @@ jobs: - run: cd doc/developer_guide; make html; make doctest build: if: ${{ github.repository != 'stfc/PSyclone-mirror' }} - runs-on: ubuntu-latest + # TODO 2837: Switch to ubuntu-latest once Python 3.7 support is removed. + runs-on: ubuntu-22.04 strategy: matrix: python-version: [3.7, 3.8, 3.13] diff --git a/changelog b/changelog index bc8831520e..33db29bebe 100644 --- a/changelog +++ b/changelog @@ -13,6 +13,17 @@ AST tree. There are two new FortranReader arguments to select the behaviour for comments and directives (by default they are not parsed). + 5) PR #2836 for #2835. Reverts GHA to use Ubuntu 22.04 as python-3.7 + not available in ubuntu-latest and linkspector is also broken. + + 6) PR #2820 for #2773. Adds support for the Vernier timing library. + + 7) PR #2840 for #2839. Raise error in FortranReader if ignore_directives + is True but ignore_comments is True. + + 8) PR #2832 for #2831. Reorders the arguments to the parser to meet best + practices. + release 3.0.0 6th of December 2024 1) PR #2477 for #2463. Add support for Fortran Namelist statements. diff --git a/doc/developer_guide/psy_data.rst b/doc/developer_guide/psy_data.rst index d13d9b80d8..f947fbebb8 100644 --- a/doc/developer_guide/psy_data.rst +++ b/doc/developer_guide/psy_data.rst @@ -72,8 +72,8 @@ the same time as checking that read-only values are indeed not modified, different module names and data types must be used. PSyData divides its application into different classes. For example, -the class "profile" is used for all profiling tools (e.g. TAU, DrHook or the -NVIDIA profiling tools). This class name is used as a prefix for +the class "profile" is used for all profiling tools (e.g. TAU, Vernier, +DrHook, or the NVIDIA profiling tools). This class name is used as a prefix for the module name, the ``PSyDataType`` and functions. So if a profiling application is linked the above code will actually look like this:: @@ -101,7 +101,7 @@ The class prefixes supported at the moment are: Class Prefix Description ======================= ======================================================= profile All libraries related to profiling tools like TAU, - DrHook, NVIDIA's profiling tools etc. See + DrHook, NVIDIA's profiling tools, Vernier etc. See :ref:`user_guide:profiling` for details. extract For libraries used for kernel data extraction. See :ref:`user_guide:psyke` for details. @@ -970,7 +970,7 @@ by storing pointers to the profiling data to be able to print all results in a ProfileFinalise() subroutine. Some of the wrapper libraries use the PSyData base class (e.g. dl_timer, simple_timing, template), others do not (e.g. NVIDIA profiling, TAU, -DrHook wrapper). +Vernier, DrHook wrapper). .. _psyke: diff --git a/doc/user_guide/profiling.rst b/doc/user_guide/profiling.rst index 9755d1b088..fb65a5b895 100644 --- a/doc/user_guide/profiling.rst +++ b/doc/user_guide/profiling.rst @@ -51,9 +51,9 @@ transformation within a transformation script. PSyclone can be used with a variety of existing profiling tools. -It currently supports dl_timer, TAU, Dr Hook, the NVIDIA GPU profiling -tools and it comes with a simple stand-alone timer library. The -:ref:`PSyData API ` (see also the +It currently supports dl_timer, TAU, Vernier, Dr Hook, the NVIDIA GPU +profiling tools and it comes with a simple stand-alone timer library. +The :ref:`PSyData API ` (see also the :ref:`Developer Guide `) is utilised to implement wrapper libraries that connect the PSyclone application to the profiling libraries. Certain adjustments to @@ -77,8 +77,8 @@ Interface to Third Party Profiling Tools ---------------------------------------- PSyclone comes with :ref:`wrapper libraries ` to support -usage of TAU, Dr Hook, dl_timer, NVTX (NVIDIA Tools Extension library), -and a simple non-thread-safe timing library. Support for further +usage of TAU, Vernier, Dr Hook, dl_timer, NVTX (NVIDIA Tools Extension +library), and a simple non-thread-safe timing library. Support for further profiling libraries will be added in the future. To compile the wrapper libraries, change into the directory ``lib/profiling`` of PSyclone and type ``make`` to compile all wrappers. If only @@ -107,23 +107,29 @@ libraries that come with PSyclone: ``lib/profiling/dl_timer`` This wrapper uses the apeg-dl_timer library. In order to use this wrapper, you must download and install the dl_timer library - from ``https://bitbucket.org/apeg/dl_timer``. This library has + from https://bitbucket.org/apeg/dl_timer. This library has various compile-time options and may be built with MPI or OpenMP support. Additional link options might therefore be required (e.g. enabling OpenMP, or linking with MPI). ``lib/profiling/tau`` This wrapper uses TAU profiling and tracing toolkit. It can be - downloaded from ``https://www.cs.uoregon.edu/research/tau``. + downloaded from https://www.cs.uoregon.edu/research/tau. ``lib/profiling/drhook`` This wrapper uses the Dr Hook library. You need to contact ECMWF to obtain a copy of Dr Hook. +``lib/profiling/vernier`` + This wrapper uses the UK Met Office's Vernier library. It can be + downloaded from https://github.com/MetOffice/Vernier. This + library writes its output to files ``vernier-out-``, and + will overwrite existing output files. + ``lib/profiling/nvidia`` This is a wrapper library that maps the PSyclone profiling API to the NVIDIA Tools Extension library (NVTX). This library is - available from ``https://developer.nvidia.com/cuda-toolkit``. + available from https://developer.nvidia.com/cuda-toolkit. ``lib/profiling/lfric_timer`` This profile wrapper uses the timer functionality provided by diff --git a/doc/user_guide/tutorials_and_examples.rst b/doc/user_guide/tutorials_and_examples.rst index e29c13383d..6a56b0c250 100644 --- a/doc/user_guide/tutorials_and_examples.rst +++ b/doc/user_guide/tutorials_and_examples.rst @@ -317,7 +317,7 @@ Example 5.2: Profiling This example shows how to use the profiling support in PSyclone. It instruments two invoke statements and can link in with any of the following profiling wrapper libraries: template, -simple_timer, dl_timer, TAU, and DrHook (see +simple_timer, dl_timer, TAU, Vernier, and DrHook (see :ref:`profiling_third_party_tools`). The ``README.md`` file contains detailed instructions on how to build the different executables. By default (i.e. just using ``make`` diff --git a/examples/gocean/eg5/profile/.gitignore b/examples/gocean/eg5/profile/.gitignore index 59e6b0edc8..418b50f206 100644 --- a/examples/gocean/eg5/profile/.gitignore +++ b/examples/gocean/eg5/profile/.gitignore @@ -2,3 +2,4 @@ alg.f90 psy.f90 profile_test* timer.txt +vernier-output-* diff --git a/examples/gocean/eg5/profile/Makefile b/examples/gocean/eg5/profile/Makefile index 923282f227..190c94003b 100644 --- a/examples/gocean/eg5/profile/Makefile +++ b/examples/gocean/eg5/profile/Makefile @@ -87,6 +87,16 @@ drhook: PROFILE_LINK="-L $(DRHOOK_DIR)/build/lib -ldrhook" \ drhook_lib $(NAME).drhook +# Needs to additionally link with the Vernier library +# As default assume Vernier is installed 'next' to PSyclone +VERNIER_DIR?=$(ROOT_DIR)/../Vernier +vernier: + $(MAKE) WRAPPER_DIR="$(PROFILE_DIR)/vernier" \ + WRAPPER_NAME="vernier_psy" \ + PROFILE_LINK="-L $(VERNIER_DIR)/local/lib \ + -lvernier_f -lvernier_c -lvernier" \ + $(NAME).vernier + TAU_DIR?=$(ROOT_DIR)/../tau # By adding the dependency to INF_LIB here, we will be invoking the original # compiler, not tau_f90.sh (since we don't want to instrument the whole @@ -146,6 +156,9 @@ $(INF_LIB): drhook_lib : $(MAKE) DRHOOK_ROOT=$(DRHOOK_DIR) -C $(WRAPPER_DIR) +vernier_lib : + $(MAKE) VERNIER_ROOT=$(VERNIER_DIR) -C $(WRAPPER_DIR) + tau_lib : $(MAKE) F90=tau_f90.sh TAU_ROOT=$(TAU_DIR) -C $(WRAPPER_DIR) diff --git a/examples/gocean/eg5/profile/README.md b/examples/gocean/eg5/profile/README.md index 929e2e20a1..733f3cdda8 100644 --- a/examples/gocean/eg5/profile/README.md +++ b/examples/gocean/eg5/profile/README.md @@ -17,6 +17,7 @@ profile wrapper libraries: - drhook - lfric - tau +- vernier By default (``make`` without an argument) the ``template`` library will be used, which just prints the name of the regions called. @@ -43,9 +44,9 @@ it yourself, and make sure that the ``tau_f90.sh`` compiler wrapper is in your path. The Makefile will automatically call ``tau_f90.sh``, there is no need to set ``$F90`` in this case. -If you are using ``dl_timer`` or ``drhook``, you need to compile these -libraries yourself first, and modify the ``Makefile`` in this directory -to specify the required linking parameters. The ``Makefile`` +If you are using ``dl_timer``, ``vernier`` or ``drhook``, you need to +compile these libraries yourself first, and modify the ``Makefile`` in +this directory to specify the required linking parameters. The ``Makefile`` supports the following environment variables that can be defined to find the various software packages: @@ -70,6 +71,10 @@ The location of the LFRic infrastructure library. It defaults to which is the small, stand-alone LFRic infrastructure library that is included in PSyclone. In spite of the dependence on LFRic, this profiling wrapper library can be used with with any application. +### VERNIER_DIR +The location of the Vernier library. It defaults to +``../../../../../Vernier``, i.e. it is assumed that Vernier is +installed next to PSyclone. The makefile here will invoke psyclone with the ``--profile invokes`` flag, which will add profiling around the two invokes used in the example. diff --git a/lib/profiling/Makefile b/lib/profiling/Makefile index 33c0eaecd5..2daa9fbf6f 100644 --- a/lib/profiling/Makefile +++ b/lib/profiling/Makefile @@ -41,11 +41,12 @@ F90 ?= gfortran F90FLAGS ?= -g # ----------------------------------------------------------------------------- -# We don't build dl_timer, drhook, nvidia, and tau since they require -# external libraries to be available. +# We don't build dl_timer, drhook, nvidia, Vernier, and tau by default +# since they require external libraries to be available. ALL_LIBS = lfric_timer simple_timing template -.PHONY: default all $(ALL_LIBS) clean allclean +.PHONY: default all $(ALL_LIBS) clean allclean \ + dl_timer drhook nvidia tau vernier default: all @@ -53,7 +54,7 @@ all: $(ALL_LIBS) # Invoke make in the corresponding subdirectory, and also support # the wrapper that need additional software to be installed -$(ALL_LIBS) dl_timer drhook nvidia tau: +$(ALL_LIBS) dl_timer drhook nvidia tau vernier: $(MAKE) -C $@ clean: @@ -62,7 +63,8 @@ clean: allclean: clean # These libs are not cleaned by 'clean' (since they # depend on external libraries) - $(MAKE) -C nvidia clean - $(MAKE) -C drhook clean $(MAKE) -C dl_timer clean + $(MAKE) -C drhook clean + $(MAKE) -C nvidia clean $(MAKE) -C tau clean + $(MAKE) -C vernier clean diff --git a/lib/profiling/README.md b/lib/profiling/README.md index 7c6f1b1b53..bba647a1b4 100644 --- a/lib/profiling/README.md +++ b/lib/profiling/README.md @@ -86,6 +86,32 @@ Example output: ============================================================================= ``` +### [Vernier](./vernier) + +This wrapper library interfaces with UK Met Office's [Vernier library]( +https://github.com/MetOffice/Vernier). Detailed building and linking +instructions are in [``vernier/README.md``]( +./vernier/README.md). + +Note that Vernier writes the output to one file per MPI rank, called +e.g. `vernier-output-0`. Example profiling output: + +``` +$ less vernier-output-0 +Profiling on 8 thread(s). + + # % Time Cumul Self Total # of calls Self Total Routine@ + (Size; Size/sec; Size/call; MinSize; MaxSize) + (self) (sec) (sec) (sec) ms/call ms/call + + 1 100.000 1.496 1.496 1.496 1 1496.066 1496.066 skeleton_constants_mod_psy:invoke_create_de_rham_matrices-compute_derham_matrices_code-r0@0 + 2 0.425 1.502 0.006 0.006 5 1.271 1.271 lfric_xios_setup_mod_psy:invoke_1_nodal_coordinates_kernel_type-nodal_coordinates_code-r1@0 + 3 0.368 1.508 0.006 0.006 10 0.550 0.550 skeleton_alg_mod_psy:invoke_compute_divergence-matrix_vector_code-r2@0 + 4 0.318 1.513 0.005 0.005 1 4.754 4.754 lfric_xios_setup_mod_psy:invoke_0_nodal_xyz_coordinates_kernel_type-nodal_xyz_coordinates_code-r0@0 +... + +``` + ### [Dr Hook](./drhook) This wrapper library interfaces with the ECMWF Dr Hook library. This diff --git a/lib/profiling/drhook/README.md b/lib/profiling/drhook/README.md index 96b47a910a..f24bd0cacb 100644 --- a/lib/profiling/drhook/README.md +++ b/lib/profiling/drhook/README.md @@ -64,10 +64,6 @@ The compilation process will create the wrapper library ``libdrhook_psy.a``. ### Linking the wrapper library -In order to use the wrapper with your application, you must provide the -location of the wrapper as an ``include`` path (so that the module file is found), -and link first with the wrapper library, then the DrHook library: - In order to use the wrapper with your application, the location of this library must be provided as an ``include`` path (so that the module file is found), and linked first with the wrapper library, ``drhook_psy``, diff --git a/lib/profiling/vernier/.gitignore b/lib/profiling/vernier/.gitignore new file mode 100644 index 0000000000..46dc25175e --- /dev/null +++ b/lib/profiling/vernier/.gitignore @@ -0,0 +1 @@ +libdrhook_psy.a diff --git a/lib/profiling/vernier/Makefile b/lib/profiling/vernier/Makefile new file mode 100644 index 0000000000..892b0e92a5 --- /dev/null +++ b/lib/profiling/vernier/Makefile @@ -0,0 +1,69 @@ +# ----------------------------------------------------------------------------- +# BSD 3-Clause License +# +# Copyright (c) 2019-2024, Science and Technology Facilities Council. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ----------------------------------------------------------------------------- +# Author J. Henrichs, Bureau of Meteorology +# Modified I. Kavcic, Met Office + +# ----------- Default "make" values, can be overwritten by the user ----------- +# Compiler and compiler flags +F90 ?= gfortran +F90FLAGS ?= +# Path to the Vernier installation. It defaults to the assumed location +# of the Vernier directory next to a clone of PSyclone repository. +# Overwrite for a custom location. +VERNIER_ROOT ?= ./../../../../Vernier +# Path to the Vernier "include" files. Overwrite for a custom location. +VERNIER_MODULES ?= $(VERNIER_ROOT)/local/include +# ----------------------------------------------------------------------------- + +F90FLAGS += -I$(VERNIER_MODULES) + +PSYDATA_LIB_NAME = vernier_psy +PSYDATA_LIB = lib$(PSYDATA_LIB_NAME).a + +OBJS = vernier_psy.o + +default: $(PSYDATA_LIB) + +.PHONY: default clean allclean + +$(PSYDATA_LIB): $(OBJS) + ar rs $(PSYDATA_LIB) $(OBJS) + +%.o: %.f90 + $(F90) $(F90FLAGS) -c $< + +clean: + rm -f *.o *.mod $(PSYDATA_LIB) + +allclean: clean diff --git a/lib/profiling/vernier/README.md b/lib/profiling/vernier/README.md new file mode 100644 index 0000000000..e150f080f8 --- /dev/null +++ b/lib/profiling/vernier/README.md @@ -0,0 +1,134 @@ +# PSyclone Wrapper Library for Vernier + +This is a wrapper library that maps the [PSyclone profiling API]( +https://psyclone.readthedocs.io/en/stable/profiling.html#profiling) +to [Vernier](https://github.com/MetOffice/Vernier). + +## Dependencies + +Vernier must be installed. + +This profiling library uses the [PSyData API]( +https://psyclone.readthedocs.io/en/stable/psy_data.html) to interface with +the application. The library is based on the [PSyData base class]( +https://psyclone-dev.readthedocs.io/en/latest/psy_data.html#psydata-base-class), +which is included in PSyclone as a Jinja template, ``psy_data_base.jinja``. +Full documentation on using this template is provided in the PSyclone +[Developer Guide]( +https://psyclone-dev.readthedocs.io/en/latest/psy_data.html#jinja). + +The library uses the ``ProfileData`` type to store a Vernier handle for each +region. + +## Compilation + +The library is compiled with ``make`` using the provided ``Makefile``. The +environment variables ``$F90`` and ``$F90FLAGS`` can be set to point to the +[Fortran compiler](./../../README.md#compilation) and flags to use. They +default to ``gfortran`` and the empty string. + +To compile the PSyclone wrapper library for Vernier, one of the following +two ``Makefile`` variables must be set to specify the path to the Vernier +installation: +VERNIER_ROOT ?= ./../../../../Vernier + +- ``VERNIER_ROOT``, the path to the Vernier root directory in which + Vernier is compiled and installed. It defaults to ``./../../../../Vernier`` + in the ``Makefile`` (i.e., it assumes Vernier is installed next to a PSyclone + repository clone). This will set ``VERNIER_MODULES`` to + ``.../Vernier/local/include``, so that the ``*.mod`` for Vernier + can be found. + +- ``VERNIER_MODULES``: Setting these environment + variables explicitly will allow to flexibly point to an existing + Vernier installation. + +For instance, compiling the wrapper library with the default compiler +flags may look something like: + +```shell +VERNIER_ROOT= make +``` + +The compilation process will create the wrapper library ``libvernier_psy.a``. + +### Linking the wrapper library + +In order to use the wrapper with your application, the location of this +library must be provided as an ``include`` path (so that the module file +is found), and linked first with the wrapper library, ``vernier_psy``, +and then with the Vernier library: + +```shell +$(F90) -c ... -I /lib/profiling/vernier somefile.f90 +$(F90) -o a.out ... -L /lib/profiling/vernier -lvernier_psy \ + -L -lvernier_f -lvernier_c -lvernier +``` + +**Note:** + +- The ```` differs depending on whether the wrapper + library is compiled in a clone of PSyclone repository or in a PSyclone + [installation](./../../README.md#installation). + +## Output + +An example output of the profiling report is below. Note that Vernier +writes the output into MPI-rank-specific output files, the output is not +added to stdout: + +``` +Profiling on 8 thread(s). + + # % Time Cumul Self Total # of calls Self Total Routine@ + (Size; Size/sec; Size/call; MinSize; MaxSize) + (self) (sec) (sec) (sec) ms/call ms/call + + 1 100.000 1.496 1.496 1.496 1 1496.066 1496.066 skeleton_constants_mod_psy:invoke_create_de_rham_matrices-compute_derham_matrices_code-r0@0 + 2 0.425 1.502 0.006 0.006 5 1.271 1.271 lfric_xios_setup_mod_psy:invoke_1_nodal_coordinates_kernel_type-nodal_coordinates_code-r1@0 + 3 0.368 1.508 0.006 0.006 10 0.550 0.550 skeleton_alg_mod_psy:invoke_compute_divergence-matrix_vector_code-r2@0 + 4 0.318 1.513 0.005 0.005 1 4.754 4.754 lfric_xios_setup_mod_psy:invoke_0_nodal_xyz_coordinates_kernel_type-nodal_xyz_coordinates_code-r0@0 + 5 0.195 1.516 0.003 0.003 3 0.971 0.971 lfric_xios_setup_mod_psy:invoke_2_nodal_coordinates_kernel_type-nodal_coordinates_code-r2@0 + +``` + + diff --git a/lib/profiling/vernier/vernier_psy.f90 b/lib/profiling/vernier/vernier_psy.f90 new file mode 100644 index 0000000000..26eb713190 --- /dev/null +++ b/lib/profiling/vernier/vernier_psy.f90 @@ -0,0 +1,145 @@ +! ----------------------------------------------------------------------------- +! BSD 3-Clause License +! +! Copyright (c) 2024, Science and Technology Facilities Council. +! All rights reserved. +! +! Redistribution and use in source and binary forms, with or without +! modification, are permitted provided that the following conditions are met: +! +! * Redistributions of source code must retain the above copyright notice, this +! list of conditions and the following disclaimer. +! +! * Redistributions in binary form must reproduce the above copyright notice, +! this list of conditions and the following disclaimer in the documentation +! and/or other materials provided with the distribution. +! +! * Neither the name of the copyright holder nor the names of its +! contributors may be used to endorse or promote products derived from +! this software without specific prior written permission. +! +! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +! DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +! FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +! ----------------------------------------------------------------------------- +! Author J. Henrichs, Bureau of Meteorology + + +!> An implemention of the PSyData API for profiling which wraps the use of Vernier. + +module profile_psy_data_mod + + ! The Vernier handle type + use vernier_mod, only : vik + implicit none + + type :: profile_PSyDataType + ! The opaque Vernier handle for a specific region + integer (kind=vik) :: vernier_handle + ! The name of the subroutine and module to be used by Vernier + character(:), allocatable :: name + ! True if this instance of PSyDataType has the name already + ! initialised. This way the copy of subroutine name is only + ! done first time PreStart is called. + logical :: initialised = .false. + contains + ! The profiling API uses only the two following calls: + procedure :: PreStart + procedure :: PostEnd + end type profile_PSyDataType + +contains + + ! --------------------------------------------------------------------------- + !> The initialisation subroutine. It is not called directly from + !! any PSyclone created code, so a call to profile_PSyDataInit must be + !! inserted manually by the developer. + + subroutine profile_PSyDataInit() + use vernier_mod, only: vernier_init + implicit none + call vernier_init(1) + end subroutine profile_PSyDataInit + + ! --------------------------------------------------------------------------- + !> Starts a profiling area. The module and region name can be used to create + !! a unique name for each region. + !! Parameters: + !! @param[in,out] this This PSyData instance. + !! @param[in] module_name Name of the module in which the region is + !! @param[in] region_name Name of the region (could be name of an invoke, or + !! subroutine name). + !! @param[in] num_pre_vars The number of variables that are declared and + !! written before the instrumented region. + !! @param[in] num_post_vars The number of variables that are also declared + !! before an instrumented region of code, but are written after + !! this region. + + subroutine PreStart(this, module_name, region_name, num_pre_vars, & + num_post_vars) + + use vernier_mod, only : vernier_start + implicit none + + class(profile_PSyDataType), intent(inout), target :: this + character(len=*), intent(in) :: module_name, region_name + integer, intent(in) :: num_pre_vars, num_post_vars + + if (.not. this%initialised) then + ! Venier only supports a single name, so we store the concatenated + ! strings to reduce runtime overhead + this%name = module_name//":"//region_name + this%initialised = .true. + endif + call vernier_start(this%vernier_handle, this%name) + + end subroutine PreStart + + ! --------------------------------------------------------------------------- + !! Ends a profiling area. It takes a PSyDataType type that corresponds to + !! to the PreStart call. + !! @param[in,out] this This PSyData instance. + ! + subroutine PostEnd(this) + + use vernier_mod, only : vernier_stop + + implicit none + + class(profile_PSyDataType), intent(inout), target :: this + + call vernier_stop(this%vernier_handle) + + end subroutine PostEnd + + ! --------------------------------------------------------------------------- + !> Called at the end of the execution of a program, usually to generate + !! all output for the profiling library. + subroutine profile_PSyDataShutdown() + use vernier_mod, only : vernier_finalize, vernier_write + + implicit none + call vernier_write() + call vernier_finalize() + end subroutine profile_PSyDataShutdown + + ! --------------------------------------------------------------------------- + !> Enable Vernier. + subroutine profile_PSyDataStart() + implicit none + end subroutine profile_PSyDataStart + + ! --------------------------------------------------------------------------- + !> Disable Vernier. + subroutine profile_PSyDataStop() + implicit none + end subroutine profile_PSyDataStop + +end module profile_psy_data_mod diff --git a/psyclone.pdf b/psyclone.pdf index 4973ec88e8..55cef3573e 100644 Binary files a/psyclone.pdf and b/psyclone.pdf differ diff --git a/src/psyclone/generator.py b/src/psyclone/generator.py index 95818823e4..f4e3583fc8 100644 --- a/src/psyclone/generator.py +++ b/src/psyclone/generator.py @@ -1,7 +1,7 @@ # ----------------------------------------------------------------------------- # BSD 3-Clause License # -# Copyright (c) 2017-2024, Science and Technology Facilities Council. +# Copyright (c) 2017-2025, Science and Technology Facilities Council. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -34,6 +34,7 @@ # Authors: R. W. Ford, A. R. Porter and N. Nobre, STFC Daresbury Lab # Modified A. J. Voysey, Met Office # Modified J. Henrichs, Bureau of Meteorology +# Modified A. R. Pirrie, Met Office ''' This module provides the PSyclone 'main' routine which is intended @@ -426,11 +427,11 @@ def main(arguments): # Common options parser.add_argument('filename', help='input source code') parser.add_argument( - '--version', '-v', action='version', + '-v', '--version', action='version', version=f'PSyclone version: {__VERSION__}', help='display version information') - parser.add_argument("--config", "-c", help="config file with " - "PSyclone specific options") + parser.add_argument('-c', '--config', help='config file with ' + 'PSyclone specific options') parser.add_argument('-s', '--script', help='filename of a PSyclone' ' optimisation recipe') parser.add_argument( @@ -439,12 +440,12 @@ def main(arguments): parser.add_argument( '-l', '--limit', dest='limit', default='off', choices=['off', 'all', 'output'], - help='limit the Fortran line length to 132 characters (default ' - '\'%(default)s\'). Use \'all\' to apply limit to both input and ' - 'output Fortran. Use \'output\' to apply line-length limit to output ' - 'Fortran only.') + help="limit the Fortran line length to 132 characters (default " + "'%(default)s'). Use 'all' to apply limit to both input and " + "output Fortran. Use 'output' to apply line-length limit to output " + "Fortran only.") parser.add_argument( - '--profile', '-p', action="append", choices=Profiler.SUPPORTED_OPTIONS, + '-p', '--profile', action="append", choices=Profiler.SUPPORTED_OPTIONS, help="add profiling hooks for 'kernels', 'invokes' or 'routines'") parser.add_argument( '--backend', dest='backend', diff --git a/src/psyclone/psyir/frontend/fortran.py b/src/psyclone/psyir/frontend/fortran.py index 481690b9dd..98285bbd6d 100644 --- a/src/psyclone/psyir/frontend/fortran.py +++ b/src/psyclone/psyir/frontend/fortran.py @@ -72,6 +72,9 @@ class FortranReader(): for more precise control it also accepts a list of module names. Defaults to False. + :raises ValueError: If ignore_directives is set to False but + ignore_comments is set to True. + ''' # Save parser object across instances to reduce the initialisation time _parser = None @@ -83,6 +86,11 @@ def __init__(self, free_form: bool = True, ignore_comments: bool = True, if not self._parser: self._parser = ParserFactory().create(std="f2008") self._free_form = free_form + if ignore_comments and not ignore_directives: + raise ValueError( + "Setting ignore_directives to False in the FortranReader will" + " only have an effect if ignore_comments is also set to False." + ) self._ignore_comments = ignore_comments self._processor = Fparser2Reader(ignore_directives, last_comments_as_codeblocks, diff --git a/src/psyclone/tests/psyir/frontend/fortran_test.py b/src/psyclone/tests/psyir/frontend/fortran_test.py index 9c81ae7905..e7c708c749 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_test.py @@ -275,3 +275,12 @@ def test_fortran_psyir_from_file(fortran_reader, tmpdir_factory): assert node.preceding_comment == "Comment on assignment" else: assert node.preceding_comment == "" + + # Check that the following combination raises an error + with pytest.raises(ValueError) as err: + FortranReader(ignore_comments=True, ignore_directives=False) + msg = ( + "Setting ignore_directives to False in the FortranReader will" + " only have an effect if ignore_comments is also set to False." + ) + assert msg in str(err.value)