From e712047fa3c1022dfeb2e6e38611a1057a5522ad Mon Sep 17 00:00:00 2001
From: Kaushik Kulkarni <15399010+kaushikcfd@users.noreply.github.com>
Date: Mon, 7 Jun 2021 14:14:37 -0500
Subject: [PATCH] Test against loopy::kernel_callables_v3-edit2 (#88)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* bessel function mangling -> BesselFunction: ScalarCallable

* query translation unit's default_entrypoint's args

* [drop before merge]: test with kcv3-e2

* Add transfer_requirements_git_urls from grudge to downstream projects

* Point requirements.txt for loopy back to main

Co-authored-by: Andreas Klöckner <inform@tiker.net>
---
 .github/workflows/ci.yml    |  9 ++--
 grudge/symbolic/compiler.py | 84 +++++++++++++++++--------------------
 2 files changed, 45 insertions(+), 48 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 55ee6c05..e76d508e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -88,6 +88,9 @@ jobs:
             env:
                 DOWNSTREAM_PROJECT: ${{ matrix.downstream_project }}
             run: |
+                curl -L -O -k https://tiker.net/ci-support-v0
+                . ./ci-support-v0
+
                 if test "$DOWNSTREAM_PROJECT" = "mirgecom"; then
                     git clone "https://github.com/illinois-ceesd/$DOWNSTREAM_PROJECT.git"
                 else
@@ -95,7 +98,10 @@ jobs:
                 fi
                 cd "$DOWNSTREAM_PROJECT"
                 echo "*** $DOWNSTREAM_PROJECT version: $(git rev-parse --short HEAD)"
+
+                transfer_requirements_git_urls ../requirements.txt ./requirements.txt
                 sed -i "/egg=grudge/ c git+file://$(readlink -f ..)#egg=grudge" requirements.txt
+
                 # Avoid slow or complicated tests in downstream projects
                 export PYTEST_ADDOPTS="-k 'not (slowtest or octave or mpi)'"
                 if test "$DOWNSTREAM_PROJECT" = "mirgecom"; then
@@ -107,9 +113,6 @@ jobs:
                 else
                     sed -i "/mpi4py/ d" requirements.txt
                 fi
-
-                curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/master/ci-support.sh
-                . ./ci-support.sh
                 build_py_project_in_conda_env
                 test_py_project
 
diff --git a/grudge/symbolic/compiler.py b/grudge/symbolic/compiler.py
index f5f7c664..fd6b9c78 100644
--- a/grudge/symbolic/compiler.py
+++ b/grudge/symbolic/compiler.py
@@ -33,6 +33,7 @@ from pymbolic.primitives import Variable, Subscript
 from sys import intern
 from functools import reduce
 
+from loopy import ScalarCallable
 from loopy.version import LOOPY_USE_LANGUAGE_VERSION_2018_2  # noqa: F401
 
 
@@ -83,7 +84,7 @@ class LoopyKernelDescriptor:
     @memoize_method
     def scalar_args(self):
         import loopy as lp
-        return [arg.name for arg in self.loopy_kernel.args
+        return [arg.name for arg in self.loopy_kernel.default_entrypoint.args
                 if isinstance(arg, lp.ValueArg)
                 and arg.name not in ["nelements", "nunit_dofs"]]
 
@@ -923,53 +924,48 @@ class ToLoopyExpressionMapper(mappers.IdentityMapper):
 
 # {{{ bessel handling
 
-BESSEL_PREAMBLE = """//CL//
-#include <pyopencl-bessel-j.cl>
-#include <pyopencl-bessel-y.cl>
-"""
-
-
-def bessel_preamble_generator(preamble_info):
-    from loopy.target.pyopencl import PyOpenCLTarget
-    if not isinstance(preamble_info.kernel.target, PyOpenCLTarget):
-        raise NotImplementedError("Only the PyOpenCLTarget is supported as of now")
-
-    if any(func.name in ["bessel_j", "bessel_y"]
-            for func in preamble_info.seen_functions):
-        yield ("50-grudge-bessel", BESSEL_PREAMBLE)
-
-
-def bessel_function_mangler(kernel, name, arg_dtypes):
-    from loopy.types import NumpyType
-    if name == "bessel_j" and len(arg_dtypes) == 2:
-        n_dtype, x_dtype, = arg_dtypes
+class BesselFunction(ScalarCallable):
+    def with_types(self, arg_id_to_dtype, clbl_inf_ctx):
+        from loopy.types import NumpyType
 
-        # *technically* takes a float, but let's not worry about that.
-        if n_dtype.numpy_dtype.kind != "i":
-            raise TypeError("%s expects an integer first argument")
+        for i in arg_id_to_dtype:
+            if not (-1 <= i <= 1):
+                raise TypeError(f"{self.name} can only take 2 arguments.")
 
-        from loopy.kernel.data import CallMangleInfo
-        return CallMangleInfo(
-                "bessel_jv",
-                (NumpyType(np.float64),),
-                (NumpyType(np.int32), NumpyType(np.float64)),
-                )
+        if (arg_id_to_dtype.get(0) is None) or (arg_id_to_dtype.get(1) is None):
+            # not enough info about input types
+            return self, clbl_inf_ctx
 
-    elif name == "bessel_y" and len(arg_dtypes) == 2:
-        n_dtype, x_dtype, = arg_dtypes
+        n_dtype = arg_id_to_dtype[0]
 
         # *technically* takes a float, but let's not worry about that.
         if n_dtype.numpy_dtype.kind != "i":
-            raise TypeError("%s expects an integer first argument")
+            raise TypeError(f"{self.name} expects an integer first argument")
 
-        from loopy.kernel.data import CallMangleInfo
-        return CallMangleInfo(
-                "bessel_yn",
-                (NumpyType(np.float64),),
-                (NumpyType(np.int32), NumpyType(np.float64)),
-                )
-
-    return None
+        if self.name == "bessel_j":
+            name_in_target = "bessel_jv"
+        else:
+            assert self.name == "bessel_y"
+            name_in_target = "bessel_yn"
+
+        return (self.copy(name_in_target=name_in_target,
+                          arg_id_to_dtype={-1: NumpyType(np.float64),
+                                           0: NumpyType(np.int32),
+                                           1: NumpyType(np.float64),
+                                           }),
+                clbl_inf_ctx)
+
+    def generate_preambles(self, target):
+        from loopy import PyOpenCLTarget
+        if not isinstance(target, PyOpenCLTarget):
+            raise NotImplementedError("Only the PyOpenCLTarget is supported as"
+                                      "of now.")
+
+        yield ("50-grudge-bessel", """//CL//
+                                   #include <pyopencl-bessel-j.cl>
+                                   #include <pyopencl-bessel-y.cl>
+                                   """)
+        return
 
 # }}}
 
@@ -1046,10 +1042,8 @@ class ToLoopyInstructionMapper:
                 self.dd_inference_mapper(expr)
                 for expr in insn.exprs)
 
-        knl = lp.register_preamble_generators(knl,
-                [bessel_preamble_generator])
-        knl = lp.register_function_manglers(knl,
-                [bessel_function_mangler])
+        knl = lp.register_callable(knl, "bessel_j", BesselFunction("bessel_j"))
+        knl = lp.register_callable(knl, "bessel_y", BesselFunction("bessel_y"))
 
         input_mappings = {}
         output_mappings = {}
-- 
GitLab