Skip to content

Commit

Permalink
Merge pull request #391 from ecmwf-ifs/nabr-fix-omni-array-function
Browse files Browse the repository at this point in the history
Fix representation of array return type in OMNI frontend
  • Loading branch information
reuterbal authored Oct 9, 2024
2 parents 0c5750b + 7d09335 commit 3834903
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 0 deletions.
5 changes: 5 additions & 0 deletions loki/frontend/omni.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,11 @@ def visit_varDecl(self, o, **kwargs):
# why we restore the return_type
_type = _type.dtype.return_type

# If the return type has a shape, we need to apply this as a dimension to the
# variable, otherwise it will be missing from the declaration
if _type.shape:
variable = variable.clone(dimensions=_type.shape)

else:
raise ValueError

Expand Down
40 changes: 40 additions & 0 deletions loki/tests/test_subroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -2305,3 +2305,43 @@ def test_resolve_typebound_var_missing_definition(frontend, tmp_path):
assert tt_invalid_val == 'tt%invalid%val'
assert tt_invalid_val.type.dtype == BasicType.DEFERRED
assert tt_invalid_val.parent.type.dtype == BasicType.DEFERRED


@pytest.mark.parametrize('frontend', available_frontends())
@pytest.mark.parametrize('dim_decl', [':: add_to_a(n)', ', DIMENSION(n) :: add_to_a'])
def test_function_array_return_type(frontend, dim_decl):
"""
Verify array return types are correctly represented with all frontends
"""
fcode = f"""
subroutine member_functions
implicit none
integer :: i
real(kind=8) :: a(3)
contains
function add_to_a(b, n)
integer, intent(in) :: n
real(kind=8), intent(in) :: b(n)
real(kind=8) {dim_decl}
do i = 1, n
add_to_a(i) = a(i) + b(i)
end do
end function
end subroutine member_functions
""".strip()
routine = Subroutine.from_source(fcode, frontend=frontend)
add_to_a = routine['add_to_a']
return_type = add_to_a.procedure_type.return_type
assert return_type.dtype == BasicType.REAL
assert return_type.shape == ('n',)
ret_var = add_to_a.variable_map['add_to_a']
assert ret_var.type.dtype == BasicType.REAL
assert ret_var.type.shape == ('n',)
assert ret_var.dimensions == ('n',)

if frontend == OMNI:
# OMNI frontend puts the shape declaration always on the variable
assert ':: add_to_a(n)' in routine.to_fortran()
else:
assert dim_decl in routine.to_fortran()

0 comments on commit 3834903

Please sign in to comment.