From fee76e90467fc6e196ca541cfe76843056808bed Mon Sep 17 00:00:00 2001 From: Pablo Brubeck Date: Wed, 4 Mar 2026 17:30:10 +0000 Subject: [PATCH 1/3] Support for GNU Scientific Library --- loopy/target/c/__init__.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index a2885b7bf..213abf96e 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -846,6 +846,30 @@ def generate_preambles(self, target): yield ("08_c_math", "#include ") +class GSLCallable(ScalarCallable): + @override + def with_types(self, + arg_id_to_dtype: Mapping[int | str, LoopyType], + clbl_inf_ctx: CallablesInferenceContext, + ) -> tuple[Self, CallablesInferenceContext]: + name = self.name + + for id in arg_id_to_dtype: + if not isinstance(id, int): + raise LoopyError(f"'{name}' can take only positional arguments") + + arg_num_to_dtype = {cast("int", id): t for id, t in arg_id_to_dtype.items()} + arg_num_to_dtype[-1] = arg_num_to_dtype[max(arg_num_to_dtype)] + + name_in_target = f"gsl_sf_{name}" + return (self.copy(name_in_target=name_in_target, + arg_id_to_dtype=constantdict(arg_num_to_dtype)), + clbl_inf_ctx) + + def generate_preambles(self, target): + yield ("40_c_gsl_math", "#include ") + + def get_c_callables(): """ Returns an instance of :class:`InKernelCallable` if the function @@ -866,6 +890,14 @@ def get_gnu_libc_callables(): func_ids = ["bessel_jn", "bessel_yn"] return {id_: GNULibcCallable(id_) for id_ in func_ids} + +def get_gsl_callables(): + # Support special functions from + # https://www.gnu.org/software/gsl/doc/html/specfunc.html + func_ids = ["hyperg_2F1"] + return {id_: GSLCallable(id_) for id_ in func_ids} + + # }}} @@ -1612,6 +1644,7 @@ class CWithGNULibcASTBuilder(CASTBuilder): def known_callables(self): callables = super().known_callables callables.update(get_gnu_libc_callables()) + callables.update(get_gsl_callables()) return callables From df3976af6ff092e1517618f13fdc603950448035 Mon Sep 17 00:00:00 2001 From: Pablo Brubeck Date: Thu, 5 Mar 2026 08:44:52 +0000 Subject: [PATCH 2/3] Update loopy/target/c/__init__.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- loopy/target/c/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 213abf96e..6429b6011 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -867,9 +867,13 @@ def with_types(self, clbl_inf_ctx) def generate_preambles(self, target): + # Base GSL math header yield ("40_c_gsl_math", "#include ") - + # Function-specific headers for GSL special functions + if self.name == "hyperg_2F1": + # gsl_sf_hyperg_2F1 is declared in + yield ("41_c_gsl_sf_hyperg", "#include ") def get_c_callables(): """ Returns an instance of :class:`InKernelCallable` if the function From b58aeb2bd7c2aeb86a25fe90084b567aae8609a1 Mon Sep 17 00:00:00 2001 From: Pablo Brubeck Date: Thu, 5 Mar 2026 10:19:29 +0000 Subject: [PATCH 3/3] ruff --- loopy/target/c/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/loopy/target/c/__init__.py b/loopy/target/c/__init__.py index 6429b6011..9a1fc821f 100644 --- a/loopy/target/c/__init__.py +++ b/loopy/target/c/__init__.py @@ -874,6 +874,8 @@ def generate_preambles(self, target): if self.name == "hyperg_2F1": # gsl_sf_hyperg_2F1 is declared in yield ("41_c_gsl_sf_hyperg", "#include ") + + def get_c_callables(): """ Returns an instance of :class:`InKernelCallable` if the function