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

297 omp sentinels #326

Merged
merged 5 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions source/fab/parse/fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from pathlib import Path
from typing import Union, Optional, Iterable, Dict, Any, Set

from fparser.common.readfortran import FortranStringReader # type: ignore
from fparser.two.Fortran2003 import ( # type: ignore
Entity_Decl_List, Use_Stmt, Module_Stmt, Program_Stmt, Subroutine_Stmt, Function_Stmt, Language_Binding_Spec,
Char_Literal_Constant, Interface_Block, Name, Comment, Module, Call_Stmt, Derived_Type_Def, Derived_Type_Stmt,
Expand Down Expand Up @@ -284,15 +285,38 @@ def _process_comment(self, analysed_file, obj):
# TODO: error handling in case we catch a genuine comment
# TODO: separate this project-specific code from the generic f analyser?
depends_str = "DEPENDS ON:"
if depends_str in obj.items[0]:
comment = obj.items[0].strip()
if depends_str in comment:
self.depends_on_comment_found = True
dep = obj.items[0].split(depends_str)[-1].strip()
dep = comment.split(depends_str)[-1].strip()
# with .o means a c file
if dep.endswith(".o"):
analysed_file.mo_commented_file_deps.add(dep.replace(".o", ".c"))
# without .o means a fortran symbol
else:
analysed_file.add_symbol_dep(dep)
if comment[:2] == "!$":
# Check if it is a use statement with an OpenMP sentinel:
# Use fparser's string reader to discard potential comment
# TODO #13: once fparser supports reading the sentinels,
# this can be removed.
MatthewHambley marked this conversation as resolved.
Show resolved Hide resolved
reader = FortranStringReader(comment[2:])
line = reader.next()
try:
# match returns a 5-tuple, the third one being the module name
module_name = Use_Stmt.match(line.strline)[2]
module_name = module_name.string
except Exception:
# Not a use statement in a sentinel, ignore:
return

# Register the module name
if module_name in self.ignore_mod_deps:
logger.debug(f"ignoring use of {module_name}")
return
if module_name.lower() not in self._intrinsic_modules:
# found a dependency on fortran
analysed_file.add_module_dep(module_name)

def _process_subroutine_or_function(self, analysed_file, fpath, obj):
# binding?
Expand Down
5 changes: 5 additions & 0 deletions tests/unit_tests/parse/fortran/test_fortran_analyser.f90
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ SUBROUTINE internal_sub
RETURN
END SUBROUTINE internal_sub

SUBROUTINE openmp_sentinel
!$ USE compute_chunk_size_mod, ONLY: compute_chunk_size ! Note OpenMP sentinel
!$ USE test that is not a sentinel with a use statement inside
END SUBROUTINE openmp_sentinel
MatthewHambley marked this conversation as resolved.
Show resolved Hide resolved

INTEGER FUNCTION internal_func()
internal_func = 456
END FUNCTION internal_func
Expand Down
10 changes: 5 additions & 5 deletions tests/unit_tests/parse/fortran/test_fortran_analyser.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,11 @@ def module_fpath():
def module_expected(module_fpath):
return AnalysedFortran(
fpath=module_fpath,
file_hash=4039845747,
file_hash=1344519263,
module_defs={'foo_mod'},
symbol_defs={'external_sub', 'external_func', 'foo_mod'},
module_deps={'bar_mod'},
symbol_deps={'monty_func', 'bar_mod'},
module_deps={'bar_mod', 'compute_chunk_size_mod'},
symbol_deps={'monty_func', 'bar_mod', 'compute_chunk_size_mod'},
file_deps=set(),
mo_commented_file_deps={'some_file.c'},
)
Expand Down Expand Up @@ -72,10 +72,10 @@ def test_program_file(self, fortran_analyser, module_fpath, module_expected):
analysis, artefact = fortran_analyser.run(fpath=Path(tmp_file.name))

module_expected.fpath = Path(tmp_file.name)
module_expected._file_hash = 768896775
module_expected._file_hash = 731743441
module_expected.program_defs = {'foo_mod'}
module_expected.module_defs = set()
module_expected.symbol_defs.update({'internal_sub', 'internal_func'})
module_expected.symbol_defs.update({'internal_sub', 'openmp_sentinel', 'internal_func'})

assert analysis == module_expected
assert artefact == fortran_analyser._config.prebuild_folder \
Expand Down