diff --git a/fortran/index.rst b/fortran/index.rst index 362e72c..c643178 100644 --- a/fortran/index.rst +++ b/fortran/index.rst @@ -92,6 +92,7 @@ points (Sy), and Single-Column related rules (SCz). rules/L17 rules/L18 rules/L19 + rules/L20 rules/I1 rules/I2 rules/I3 diff --git a/fortran/rules/L12.rst b/fortran/rules/L12.rst index 21c0613..0798cb0 100644 --- a/fortran/rules/L12.rst +++ b/fortran/rules/L12.rst @@ -14,6 +14,3 @@ The leading dimensions of these array should be ``NPROMA``. Any other arrays are forbidden in NPROMA routines. These other arrays (not depending on the meteorological situation) should be computed in the setup and passed as arguments to NPROMA compute routines, or integrated into sub-components of YDMODEL. - -Arrays declared in NPROMA routines be automatic arrays; ALLOCATABLEs and POINTERs are -forbidden. diff --git a/fortran/rules/L13.rst b/fortran/rules/L13.rst index 5845c00..e156279 100644 --- a/fortran/rules/L13.rst +++ b/fortran/rules/L13.rst @@ -1,11 +1,12 @@ -L13 : array declarations in parallel routines -********************************************* +L13 : allocatable arrays in NPROMA routines +******************************************* -Parallel routines (those processing a list of NPROMA blocks) should wrap their field data -into Field API objects. +Arrays declared in NPROMA routines (those processing a single NPROMA block) should be automatic, rather +than allocatable or pointer-based. -In particular the legacy data representation for model state (PGMV/PGFL arrays) should be -considered obsolescent and replaced by YDVARS wherever possible. +Rationale : + +NPROMA routines are typically called a large number of times so efficient handling of memory is +of particular importance in them. Automatic arrays, which are placed on the stack, incur lower +overheads than allocatable arrays, which are by default placed on the heap. -Parallel routines should never declare an array that will be involved in calculations -(ie passed to NPROMA routines or used in OpenMP sections). diff --git a/fortran/rules/L14.rst b/fortran/rules/L14.rst index 3202ae2..ec53e08 100644 --- a/fortran/rules/L14.rst +++ b/fortran/rules/L14.rst @@ -1,9 +1,11 @@ -L14 : notations -*************** +L14 : array declarations in parallel routines +********************************************* -Notations should homogeneous for the loop index, NPROMA array leading dimension, first iteration, last iteration: +Parallel routines (those processing a list of NPROMA blocks) should wrap their field data +into Field API objects. -* ``JLON/KLON/KIDIA/KFDIA`` in ARPEGE physics -* ``JL/KLON/KIDIA/KFDIA`` in ECMWF physics -* ``JROF/NPROMA/KST/KEND`` in dynamics routines (call_sl.F90, cpg_gp.F90, cpg_dyn.F90) +In particular the legacy data representation for model state (PGMV/PGFL arrays) should be +considered obsolescent and replaced by YDVARS wherever possible. +Parallel routines should never declare an array that will be involved in calculations +(ie passed to NPROMA routines or used in OpenMP sections). diff --git a/fortran/rules/L15.rst b/fortran/rules/L15.rst index 4dcfe4e..1bc4931 100644 --- a/fortran/rules/L15.rst +++ b/fortran/rules/L15.rst @@ -1,16 +1,9 @@ -L15 : dummy/actual array dimensions -*********************************** +L15 : notations +*************** -If an actual argument is an array, then : +Notations should homogeneous for the loop index, NPROMA array leading dimension, first iteration, last iteration: -- its rank should match the rank of the corresponding dummy argument +* ``JLON/KLON/KIDIA/KFDIA`` in ARPEGE physics +* ``JL/KLON/KIDIA/KFDIA`` in ECMWF physics +* ``JROF/NPROMA/KST/KEND`` in dynamics routines (call_sl.F90, cpg_gp.F90, cpg_dyn.F90) -- its dimensions should match those of the corresponding dummy argument - -Notable exceptions are the interpolation routines of the Semi-Lagrangian: - -* ``laitli.F90`` - -* ``laitri.F90`` - -* etc. diff --git a/fortran/rules/L16.rst b/fortran/rules/L16.rst index 505bf6e..c9164dd 100644 --- a/fortran/rules/L16.rst +++ b/fortran/rules/L16.rst @@ -1,23 +1,16 @@ -L16 : INTENT attribute in NPROMA routines -***************************************** +L16 : dummy/actual array dimensions +*********************************** -In NPROMA routines (those processing a single NPROMA block), only NPROMA data should -be allowed to have an INTENT different of IN. -All other argument data should have the ``INTENT(IN)`` attribute. +If an actual argument is an array, then : -This, for instance should be forbidden: +- its rank should match the rank of the corresponding dummy argument -.. code-block:: fortran +- its dimensions should match those of the corresponding dummy argument - SUBROUTINE LAPINEA(& - & YDGEOMETRY, YDML_GCONF,YDML_DYN,KST,KPROF,YDSL,KIBL,PB1,PB2,PWRL9,& - & KVSEPC,KVSEPL,& - & PSAVEDP,PCCO,PUF,PVF,KL0,KLH0,PLSCAW,PRSCAW,KL0H,PLSCAWH,PRSCAWH,& - & PSCO,PGFLT1,KNOWENO) +Notable exceptions are the interpolation routines of the Semi-Lagrangian: - INTEGER(KIND=JPIM),INTENT(INOUT) :: KVSEPC - INTEGER(KIND=JPIM),INTENT(INOUT) :: KVSEPL +* ``laitli.F90`` -In particular, ``YDMODEL`` and ``YDGEOMETRY`` as well as all their sub-components passed as arguments (eg ``YDDYNA``) should -have the ``INTENT(IN)`` attribute in NPROMA routines. +* ``laitri.F90`` +* etc. diff --git a/fortran/rules/L17.rst b/fortran/rules/L17.rst index 6c3eccd..209f70f 100644 --- a/fortran/rules/L17.rst +++ b/fortran/rules/L17.rst @@ -1,27 +1,23 @@ -L17 : Pointers in NPROMA routines -********************************* +L17 : INTENT attribute in NPROMA routines +***************************************** -The use of Fortran pointers in compute NPROMA routines should be forbidden except for the following pattern: +In NPROMA routines (those processing a single NPROMA block), only NPROMA data should +be allowed to have an INTENT different of IN. +All other argument data should have the ``INTENT(IN)`` attribute. +This, for instance should be forbidden: .. code-block:: fortran - SUBROUTINE GPRCP_EXPL (YDCST, YDCPG_BNDS, YDCPG_OPTS, PCP, PR, PKAP, YDVARS, KGFLTYP) + SUBROUTINE LAPINEA(& + & YDGEOMETRY, YDML_GCONF,YDML_DYN,KST,KPROF,YDSL,KIBL,PB1,PB2,PWRL9,& + & KVSEPC,KVSEPL,& + & PSAVEDP,PCCO,PUF,PVF,KL0,KLH0,PLSCAW,PRSCAW,KL0H,PLSCAWH,PRSCAWH,& + & PSCO,PGFLT1,KNOWENO) - REAL(KIND=JPRB),OPTIONAL,TARGET,INTENT(OUT) :: PCP(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) - REAL(KIND=JPRB),OPTIONAL,TARGET,INTENT(OUT) :: PR(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) - REAL(KIND=JPRB),OPTIONAL, INTENT(OUT) :: PKAP(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) + INTEGER(KIND=JPIM),INTENT(INOUT) :: KVSEPC + INTEGER(KIND=JPIM),INTENT(INOUT) :: KVSEPL - REAL(KIND=JPRB), POINTER :: ZR(:,:) - REAL(KIND=JPRB), TARGET :: ZR0(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) +In particular, ``YDMODEL`` and ``YDGEOMETRY`` as well as all their sub-components passed as arguments (eg ``YDDYNA``) should +have the ``INTENT(IN)`` attribute in NPROMA routines. - IF (PRESENT (PR)) THEN - ZR => PR - ELSEIF (PRESENT (PKAP)) THEN - ZR => ZR0 - ELSE - CALL ABOR1 ('GPRCP_EXPL: EXPECTED PR OR PKAP') - ENDIF - - -And such pointers should always point to arrays with the same shapes. diff --git a/fortran/rules/L18.rst b/fortran/rules/L18.rst index 9d07606..cffa7f6 100644 --- a/fortran/rules/L18.rst +++ b/fortran/rules/L18.rst @@ -1,16 +1,27 @@ -L18 : Design of NPROMA routines -******************************* +L18 : Pointers in NPROMA routines +********************************* -NPROMA routines should be individual subroutines, allowing for : +The use of Fortran pointers in compute NPROMA routines should be forbidden except for the following pattern: -- automatic interface generation -- separate compilation -- easiness of automatic analysis and transformation -In particular implementing a routine or a set of subroutines inside a module in -order to benefit from the automatic generation of an interface in a .mod file -should be prohibited. +.. code-block:: fortran -The use of modules should be restricted to derived types definition and implementation (methods). + SUBROUTINE GPRCP_EXPL (YDCST, YDCPG_BNDS, YDCPG_OPTS, PCP, PR, PKAP, YDVARS, KGFLTYP) + REAL(KIND=JPRB),OPTIONAL,TARGET,INTENT(OUT) :: PCP(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) + REAL(KIND=JPRB),OPTIONAL,TARGET,INTENT(OUT) :: PR(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) + REAL(KIND=JPRB),OPTIONAL, INTENT(OUT) :: PKAP(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) + REAL(KIND=JPRB), POINTER :: ZR(:,:) + REAL(KIND=JPRB), TARGET :: ZR0(YDCPG_OPTS%KLON,YDCPG_OPTS%KFLEVG) + + IF (PRESENT (PR)) THEN + ZR => PR + ELSEIF (PRESENT (PKAP)) THEN + ZR => ZR0 + ELSE + CALL ABOR1 ('GPRCP_EXPL: EXPECTED PR OR PKAP') + ENDIF + + +And such pointers should always point to arrays with the same shapes. diff --git a/fortran/rules/L19.rst b/fortran/rules/L19.rst index 590c0c3..95a4a53 100644 --- a/fortran/rules/L19.rst +++ b/fortran/rules/L19.rst @@ -1,9 +1,16 @@ -L19 : Design of derived types -***************************** +L19 : Design of NPROMA routines +******************************* + +NPROMA routines should be individual subroutines, allowing for : + +- automatic interface generation +- separate compilation +- easiness of automatic analysis and transformation + +In particular implementing a routine or a set of subroutines inside a module in +order to benefit from the automatic generation of an interface in a .mod file +should be prohibited. + +The use of modules should be restricted to derived types definition and implementation (methods). -Dervived types should be implemented in modules. Their methods (the minimal code accessing their private attributes) -should be implemented in the module where they are defined. -The SEQUENCE statement is forbidden in the definition of complex (embedding some POINTER or ALLOCATABLE members) derived types -meant to be used on accelerators, as the SEQUENCE statement -forbids the implementation of object methods. diff --git a/fortran/rules/L20.rst b/fortran/rules/L20.rst new file mode 100644 index 0000000..e10883f --- /dev/null +++ b/fortran/rules/L20.rst @@ -0,0 +1,9 @@ +L20 : Design of derived types +***************************** + +Dervived types should be implemented in modules. Their methods (the minimal code accessing their private attributes) +should be implemented in the module where they are defined. + +The SEQUENCE statement is forbidden in the definition of complex (embedding some POINTER or ALLOCATABLE members) derived types +meant to be used on accelerators, as the SEQUENCE statement +forbids the implementation of object methods.