Open JoeffreyLegaux opened 1 week ago
Example of routine with member call
! test_inline.F90
SUBROUTINE TEST_INLINE(YDXFU, YDCPG_OPTS, YDMF_PHYS_OUT)
USE CPG_OPTS_TYPE_MOD, ONLY : CPG_OPTS_TYPE
USE PARKIND1 , ONLY : JPIM, JPRB
USE YOMXFU , ONLY : TXFU
USE MF_PHYS_TYPE_MOD , ONLY : MF_PHYS_OUT_TYPE
IMPLICIT NONE
TYPE(TXFU) ,INTENT(INOUT) :: YDXFU
TYPE(CPG_OPTS_TYPE) ,INTENT(IN) :: YDCPG_OPTS
TYPE(MF_PHYS_OUT_TYPE) ,INTENT(IN) :: YDMF_PHYS_OUT
IF (YDXFU%YVISICLD%LACTIVE) THEN
CALL MEMBER_ROUT (YDXFU%VISICLD, PVMIN=YDMF_PHYS_OUT%VISICLD, PSMAX=0.0_JPRB, PSMIN=-1.0_JPRB)
ENDIF
CONTAINS
SUBROUTINE MEMBER_ROUT (X, PVMIN, PVMAX, PSMIN, PSMAX)
REAL(KIND=JPRB) ,INTENT(INOUT) :: X(1:YDCPG_OPTS%KLON)
REAL(KIND=JPRB) ,INTENT(IN) ,OPTIONAL :: PVMIN(1:YDCPG_OPTS%KLON)
REAL(KIND=JPRB) ,INTENT(IN) ,OPTIONAL :: PVMAX(1:YDCPG_OPTS%KLON)
REAL(KIND=JPRB) ,INTENT(IN) ,OPTIONAL :: PSMIN
REAL(KIND=JPRB) ,INTENT(IN) ,OPTIONAL :: PSMAX
IF (PRESENT (PSMIN)) THEN
X = X + PSMIN
ELSEIF (PRESENT (PSMAX)) THEN
X = X + PSMAX
ELSEIF (PRESENT (PVMIN)) THEN
X = X + MINVAL(PVMIN(:))
ELSEIF (PRESENT (PVMAX)) THEN
X = X + MAXVAL(PVMAX(:))
ENDIF
END SUBROUTINE MEMBER_ROUT
END SUBROUTINE TEST_INLINE
Example loki script that applies inlining
from loki import Frontend, Sourcefile
from loki.transformations import inline_member_procedures, resolve_associates
source = Sourcefile.from_file('./test_inline.F90', frontend=Frontend.FP)
f = open('./test_inline_transfo.F90', 'w')
for routine in source.subroutines:
inline_member_procedures(routine)
f.write(routine.to_fortran())
f.write('\n')
f.close()
Without the proposed change, PRESENT(PVMIN) becomes .false. in the transformed routine.
All modified and coverable lines are covered by tests :white_check_mark:
Project coverage is 95.25%. Comparing base (
a39336b
) to head (5b4fc70
).
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
During inlining_member_procedures, PRESENT intrinsics are evaluated according the the actual presence of the concerned variables in the caller arguments.
However, this evaluation always returns false when evaluating Array variables.
This is due to the fact that we compare the array in the PRESENT call which has only the array's name, with the array declaration (from call.arg_map) which includes the dimensions.
I propose to correct that by checking the existence of the variable in the list of variables names from call.arg_map, instead of checking directly in the variables from call.arg_map.