Skip to content

Commit

Permalink
Merge pull request #341 from JoeffreyLegaux/bugfix-inlining-present-a…
Browse files Browse the repository at this point in the history
…rray

Fixed logical evaluation of PRESENT intrinsics on Array variables
  • Loading branch information
mlange05 committed Aug 13, 2024
2 parents abf7968 + 65b58a1 commit a0207ce
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
3 changes: 2 additions & 1 deletion loki/transformations/inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,8 @@ def _map_unbound_dims(var, val):
check for check in FindInlineCalls().visit(callee.body) if check.function == 'PRESENT'
)
present_map = {
check: sym.Literal('.true.') if check.arguments[0] in call.arg_map else sym.Literal('.false.')
check: sym.Literal('.true.') if check.arguments[0] in [arg.name for arg in call.arg_map]
else sym.Literal('.false.')
for check in present_checks
}
argmap.update(present_map)
Expand Down
58 changes: 58 additions & 0 deletions loki/transformations/tests/test_inline.py
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,63 @@ def test_inline_member_routines_with_associate(frontend):
assert len(assocs) == 2


@pytest.mark.parametrize('frontend', available_frontends(
xfail=[(OMNI, 'OMNI does not handle missing type definitions')]
))
def test_inline_member_routines_with_optionals(frontend):
"""
Ensure that internal routines with optional arguments get
inlined as expected (esp. present instrinsics are correctly
evaluated for all variables types)
"""
fcode = """
subroutine test_inline(klon, ydxfu, ydmf_phys_out)
use yomxfu , only : txfu
use mf_phys_type_mod , only : mf_phys_out_type
implicit none
integer(kind=4), intent(in) :: klon
type(txfu) ,intent(inout) :: ydxfu
type(mf_phys_out_type) ,intent(in) :: ydmf_phys_out
call member_rout (ydxfu%visicld, pvmin=ydmf_phys_out%visicld, psmax=1.0_8)
contains
subroutine member_rout (x, pvmin, pvmax, psmin, psmax)
real(kind=8) ,intent(inout) :: x(1:klon)
real(kind=8) ,intent(in) ,optional :: pvmin(1:klon)
real(kind=8) ,intent(in) ,optional :: pvmax(1:klon)
real(kind=8) ,intent(in) ,optional :: psmin
real(kind=8) ,intent(in) ,optional :: psmax
if (present (psmin)) x = psmin
if (present (psmax)) x = psmax
if (present (pvmin)) x = minval(pvmin(:))
if (present (pvmax)) x = maxval(pvmax(:))
end subroutine member_rout
end subroutine test_inline
"""

routine = Subroutine.from_source(fcode, frontend=frontend)

inline_member_procedures(routine=routine)

assert not routine.members

conds = FindNodes(ir.Conditional).visit(routine.body)
assert len(conds) == 4
assert conds[0].condition == 'False'
assert conds[1].condition == 'True'
assert conds[2].condition == 'True'
assert conds[3].condition == 'False'


@pytest.mark.parametrize('frontend', available_frontends(
skip={OFP: "OFP apparently has problems dealing with those Statement Functions",
OMNI: "OMNI automatically inlines Statement Functions"}
Expand Down Expand Up @@ -749,6 +806,7 @@ def test_inline_statement_functions(frontend, stmt_decls):
else:
assert FindInlineCalls().visit(routine.body)


@pytest.mark.parametrize('frontend', available_frontends())
@pytest.mark.parametrize('adjust_imports', [True, False])
def test_inline_marked_subroutines(frontend, adjust_imports, tmp_path):
Expand Down

0 comments on commit a0207ce

Please sign in to comment.