From d8be1eaedc7561ea4e84edebad6d7c74878246a4 Mon Sep 17 00:00:00 2001
From: Andreas Kloeckner <inform@tiker.net>
Date: Wed, 10 Jun 2015 20:57:44 -0500
Subject: [PATCH] Revamp how Fortran source processing is done, expose passes
 in Python transforms

---
 bin/loopy                                  |  29 ++-
 doc/reference.rst                          |   6 +
 examples/fortran/foo.floopy                |  15 +-
 examples/fortran/matmul.floopy             |   6 +-
 examples/fortran/outerprod.py              |   8 -
 examples/fortran/sparse.floopy             |   6 +-
 examples/fortran/tagging.floopy            |   7 +-
 examples/fortran/volumeKernel.floopy       |   6 +-
 examples/fortran/volumeKernelSimple.floopy |   6 +-
 examples/python/hello-loopy-lp.py          |  11 ++
 loopy/__init__.py                          |   3 +
 loopy/frontend/fortran/__init__.py         | 211 +++++++++++++++------
 loopy/frontend/fortran/translator.py       |  51 +----
 test/test_fortran.py                       |  48 ++---
 14 files changed, 240 insertions(+), 173 deletions(-)
 delete mode 100644 examples/fortran/outerprod.py
 create mode 100644 examples/python/hello-loopy-lp.py

diff --git a/bin/loopy b/bin/loopy
index 0f7b9a607..e607a6793 100644
--- a/bin/loopy
+++ b/bin/loopy
@@ -71,23 +71,23 @@ def main():
         with open(args.infile, "r") as infile_fd:
             infile_content = infile_fd.read()
 
-    # {{{ path wrangling
+    if args.lang == "loopy":
+        # {{{ path wrangling
 
-    from os.path import dirname, abspath
-    from os import getcwd
+        from os.path import dirname, abspath
+        from os import getcwd
 
-    infile_dirname = dirname(args.infile)
-    if infile_dirname:
-        infile_dirname = abspath(infile_dirname)
-    else:
-        infile_dirname = getcwd()
+        infile_dirname = dirname(args.infile)
+        if infile_dirname:
+            infile_dirname = abspath(infile_dirname)
+        else:
+            infile_dirname = getcwd()
 
-    import sys
-    sys.path.append(infile_dirname)
+        import sys
+        sys.path.append(infile_dirname)
 
-    # }}}
+        # }}}
 
-    if args.lang == "loopy":
         data_dic = {}
         data_dic["lp"] = lp
         data_dic["np"] = np
@@ -131,9 +131,8 @@ def main():
                         defines_to_python_code(defines_fd.read())
                         + pre_transform_code)
 
-        from loopy.frontend.fortran import f2loopy
-        kernels = f2loopy(infile_content, pre_transform_code=pre_transform_code,
-                use_c_preprocessor=(args.lang == "fpp"))
+        kernels = lp.parse_transformed_fortran(
+                infile_content, pre_transform_code=pre_transform_code)
 
         if args.name is not None:
             kernels = [kernel for kernel in kernels
diff --git a/doc/reference.rst b/doc/reference.rst
index af39de655..6ed83d430 100644
--- a/doc/reference.rst
+++ b/doc/reference.rst
@@ -334,10 +334,16 @@ function, which is responsible for creating kernels:
 
 .. autofunction:: make_kernel
 
+.. autofunction:: parse_fortran
+
+.. autofunction:: parse_transformed_fortran
+
 .. autofunction:: make_copy_kernel
 
 .. autofunction:: fuse_kernels
 
+.. autofunction:: c_preprocess
+
 Transforming Kernels
 --------------------
 
diff --git a/examples/fortran/foo.floopy b/examples/fortran/foo.floopy
index 9b0575607..6b8741e11 100644
--- a/examples/fortran/foo.floopy
+++ b/examples/fortran/foo.floopy
@@ -1,8 +1,3 @@
-!$loopy begin define
-! define("factor 4.0")
-! define("real_type real*8")
-!$loopy end define
-
 subroutine fill(out, a, n)
   implicit none
 
@@ -17,13 +12,19 @@ subroutine fill(out, a, n)
   end do
 end
 
-!$loopy begin transform
+!$loopy begin
 !
+! SOURCE = lp.c_preprocess(SOURCE, [
+!       "factor 4.0",
+!       "real_type real*8",
+!       ])
+! fill, = lp.parse_fortran(SOURCE, FILENAME)
 ! fill = lp.split_iname(fill, "i", 128,
 !     outer_tag="g.0", inner_tag="l.0")
 ! fill = lp.split_iname(fill, "i_1", 128,
 !     outer_tag="g.0", inner_tag="l.0")
+! RESULT = [fill]
 !
-!$loopy end transform
+!$loopy end
 
 ! vim:filetype=floopy
diff --git a/examples/fortran/matmul.floopy b/examples/fortran/matmul.floopy
index ea85b0c6b..3352449d7 100644
--- a/examples/fortran/matmul.floopy
+++ b/examples/fortran/matmul.floopy
@@ -12,7 +12,8 @@ subroutine dgemm(m,n,l,alpha,a,b,c)
   end do
 end subroutine
 
-!$loopy begin transform
+!$loopy begin
+! dgemm, = lp.parse_fortran(SOURCE, FILENAME)
 ! dgemm = lp.split_iname(dgemm, "i", 16,
 !         outer_tag="g.0", inner_tag="l.1")
 ! dgemm = lp.split_iname(dgemm, "j", 8,
@@ -23,4 +24,5 @@ end subroutine
 ! dgemm = lp.extract_subst(dgemm, "b_acc", "b[i1,i2]", parameters="i1, i2")
 ! dgemm = lp.precompute(dgemm, "a_acc", "k_inner,i_inner")
 ! dgemm = lp.precompute(dgemm, "b_acc", "j_inner,k_inner")
-!$loopy end transform
+! RESULT = [dgemm]
+!$loopy end
diff --git a/examples/fortran/outerprod.py b/examples/fortran/outerprod.py
deleted file mode 100644
index 4122c8437..000000000
--- a/examples/fortran/outerprod.py
+++ /dev/null
@@ -1,8 +0,0 @@
-lp_knl = lp.make_kernel(
-	"{[i,j]: 0<=i,j<n}",
-	"c[i,j] = a[i]*b[j]")
-
-lp_knl = lp.add_dtypes(lp_knl, {"a": np.float64, "b": np.float64})
-lp_knl = lp.split_iname(lp_knl, "i", 16, outer_tag="g.0", inner_tag="l.0")
-lp_knl = lp.split_iname(lp_knl, "j", 16, outer_tag="g.1", inner_tag="l.1")
-
diff --git a/examples/fortran/sparse.floopy b/examples/fortran/sparse.floopy
index f3cb50290..18542e6b0 100644
--- a/examples/fortran/sparse.floopy
+++ b/examples/fortran/sparse.floopy
@@ -22,10 +22,12 @@ subroutine sparse(rowstarts, colindices, values, m, n, nvals, x, y)
   end do
 end
 
-!$loopy begin transform
+!$loopy begin
+! sparse, = lp.parse_fortran(SOURCE, FILENAME)
 ! sparse = lp.split_iname(sparse, "i", 128)
 ! sparse = lp.tag_inames(sparse, {"i_outer": "g.0"})
 ! sparse = lp.tag_inames(sparse, {"i_inner": "l.0"})
 ! sparse = lp.split_iname(sparse, "j", 4)
 ! sparse = lp.tag_inames(sparse, {"j_inner": "unr"})
-!$loopy end transform
+! RESULT = [sparse]
+!$loopy end
diff --git a/examples/fortran/tagging.floopy b/examples/fortran/tagging.floopy
index e7deb113a..40b487528 100644
--- a/examples/fortran/tagging.floopy
+++ b/examples/fortran/tagging.floopy
@@ -14,11 +14,12 @@ subroutine fill(out, a, n)
   end do
 end
 
-!$loopy begin transform
-!
+!$loopy begin
+! fill, = lp.parse_fortran(SOURCE, FILENAME)
 ! fill = lp.split_iname(fill, "i", 128,
 !     outer_tag="g.0", inner_tag="l.0")
 ! fill = lp.split_iname(fill, "i_1", 128,
 !     outer_tag="g.0", inner_tag="l.0")
-!$loopy end transform
+! RESULT = [fill]
+!$loopy end
 ! vim:filetype=floopy
diff --git a/examples/fortran/volumeKernel.floopy b/examples/fortran/volumeKernel.floopy
index 953432d22..c5784b634 100644
--- a/examples/fortran/volumeKernel.floopy
+++ b/examples/fortran/volumeKernel.floopy
@@ -65,8 +65,9 @@ subroutine volumeKernel(elements, Nfields, Ngeo, Ndim, Dop, geo, Q, rhsQ  )
 
 end subroutine volumeKernel
 
-!$loopy begin transform
+!$loopy begin
 !
+! volumeKernel, = lp.parse_fortran(SOURCE, FILENAME)
 ! volumeKernel = lp.split_iname(volumeKernel,
 !     "e", 32, outer_tag="g.1", inner_tag="g.0")
 ! volumeKernel = lp.fix_parameters(volumeKernel,
@@ -75,5 +76,6 @@ end subroutine volumeKernel
 !     i="l.0", j="l.1", k="l.2",
 !     i_1="l.0", j_1="l.1", k_1="l.2"
 !     ))
+! RESULT = [volumeKernel]
 !
-!$loopy end transform
+!$loopy end
diff --git a/examples/fortran/volumeKernelSimple.floopy b/examples/fortran/volumeKernelSimple.floopy
index 67948020d..afc3321b8 100644
--- a/examples/fortran/volumeKernelSimple.floopy
+++ b/examples/fortran/volumeKernelSimple.floopy
@@ -27,10 +27,12 @@ subroutine volumeKernel(elements, Nfields, Ngeo, Ndim, Dop, geo, Q, rhsQ  )
 
 end subroutine volumeKernel
 
-!$loopy begin transform
+!$loopy begin
 !
+! volumeKernel, = lp.parse_fortran(SOURCE, FILENAME)
 ! volumeKernel = lp.fix_parameters(volumeKernel,
 !     Nq=5, Ndim=3)
 ! volumeKernel = lp.tag_inames(volumeKernel, dict(i="l.0"))
+! RESULT = [volumeKernel]
 !
-!$loopy end transform
+!$loopy end
diff --git a/examples/python/hello-loopy-lp.py b/examples/python/hello-loopy-lp.py
new file mode 100644
index 000000000..382aadc09
--- /dev/null
+++ b/examples/python/hello-loopy-lp.py
@@ -0,0 +1,11 @@
+# This is a version of hello-loopy.py that can be run through
+# a loopy binary using
+#
+# ./loopy --lang=loopy hello-loopy-lp.py -
+
+knl = lp.make_kernel(
+        "{ [i]: 0<=i<n }",
+        "out[i] = 2*a[i]")
+
+knl = lp.add_and_infer_dtypes(knl, dict(a=np.float32))
+lp_knl = lp.split_iname(knl, "i", 128, outer_tag="g.0", inner_tag="l.0")
diff --git a/loopy/__init__.py b/loopy/__init__.py
index 7bc45d3b1..f2b04d49f 100644
--- a/loopy/__init__.py
+++ b/loopy/__init__.py
@@ -67,6 +67,8 @@ from loopy.codegen import generate_code, generate_body
 from loopy.compiled import CompiledKernel
 from loopy.options import Options
 from loopy.auto_test import auto_test_vs_ref
+from loopy.frontend.fortran import (c_preprocess, parse_transformed_fortran,
+        parse_fortran)
 
 __all__ = [
         "TaggedVariable", "Reduction", "LinearSubscript",
@@ -107,6 +109,7 @@ __all__ = [
         "Options",
 
         "make_kernel",
+        "c_preprocess", "parse_transformed_fortran", "parse_fortran",
 
         # {{{ from this file
 
diff --git a/loopy/frontend/fortran/__init__.py b/loopy/frontend/fortran/__init__.py
index c6b6b3c71..bd798966d 100644
--- a/loopy/frontend/fortran/__init__.py
+++ b/loopy/frontend/fortran/__init__.py
@@ -25,22 +25,61 @@ THE SOFTWARE.
 from loopy.diagnostic import LoopyError
 
 
-def _extract_define_lines(source):
+def c_preprocess(source, defines=None, file_name="<floopy source>"):
+    """
+    :arg source: a string, possibly containing C preprocessor constructs
+    :arg defines: a list of strings as they might occur after a
+        C-style ``#define`` directive, for example ``deg2rad(x) (x/180d0 * 3.14d0)``.
+    :return: a string
+    """
+    try:
+        import ply.lex as lex
+        import ply.cpp as cpp
+    except ImportError:
+        raise LoopyError("Using the C preprocessor requires PLY to be installed")
+
+    lexer = lex.lex(cpp)
+
+    from ply.cpp import Preprocessor
+    p = Preprocessor(lexer)
+
+    if defines:
+        for d in defines:
+            p.define(d)
+
+    p.parse(source, file_name)
+
+    tokens = []
+    while True:
+        tok = p.token()
+
+        if not tok:
+            break
+
+        if tok.type == "CPP_COMMENT":
+            continue
+
+        tokens.append(tok.value)
+
+    return "".join(tokens)
+
+
+def _extract_loopy_lines(source):
     lines = source.split("\n")
 
     import re
     comment_re = re.compile(r"^\s*\!(.*)$")
 
     remaining_lines = []
-    define_lines = []
+    loopy_lines = []
 
-    in_define_code = False
+    in_loopy_code = False
     for l in lines:
         comment_match = comment_re.match(l)
 
         if comment_match is None:
-            if in_define_code:
-                raise LoopyError("non-comment source line in define block")
+            if in_loopy_code:
+                raise LoopyError("non-comment source line in loopy block")
 
             remaining_lines.append(l)
             continue
@@ -48,91 +87,143 @@ def _extract_define_lines(source):
         cmt = comment_match.group(1)
         cmt_stripped = cmt.strip()
 
-        if cmt_stripped == "$loopy begin define":
-            if in_define_code:
-                raise LoopyError("can't enter transform code twice")
-            in_define_code = True
+        if cmt_stripped == "$loopy begin":
+            if in_loopy_code:
+                raise LoopyError("can't enter loopy block twice")
+            in_loopy_code = True
 
-        elif cmt_stripped == "$loopy end define":
-            if not in_define_code:
-                raise LoopyError("can't leave transform code twice")
-            in_define_code = False
+        elif cmt_stripped == "$loopy end":
+            if not in_loopy_code:
+                raise LoopyError("can't leave loopy block twice")
+            in_loopy_code = False
 
-        elif in_define_code:
-            define_lines.append(cmt)
+        elif in_loopy_code:
+            loopy_lines.append(cmt)
 
         else:
             remaining_lines.append(l)
 
-    return "\n".join(remaining_lines), "\n".join(define_lines)
+    return "\n".join(remaining_lines), "\n".join(loopy_lines)
 
 
-def f2loopy(source, free_form=True, strict=True,
+def parse_transformed_fortran(source, free_form=True, strict=True,
         pre_transform_code=None, transform_code_context=None,
-        use_c_preprocessor=False, preprocessor_defines=None,
-        file_name="<floopy code>"):
+        filename="<floopy code>"):
     """
-    :arg preprocessor_defines: a list of strings as they might occur after a
-        C-style ``#define`` directive, for example ``deg2rad(x) (x/180d0 * 3.14d0)``.
+    :arg source: a string of Fortran source code which must include
+        a snippet of transform code as described below.
+    :arg pre_transform_code: code that is run in the same context
+        as the transform
+
+    *source* may contain snippets of loopy transform code between markers::
+
+        !$loopy begin
+        ! ...
+        !$loopy end
+
+    Within the transform code, the following symbols are predefined:
+
+    * ``lp``: a reference to the :mod:`loopy` package
+    * ``np``: a reference to the :mod:`numpy` package
+    * ``SOURCE``: the source code surrounding the transform block.
+      This may be processed using :func:`c_preprocess` and
+      :func:`parse_fortran`.
+    * ``FILENAME``: the file name of the code being processed
+
+    The transform code must define ``RESULT``, conventionally a list of
+    kernels, which is returned from this function unmodified.
+
+    An example of *source* may look as follows::
+
+        subroutine fill(out, a, n)
+          implicit none
+
+          real*8 a, out(n)
+          integer n, i
+
+          do i = 1, n
+            out(i) = a
+          end do
+        end
+
+        !$loopy begin
+        !
+        ! fill, = lp.parse_fortran(SOURCE, FILENAME)
+        ! fill = lp.split_iname(fill, "i", split_amount,
+        !     outer_tag="g.0", inner_tag="l.0")
+        ! RESULT = [fill]
+        !
+        !$loopy end
     """
-    if use_c_preprocessor:
-        try:
-            import ply.lex as lex
-            import ply.cpp as cpp
-        except ImportError:
-            raise LoopyError("Using the C preprocessor requires PLY to be installed")
 
-        lexer = lex.lex(cpp)
+    source, transform_code = _extract_loopy_lines(source)
+    if not transform_code:
+        raise LoopyError("no transform code found")
+
+    from loopy.tools import remove_common_indentation
+    transform_code = remove_common_indentation(
+            transform_code,
+            require_leading_newline=False)
 
-        from ply.cpp import Preprocessor
-        p = Preprocessor(lexer)
+    if transform_code_context is None:
+        proc_dict = {}
+    else:
+        proc_dict = transform_code_context.copy()
 
-        if preprocessor_defines:
-            for d in preprocessor_defines:
-                p.define(d)
+    import loopy as lp
+    import numpy as np
 
-        source, define_code = _extract_define_lines(source)
-        if define_code is not None:
-            from loopy.tools import remove_common_indentation
-            define_code = remove_common_indentation(
-                    define_code,
-                    require_leading_newline=False)
-            def_dict = {}
-            def_dict["define"] = p.define
+    proc_dict["lp"] = lp
+    proc_dict["np"] = np
 
-            if pre_transform_code is not None:
-                def_dict["_MODULE_SOURCE_CODE"] = pre_transform_code
-                exec(compile(pre_transform_code,
-                    "<loopy pre-transform code>", "exec"), def_dict)
+    proc_dict["SOURCE"] = source
+    proc_dict["FILENAME"] = filename
 
-            def_dict["_MODULE_SOURCE_CODE"] = define_code
-            exec(compile(define_code, "<loopy defines>", "exec"), def_dict)
+    from os.path import dirname, abspath
+    from os import getcwd
 
-        p.parse(source, file_name)
+    infile_dirname = dirname(filename)
+    if infile_dirname:
+        infile_dirname = abspath(infile_dirname)
+    else:
+        infile_dirname = getcwd()
 
-        tokens = []
-        while True:
-            tok = p.token()
+    import sys
+    prev_sys_path = sys.path
+    try:
+        if infile_dirname:
+            sys.path = prev_sys_path + [infile_dirname]
 
-            if not tok:
-                break
+        if pre_transform_code is not None:
+            proc_dict["_MODULE_SOURCE_CODE"] = pre_transform_code
+            exec(compile(pre_transform_code,
+                "<loopy pre-transform code>", "exec"), proc_dict)
 
-            if tok.type == "CPP_COMMENT":
-                continue
+        proc_dict["_MODULE_SOURCE_CODE"] = transform_code
+        exec(compile(transform_code, filename, "exec"), proc_dict)
 
-            tokens.append(tok.value)
+    finally:
+        sys.path = prev_sys_path
 
-        source = "".join(tokens)
+    if "RESULT" not in proc_dict:
+        raise LoopyError("transform code did not set RESULT")
 
+    return proc_dict["RESULT"]
+
+
+def parse_fortran(source, filename="<floopy code>", free_form=True, strict=True):
+    """
+    :returns: a list of :class:`loopy.LoopKernel` objects
+    """
     from fparser import api
     tree = api.parse(source, isfree=free_form, isstrict=strict,
             analyze=False, ignore_comments=False)
 
     from loopy.frontend.fortran.translator import F2LoopyTranslator
-    f2loopy = F2LoopyTranslator(file_name)
+    f2loopy = F2LoopyTranslator(filename)
     f2loopy(tree)
 
-    return f2loopy.make_kernels(pre_transform_code=pre_transform_code,
-            transform_code_context=transform_code_context)
+    return f2loopy.make_kernels()
+
 
 # vim: foldmethod=marker
diff --git a/loopy/frontend/fortran/translator.py b/loopy/frontend/fortran/translator.py
index eba76338d..9d6e3ea95 100644
--- a/loopy/frontend/fortran/translator.py
+++ b/loopy/frontend/fortran/translator.py
@@ -208,15 +208,9 @@ class F2LoopyTranslator(FTreeWalkerBase):
 
         self.kernels = []
 
-        # Flag to record whether 'loopy begin transform' comment
-        # has been seen.
-        self.in_transform_code = False
-
         self.instruction_tags = []
         self.conditions = []
 
-        self.transform_code_lines = []
-
         self.filename = filename
 
         self.index_dtype = None
@@ -606,17 +600,7 @@ class F2LoopyTranslator(FTreeWalkerBase):
         faulty_loopy_pragma_match = self.faulty_loopy_pragma.match(
                 stripped_comment_line)
 
-        if stripped_comment_line == "$loopy begin transform":
-            if self.in_transform_code:
-                raise TranslationError("can't enter transform code twice")
-            self.in_transform_code = True
-
-        elif stripped_comment_line == "$loopy end transform":
-            if not self.in_transform_code:
-                raise TranslationError("can't leave transform code twice")
-            self.in_transform_code = False
-
-        elif begin_tag_match:
+        if begin_tag_match:
             tag = begin_tag_match.group(1)
             if tag in self.instruction_tags:
                 raise TranslationError("nested begin tag for tag '%s'" % tag)
@@ -629,9 +613,6 @@ class F2LoopyTranslator(FTreeWalkerBase):
                         "end tag without begin tag for tag '%s'" % tag)
             self.instruction_tags.remove(tag)
 
-        elif self.in_transform_code:
-            self.transform_code_lines.append(node.content)
-
         elif faulty_loopy_pragma_match is not None:
             from warnings import warn
             warn("The comment line '%s' was not recognized as a loopy directive"
@@ -641,18 +622,12 @@ class F2LoopyTranslator(FTreeWalkerBase):
 
     # }}}
 
-    def make_kernels(self, pre_transform_code=None, transform_code_context=None):
+    def make_kernels(self):
         kernel_names = [
                 sub.subprogram_name
                 for sub in self.kernels]
 
-        if transform_code_context is None:
-            proc_dict = {}
-        else:
-            proc_dict = transform_code_context.copy()
-
-        proc_dict["lp"] = lp
-        proc_dict["np"] = np
+        result = []
 
         for sub in self.kernels:
             # {{{ figure out arguments
@@ -704,25 +679,11 @@ class F2LoopyTranslator(FTreeWalkerBase):
 
             from loopy.loop import fuse_loop_domains
             knl = fuse_loop_domains(knl)
+            knl = lp.fold_constants(knl)
 
-            proc_dict[sub.subprogram_name] = lp.fold_constants(knl)
-
-        from loopy.tools import remove_common_indentation
-        transform_code = remove_common_indentation(
-                "\n".join(self.transform_code_lines),
-                require_leading_newline=False)
-
-        if pre_transform_code is not None:
-            proc_dict["_MODULE_SOURCE_CODE"] = pre_transform_code
-            exec(compile(pre_transform_code,
-                "<loopy pre-transform code>", "exec"), proc_dict)
-
-        proc_dict["_MODULE_SOURCE_CODE"] = transform_code
-        exec(compile(transform_code,
-            "<loopy transforms>", "exec"), proc_dict)
+            result.append(knl)
 
-        return [proc_dict[knl_name]
-                for knl_name in kernel_names]
+        return result
 
 # }}}
 
diff --git a/test/test_fortran.py b/test/test_fortran.py
index ce27424d8..124035e52 100644
--- a/test/test_fortran.py
+++ b/test/test_fortran.py
@@ -58,16 +58,20 @@ def test_fill(ctx_factory):
           end do
         end
 
-        !$loopy begin transform
+        !$loopy begin
         !
-        ! fill = lp.split_iname(fill, "i", 128,
+        ! fill, = lp.parse_fortran(SOURCE)
+        ! fill = lp.split_iname(fill, "i", split_amount,
         !     outer_tag="g.0", inner_tag="l.0")
+        ! RESULT = [fill]
         !
-        !$loopy end transform
+        !$loopy end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_transformed_fortran(fortran_src,
+            pre_transform_code="split_amount = 128")
+
+    assert "i_inner" in knl.all_inames()
 
     ctx = ctx_factory()
 
@@ -88,8 +92,7 @@ def test_fill_const(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     ctx = ctx_factory()
 
@@ -112,8 +115,7 @@ def test_asterisk_in_shape(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     ctx = ctx_factory()
     queue = cl.CommandQueue(ctx)
@@ -137,8 +139,7 @@ def test_temporary_to_subst(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     ref_knl = knl
 
@@ -165,8 +166,7 @@ def test_temporary_to_subst_two_defs(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     ref_knl = knl
 
@@ -194,8 +194,7 @@ def test_temporary_to_subst_indices(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     knl = lp.fix_parameters(knl, n=5)
 
@@ -232,8 +231,7 @@ def test_if(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     ref_knl = knl
 
@@ -267,8 +265,7 @@ def test_tagged(ctx_factory):
         end
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     assert sum(1 for insn in lp.find_instructions(knl, "*$input")) == 2
 
@@ -294,8 +291,7 @@ def test_matmul(ctx_factory, buffer_inames):
         end subroutine
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     assert len(knl.domains) == 1
 
@@ -357,8 +353,7 @@ def test_batched_sparse():
 
         """
 
-    from loopy.frontend.fortran import f2loopy
-    knl, = f2loopy(fortran_src)
+    knl, = lp.parse_fortran(fortran_src)
 
     knl = lp.split_iname(knl, "i", 128)
     knl = lp.tag_inames(knl, {"i_outer": "g.0"})
@@ -393,12 +388,11 @@ def test_fuse_kernels(ctx_factory):
     xd_line = "result(e,i,j) = result(e,i,j) + d(i,k)*q(e,i,k)"
     yd_line = "result(e,i,j) = result(e,i,j) + d(i,k)*q(e,k,j)"
 
-    from loopy.frontend.fortran import f2loopy
-    xderiv, = f2loopy(
+    xderiv, = lp.parse_fortran(
             fortran_template.format(line=xd_line, name="xderiv"))
-    yderiv, = f2loopy(
+    yderiv, = lp.parse_fortran(
             fortran_template.format(line=yd_line, name="yderiv"))
-    xyderiv, = f2loopy(
+    xyderiv, = lp.parse_fortran(
             fortran_template.format(
                 line=(xd_line + "\n" + yd_line), name="xyderiv"))
 
-- 
GitLab