Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

problem with procedure pointers #393

Closed
npenigaud opened this issue Oct 10, 2024 · 2 comments · Fixed by #399
Closed

problem with procedure pointers #393

npenigaud opened this issue Oct 10, 2024 · 2 comments · Fixed by #399
Labels
bug Something isn't working

Comments

@npenigaud
Copy link

Procedure pointers are used in recent versions of the semi-implicit. However, the following leads to a bug in Loki :
spcmnew_pb.F90:

SUBROUTINE SPCMNEW(YDGEOMETRY)

USE SPSI_MODNEW, ONLY : SPNSI
IMPLICIT NONE
PROCEDURE(SPNSI), POINTER :: SPNSIPTR
END SUBROUTINE SPCMNEW

launch.py:

from loki import Sourcefile,fgen
source=Sourcefile.from_file('spcmnew_pb.F90',preprocess=True)
spcmnew=source['spcmnew']
print(fgen(spcmnew.spec))

(SPNSI is an abstract interface for a subroutine, included in spsi_modnew.F90).

@reuterbal
Copy link
Collaborator

Thanks for reporting this, I can reproduce the problem:

from loki import Sourcefile
fcode = """
SUBROUTINE SPCMNEW
USE SPSI_MODNEW, ONLY : SPNSI
IMPLICIT NONE
PROCEDURE(SPNSI), POINTER :: SPNSIPTR
END SUBROUTINE SPCMNEW
"""
source = Sourcefile.from_source(fcode)
print(source.to_fortran())

This fails with an assertion in the fgen backend because the type information for SPNSI is missing:

File "/.../main/loki/backend/fgen.py", line 406, in visit_ProcedureDeclaration
    assert all(isinstance(t.dtype, ProcedureType) for t in types)

It works correctly if the type definition is provided to Loki, as in the following example:

fcode_module = """
MODULE SPSI_MODNEW
IMPLICIT NONE
INTERFACE
  SUBROUTINE SPNSI
  END SUBROUTINE SPNSI
END INTERFACE
END MODULE SPSI_MODNEW
"""
fcode = "..."
module = Sourcefile.from_source(fcode_module)
source = Sourcefile.from_source(fcode, definitions=module.definitions)
print(source.to_fortran())

This produces the correct output:

SUBROUTINE SPCMNEW ()
  USE SPSI_MODNEW, ONLY: SPNSI
  IMPLICIT NONE
  PROCEDURE(SPNSI), POINTER :: SPNSIPTR
END SUBROUTINE SPCMNEW

The fix is to allow also deferred type information for the procedure interface, for which the following seems to suffice:

diff --git a/loki/backend/fgen.py b/loki/backend/fgen.py
index 5ca129cf..090e3c3b 100644
--- a/loki/backend/fgen.py
+++ b/loki/backend/fgen.py
@@ -403,12 +403,15 @@ class FortranCodegen(Stringifier):
         # TODO: We can't fully compare procedure types, yet, but we can make at least sure
         # names match and other declared attributes are compatible
         ignore = ['dtype', 'shape', 'dimensions', 'symbols', 'source', 'initial']
-        assert all(isinstance(t.dtype, ProcedureType) for t in types)
+        assert all(isinstance(t.dtype, ProcedureType) or t.dtype == BasicType.DEFERRED for t in types)
         assert all(t.compare(types[0], ignore=ignore) for t in types)
         if isinstance(o.interface, DataType):
             assert all(t.dtype.return_type.dtype == o.interface for t in types)
         elif o.interface is not None:
-            assert all(t.dtype.name == o.interface for t in types)
+            if types[0].dtype == BasicType.DEFERRED:
+                assert all(t.dtype == BasicType.DEFERRED for t in types)
+            else:
+                assert all(t.dtype.name == o.interface for t in types)

         if o.external:
             # This is an EXTERNAL statement (i.e., a kind of forward declaration)

@npenigaud Can you please confirm that the fix works for you? Then I will file a PR with these changes later.

@npenigaud
Copy link
Author

npenigaud commented Oct 10, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants