LMDZ Coding conventions and guidelines : Différence entre versions
(Add link to GPU-Morphosis coding rules for Fortran codes) |
|||
| Ligne 6 : | Ligne 6 : | ||
* '''IMPLICT NONE''' | * '''IMPLICT NONE''' | ||
| − | * | + | * For declarations of input/inout/output variables, systematically specify '''INTENT(IN)''', '''INTENT(INOUT)''', or '''INTENT(OUT)''' |
| − | * | + | Mor generally, all the variables in a routine must be 'properly' declared with '''TYPE''', '''DIMENSION''' and '''INTENT''' for arguments to the routine |
| − | * in the physics module, all '''SAVE''' variables should be declared as '''THREADPRIVATE''' (this includes all variables that are initialized in their declaration) | + | * It is '''HIGHLY RECOMMENDED''' to comment every input/output/inout variable with a short definition and the units. |
| + | * Be generous and rigorous when commenting routines (of course) | ||
| + | * Fortran keywords in fortran files will be in '''UPPER''' case | ||
| + | * Indent your routine. We recommend using the script format_code.sh (based on fprettify) in LMDZ/tools for this purpose. | ||
| + | * In the physics module, all '''SAVE''' variables should be declared as '''THREADPRIVATE''' (this includes all variables that are initialized in their declaration) | ||
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
LOGICAL, SAVE :: first = .TRUE. | LOGICAL, SAVE :: first = .TRUE. | ||
!$OMP THREADPRIVATE(first) | !$OMP THREADPRIVATE(first) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | * | + | * Variables and functions included through modules should be explicitly defined through the '''USE ..., ONLY''' statement: |
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
USE ioipsl_getin_p_mod, ONLY : getin_p | USE ioipsl_getin_p_mod, ONLY : getin_p | ||
| Ligne 45 : | Ligne 49 : | ||
Following different discussions among LMDZ developpers (summarized in one of our weekly meetings [https://lmdz.lmd.jussieu.fr/le-coin-des-developpeurs/cr-de-reunions/poihl/compte-rendus-poihl-2022/2022-05-16 here]), the following coding rules apply to the development of LMDZ parametrizations: | Following different discussions among LMDZ developpers (summarized in one of our weekly meetings [https://lmdz.lmd.jussieu.fr/le-coin-des-developpeurs/cr-de-reunions/poihl/compte-rendus-poihl-2022/2022-05-16 here]), the following coding rules apply to the development of LMDZ parametrizations: | ||
| − | * constants and variables that need to be initialized for all routines of | + | * constants and variables that need to be initialized for all routines of a given "group" of parametrizations '''''groupparam''''' should be declared and initialized in a specific initialisation module called '''lmdz_''groupparam''_ini''' |
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
| − | MODULE | + | MODULE lmdz_groupparam_ini |
REAL, SAVE :: cst1 | REAL, SAVE :: cst1 | ||
!$OMPTREADPRIVATE cst1 | !$OMPTREADPRIVATE cst1 | ||
... | ... | ||
| − | END MODULE | + | END MODULE lmdz_groupparam_ini |
</syntaxhighlight> | </syntaxhighlight> | ||
| − | * the routines associated to a parametrization can either be gathered in a unique module or each have their own module. The name of the module will reflect the | + | * the routines associated to a parametrization can either be gathered in a unique module or each have their own module. The name of the module will reflect the group of parametrizations the routine belongs to. |
| − | + | * Furthermore, to make parameterizations as independent as possible, each parameterization should use only one module, which corresponds to the "ini" of its group. | |
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
| − | MODULE | + | MODULE lmdz_groupparam1_subroutine1 |
CONTAINS | CONTAINS | ||
SUBROUTINE param1_subroutine1 | SUBROUTINE param1_subroutine1 | ||
| − | USE | + | USE lmdz_groupparam1_ini, ONLY : cst1 |
... | ... | ||
END SUBROUTINE param1_subroutine1 | END SUBROUTINE param1_subroutine1 | ||
| − | END MODULE | + | END MODULE lmdz_groupparam1_subroutine1 |
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
* the first arguments of parametrization routines should be the dimensions of the domain (e.g. '''klon, klev''') | * the first arguments of parametrization routines should be the dimensions of the domain (e.g. '''klon, klev''') | ||
| − | |||
<syntaxhighlight lang="fortran" line> | <syntaxhighlight lang="fortran" line> | ||
MODULE lmdz_param1_subroutine1 | MODULE lmdz_param1_subroutine1 | ||
Version du 28 janvier 2026 à 09:38
Coding rules related to GPU porting with GPU-Morphosis are available on this webpage.
Generalities
- IMPLICT NONE
- For declarations of input/inout/output variables, systematically specify INTENT(IN), INTENT(INOUT), or INTENT(OUT)
Mor generally, all the variables in a routine must be 'properly' declared with TYPE, DIMENSION and INTENT for arguments to the routine
- It is HIGHLY RECOMMENDED to comment every input/output/inout variable with a short definition and the units.
- Be generous and rigorous when commenting routines (of course)
- Fortran keywords in fortran files will be in UPPER case
- Indent your routine. We recommend using the script format_code.sh (based on fprettify) in LMDZ/tools for this purpose.
- In the physics module, all SAVE variables should be declared as THREADPRIVATE (this includes all variables that are initialized in their declaration)
1 LOGICAL, SAVE :: first = .TRUE.
2 !$OMP THREADPRIVATE(first)
- Variables and functions included through modules should be explicitly defined through the USE ..., ONLY statement:
1 USE ioipsl_getin_p_mod, ONLY : getin_p
Naming of modules
Module names should have a lmdz_ prefix. For example, the file lmdz_wave.F90 would be a module containing one or more subroutines:
1 MODULE lmdz_wave
2 IMPLICIT NONE
3
4 CONTAINS
5
6 SUBROUTINE wave_init (...)
7 ...
8 END SUBROUTINE wave_init
9
10 SUBROUTINE wave_calc (...)
11 ...
12 END SUBROUTINE wave_calc
13
14 END MODULE lmdz_wave
Beware: the renaming of already existing parametrization modules (to the lmdz_ format) should only occur once they have been re-written to adhere to the coding conventions for parametrizations (see below) as we use it as a marker that the recoding work on that particular parametrization has been done.
Coding conventions for parametrizations
Following different discussions among LMDZ developpers (summarized in one of our weekly meetings here), the following coding rules apply to the development of LMDZ parametrizations:
- constants and variables that need to be initialized for all routines of a given "group" of parametrizations groupparam should be declared and initialized in a specific initialisation module called lmdz_groupparam_ini
1 MODULE lmdz_groupparam_ini
2 REAL, SAVE :: cst1
3 !$OMPTREADPRIVATE cst1
4 ...
5 END MODULE lmdz_groupparam_ini
- the routines associated to a parametrization can either be gathered in a unique module or each have their own module. The name of the module will reflect the group of parametrizations the routine belongs to.
- Furthermore, to make parameterizations as independent as possible, each parameterization should use only one module, which corresponds to the "ini" of its group.
1 MODULE lmdz_groupparam1_subroutine1
2 CONTAINS
3 SUBROUTINE param1_subroutine1
4 USE lmdz_groupparam1_ini, ONLY : cst1
5 ...
6 END SUBROUTINE param1_subroutine1
7 END MODULE lmdz_groupparam1_subroutine1
- the first arguments of parametrization routines should be the dimensions of the domain (e.g. klon, klev)
1 MODULE lmdz_param1_subroutine1
2 CONTAINS
3 SUBROUTINE param1_subroutine1(klon, klev, ..., dtdwn, dqdwn, ..., dth, ...)
4 ! Input arguments to routine
5 INTEGER, INTENT(IN) :: klon,klev
6 REAL, DIMENSION (klon, klev), INTENT(IN) :: dtdwn, dqdwn
7 ...
8 ! Output arguments
9 REAL, DIMENSION (klon, klev), INTENT(OUT) :: dth
10 ...
11 ! Local variables
12 REAL, DIMENSION(klon) :: act
13 ...
- all dimensions of tables (e.g. nbsrf) should be passed as arguments to the routine rather than passed through a module
24 janvier 2025 à 17:37 (CET)