From 94b387f58973b1b35512defd0fc18e520a4433cb Mon Sep 17 00:00:00 2001 From: Kaushik Kulkarni Date: Tue, 1 Mar 2022 00:21:13 -0600 Subject: [PATCH] Implements CWithGNULibCTarget --- loopy/__init__.py | 5 ++- loopy/target/c/__init__.py | 72 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/loopy/__init__.py b/loopy/__init__.py index 0e6e9f87c..1f61c7719 100644 --- a/loopy/__init__.py +++ b/loopy/__init__.py @@ -149,7 +149,9 @@ from loopy.frontend.fortran import (c_preprocess, parse_transformed_fortran, parse_fortran) from loopy.target import TargetBase, ASTBuilderBase -from loopy.target.c import CFamilyTarget, CTarget, ExecutableCTarget, generate_header +from loopy.target.c import (CFamilyTarget, CTarget, ExecutableCTarget, + generate_header, CWithGNULibcTarget, + ExecutableCWithGNULibcTarget) from loopy.target.cuda import CudaTarget from loopy.target.opencl import OpenCLTarget from loopy.target.pyopencl import PyOpenCLTarget @@ -296,6 +298,7 @@ __all__ = [ "TargetBase", "CFamilyTarget", "CTarget", "ExecutableCTarget", "generate_header", + "CWithGNULibcTarget", "ExecutableCWithGNULibcTarget", "CudaTarget", "OpenCLTarget", "PyOpenCLTarget", "ISPCTarget", "NumbaTarget", "NumbaCudaTarget", diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 0058ad47f..3457b8e7e 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -677,6 +677,49 @@ class CMathCallable(ScalarCallable): }}""") +class GNULibcCallable(ScalarCallable): + def with_types(self, arg_id_to_dtype, callables_table): + name = self.name + + if name in ["bessel_jn", "bessel_yn"]: + # bessel functions + # https://www.gnu.org/software/libc/manual/html_node/Special-Functions.html + for id in arg_id_to_dtype: + if not -1 <= id <= 1: + raise LoopyError(f"'{name}' can take exactly 2 arguments.") + + if (not arg_id_to_dtype.get(0)) or (not arg_id_to_dtype.get(1)): + # the types provided aren't mature enough to specialize the + # callable + return ( + self.copy(arg_id_to_dtype=arg_id_to_dtype), + callables_table) + + if not arg_id_to_dtype[0].is_integral(): + raise LoopyTypeError(f"'{name}' needs order to be an int-type.") + + if arg_id_to_dtype[1].numpy_dtype == np.float32: + name_in_target = name[-2:]+"f" + elif arg_id_to_dtype[1].numpy_dtype == np.float64: + name_in_target = name[-2:] + else: + raise LoopyTypeError("argument to bessel function must be f32," + f"f64, got {arg_id_to_dtype[1].numpy_dtype}.") + + return ( + self.copy(name_in_target=name_in_target, + arg_id_to_dtype={-1: arg_id_to_dtype[1], + 0: NumpyType(np.int32), + 1: arg_id_to_dtype[1]}), + callables_table) + else: + raise NotImplementedError(f"with_types for '{name}'") + + def generate_preambles(self, target): + if self.name in ["bessel_yn", "bessel_jn"]: + yield("08_c_math", "#include ") + + def get_c_callables(): """ Returns an instance of :class:`InKernelCallable` if the function @@ -690,6 +733,13 @@ def get_c_callables(): return {id_: CMathCallable(id_) for id_ in cmath_ids} + +def get_gnu_libc_callables(): + # Support special functions from + # https://www.gnu.org/software/libc/manual/html_node/Special-Functions.html + func_ids = ["bessel_jn", "bessel_yn"] + return {id_: GNULibcCallable(id_) for id_ in func_ids} + # }}} @@ -1317,4 +1367,26 @@ class ExecutableCTarget(CTarget): # }}} + +# {{{ C99 (with GNULibc) callable target + +class CWithGNULibcTarget(CTarget): + def get_device_ast_builder(self): + return CWithGNULibcASTBuilder(self) + + +class CWithGNULibcASTBuilder(CASTBuilder): + @property + def known_callables(self): + callables = super().known_callables + callables.update(get_gnu_libc_callables()) + return callables + + +class ExecutableCWithGNULibcTarget(ExecutableCTarget): + def get_device_ast_builder(self): + return CWithGNULibcASTBuilder(self) + +# }}} + # vim: foldmethod=marker -- GitLab