def _register(self): # _ctor_kwargs from numba.core.typing.templates import (make_intrinsic_template, infer_global) template = make_intrinsic_template(self, self._defn, self._name, self._ctor_kwargs) infer(template) infer_global(self, types.Function(template))
def _numpy_ufunc(name): func = getattr(np, name) class typing_class(Numpy_rules_ufunc): key = func typing_class.__name__ = "resolve_{0}".format(name) if not name in _aliases: infer_global(func, types.Function(typing_class))
def decorate(cls, typing_key): class Template(cls): key = typing_key if callable(val): typ = types.Function(Template) else: raise TypeError("cannot infer type for global value %r") self.globals.append((val, typ)) return cls
def insert_user_function(self, fn, ft): """Insert a user function. Args ---- - fn: object used as callee - ft: function template """ self._insert_global(fn, types.Function(ft))
def decorate(typing_func): def generic(self): return typing_func(self.context) name = "%s_CallableTemplate" % (func_name, ) bases = (CallableTemplate, ) class_dict = dict(key=func, generic=generic) template = type(name, bases, class_dict) infer(template) if callable(func): infer_global(func, types.Function(template)) return typing_func
def _numpy_ufunc(name): func = getattr(np, name) class typing_class(Numpy_rules_ufunc): key = func typing_class.__name__ = "resolve_{0}".format(name) # A list of ufuncs that are in fact aliases of other ufuncs. They need to # insert the resolve method, but not register the ufunc itself aliases = ("abs", "bitwise_not", "divide", "abs") if name not in aliases: infer_global(func, types.Function(typing_class))
def resolve___call__(self, classty): """ Resolve a number class's constructor (e.g. calling int(...)) """ ty = classty.instance_type def typer(val): if isinstance(val, (types.BaseTuple, types.Sequence)): # Array constructor, e.g. np.int32([1, 2]) sig = self.context.resolve_function_type( np.array, (val, ), {'dtype': types.DType(ty)}) return sig.return_type else: # Scalar constructor, e.g. np.int32(42) return ty return types.Function(make_callable_template(key=ty, typer=typer))
def test_function_incompatible_templates(self): # issue 4345 def func_stub(): pass def func_stub2(): pass def ol(): pass template1 = make_overload_template(func_stub, ol, {}, True, 'never') template2 = make_overload_template(func_stub2, ol, {}, True, 'never') with self.assertRaises(ValueError) as raises: types.Function((template1, template2)) self.assertIn("incompatible templates:", str(raises.exception))
def register(self): # typing class ExternalTemplate(typing.templates.AbstractTemplate): obj = self key = self.key def generic(self, args, kws): # get the correct signature and function name for the current device atypes = tuple(map(Type.fromobject, args)) t = self.obj.match_signature(atypes) TargetInfo().add_external(t.name) codegen = self.obj.get_codegen() extending.lower_builtin(self.key, *t.tonumba().args)(codegen) return t.tonumba() typing.templates.infer(ExternalTemplate) typing.templates.infer_global(self, types.Function(ExternalTemplate))
def resolve___call__(self, classty): """ Resolve a number class's constructor (e.g. calling int(...)) """ ty = classty.instance_type def typer(val): if isinstance(val, (types.BaseTuple, types.Sequence)): # Array constructor, e.g. np.int32([1, 2]) fnty = self.context.resolve_value_type(np.array) sig = fnty.get_call_type(self.context, (val, types.DType(ty)), {}) return sig.return_type elif isinstance( val, (types.Number, types.Boolean, types.IntEnumMember)): # Scalar constructor, e.g. np.int32(42) return ty elif isinstance(val, (types.NPDatetime, types.NPTimedelta)): # Constructor cast from datetime-like, e.g. # > np.int64(np.datetime64("2000-01-01")) if ty.bitwidth == 64: return ty else: msg = (f"Cannot cast {val} to {ty} as {ty} is not 64 bits " "wide.") raise errors.TypingError(msg) else: if (isinstance(val, types.Array) and val.ndim == 0 and val.dtype == ty): # This is 0d array -> scalar degrading return ty else: # unsupported msg = f"Casting {val} to {ty} directly is unsupported." if isinstance(val, types.Array): # array casts are supported a different way. msg += f" Try doing '<array>.astype(np.{ty})' instead" raise errors.TypingError(msg) return types.Function(make_callable_template(key=ty, typer=typer))
def register(self): # typing class ExternalTemplate(typing.templates.AbstractTemplate): obj = self key = self.name def generic(self, args, kws): t = Type.fromobject(self.obj._signature).tonumba() name = self.key # lowering def codegen(context, builder, sig, args): fndesc = funcdesc.ExternalFunctionDescriptor( name, sig.return_type, sig.args) func = context.declare_external_function( builder.module, fndesc) return builder.call(func, args) extending.lower_builtin(name, *t.args)(codegen) return t typing.templates.infer(ExternalTemplate) typing.templates.infer_global(self, types.Function(ExternalTemplate))
def resolve_radians(self, mod): return types.Function(Math_radians)
def resolve_degrees(self, mod): return types.Function(Math_degrees)
def resolve_isinf(self, mod): return types.Function(Math_isinf)
def resolve_isnan(self, mod): return types.Function(Math_isnan)
def resolve_trunc(self, mod): return types.Function(Math_trunc)
def resolve_lgamma(self, mod): return types.Function(Math_lgamma)
def resolve_acosh(self, mod): return types.Function(Math_acosh)
def resolve_atanh(self, mod): return types.Function(Math_atanh)
def resolve_pow(self, mod): return types.Function(Math_pow)
def resolve_asin(self, mod): return types.Function(Math_asin)
def resolve_sqrt(self, mod): return types.Function(Math_sqrt)
def resolve_expm1(self, mod): return types.Function(Math_expm1)
def resolve_fabs(self, mod): return types.Function(Math_fabs)
def resolve_copysign(self, mod): return types.Function(Math_copysign)
def resolve_floor(self, mod): return types.Function(Math_floor)
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))
def resolve_ceil(self, mod): return types.Function(Math_ceil)
def resolve_log10(self, mod): return types.Function(Math_log10)
def resolve_erfc(self, mod): return types.Function(Math_erfc)