Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1991 better compilation support #2026

Merged
merged 94 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from 92 commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
ff2acdf
#1991 Added first WIP version of inlining all required modules.
hiker Jan 12, 2023
122bb52
#1991 Updated example to support inlined modules.
hiker Jan 12, 2023
b1fe078
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 12, 2023
3f9896b
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 12, 2023
4db5602
#1991 Renamed module information to module manager, moved it to the p…
hiker Jan 12, 2023
a3abce0
#1991 Made the module manager a singleton.
hiker Jan 12, 2023
316f6eb
#1991 Make the ModuleManager work with search directories instead of …
hiker Jan 13, 2023
db4c96a
#1991 Added tests and make sure to cover all lines.
hiker Jan 16, 2023
ad6a5ae
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 16, 2023
c2ea7b0
#1991 Use os.access isntead of exists, which is a stricter test.
hiker Jan 16, 2023
f7d3517
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 16, 2023
6ec0ba3
#1991 Fixed handling of modules that are not found.
hiker Jan 16, 2023
6baceaa
#1991 Added missing docstring.
hiker Jan 18, 2023
fcc2fd8
#1991 Started to add a new ModuleInfo object to better encapsulate ca…
hiker Jan 18, 2023
788ddb3
#1991 Moved parse tree handling to module info.
hiker Jan 19, 2023
6eb10d7
#1991 Moved used module detection into ModuleInformation.
hiker Jan 19, 2023
cff0173
#1991 Split ModuleManager and ModuleInformation into two files.
hiker Jan 19, 2023
b901548
#1991 Split the module manager tests into two files, each one testing…
hiker Jan 19, 2023
9c98768
#1991 Moved recursive collection of dependencies into module manager,…
hiker Jan 19, 2023
0dd95be
#1991 Make the module dependency function a static method in the Modu…
hiker Jan 20, 2023
6bc09ce
#1991 Simplified search loop.
hiker Jan 20, 2023
23fdc4a
#1991 Fixed test to handle empty modules as expected.
hiker Jan 20, 2023
722b408
#1991 Updated driver tests to work with the .F90 file extension.
hiker Jan 20, 2023
78941b8
#1991 Removed old precision handling in driver creation which is not …
hiker Jan 20, 2023
121c88d
#1991 Added r_second which is required for gungho.
hiker Jan 20, 2023
805bd51
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 22, 2023
c042a20
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 23, 2023
6f618ce
#1991 Add l_def to the list of imported symbols.
hiker Jan 23, 2023
7a43fc8
#1991 Use 2008 Fortran standard, not 2003.
hiker Jan 23, 2023
5d29837
#1991 Fixed handling of invalid paths as -d command line parameter, t…
hiker Jan 24, 2023
3620ec4
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 24, 2023
1ae4a9f
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 24, 2023
b971bc8
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 30, 2023
a5fe136
#1991 Removed exception handling that could never happen.
hiker Jan 30, 2023
66dc3a9
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 31, 2023
087ab63
#1991 Removed work-around for l_def not being in the precision list.
hiker Jan 31, 2023
3ffa560
#1991 Added comments, minor code cleanup.
hiker Jan 31, 2023
0467210
#1991 Fixed cleanup of example.
hiker Jan 31, 2023
772a06e
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Jan 31, 2023
91da2c0
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 2, 2023
66adfcb
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 6, 2023
b7cad2d
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 6, 2023
e1fb8a3
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 9, 2023
8c8c5a0
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 13, 2023
54dac14
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Feb 21, 2023
fa13d03
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Mar 6, 2023
d12fa45
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Mar 19, 2023
a679b76
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Mar 21, 2023
8a61a2f
#1991 Add first compilation test.
hiker Mar 24, 2023
158ad9a
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Mar 24, 2023
ca5813d
1991 Removed debug print.
hiker Mar 24, 2023
80e25bf
#1991 Added compilation tests for driver creation.
hiker Mar 24, 2023
ab619c6
#1991 Renamed extension for auto-created files in compiler_strings fr…
hiker Mar 24, 2023
6f7b01c
#1991 Fixed pylint issues.
hiker Mar 24, 2023
86317da
#1991 Test that the expected modules are in the created driver.
hiker Mar 24, 2023
664b5d1
#1483 Ignore doxygen directory which is auto-created.
hiker Mar 28, 2023
f71f6ee
Merge branch '1483_lfric_extraction_driver-test-merge-psyir' into 199…
hiker Mar 28, 2023
86fdb71
#1991 Added documentation for module manager to user guide.
hiker Mar 28, 2023
284d82f
#1911 Updated documentation for LFRic extract example.
hiker Mar 28, 2023
d5777b5
#1911 Fixed unecessary options and fixed some bugs.
hiker Mar 28, 2023
8adc6dd
#1911 Updated comment.
hiker Mar 28, 2023
261ba88
#1991 Added debug information to check why CI cannot find files.
hiker Mar 28, 2023
e9bdd3f
Revert "#1991 Added debug information to check why CI cannot find fil…
hiker Mar 28, 2023
10bfcf8
#1991 Add the pre-processed read_kerbel_data_mod.f90 files to the rep…
hiker Mar 28, 2023
24015eb
#1991 Fixed incorrect documentation.
hiker Mar 29, 2023
c86ecf6
#1991 Updated documentation.
hiker Mar 29, 2023
fd90d24
#1991 Fixed pylint issues.
hiker Mar 29, 2023
1e04d01
Merge remote-tracking branch 'origin/master' into 1991_better_compila…
hiker Mar 29, 2023
0580908
#1991 Fixed doctests.
hiker Mar 29, 2023
513aba4
#1991 Restrict output line length of driver.
hiker Apr 5, 2023
6fd441b
#1991 Support more than one module in a file, and remove unused test …
hiker Apr 5, 2023
c4aa35e
#1991 Move initialisation of module manager to be after verification …
hiker Apr 5, 2023
dab68e8
#1991 Updated comments as indicated in review.
hiker Apr 5, 2023
a79faee
Merge remote-tracking branch 'origin/master' into 1991_better_compila…
hiker Apr 5, 2023
0b7e7e5
Merge remote-tracking branch 'origin/master' into 1991_better_compila…
hiker Apr 18, 2023
6021825
#1991 Fix some documentation issues raised in review.
hiker Apr 24, 2023
3f98609
#1991 Use OrderedDict to avoid checking if an entry already exists.
hiker Apr 24, 2023
f631964
#1991 Pre-process all .F90 LFRic infrastructure files so all these fi…
hiker Apr 26, 2023
d6a8cac
#1991 Fixed comments.
hiker Apr 26, 2023
4d8358e
#1991 Prefer pre-processed files over non-preprocessed files.
hiker Apr 26, 2023
c8e4a4f
#1991 Fixed preprocessing to exclude additinal markups like line numb…
hiker Apr 26, 2023
48cbedc
#1991 Addressed remaining reviewer comments about documentation.
hiker Apr 26, 2023
ee20965
#1991 Renamed _search_paths to _remaining_search_paths.
hiker Apr 26, 2023
213a09d
#1991 Added TODO for supporting an abort option.
hiker Apr 26, 2023
6032f40
Merge remote-tracking branch 'origin/master' into 1991_better_compila…
hiker Apr 26, 2023
1582ad3
#1991 Fixed failing doc test due to usage of pre-processed files.
hiker Apr 26, 2023
2287151
#1991 Moved module manager setup into conftest file.
hiker Apr 27, 2023
02c4ca5
#1991 Add search path to error message.
hiker Apr 28, 2023
b7948c2
#1991 Updated comment.
hiker Apr 28, 2023
ae2c74e
#1991 Updated README to justify why we add automatically created file…
hiker Apr 28, 2023
8368993
#1991 Replace '..' with os.path.dirname.
hiker Apr 28, 2023
e08aed0
Merge remote-tracking branch 'origin/master' into 1991_better_compila…
hiker May 2, 2023
834ee09
#2026 fix language in code block in psyke.rst
arporter May 2, 2023
0f40b13
#2026 update changelog and UG
arporter May 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions doc/developer_guide/psy_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@

.. testsetup::

import os
from psyclone.parse import ModuleManager

# Define SOURCE_FILE to point to an existing gocean 1.0 file.
SOURCE_FILE = ("../../src/psyclone/tests/test_files/"
"gocean1p0/test11_different_iterates_over_one_invoke.f90")
Expand Down Expand Up @@ -1214,3 +1217,71 @@ compared with the expected values in ``field1_post``.

.. note:: For now the created driver still depends on the infrastructure
library and any other modules used. Issue #1991 improves this.

Module Manager
++++++++++++++
The LFRic driver creation utilises a ``ModuleManager`` to find
and inline all modules required by the driver.


.. autoclass:: psyclone.parse.ModuleManager
:members:

Any PSyclone command line option ``-d`` (see :ref:`psyclone_command`)
will be added to the ``ModuleManager`` as recursive search paths. The
``ModuleManager`` is a singleton and it can be queried for information about
any module. It internally uses caching to avoid repeatedly searching
directories, and it will only access search paths as required. For example,
if the first search path will be sufficient to find all modules during the
lifetime of the module manager, no other search path will ever be accessed.
The caching also implies that the ModuleManager will not detect if new files
should be created during its lifetime.

The ``ModuleManager`` also provides a static function that will sort
a list of module dependencies, so that compiling the modules in this order
(or adding them in this order to a file) will allow compilation, i.e. any
module will only depend on previously defined modules.


The ``ModuleManager`` will return a ``ModuleInfo`` object to make information
about a module available:

.. autoclass:: psyclone.parse.ModuleInfo
:members:

Similar to the ``ModuleManager``, a ``ModuleInfo`` object will heavily rely on
caching to avoid repeatedly reading a source file or parsing it. The side
effect is that changes to a source file during the lifetime of the
``ModuleManager`` will not be reflected in its information.

At this stage, the ``ModuleInfo`` can be used to get the original source
code of a module as string and to query a module about modules and symbols
it depends on. It uses the fparser parse tree to detect this information (which
means it can handle files that are not supported by PSyIR, e.g. files with
preprocessor directives).

An example usage of the ``ModuleManager`` and ``ModuleInfo`` objects,
which prints the filenames of all modules used in ``tl_testkern_mod``:

.. testcode ::

mod_manager = ModuleManager.get()
# Add the path to the PSyclone LFRic example codes:
mod_manager.add_search_path("../../src/psyclone/tests/test_files/"
"dynamo0p3")

testkern_info = mod_manager.get_module_info("tl_testkern_mod")

used_mods = testkern_info.get_used_modules()
# Sort the modules so we get a reproducible output ordering
used_mods_list = sorted(list(used_mods))
for module_name in used_mods_list:
mod_info = mod_manager.get_module_info(module_name)
print("Module:", module_name, os.path.basename(mod_info.filename))

.. testoutput::

Module: argument_mod argument_mod.f90
Module: constants_mod constants_mod.f90
Module: fs_continuity_mod fs_continuity_mod.f90
Module: kernel_mod kernel_mod.f90
1 change: 1 addition & 0 deletions doc/reference_guide/source/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
doxygen
35 changes: 23 additions & 12 deletions doc/user_guide/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ target checks the various Jupyter notebooks using ``nbconvert``.
``examples`` directory but still wish to use ``make`` then you
will also have to set the ``PSYCLONE_CONFIG`` environment variable
to the full path to the PSyclone configuration file, e.g.
``$ PSYCLONE_CONFIG=/some/path/psyclone.cfg make``.
``PSYCLONE_CONFIG=/some/path/psyclone.cfg make``.

.. _examples-compilation:

Expand Down Expand Up @@ -574,24 +574,35 @@ Example 17.3: Kernel Data Extraction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The example in the subdirectory ``full_example_extract`` shows the
use of :ref:`kernel extraction <psyke>`. It requires the
installation of a NetCDF development environment (see
`here
use of :ref:`kernel extraction <psyke>`. The code can be compiled with
``make compile``, and the binary executed with either ``make run`` or
``./extract.standalone``. By default, it will be using
a stand-alone extraction library (see :ref:`extraction_libraries`).
If you want to use the NetCDF version, set the environment variable
``TYPE`` to be ``netcdf``:

.. code-block:: bash

TYPE=netcdf make compile

This requires the installation of a NetCDF development environment
(see `here
<https://github.com/stfc/PSyclone/tree/master/tutorial/practicals#user-content-netcdf-library-lfric-examples>`_
for installing NetCDF).
The code can be compiled with ``make compile``, and
the binary executed with either ``make run`` or ``./extract``
Running the compiled binary will create one NetCDF file ``main-update.nc``
containing the input and output parameters for the ``testkern_w0``
kernel call. For example:
for installing NetCDF). The binary will be called ``extract.netcdf``,
and the output files will have the ``.nc`` extension.

Running the compiled binary will create two Fortran binary files or
two NetCDF files if the NetCDF library was used. They contain
the input and output parameters for the two invokes in this example:

.. code-block:: bash

cd full_example_extraction
make compile
./extract
TYPE=netcdf make compile
./extract.netcdf
ncdump ./main-update.nc | less


Example 18: Special Accesses of Continuous Fields - Incrementing After Reading and Writing Before (Potentially) Reading
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
31 changes: 26 additions & 5 deletions doc/user_guide/psyke.rst
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ be set to true:
{"create_driver": True,
"region_name": ("main", "init")})

This will create a Fortran file called ``driver-main-init.f90``, which
This will create a Fortran file called ``driver-main-init.F90``, which
can then be compiled and executed. This stand-alone program will read
the output file created during an execution of the actual program, call
the kernel with all required input parameter, and compare the output
Expand All @@ -503,10 +503,31 @@ optimisation of a stand-alone kernel.
run stand-alone. As a work-around, these values can be added manually
to the driver program. Issue #1990 tracks improvement of this situation.

When linking the driver program, it needs to be provided with all
dependencies required by the driver and the kernel used. If the kernel calls
many other functions, this can result in a long parameter list for the
linker. Issue #1991 aims at simplifying this.
The LFRic kernel driver will inline all required external modules into the
driver. It uses a ``ModuleManager`` to find the required modules, based on the
assumption that a file ``my_special_mod.f90`` will define exactly one module
called ``my_special_mod`` (the ``_mod`` is required to be part of the
filename). The driver creator will sort the modules in the appropriate order
and add the source code directly into the driver. As a result, the driver
program is truly stand-alone and does not need any external dependency (the
only exception being NetCDF if the NetCDF-based extraction library is used).
The ``ModuleManager`` uses all kernel search paths specified on the
command line (see ``-d`` option in :ref:`psyclone_command`), and it will
recursively search for all files under each path specified on the command
line.

Therefore, compilation for a created driver, e.g. the one created in
``examples/lfric/eg17/full_example_extract``, is simple::

$ gfortran -g -O0 driver-main-update.F90 -o driver-main-update
$ ./driver-main-update
cell correct
field1 correct

Note that the Makefile in the example will actually provide additional include
paths (infrastructure files and extraction library) for the compiler, but
these flags are actually only required for compiling the example program, not
for the driver.


Extraction for NEMO
Expand Down
21 changes: 10 additions & 11 deletions examples/lfric/eg17/full_example_extract/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ ifeq ($(TYPE), netcdf)
else
GENERATED_FILES += main-update.binary main-init.binary
endif
GENERATED_FILES += driver-main-init driver-main-init.F90 \
driver-main-update driver-main-update.F90 \
*.o *.mod $(EXEC) main_alg.f90 main_psy.f90

F90 ?= gfortran
F90FLAGS ?= -Wall -g -ffree-line-length-none
Expand All @@ -60,12 +63,12 @@ OBJ = main_psy.o main_alg.o testkern_w0_kernel_mod.o
ifeq ($(TYPE), netcdf)
EXTRACT_DIR ?= $(PSYROOT)/lib/extract/netcdf/lfric
LDFLAGS += $$(nf-config --flibs)
F90FLAGS += $$(nf-config --fflags)
else
EXTRACT_DIR ?= $(PSYROOT)/lib/extract/standalone/lfric
endif

EXEC = extract.$(TYPE)
GENERATED_FILES = *.o *.mod $(EXEC) main_alg.f90 main_psy.f90
EXTRACT_NAME ?= _extract
EXTRACT_LIB = $(EXTRACT_DIR)/lib$(EXTRACT_NAME).a
READ_KERNEL_DATA_OBJ = $(EXTRACT_DIR)/../read_kernel_data_mod.o
Expand All @@ -83,7 +86,7 @@ transform: main_psy.f90 main_alg.f90
compile: transform $(EXEC)

run: compile
./extract
./$(EXEC)

$(EXEC): $(LFRIC_LIB) $(EXTRACT_LIB) $(OBJ)
$(F90) $(F90FLAGS) $(LFRIC_INCLUDE_FLAGS) $(OBJ) -o $(EXEC) -L$(EXTRACT_DIR) -l$(EXTRACT_NAME) \
Expand All @@ -103,18 +106,12 @@ testkern_w0_kernel_mod.o: $(LFRIC_LIB)
driver-main-update: LFRIC_INCLUDE_FLAGS += -I $(EXTRACT_DIR)/..
driver-main-update: driver-main-update.o $(READ_KERNEL_DATA_OBJ)
$(F90) $(F90FLAGS) $(LFRIC_INCLUDE_FLAGS) driver-main-update.o \
testkern_w0_kernel_mod.o \
$(READ_KERNEL_DATA_OBJ) \
-L$(LFRIC_PATH) -l$(LFRIC_NAME) $(LDFLAGS) \
-o driver-main-update
$(LDFLAGS) -o driver-main-update

driver-main-init: LFRIC_INCLUDE_FLAGS += -I $(EXTRACT_DIR)/..
driver-main-init: driver-main-init.o $(READ_KERNEL_DATA_OBJ)
$(F90) $(F90FLAGS) $(LFRIC_INCLUDE_FLAGS) driver-main-init.o \
testkern_w0_kernel_mod.o \
$(READ_KERNEL_DATA_OBJ) \
-L$(LFRIC_PATH) -l$(LFRIC_NAME) $(LDFLAGS) \
-o driver-main-init
$(LDFLAGS) -o driver-main-init

driver-main-update.o driver-main-init.o: $(READ_KERNEL_DATA_OBJ)

Expand All @@ -133,7 +130,9 @@ $(READ_KERNEL_DATA_OBJ):
$(MAKE) -C $(EXTRACT_DIR)/..

%_psy.f90: %.x90
${PSYCLONE} -s ./extract_transform.py \
${PSYCLONE} -s ./extract_transform.py \
-d . -d $(EXTRACT_DIR) -d $(EXTRACT_DIR)/.. \
-d $(LFRIC_PATH) \
-nodm -opsy $*_psy.f90 -oalg $*_alg.f90 $<

allclean: clean
Expand Down
1 change: 0 additions & 1 deletion lib/extract/netcdf/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
extract_netcdf_base.f90
read_kernel_data_mod.f90

Loading