def typeof_pyval(self, val): # Based on _DispatcherBase.typeof_pyval, but differs from it to support # the CUDA Array Interface. try: return typeof(val, Purpose.argument) except ValueError: if numba.cuda.is_cuda_array(val): # When typing, we don't need to synchronize on the array's # stream - this is done when the kernel is launched. return typeof(numba.cuda.as_cuda_array(val, sync=False), Purpose.argument) else: raise
def __init__(self): self.lookup = { type(example): typeof(example) for example in [ 0, 0.0, complex(0), "numba", True, None, ] } self.functions = [self._builtin_infer, self._numba_type_infer]
def box_slice_literal(typ, val, c): # Check for integer overflows at compile time. slice_lit = typ.literal_value for field_name in ("start", "stop", "step"): field_obj = getattr(slice_lit, field_name) if isinstance(field_obj, int): try: typeof(field_obj, Purpose) except ValueError as e: raise ValueError(( f"Unable to create literal slice. " f"Error encountered with {field_name} " f"attribute. {str(e)}") ) py_ctor, py_args = typ.literal_value.__reduce__() serialized_ctor = c.pyapi.serialize_object(py_ctor) serialized_args = c.pyapi.serialize_object(py_args) ctor = c.pyapi.unserialize(serialized_ctor) args = c.pyapi.unserialize(serialized_args) obj = c.pyapi.call(ctor, args) c.pyapi.decref(ctor) c.pyapi.decref(args) return obj
def typeof_pyval(self, val): """ Resolve the Numba type of Python value *val*. This is called from numba._dispatcher as a fallback if the native code cannot decide the type. """ # Not going through the resolve_argument_type() indirection # can save a couple µs. try: tp = typeof(val, Purpose.argument) except ValueError: tp = types.pyobject else: if tp is None: tp = types.pyobject return tp
def _compile_for_args(self, *args, **kws): """ For internal use. Compile a specialized version of the function for the given *args* and *kws*, and return the resulting callable. """ assert not kws # call any initialisation required for the compilation chain (e.g. # extension point registration). self._compilation_chain_init_hook() def error_rewrite(e, issue_type): """ Rewrite and raise Exception `e` with help supplied based on the specified issue_type. """ if config.SHOW_HELP: help_msg = errors.error_extras[issue_type] e.patch_message('\n'.join((str(e).rstrip(), help_msg))) if config.FULL_TRACEBACKS: raise e else: reraise(type(e), e, None) argtypes = [] for a in args: if isinstance(a, OmittedArg): argtypes.append(types.Omitted(a.value)) else: argtypes.append(self.typeof_pyval(a)) try: return self.compile(tuple(argtypes)) except errors.ForceLiteralArg as e: # Received request for compiler re-entry with the list of arguments # indicated by e.requested_args. # First, check if any of these args are already Literal-ized already_lit_pos = [i for i in e.requested_args if isinstance(args[i], types.Literal)] if already_lit_pos: # Abort compilation if any argument is already a Literal. # Letting this continue will cause infinite compilation loop. m = ("Repeated literal typing request.\n" "{}.\n" "This is likely caused by an error in typing. " "Please see nested and suppressed exceptions.") info = ', '.join('Arg #{} is {}'.format(i, args[i]) for i in sorted(already_lit_pos)) raise errors.CompilerError(m.format(info)) # Convert requested arguments into a Literal. args = [(types.literal if i in e.requested_args else lambda x: x)(args[i]) for i, v in enumerate(args)] # Re-enter compilation with the Literal-ized arguments return self._compile_for_args(*args) except errors.TypingError as e: # Intercept typing error that may be due to an argument # that failed inferencing as a Numba type failed_args = [] for i, arg in enumerate(args): val = arg.value if isinstance(arg, OmittedArg) else arg try: tp = typeof(val, Purpose.argument) except ValueError as typeof_exc: failed_args.append((i, str(typeof_exc))) else: if tp is None: failed_args.append( (i, "cannot determine Numba type of value %r" % (val,))) if failed_args: # Patch error message to ease debugging msg = str(e).rstrip() + ( "\n\nThis error may have been caused by the following argument(s):\n%s\n" % "\n".join("- argument %d: %s" % (i, err) for i, err in failed_args)) e.patch_message(msg) error_rewrite(e, 'typing') except errors.UnsupportedError as e: # Something unsupported is present in the user code, add help info error_rewrite(e, 'unsupported_error') except (errors.NotDefinedError, errors.RedefinedError, errors.VerificationError) as e: # These errors are probably from an issue with either the code supplied # being syntactically or otherwise invalid error_rewrite(e, 'interpreter') except errors.ConstantInferenceError as e: # this is from trying to infer something as constant when it isn't # or isn't supported as a constant error_rewrite(e, 'constant_inference') except Exception as e: if config.SHOW_HELP: if hasattr(e, 'patch_message'): help_msg = errors.error_extras['reportable'] e.patch_message('\n'.join((str(e).rstrip(), help_msg))) # ignore the FULL_TRACEBACKS config, this needs reporting! raise e
def _numba_type_(self): return typeof(self.value, Purpose.argument)
def typeof_masked(val, c): return MaskedType(typeof(val.value))
class TestAsNumbaType(TestCase): int_nb_type = typeof(0) float_nb_type = typeof(0.0) complex_nb_type = typeof(complex(0)) str_nb_type = typeof("numba") bool_nb_type = typeof(True) none_nb_type = typeof(None) def test_simple_types(self): self.assertEqual(as_numba_type(int), self.int_nb_type) self.assertEqual(as_numba_type(float), self.float_nb_type) self.assertEqual(as_numba_type(complex), self.complex_nb_type) self.assertEqual(as_numba_type(str), self.str_nb_type) self.assertEqual(as_numba_type(bool), self.bool_nb_type) self.assertEqual(as_numba_type(type(None)), self.none_nb_type) def test_numba_types(self): numba_types = [ types.intp, types.boolean, types.ListType(types.float64), types.DictType(types.intp, types.Tuple([types.float32, types.float32])), ] for ty in numba_types: self.assertEqual(as_numba_type(ty), ty) def test_single_containers(self): self.assertEqual( as_numba_type(py_typing.List[float]), types.ListType(self.float_nb_type), ) self.assertEqual( as_numba_type(py_typing.Dict[float, str]), types.DictType(self.float_nb_type, self.str_nb_type), ) self.assertEqual( as_numba_type(py_typing.Set[complex]), types.Set(self.complex_nb_type), ) self.assertEqual( as_numba_type(py_typing.Tuple[float, float]), types.Tuple([self.float_nb_type, self.float_nb_type]), ) self.assertEqual( as_numba_type(py_typing.Tuple[float, complex]), types.Tuple([self.float_nb_type, self.complex_nb_type]), ) def test_optional(self): self.assertEqual( as_numba_type(py_typing.Optional[float]), types.Optional(self.float_nb_type), ) self.assertEqual( as_numba_type(py_typing.Union[str, None]), types.Optional(self.str_nb_type), ) self.assertEqual( as_numba_type(py_typing.Union[None, bool]), types.Optional(self.bool_nb_type), ) # Optional[x] is a special case of Union[x, None]. We raise a # TypingError if the right type is not NoneType. with self.assertRaises(TypingError) as raises: as_numba_type(py_typing.Union[int, float]) self.assertIn("Cannot type Union that is not an Optional", str(raises.exception)) def test_nested_containers(self): IntList = py_typing.List[int] self.assertEqual( as_numba_type(py_typing.List[IntList]), types.ListType(types.ListType(self.int_nb_type)), ) self.assertEqual( as_numba_type(py_typing.List[py_typing.Dict[float, bool]]), types.ListType( types.DictType(self.float_nb_type, self.bool_nb_type)), ) self.assertEqual( as_numba_type( py_typing.Set[py_typing.Tuple[py_typing.Optional[int], float]]), types.Set( types.Tuple( [types.Optional(self.int_nb_type), self.float_nb_type])), ) def test_jitclass_registers(self): @jitclass class MyInt: x: int def __init__(self, value): self.x = value self.assertEqual(as_numba_type(MyInt), MyInt.class_type.instance_type) def test_type_alias(self): Pair = py_typing.Tuple[int, int] ListOfPairs = py_typing.List[Pair] pair_nb_type = types.Tuple((self.int_nb_type, self.int_nb_type)) self.assertEqual(as_numba_type(Pair), pair_nb_type) self.assertEqual(as_numba_type(ListOfPairs), types.ListType(pair_nb_type)) def test_overwrite_type(self): as_numba_type = AsNumbaTypeRegistry() self.assertEqual(as_numba_type(float), self.float_nb_type) as_numba_type.register(float, types.float32) self.assertEqual(as_numba_type(float), types.float32) self.assertNotEqual(as_numba_type(float), self.float_nb_type) def test_any_throws(self): Any = py_typing.Any any_types = [ py_typing.Optional[Any], py_typing.List[Any], py_typing.Set[Any], py_typing.Dict[float, Any], py_typing.Dict[Any, float], py_typing.Tuple[int, Any], ] for bad_py_type in any_types: with self.assertRaises(TypingError) as raises: as_numba_type(bad_py_type) self.assertIn( "Cannot infer numba type of python type", str(raises.exception), ) def test_bad_union_throws(self): bad_unions = [ py_typing.Union[str, int], py_typing.Union[int, type(None), py_typing.Tuple[bool, bool]], ] for bad_py_type in bad_unions: with self.assertRaises(TypingError) as raises: as_numba_type(bad_py_type) self.assertIn("Cannot type Union", str(raises.exception))