Skip to content

Commit

Permalink
Merge pull request #411 from ecmwf-ifs/naml-deprecate-ofp
Browse files Browse the repository at this point in the history
Frontend: Deprecate OFP and purge from test base
  • Loading branch information
reuterbal authored Oct 18, 2024
2 parents cc30c9e + f6c2151 commit 58adb24
Show file tree
Hide file tree
Showing 23 changed files with 79 additions and 102 deletions.
7 changes: 2 additions & 5 deletions loki/backend/tests/test_fgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from loki import Module, Subroutine, Sourcefile
from loki.backend import fgen
from loki.expression import symbols as sym
from loki.frontend import available_frontends, OMNI, OFP
from loki.frontend import available_frontends, OMNI
from loki.ir import Intrinsic, DataDeclaration
from loki.types import ProcedureType, BasicType

Expand Down Expand Up @@ -107,10 +107,7 @@ def test_fgen_data_stmt(frontend):
""".strip()

routine = Subroutine.from_source(fcode, frontend=frontend)
if frontend == OFP:
assert isinstance(routine.spec.body[-1], Intrinsic)
else:
assert isinstance(routine.spec.body[-1], DataDeclaration)
assert isinstance(routine.spec.body[-1], DataDeclaration)
spec_code = fgen(routine.spec)
assert spec_code.lower().count('data ') == 2
assert spec_code.count('/') == 4
Expand Down
4 changes: 2 additions & 2 deletions loki/backend/tests/test_pygen.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from loki import Subroutine
from loki.backend import pygen
from loki.build import jit_compile, clean_test
from loki.frontend import available_frontends, OFP, OMNI
from loki.frontend import available_frontends, OMNI
from loki.transformations.transpile import FortranPythonTransformation


Expand Down Expand Up @@ -452,7 +452,7 @@ def test_pygen_logical_statements(tmp_path, frontend):
f2p.py_path.unlink()


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'OFP cannot handle stmt functions')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_pygen_downcasing(tmp_path, frontend):
"""
A simple test routine to test the conversion to lower case.
Expand Down
6 changes: 3 additions & 3 deletions loki/batch/tests/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@
)
from loki.expression import Scalar, Array, Literal, ProcedureSymbol
from loki.frontend import (
available_frontends, OMNI, OFP, FP, REGEX, HAVE_FP, HAVE_OFP, HAVE_OMNI
available_frontends, OMNI, FP, REGEX, HAVE_FP, HAVE_OMNI
)
from loki.ir import nodes as ir, FindNodes, FindInlineCalls
from loki.transformations import (
DependencyTransformation, ModuleWrapTransformation
)


pytestmark = pytest.mark.skipif(not HAVE_FP and not HAVE_OFP, reason='Fparser and OFP not available')
pytestmark = pytest.mark.skipif(not HAVE_FP, reason='Fparser not available')


@pytest.fixture(scope='module', name='here')
Expand Down Expand Up @@ -116,7 +116,7 @@ def fixture_frontend():
independent from the specific frontend used. Cannot use OMNI for this
as not all tests have dependencies fully resolved.
"""
return FP if HAVE_FP else OFP
return FP


@pytest.fixture(name='driverA_dependencies')
Expand Down
16 changes: 5 additions & 11 deletions loki/expression/tests/test_expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from loki.build import jit_compile, clean_test
from loki.expression import symbols as sym, parse_expr, AttachScopesMapper
from loki.frontend import (
available_frontends, OFP, OMNI, FP, HAVE_FP, parse_fparser_expression
available_frontends, OMNI, FP, HAVE_FP, parse_fparser_expression
)
from loki.ir import (
nodes as ir, FindNodes, FindVariables, FindExpressions,
Expand Down Expand Up @@ -208,9 +208,7 @@ def test_boz_literals(tmp_path, frontend):
assert stmts[5].rhs.parameters[0].value == 'z"babe"'


@pytest.mark.parametrize('frontend', available_frontends(
skip={OFP: "Not implemented because too stupid in OFP parse tree"})
)
@pytest.mark.parametrize('frontend', available_frontends())
def test_complex_literals(tmp_path, frontend):
"""
Test complex literal values.
Expand Down Expand Up @@ -310,9 +308,7 @@ def test_logical_array(tmp_path, frontend):
clean_test(filepath)


@pytest.mark.parametrize('frontend', available_frontends(
xfail=[(OFP, 'Not implemented')]
))
@pytest.mark.parametrize('frontend', available_frontends())
def test_array_constructor(tmp_path, frontend):
"""
Test various array constructor formats
Expand Down Expand Up @@ -796,9 +792,7 @@ def test_masked_statements(tmp_path, frontend):
clean_test(filepath)


@pytest.mark.parametrize('frontend', available_frontends(xfail=[
(OFP, 'Current implementation does not handle nested where constructs')
]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_masked_statements_nested(tmp_path, frontend):
"""
Nested masked statements (WHERE(...) ... [ELSEWHERE ...] ENDWHERE)
Expand Down Expand Up @@ -1607,7 +1601,7 @@ def test_typebound_resolution_type_info(frontend, tmp_path):
))
def test_stmt_func_heuristic(frontend, tmp_path):
"""
Our Fparser/OFP translation has a heuristic to detect statement function declarations,
Our Fparser translation has a heuristic to detect statement function declarations,
but that falsely misinterpreted some assignments as statement functions due to
missing shape information (reported in #326)
"""
Expand Down
7 changes: 6 additions & 1 deletion loki/frontend/ofp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from loki.frontend.source import extract_source, extract_source_from_range
from loki.frontend.preprocessing import sanitize_registry
from loki.frontend.util import OFP, sanitize_ir
from loki.frontend.util import sanitize_ir, Frontend

from loki import ir
from loki.ir import (
Expand All @@ -47,6 +47,9 @@
__all__ = ['HAVE_OFP', 'parse_ofp_file', 'parse_ofp_source', 'parse_ofp_ast']


OFP = Frontend.OFP


@Timer(logger=debug, text=lambda s: f'[Loki::OFP] Executed parse_ofp_file in {s:.2f}s')
@disk_cached(argname='filename', suffix='ofpast')
def parse_ofp_file(filename):
Expand All @@ -58,6 +61,8 @@ def parse_ofp_file(filename):
if not HAVE_OFP:
error('OpenFortranParser is not available.')

warning('[DEPRECATION]: The OFP frontend is deprecated and will be removed soon!')

filepath = Path(filename)
info(f'[Loki::OFP] Parsing {filepath}')
return open_fortran_parser.parse(filepath, raise_on_error=True)
Expand Down
5 changes: 4 additions & 1 deletion loki/frontend/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
from loki.config import config
from loki.tools import as_tuple, gettempdir, filehash
from loki.ir import VariableDeclaration, Intrinsic, FindNodes
from loki.frontend.util import OMNI, OFP, FP, REGEX
from loki.frontend.util import OMNI, FP, REGEX, Frontend


__all__ = ['preprocess_cpp', 'sanitize_input', 'sanitize_registry', 'PPRule']


OFP = Frontend.OFP


def preprocess_cpp(source, filepath=None, includes=None, defines=None):
"""
Invoke an external C-preprocessor to sanitize input files.
Expand Down
17 changes: 6 additions & 11 deletions loki/frontend/tests/test_frontends.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
)
from loki.build import jit_compile, clean_test
from loki.expression import symbols as sym
from loki.frontend import available_frontends, OMNI, OFP, FP, REGEX
from loki.frontend import available_frontends, OMNI, FP, REGEX
from loki.ir import nodes as ir, FindNodes


Expand Down Expand Up @@ -364,9 +364,7 @@ def test_enum(tmp_path, frontend):
clean_test(filepath)


@pytest.mark.parametrize('frontend', available_frontends(
xfail=[(OFP, 'OFP fails to parse parameterized types')]
))
@pytest.mark.parametrize('frontend', available_frontends())
@pytest.mark.usefixtures('reset_frontend_mode')
def test_frontend_strict_mode(frontend, tmp_path):
"""
Expand Down Expand Up @@ -1622,7 +1620,7 @@ def test_regex_function_inline_return_type():
assert 'dot_product_ecv' in routine.variables


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'No support for prefix implemented')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_regex_prefix(frontend, tmp_path):
fcode = """
module some_mod
Expand Down Expand Up @@ -1842,12 +1840,9 @@ def test_inline_comments(frontend):
assert assigns[3].comment.text == '! wall !'

comments = FindNodes(ir.Comment).visit(routine.body)
assert len(comments) == 1 if frontend == OFP else 4
if frontend == OFP:
assert comments[0].text == '! Who said that?'
else:
assert comments[1].text == '! Who said that?'
assert comments[0].text == comments[2].text == comments[3].text == ''
assert len(comments) == 4
assert comments[1].text == '! Who said that?'
assert comments[0].text == comments[2].text == comments[3].text == ''


@pytest.mark.parametrize('from_file', (True, False))
Expand Down
9 changes: 5 additions & 4 deletions loki/frontend/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


__all__ = [
'Frontend', 'OFP', 'OMNI', 'FP', 'REGEX', 'available_frontends',
'Frontend', 'OMNI', 'FP', 'REGEX', 'available_frontends',
'read_file', 'InlineCommentTransformer',
'ClusterCommentTransformer', 'CombineMultilinePragmasTransformer',
'sanitize_ir'
Expand All @@ -50,7 +50,6 @@ def __str__(self):
return self.name.lower() # pylint: disable=no-member

OMNI = Frontend.OMNI
OFP = Frontend.OFP
FP = Frontend.FP
REGEX = Frontend.REGEX

Expand Down Expand Up @@ -113,6 +112,8 @@ def my_test(frontend):
# Build the list of parameters
params = []
for f in Frontend:
if f == Frontend.OFP:
continue # OFP is now deprecated!
if f in skip:
params += [pytest.param(f, marks=pytest.mark.skip(reason=skip[f]))]
elif f in xfail:
Expand Down Expand Up @@ -381,10 +382,10 @@ def sanitize_ir(_ir, frontend, pp_registry=None, pp_info=None):
# Revert OMNI's array dimension expansion from `a(n)` => `arr(1:n)`
_ir = RangeIndexTransformer(invalidate_source=False).visit(_ir)

if frontend in (OMNI, OFP):
if frontend in (OMNI, Frontend.OFP):
_ir = inline_labels(_ir)

if frontend in (FP, OFP):
if frontend in (FP, Frontend.OFP):
_ir = CombineMultilinePragmasTransformer(inplace=True, invalidate_source=False).visit(_ir)
_ir = RemoveDuplicateVariableDeclarationsForExternalProcedures(inplace=True, invalidate_source=False).visit(_ir)

Expand Down
3 changes: 1 addition & 2 deletions loki/ir/tests/test_control_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from loki import Subroutine
from loki.backend import fgen
from loki.build import jit_compile, clean_test
from loki.frontend import available_frontends, OMNI, OFP
from loki.frontend import available_frontends, OMNI
from loki.ir import nodes as ir, FindNodes


Expand Down Expand Up @@ -610,7 +610,6 @@ def test_single_line_forall_masked_stmt(tmp_path, frontend):

@pytest.mark.parametrize('frontend', available_frontends(xfail=[
(OMNI, 'Renames index variable to omnitmp000'),
(OFP, 'Parser fails to parse'),
]))
def test_multi_line_forall_construct(tmp_path, frontend):
fcode = """
Expand Down
5 changes: 4 additions & 1 deletion loki/sourcefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from loki.backend.fgen import fgen
from loki.backend.cufgen import cufgen
from loki.frontend import (
Frontend, OMNI, OFP, FP, REGEX, sanitize_input, Source, read_file, preprocess_cpp,
Frontend, OMNI, FP, REGEX, sanitize_input, Source, read_file, preprocess_cpp,
parse_omni_source, parse_ofp_source, parse_fparser_source,
parse_omni_ast, parse_ofp_ast, parse_fparser_ast, parse_regex_source,
RegexParserClass
Expand All @@ -32,6 +32,9 @@
__all__ = ['Sourcefile']


OFP = Frontend.OFP


class Sourcefile:
"""
Class to handle and manipulate source files, storing :any:`Module` and
Expand Down
6 changes: 2 additions & 4 deletions loki/tests/test_derived_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
FindVariables
)
from loki.build import jit_compile, jit_compile_lib, clean_test, Obj
from loki.frontend import available_frontends, OMNI, OFP
from loki.frontend import available_frontends, OMNI


@pytest.fixture(name='builder')
Expand Down Expand Up @@ -1204,9 +1204,7 @@ def test_derived_type_rescope_symbols_shadowed(tmp_path, shadowed_typedef_symbol
clean_test(filepath)


@pytest.mark.parametrize('frontend', available_frontends(xfail=[
(OFP, 'OFP cannot parse the Fortran')
]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_derived_types_character_array_subscript(frontend, tmp_path):
fcode = """
module derived_type_char_arr_mod
Expand Down
6 changes: 2 additions & 4 deletions loki/tests/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Scalar, DeferredTypeSymbol, FindVariables, SubstituteExpressions, Literal
)
from loki.build import jit_compile, clean_test
from loki.frontend import available_frontends, OFP, OMNI
from loki.frontend import available_frontends, OMNI
from loki.sourcefile import Sourcefile


Expand Down Expand Up @@ -933,9 +933,7 @@ def test_module_rename_imports_no_definitions(frontend, tmp_path):
assert use_name is None or f'{s} => {use_name}' in fcode


@pytest.mark.parametrize('frontend', available_frontends(
xfail=[(OFP, 'hasModuleNature on use-stmt but without conveying actual nature')]
))
@pytest.mark.parametrize('frontend', available_frontends())
def test_module_use_module_nature(frontend, tmp_path):
"""
Test module natures attributes in ``USE`` statements
Expand Down
6 changes: 3 additions & 3 deletions loki/tests/test_sourcefile.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
StatementFunction, Comment, CommentBlock, RawSource, Scalar
)
from loki.build import jit_compile, clean_test
from loki.frontend import available_frontends, OFP, OMNI, FP, REGEX
from loki.frontend import available_frontends, OMNI, FP, REGEX


@pytest.fixture(scope='module', name='here')
Expand Down Expand Up @@ -120,7 +120,7 @@ def test_sourcefile_pp_macros(here, frontend):


@pytest.mark.parametrize('frontend', available_frontends(xfail=[
(OFP, 'Cannot handle directives'), (OMNI, 'Files are preprocessed')
(OMNI, 'Files are preprocessed')
]))
def test_sourcefile_pp_directives(here, frontend):
filepath = here/'sources/sourcefile_pp_directives.F90'
Expand Down Expand Up @@ -193,7 +193,7 @@ def test_sourcefile_cpp_preprocessing(here, frontend):
assert 'b = 6' in fgen(routine)


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'No support for statement functions')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_sourcefile_cpp_stmt_func(here, frontend, tmp_path):
"""
Test the correct identification of statement functions
Expand Down
8 changes: 4 additions & 4 deletions loki/tests/test_subroutine.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
ProcedureSymbol, StatementFunction, DeferredTypeSymbol
)
from loki.build import jit_compile, jit_compile_lib, clean_test
from loki.frontend import available_frontends, OFP, OMNI, REGEX
from loki.frontend import available_frontends, OMNI, REGEX
from loki.types import BasicType, DerivedType, ProcedureType
from loki.ir import nodes as ir

Expand Down Expand Up @@ -1465,7 +1465,7 @@ def test_subroutine_rescope_clone(frontend):
)


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'No support for statement functions')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_subroutine_stmt_func(tmp_path, frontend):
"""
Test the correct identification of statement functions
Expand Down Expand Up @@ -1537,7 +1537,7 @@ def test_mixed_declaration_interface(frontend):
assert "Declarations must have intents" in str(error.value)


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'Prefix support not implemented')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_subroutine_prefix(frontend):
"""
Test various prefixes that can occur in function/subroutine definitions
Expand Down Expand Up @@ -1852,7 +1852,7 @@ def test_subroutine_lazy_arguments_incomplete2(frontend):
assert all(isinstance(arg, Array) for arg in routine.arguments[4:])


@pytest.mark.parametrize('frontend', available_frontends(xfail=[(OFP, 'Prefix support not implemented')]))
@pytest.mark.parametrize('frontend', available_frontends())
def test_subroutine_lazy_prefix(frontend):
"""
Test that prefixes for functions are correctly captured when the object is made
Expand Down
2 changes: 1 addition & 1 deletion loki/tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
FindNodes, ProcedureDeclaration
)
from loki.expression import symbols as sym
from loki.frontend import available_frontends, OFP, OMNI
from loki.frontend import available_frontends, OMNI


@pytest.fixture(scope='module', name='here')
Expand Down
Loading

0 comments on commit 58adb24

Please sign in to comment.