def compile2(env, func, restype=None, argtypes=None, ctypes=False, compile_only=False, func_ast=None, **kwds): """ Compile a numba annotated function. - decompile function into a Python ast - run type inference using the given input types - compile the function to LLVM """ # Let the pipeline create a module for the function it is compiling # and the user will link that in. assert 'llvm_module' not in kwds kwds['llvm_module'] = lc.Module.new(module_name(func)) logger.debug(kwds) if func_ast is None: func_ast = functions._get_ast(func) else: func_ast = copy.deepcopy(func_ast) func_signature = typesystem.function(restype, argtypes) #pipeline, (func_signature, symtab, ast) = _infer_types2( # env, func, restype, argtypes, codegen=True, **kwds) with env.TranslationContext(env, func, func_ast, func_signature, need_lfunc_wrapper=not compile_only, **kwds) as func_env: pipeline = env.get_pipeline(kwds.get('pipeline_name', None)) func_ast.pipeline = pipeline post_ast = pipeline(func_ast, env) func_signature = func_env.func_signature symtab = func_env.symtab t = func_env.translator return func_env
def resolve_argtypes(self, args, kwargs): assert not kwargs # argtypes = map(self.env.crnt.typesystem.typeof, args) argtypes = map( numba.typeof, args) # TODO: allow registering a type system and using it here signature = typesystem.function(None, argtypes) return signature
def run_pipeline(self, func): func_sig = typesystem.function(typesystem.void, []) source = inspect.getsource(func) astree = ast.parse(source) with environment.TranslationContext(self.env, func, astree, func_sig): pipeline_callable = self.env.get_or_add_pipeline("const_folding", pipeline.ConstFolding) astree = pipeline.AST3to2()(astree, self.env) ret_val = pipeline_callable(astree, self.env) return ret_val
def run_pipeline(self, func): func_sig = typesystem.function(typesystem.void, []) source = inspect.getsource(func) astree = ast.parse(source) with environment.TranslationContext(self.env, func, astree, func_sig): pipeline_callable = self.env.get_or_add_pipeline( 'const_folding', pipeline.ConstFolding) astree = pipeline.AST3to2()(astree, self.env) ret_val = pipeline_callable(astree, self.env) return ret_val
def update_signature(self, method): """ Update a method signature with the extension type for 'self'. class Foo(object): @void() # becomes: void(ext_type(Foo)) def method(self): ... """ argtypes = method_argtypes(method, self.ext_type, method.signature.args) restype = method.signature.return_type method.signature = typesystem.function(restype, argtypes) method.signature = self.method_maker.make_method_type(method)
def handle_jit_decorator(visit_func, func_def, decorator): jit_args = module_type_inference.parse_args(decorator, ["restype", "argtypes", "backend", "target", "nopython"]) if decorator.args or decorator.keywords: restype = parse_restype(visit_func, decorator, jit_args) if restype is not None and restype.is_function: signature = restype else: argtypes = parse_argtypes(visit_func, decorator, func_def, jit_args) signature = typesystem.function(restype, argtypes, name=func_def.name) else: # elif func_def.args: raise error.NumbaError(decorator, "The argument types and return type " "need to be specified") # TODO: Analyse closure at call or outer function return time to # TODO: infer return type # TODO: parse out nopython argument return signature
def resolve_argtypes(env, py_func, template_signature, args, kwargs, translator_kwargs): """ Given an autojitting numba function, return the argument types. These need to be resolved in order for the function cache to work. TODO: have a single entry point that resolves the argument types! """ assert not kwargs, "Keyword arguments are not supported yet" locals_dict = translator_kwargs.get("locals", None) argcount = py_func.__code__.co_argcount if argcount != len(args): if argcount == 1: arguments = 'argument' else: arguments = 'arguments' raise TypeError("%s() takes exactly %d %s (%d given)" % ( py_func.__name__, argcount, arguments, len(args))) return_type = None argnames = inspect.getargspec(py_func).args argtypes = [env.context.typemapper.from_python(x) for x in args] if template_signature is not None: template_context, signature = typesystem.resolve_templates( locals_dict, template_signature, argnames, argtypes) return_type = signature.return_type argtypes = list(signature.args) if locals_dict is not None: for i, argname in enumerate(argnames): if argname in locals_dict: new_type = locals_dict[argname] argtypes[i] = new_type return typesystem.function(return_type, tuple(argtypes))
def resolve_argtypes(env, py_func, template_signature, args, kwargs, translator_kwargs): """ Given an autojitting numba function, return the argument types. These need to be resolved in order for the function cache to work. TODO: have a single entry point that resolves the argument types! """ assert not kwargs, "Keyword arguments are not supported yet" locals_dict = translator_kwargs.get("locals", None) argcount = py_func.__code__.co_argcount if argcount != len(args): if argcount == 1: arguments = 'argument' else: arguments = 'arguments' raise TypeError("%s() takes exactly %d %s (%d given)" % ( py_func.__name__, argcount, arguments, len(args))) return_type = None argnames = inspect.getargspec(py_func).args argtypes = [typesystem.numba_typesystem.typeof(x) for x in args] if template_signature is not None: template_context, signature = typesystem.resolve_templates( locals_dict, template_signature, argnames, argtypes) return_type = signature.return_type argtypes = list(signature.args) if locals_dict is not None: for i, argname in enumerate(argnames): if argname in locals_dict: new_type = locals_dict[argname] argtypes[i] = new_type return typesystem.function(return_type, tuple(argtypes))
def handle_jit_decorator(visit_func, func_def, decorator): jit_args = module_type_inference.parse_args( decorator, ['restype', 'argtypes', 'backend', 'target', 'nopython']) if decorator.args or decorator.keywords: restype = parse_restype(visit_func, decorator, jit_args) if restype is not None and restype.is_function: signature = restype else: argtypes = parse_argtypes(visit_func, decorator, func_def, jit_args) signature = typesystem.function(restype, argtypes, name=func_def.name) else: #elif func_def.args: raise error.NumbaError( decorator, "The argument types and return type " "need to be specified") # TODO: Analyse closure at call or outer function return time to # TODO: infer return type # TODO: parse out nopython argument return signature
def resolve_argtypes(self, args, kwargs): assert not kwargs # argtypes = map(self.env.crnt.typesystem.typeof, args) argtypes = map(numba.typeof, args) # TODO: allow registering a type system and using it here signature = typesystem.function(None, argtypes) return signature
def _infer_types2(env, func, restype=None, argtypes=None, **kwargs): ast = functions._get_ast(func) func_signature = typesystem.function(restype, argtypes) return run_pipeline2(env, func, ast, func_signature, **kwargs)
def myfunc3(a, b, c): pass types = list(nb.numeric) + [object_] array_types = [t[:] for t in types] array_types += [t[:, :] for t in types] array_types += [t[:, :, :] for t in types] all_types = types + array_types def method(func, name, sig): return Method(func, name, sig, False, False) make_methods1 = lambda: [ method(myfunc1, 'method', typesystem.function(argtype, [argtype])) for argtype in all_types] make_methods2 = lambda: [ method(myfunc2, 'method', typesystem.function(argtype1, [argtype1, argtype2])) for argtype1, argtype2 in itertools.product(all_types, all_types)] #------------------------------------------------------------------------ # Table building #------------------------------------------------------------------------ def make_table(methods): table = methodtable.VTabType(py_class, []) table.create_method_ordering() for i, method in enumerate(methods):
def functype(restype=None, argtypes=()): return typesystem.function(return_type=restype, args=list(argtypes))
# TODO: Create a subclass of # llpython.byte_translator.LLVMTranslator that does macro # expansion. def c_string_slice_2 (context, builder, c_string, lb, ub = None): module = builder.basic_block.function.module logger.debug((context, builder, c_string, lb, ub)) _, CStringSlice2Len = context.intrinsic_library.declare(module, 'CStringSlice2Len') _, CStringSlice2 = context.intrinsic_library.declare(module, 'CStringSlice2') _, strlen = context.external_library.declare(module, 'strlen') c_str_len = builder.call(strlen, [c_string]) if ub is None: ub = c_str_len out_len = builder.call(CStringSlice2Len, [c_string, c_str_len, lb, ub]) ret_val = builder.alloca_array(llvm_types._int8, out_len) builder.call(CStringSlice2, [ret_val, c_string, c_str_len, lb, ub]) return ret_val c_string_slice_2.__signature__ = typesystem.function( return_type = char.pointer(), args = (char.pointer(), Py_ssize_t, Py_ssize_t)) def c_string_slice_1 (context, builder, c_string, lb): return c_string_slice_2(context, builder, c_string, lb) c_string_slice_1.__signature__ = typesystem.function( return_type = char.pointer(), args = (char.pointer(), Py_ssize_t))
types = list(nb.numeric) + [object_] array_types = [t[:] for t in types] array_types += [t[:, :] for t in types] array_types += [t[:, :, :] for t in types] all_types = types + array_types def method(func, name, sig): return Method(func, name, sig, False, False) make_methods1 = lambda: [ method(myfunc1, 'method', typesystem.function(argtype, [argtype])) for argtype in all_types ] make_methods2 = lambda: [ method(myfunc2, 'method', typesystem.function(argtype1, [argtype1, argtype2])) for argtype1, argtype2 in itertools.product(all_types, all_types) ] #------------------------------------------------------------------------ # Table building #------------------------------------------------------------------------ def make_table(methods):
def resolve_argtypes(self, args, kwargs): assert not kwargs argtypes = map(self.env.context.typemapper.from_python, args) signature = typesystem.function(None, argtypes) return signature
def signature(self): return function(self.return_type, self.arg_types, self.is_vararg)
# expansion. def c_string_slice_2(context, builder, c_string, lb, ub=None): module = builder.basic_block.function.module logger.debug((context, builder, c_string, lb, ub)) _, CStringSlice2Len = context.intrinsic_library.declare( module, 'CStringSlice2Len') _, CStringSlice2 = context.intrinsic_library.declare( module, 'CStringSlice2') _, strlen = context.external_library.declare(module, 'strlen') c_str_len = builder.call(strlen, [c_string]) if ub is None: ub = c_str_len out_len = builder.call(CStringSlice2Len, [c_string, c_str_len, lb, ub]) ret_val = builder.alloca_array(llvm_types._int8, out_len) builder.call(CStringSlice2, [ret_val, c_string, c_str_len, lb, ub]) return ret_val c_string_slice_2.__signature__ = typesystem.function( return_type=char.pointer(), args=(char.pointer(), Py_ssize_t, Py_ssize_t)) def c_string_slice_1(context, builder, c_string, lb): return c_string_slice_2(context, builder, c_string, lb) c_string_slice_1.__signature__ = typesystem.function( return_type=char.pointer(), args=(char.pointer(), Py_ssize_t))