From f9fdb91323c6b786e4a9c3de7f0762108376d89d Mon Sep 17 00:00:00 2001 From: Diptorup Deb Date: Wed, 3 Apr 2024 16:01:47 -0500 Subject: [PATCH] Move ocl.mathimpl and ocl.mathdecl into kernel_api_impl.spirv.math --- numba_dpex/dpnp_iface/dpnp_ufunc_db.py | 3 +- .../kernel_api_impl/spirv/math/__init__.py | 3 + .../kernel_api_impl/spirv/math/mathdecl.py | 347 ++++++++++++++++++ .../spirv/math}/mathimpl.py | 36 +- numba_dpex/kernel_api_impl/spirv/target.py | 18 +- numba_dpex/ocl/__init__.py | 3 - numba_dpex/ocl/mathdecl.py | 343 ----------------- 7 files changed, 380 insertions(+), 373 deletions(-) create mode 100644 numba_dpex/kernel_api_impl/spirv/math/__init__.py create mode 100644 numba_dpex/kernel_api_impl/spirv/math/mathdecl.py rename numba_dpex/{ocl => kernel_api_impl/spirv/math}/mathimpl.py (84%) delete mode 100644 numba_dpex/ocl/__init__.py delete mode 100644 numba_dpex/ocl/mathdecl.py diff --git a/numba_dpex/dpnp_iface/dpnp_ufunc_db.py b/numba_dpex/dpnp_iface/dpnp_ufunc_db.py index 3387c80bb0..def71adb17 100644 --- a/numba_dpex/dpnp_iface/dpnp_ufunc_db.py +++ b/numba_dpex/dpnp_iface/dpnp_ufunc_db.py @@ -9,8 +9,7 @@ from numba.core import types from numba_dpex.core.typing import dpnpdecl - -from ..ocl import mathimpl +from numba_dpex.kernel_api_impl.spirv.math import mathimpl # A global instance of dpnp ufuncs that are supported by numba-dpex _dpnp_ufunc_db = None diff --git a/numba_dpex/kernel_api_impl/spirv/math/__init__.py b/numba_dpex/kernel_api_impl/spirv/math/__init__.py new file mode 100644 index 0000000000..ee20629a35 --- /dev/null +++ b/numba_dpex/kernel_api_impl/spirv/math/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 diff --git a/numba_dpex/kernel_api_impl/spirv/math/mathdecl.py b/numba_dpex/kernel_api_impl/spirv/math/mathdecl.py new file mode 100644 index 0000000000..e89fd27c3f --- /dev/null +++ b/numba_dpex/kernel_api_impl/spirv/math/mathdecl.py @@ -0,0 +1,347 @@ +# SPDX-FileCopyrightText: 2020 - 2024 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 + +# pylint: skip-file + +"""Typing declarations for all ``math`` stdlib function in SPIRVTypingContext. +""" +import math + +from numba.core import types +from numba.core.typing.templates import ( + AttributeTemplate, + ConcreteTemplate, + Registry, + signature, +) + +registry = Registry() +builtin_attr = registry.register_attr +infer_global = registry.register_global + + +@builtin_attr +class MathModuleAttribute(AttributeTemplate): + key = types.Module(math) + + def resolve_fabs(self, mod): + return types.Function(MathFabsFn) + + def resolve_exp(self, mod): + return types.Function(MathExpFn) + + def resolve_expm1(self, mod): + return types.Function(MathExpm1Fn) + + def resolve_sqrt(self, mod): + return types.Function(MathSqrtFn) + + def resolve_log(self, mod): + return types.Function(MathLogFn) + + def resolve_log1p(self, mod): + return types.Function(MathLog1pFn) + + def resolve_log10(self, mod): + return types.Function(MathLog10Fn) + + def resolve_sin(self, mod): + return types.Function(MathSinFn) + + def resolve_cos(self, mod): + return types.Function(MathCosFn) + + def resolve_tan(self, mod): + return types.Function(MathTanFn) + + def resolve_sinh(self, mod): + return types.Function(MathSinhFn) + + def resolve_cosh(self, mod): + return types.Function(MathCoshFn) + + def resolve_tanh(self, mod): + return types.Function(MathTanhFn) + + def resolve_asin(self, mod): + return types.Function(MathAsinFn) + + def resolve_acos(self, mod): + return types.Function(MathAcosFn) + + def resolve_atan(self, mod): + return types.Function(MathAtanFn) + + def resolve_atan2(self, mod): + return types.Function(MathAtan2Fn) + + def resolve_asinh(self, mod): + return types.Function(MathAsinhFn) + + def resolve_acosh(self, mod): + return types.Function(MathAcoshFn) + + def resolve_atanh(self, mod): + return types.Function(MathAtanhFn) + + def resolve_pi(self, mod): + return types.float64 + + def resolve_e(self, mod): + return types.float64 + + def resolve_floor(self, mod): + return types.Function(MathFloorFn) + + def resolve_ceil(self, mod): + return types.Function(MathCeilFn) + + def resolve_trunc(self, mod): + return types.Function(MathTruncFn) + + def resolve_isnan(self, mod): + return types.Function(MathIsnanFn) + + def resolve_isinf(self, mod): + return types.Function(MathIsinfFn) + + def resolve_degrees(self, mod): + return types.Function(MathDegreesFn) + + def resolve_radians(self, mod): + return types.Function(MathRadiansFn) + + def resolve_copysign(self, mod): + return types.Function(MathCopysignFn) + + def resolve_fmod(self, mod): + return types.Function(MathFmodFn) + + def resolve_pow(self, mod): + return types.Function(MathPowFn) + + def resolve_erf(self, mod): + return types.Function(MathErfFn) + + def resolve_erfc(self, mod): + return types.Function(MathErfcFn) + + def resolve_gamma(self, mod): + return types.Function(MathGammaFn) + + def resolve_lgamma(self, mod): + return types.Function(MathLgammaFn) + + +class UnaryMathFuncTemplate(ConcreteTemplate): + cases = [ + signature(types.float64, types.int64), + signature(types.float64, types.uint64), + signature(types.float32, types.float32), + signature(types.float64, types.float64), + ] + + +class MathFabsFn(UnaryMathFuncTemplate): + key = math.fabs + + +class MathExpFn(UnaryMathFuncTemplate): + key = math.exp + + +class MathExpm1Fn(UnaryMathFuncTemplate): + key = math.expm1 + + +class MathSqrtFn(UnaryMathFuncTemplate): + key = math.sqrt + + +class MathLogFn(UnaryMathFuncTemplate): + key = math.log + + +class MathLog1pFn(UnaryMathFuncTemplate): + key = math.log1p + + +class MathLog10Fn(UnaryMathFuncTemplate): + key = math.log10 + + +class MathSinFn(UnaryMathFuncTemplate): + key = math.sin + + +class MathCosFn(UnaryMathFuncTemplate): + key = math.cos + + +class MathTanFn(UnaryMathFuncTemplate): + key = math.tan + + +class MathSinhFn(UnaryMathFuncTemplate): + key = math.sinh + + +class MathCoshFn(UnaryMathFuncTemplate): + key = math.cosh + + +class MathTanhFn(UnaryMathFuncTemplate): + key = math.tanh + + +class MathAsinFn(UnaryMathFuncTemplate): + key = math.asin + + +class MathAcosFn(UnaryMathFuncTemplate): + key = math.acos + + +class MathAtanFn(UnaryMathFuncTemplate): + key = math.atan + + +class MathAtan2Fn(ConcreteTemplate): + key = math.atan2 + cases = [ + signature(types.float64, types.int64, types.int64), + signature(types.float64, types.uint64, types.uint64), + signature(types.float32, types.float32, types.float32), + signature(types.float64, types.float64, types.float64), + ] + + +class MathAsinhFn(UnaryMathFuncTemplate): + key = math.asinh + + +class MathAcoshFn(UnaryMathFuncTemplate): + key = math.acosh + + +class MathAtanhFn(UnaryMathFuncTemplate): + key = math.atanh + + +class MathFloorFn(UnaryMathFuncTemplate): + key = math.floor + + +class MathCeilFn(UnaryMathFuncTemplate): + key = math.ceil + + +class MathTruncFn(UnaryMathFuncTemplate): + key = math.trunc + + +class MathRadiansFn(UnaryMathFuncTemplate): + key = math.radians + + +class MathDegreesFn(UnaryMathFuncTemplate): + key = math.degrees + + +class MathErfFn(UnaryMathFuncTemplate): + key = math.erf + + +class MathErfcFn(UnaryMathFuncTemplate): + key = math.erfc + + +class MathGammaFn(UnaryMathFuncTemplate): + key = math.gamma + + +class MathLgammaFn(UnaryMathFuncTemplate): + key = math.lgamma + + +class BinaryMathFuncTemplate(ConcreteTemplate): + cases = [ + signature(types.float32, types.float32, types.float32), + signature(types.float64, types.float64, types.float64), + ] + + +class MathCopysignFn(BinaryMathFuncTemplate): + key = math.copysign + + +class MathFmodFn(BinaryMathFuncTemplate): + key = math.fmod + + +class MathPowFn(ConcreteTemplate): + key = math.pow + cases = [ + signature(types.float32, types.float32, types.float32), + signature(types.float64, types.float64, types.float64), + signature(types.float32, types.float32, types.int32), + signature(types.float64, types.float64, types.int32), + ] + + +class MathIsnanFn(ConcreteTemplate): + key = math.isnan + cases = [ + signature(types.boolean, types.int64), + signature(types.boolean, types.uint64), + signature(types.boolean, types.float32), + signature(types.boolean, types.float64), + ] + + +class MathIsinfFn(ConcreteTemplate): + key = math.isinf + cases = [ + signature(types.boolean, types.int64), + signature(types.boolean, types.uint64), + signature(types.boolean, types.float32), + signature(types.boolean, types.float64), + ] + + +infer_global(math, types.Module(math)) +infer_global(math.fabs, types.Function(MathFabsFn)) +infer_global(math.exp, types.Function(MathExpFn)) +infer_global(math.expm1, types.Function(MathExpm1Fn)) +infer_global(math.sqrt, types.Function(MathSqrtFn)) +infer_global(math.log, types.Function(MathLogFn)) +infer_global(math.log1p, types.Function(MathLog1pFn)) +infer_global(math.log10, types.Function(MathLog10Fn)) +infer_global(math.sin, types.Function(MathSinFn)) +infer_global(math.cos, types.Function(MathCosFn)) +infer_global(math.tan, types.Function(MathTanFn)) +infer_global(math.sinh, types.Function(MathSinhFn)) +infer_global(math.cosh, types.Function(MathCoshFn)) +infer_global(math.tanh, types.Function(MathTanhFn)) +infer_global(math.asin, types.Function(MathAsinFn)) +infer_global(math.acos, types.Function(MathAcosFn)) +infer_global(math.atan, types.Function(MathAtanFn)) +infer_global(math.atan2, types.Function(MathAtan2Fn)) +infer_global(math.asinh, types.Function(MathAsinhFn)) +infer_global(math.acosh, types.Function(MathAcoshFn)) +infer_global(math.atanh, types.Function(MathAtanhFn)) +infer_global(math.floor, types.Function(MathFloorFn)) +infer_global(math.ceil, types.Function(MathCeilFn)) +infer_global(math.trunc, types.Function(MathTruncFn)) +infer_global(math.isnan, types.Function(MathIsnanFn)) +infer_global(math.isinf, types.Function(MathIsinfFn)) +infer_global(math.degrees, types.Function(MathDegreesFn)) +infer_global(math.radians, types.Function(MathRadiansFn)) +infer_global(math.copysign, types.Function(MathCopysignFn)) +infer_global(math.fmod, types.Function(MathFmodFn)) +infer_global(math.pow, types.Function(MathPowFn)) +infer_global(math.erf, types.Function(MathErfFn)) +infer_global(math.erfc, types.Function(MathErfcFn)) +infer_global(math.gamma, types.Function(MathGammaFn)) +infer_global(math.lgamma, types.Function(MathLgammaFn)) diff --git a/numba_dpex/ocl/mathimpl.py b/numba_dpex/kernel_api_impl/spirv/math/mathimpl.py similarity index 84% rename from numba_dpex/ocl/mathimpl.py rename to numba_dpex/kernel_api_impl/spirv/math/mathimpl.py index 9fd49caa22..e5e0ca0ab3 100644 --- a/numba_dpex/ocl/mathimpl.py +++ b/numba_dpex/kernel_api_impl/spirv/math/mathimpl.py @@ -2,6 +2,9 @@ # # SPDX-License-Identifier: Apache-2.0 +""" Codegen implementation for supported math functions in SPIRVKernelTarget. +""" + import math import warnings @@ -35,10 +38,8 @@ "dd->d": _binary_d_dd, "fi->f": _binary_f_fi, "fl->f": _binary_f_fl, - "ff->f": _binary_f_ff, "di->d": _binary_d_di, "dl->d": _binary_d_dl, - "dd->d": _binary_d_dd, } function_descriptors = { @@ -147,28 +148,33 @@ def core(context, builder, sig, args): ] -lower_ocl_impl = dict() +lower_ocl_impl = {} def function_name_to_supported_decl(name, sig): + """Maps a math function to a specific implementation for given signature.""" + key = None try: # only symbols present in the math module key = getattr(math, name) except AttributeError: try: key = getattr(numpy, name) - except: - return None - - fn = _mk_fn_decl(name, sig) - lower_ocl_impl[(name, sig)] = lower(key, *sig.args)(fn) - - -for name in _supported: - sigs = function_descriptors.get(name) + except AttributeError: + warnings.warn( + f"No declaration for function {name} for signature {sig} " + "in math or NumPy modules" + ) + if key is not None: + fn = _mk_fn_decl(name, sig) + lower_ocl_impl[(name, sig)] = lower(key, *sig.args)(fn) + + +for supported_fn_name in _supported: + sigs = function_descriptors.get(supported_fn_name) if sigs is None: - warnings.warn("OCL - failed to register '{0}'".format(name)) + warnings.warn(f"OCL - failed to register '{supported_fn_name}'") continue - for sig in sigs: - function_name_to_supported_decl(name, sig) + for supported_sig in sigs: + function_name_to_supported_decl(supported_fn_name, supported_sig) diff --git a/numba_dpex/kernel_api_impl/spirv/target.py b/numba_dpex/kernel_api_impl/spirv/target.py index 689fc45514..e1e4bcbc65 100644 --- a/numba_dpex/kernel_api_impl/spirv/target.py +++ b/numba_dpex/kernel_api_impl/spirv/target.py @@ -25,8 +25,9 @@ from numba_dpex.core.typing import dpnpdecl from numba_dpex.kernel_api.flag_enum import FlagEnum from numba_dpex.kernel_api.memory_enums import AddressSpace as address_space +from numba_dpex.kernel_api_impl.spirv import printimpl from numba_dpex.kernel_api_impl.spirv.arrayobj import populate_array -from numba_dpex.ocl.mathimpl import lower_ocl_impl, sig_mapper +from numba_dpex.kernel_api_impl.spirv.math import mathdecl, mathimpl from . import codegen from .overloads._registry import registry as spirv_registry @@ -100,9 +101,7 @@ def resolve_getattr(self, typ, attr): return retty def load_additional_registries(self): - """Register the OpenCL API and math and other functions.""" - # pylint: disable=import-outside-toplevel - from numba_dpex.ocl import mathdecl + """Register the OpenCL math functions along with dpnp math functions.""" self.install_registry(mathdecl.registry) self.install_registry(cmathdecl.registry) @@ -273,11 +272,12 @@ def replace_dpnp_ufunc_with_ocl_intrinsics(self): for name, ufunc in ufuncs: for sig in self.ufunc_db[ufunc].keys(): if ( - sig in sig_mapper - and (name, sig_mapper[sig]) in lower_ocl_impl + sig in mathimpl.sig_mapper + and (name, mathimpl.sig_mapper[sig]) + in mathimpl.lower_ocl_impl ): - self.ufunc_db[ufunc][sig] = lower_ocl_impl[ - (name, sig_mapper[sig]) + self.ufunc_db[ufunc][sig] = mathimpl.lower_ocl_impl[ + (name, mathimpl.sig_mapper[sig]) ] def load_additional_registries(self): @@ -293,8 +293,6 @@ def load_additional_registries(self): # pylint: disable=import-outside-toplevel from numba_dpex.dpctl_iface import dpctlimpl from numba_dpex.dpnp_iface import dpnpimpl - from numba_dpex.kernel_api_impl.spirv import printimpl - from numba_dpex.ocl import mathimpl self.insert_func_defn(mathimpl.registry.functions) self.insert_func_defn(dpnpimpl.registry.functions) diff --git a/numba_dpex/ocl/__init__.py b/numba_dpex/ocl/__init__.py deleted file mode 100644 index 7206ff64a6..0000000000 --- a/numba_dpex/ocl/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 diff --git a/numba_dpex/ocl/mathdecl.py b/numba_dpex/ocl/mathdecl.py deleted file mode 100644 index a9b7e12aca..0000000000 --- a/numba_dpex/ocl/mathdecl.py +++ /dev/null @@ -1,343 +0,0 @@ -# SPDX-FileCopyrightText: 2020 - 2024 Intel Corporation -# -# SPDX-License-Identifier: Apache-2.0 - -import math - -from numba.core import types -from numba.core.typing.templates import ( - AttributeTemplate, - ConcreteTemplate, - Registry, - signature, -) - -registry = Registry() -builtin_attr = registry.register_attr -infer_global = registry.register_global - - -@builtin_attr -class MathModuleAttribute(AttributeTemplate): - key = types.Module(math) - - def resolve_fabs(self, mod): - return types.Function(Math_fabs) - - def resolve_exp(self, mod): - return types.Function(Math_exp) - - def resolve_expm1(self, mod): - return types.Function(Math_expm1) - - def resolve_sqrt(self, mod): - return types.Function(Math_sqrt) - - def resolve_log(self, mod): - return types.Function(Math_log) - - def resolve_log1p(self, mod): - return types.Function(Math_log1p) - - def resolve_log10(self, mod): - return types.Function(Math_log10) - - def resolve_sin(self, mod): - return types.Function(Math_sin) - - def resolve_cos(self, mod): - return types.Function(Math_cos) - - def resolve_tan(self, mod): - return types.Function(Math_tan) - - def resolve_sinh(self, mod): - return types.Function(Math_sinh) - - def resolve_cosh(self, mod): - return types.Function(Math_cosh) - - def resolve_tanh(self, mod): - return types.Function(Math_tanh) - - def resolve_asin(self, mod): - return types.Function(Math_asin) - - def resolve_acos(self, mod): - return types.Function(Math_acos) - - def resolve_atan(self, mod): - return types.Function(Math_atan) - - def resolve_atan2(self, mod): - return types.Function(Math_atan2) - - def resolve_asinh(self, mod): - return types.Function(Math_asinh) - - def resolve_acosh(self, mod): - return types.Function(Math_acosh) - - def resolve_atanh(self, mod): - return types.Function(Math_atanh) - - def resolve_pi(self, mod): - return types.float64 - - def resolve_e(self, mod): - return types.float64 - - def resolve_floor(self, mod): - return types.Function(Math_floor) - - def resolve_ceil(self, mod): - return types.Function(Math_ceil) - - def resolve_trunc(self, mod): - return types.Function(Math_trunc) - - def resolve_isnan(self, mod): - return types.Function(Math_isnan) - - def resolve_isinf(self, mod): - return types.Function(Math_isinf) - - def resolve_degrees(self, mod): - return types.Function(Math_degrees) - - def resolve_radians(self, mod): - return types.Function(Math_radians) - - def resolve_copysign(self, mod): - return types.Function(Math_copysign) - - def resolve_fmod(self, mod): - return types.Function(Math_fmod) - - def resolve_pow(self, mod): - return types.Function(Math_pow) - - def resolve_erf(self, mod): - return types.Function(Math_erf) - - def resolve_erfc(self, mod): - return types.Function(Math_erfc) - - def resolve_gamma(self, mod): - return types.Function(Math_gamma) - - def resolve_lgamma(self, mod): - return types.Function(Math_lgamma) - - -class Math_unary(ConcreteTemplate): - cases = [ - signature(types.float64, types.int64), - signature(types.float64, types.uint64), - signature(types.float32, types.float32), - signature(types.float64, types.float64), - ] - - -class Math_fabs(Math_unary): - key = math.fabs - - -class Math_exp(Math_unary): - key = math.exp - - -class Math_expm1(Math_unary): - key = math.expm1 - - -class Math_sqrt(Math_unary): - key = math.sqrt - - -class Math_log(Math_unary): - key = math.log - - -class Math_log1p(Math_unary): - key = math.log1p - - -class Math_log10(Math_unary): - key = math.log10 - - -class Math_sin(Math_unary): - key = math.sin - - -class Math_cos(Math_unary): - key = math.cos - - -class Math_tan(Math_unary): - key = math.tan - - -class Math_sinh(Math_unary): - key = math.sinh - - -class Math_cosh(Math_unary): - key = math.cosh - - -class Math_tanh(Math_unary): - key = math.tanh - - -class Math_asin(Math_unary): - key = math.asin - - -class Math_acos(Math_unary): - key = math.acos - - -class Math_atan(Math_unary): - key = math.atan - - -class Math_atan2(ConcreteTemplate): - key = math.atan2 - cases = [ - signature(types.float64, types.int64, types.int64), - signature(types.float64, types.uint64, types.uint64), - signature(types.float32, types.float32, types.float32), - signature(types.float64, types.float64, types.float64), - ] - - -class Math_asinh(Math_unary): - key = math.asinh - - -class Math_acosh(Math_unary): - key = math.acosh - - -class Math_atanh(Math_unary): - key = math.atanh - - -class Math_floor(Math_unary): - key = math.floor - - -class Math_ceil(Math_unary): - key = math.ceil - - -class Math_trunc(Math_unary): - key = math.trunc - - -class Math_radians(Math_unary): - key = math.radians - - -class Math_degrees(Math_unary): - key = math.degrees - - -class Math_erf(Math_unary): - key = math.erf - - -class Math_erfc(Math_unary): - key = math.erfc - - -class Math_gamma(Math_unary): - key = math.gamma - - -class Math_lgamma(Math_unary): - key = math.lgamma - - -class Math_binary(ConcreteTemplate): - cases = [ - signature(types.float32, types.float32, types.float32), - signature(types.float64, types.float64, types.float64), - ] - - -class Math_copysign(Math_binary): - key = math.copysign - - -class Math_fmod(Math_binary): - key = math.fmod - - -class Math_pow(ConcreteTemplate): - key = math.pow - cases = [ - signature(types.float32, types.float32, types.float32), - signature(types.float64, types.float64, types.float64), - signature(types.float32, types.float32, types.int32), - signature(types.float64, types.float64, types.int32), - ] - - -class Math_isnan(ConcreteTemplate): - key = math.isnan - cases = [ - signature(types.boolean, types.int64), - signature(types.boolean, types.uint64), - signature(types.boolean, types.float32), - signature(types.boolean, types.float64), - ] - - -class Math_isinf(ConcreteTemplate): - key = math.isinf - cases = [ - signature(types.boolean, types.int64), - signature(types.boolean, types.uint64), - signature(types.boolean, types.float32), - signature(types.boolean, types.float64), - ] - - -infer_global(math, types.Module(math)) -infer_global(math.fabs, types.Function(Math_fabs)) -infer_global(math.exp, types.Function(Math_exp)) -infer_global(math.expm1, types.Function(Math_expm1)) -infer_global(math.sqrt, types.Function(Math_sqrt)) -infer_global(math.log, types.Function(Math_log)) -infer_global(math.log1p, types.Function(Math_log1p)) -infer_global(math.log10, types.Function(Math_log10)) -infer_global(math.sin, types.Function(Math_sin)) -infer_global(math.cos, types.Function(Math_cos)) -infer_global(math.tan, types.Function(Math_tan)) -infer_global(math.sinh, types.Function(Math_sinh)) -infer_global(math.cosh, types.Function(Math_cosh)) -infer_global(math.tanh, types.Function(Math_tanh)) -infer_global(math.asin, types.Function(Math_asin)) -infer_global(math.acos, types.Function(Math_acos)) -infer_global(math.atan, types.Function(Math_atan)) -infer_global(math.atan2, types.Function(Math_atan2)) -infer_global(math.asinh, types.Function(Math_asinh)) -infer_global(math.acosh, types.Function(Math_acosh)) -infer_global(math.atanh, types.Function(Math_atanh)) -infer_global(math.floor, types.Function(Math_floor)) -infer_global(math.ceil, types.Function(Math_ceil)) -infer_global(math.trunc, types.Function(Math_trunc)) -infer_global(math.isnan, types.Function(Math_isnan)) -infer_global(math.isinf, types.Function(Math_isinf)) -infer_global(math.degrees, types.Function(Math_degrees)) -infer_global(math.radians, types.Function(Math_radians)) -infer_global(math.copysign, types.Function(Math_copysign)) -infer_global(math.fmod, types.Function(Math_fmod)) -infer_global(math.pow, types.Function(Math_pow)) -infer_global(math.erf, types.Function(Math_erf)) -infer_global(math.erfc, types.Function(Math_erfc)) -infer_global(math.gamma, types.Function(Math_gamma)) -infer_global(math.lgamma, types.Function(Math_lgamma))