stfc / PSyclone

Domain-specific compiler and code transformation system for Finite Difference/Volume/Element Earth-system models in Fortran
BSD 3-Clause "New" or "Revised" License
107 stars 29 forks source link

Use of module: UnresolvedType instead of ScalarType for a pointer to a scalar. #2728

Closed hbrunie closed 1 month ago

hbrunie commented 1 month ago

Here is the test snippet:

@pytest.mark.xfail
def test_psyclone_limits_on_module_pointers():
    from psyclone.psyir import nodes as psyir_nodes
    from psyclone.psyir import symbols as psyir_symbols
    from psyclone.psyir.frontend.fortran import FortranReader
    from psyclone.psyir.transformations import Reference2ArrayRangeTrans

    code = """module hydro
    real :: toto
    contains
    subroutine foo()
    use hydro, only : tata => toto
    tata = 3.2
    end subroutine foo
    end module
    """
    reader = FortranReader()
    psyir_tree: psyir_nodes.Node = reader.psyir_from_source(code)
    node: psyir_nodes.Assignment = psyir_tree.walk(psyir_nodes.Assignment)[0]
    ref = node.children[0]
    assert type(ref) is psyir_nodes.Reference
    assert ref.name == "tata"
    assert not type(ref.datatype) is psyir_symbols.UnresolvedType
    assert type(ref.datatype) is psyir_symbols.ScalarType
arporter commented 1 month ago

Hi @hbrunie, I don't think this is a bug. By default, PSyclone does not follow module imports to find symbol definitions - a user (script) has to explicitly request that this be done. However, if I run your test (which is a great reproducer - thank you) and try to do this I get:

(Pdb) ref.symbol.resolve_type()
*** psyclone.psyir.symbols.symbol.SymbolError: PSyclone SymbolTable error: Error trying to resolve the properties of symbol 'tata' in module 'hydro': PSyclone SymbolTable error: Module 'hydro' not found in any of the include_paths directories [].

so we're close but not that close. Sergi and I had never seen code like this before so I expect we simply miss the fact that the named module is in fact the one that contains this routine. Presumably you've hit this form of code in an existing model that does compile?

EDIT: so it is in fact a bug but the bug is in Symbol.resolve_type().

hbrunie commented 1 month ago

I have to confess this is not exactly how the real code look like. The module is indeed in a different file from the subroutine it contains. So if I understand correctly I need to provide the path to the module that contains the symbol and psyclone will make the link automatically to know it's a ScalarType.

@arporter Could you point me to a place where I could find a script example of explicit request to solve the symbols by looking at module file? If you don't have time I should be able to find it by myself looking more carefully at Psyclone documentation and unit tests.

Thus I do think we can close this Issue, because this case has not been encountered yet indeed (and might never be!).

arporter commented 1 month ago

That's good news :-) Essentially, you need to supply the location of any module source files via the -I flag to PSyclone. Note that this does not currently mimic typical compiler behaviour as PSyclone searches recursively from the location(s) you specify - we intend to change this in future. Then, if it is in your script that you are encountering a Symbol of unresolved type, you can do symbol.resolve_type() and hopefully that will resolve it. Unfortunately, if it is brought in via a 'wildcard' import (i.e. USE my_mod without an ONLY clause) then its definition still won't be found. In that situation you might need to explicitly handle those imports - see https://github.com/stfc/PSyclone/blob/master/examples/nemo/scripts/utils.py#L100 for an example of this.

hbrunie commented 1 month ago

Thank you.

I changed this issue to 'enhancement' because there is no real need (apart for my pytest hand made tests on FlashX) to handle Module and use module only from a subroutine contained in the module itself.

I keep this open because I think this could be easy to fix if I have time one day to understand the inner workings of how Psyclone handles modules.

hbrunie commented 1 month ago

This issue is not a real one as the code does not even compile: this is not possible in Fortran to have the module used in the subroutine it contains.