def __call__(self, *args): if not impl.inside_kernel(): if not self.pyfunc: raise TaichiSyntaxError( "Taichi functions cannot be called from Python-scope." " Use @ti.pyfunc if you wish to call Taichi functions " "from both Python-scope and Taichi-scope.") return self.func(*args) if impl.get_runtime().experimental_real_function: if impl.get_runtime().current_kernel.is_grad: raise TaichiSyntaxError( "Real function in gradient kernels unsupported.") instance_id, _ = self.mapper.lookup(args) key = _ti_core.FunctionKey(self.func.__name__, self.func_id, instance_id) if self.compiled is None: self.compiled = {} if key.instance_id not in self.compiled: self.do_compile(key=key, args=args) return self.func_call_rvalue(key=key, args=args) tree, ctx = _get_tree_and_ctx( self, is_kernel=False, args=args, ast_builder=impl.get_runtime().prog.current_ast_builder()) ret = transform_tree(tree, ctx) if not impl.get_runtime().experimental_real_function: if self.return_type and not ctx.returned: raise TaichiSyntaxError( "Function has a return type but does not have a return statement" ) return ret
def __call__(self, *args, **kwargs): args = _process_args(self, args, kwargs) if not impl.inside_kernel(): if not self.pyfunc: raise TaichiSyntaxError( "Taichi functions cannot be called from Python-scope.") return self.func(*args) if self.is_real_function: if impl.get_runtime( ).current_kernel.autodiff_mode != AutodiffMode.NONE: raise TaichiSyntaxError( "Real function in gradient kernels unsupported.") instance_id, _ = self.mapper.lookup(args) key = _ti_core.FunctionKey(self.func.__name__, self.func_id, instance_id) if self.compiled is None: self.compiled = {} if key.instance_id not in self.compiled: self.do_compile(key=key, args=args) return self.func_call_rvalue(key=key, args=args) tree, ctx = _get_tree_and_ctx( self, is_kernel=False, args=args, ast_builder=impl.get_runtime().prog.current_ast_builder(), is_real_function=self.is_real_function) ret = transform_tree(tree, ctx) if not self.is_real_function: if self.return_type and ctx.returned != ReturnStatus.ReturnedValue: raise TaichiSyntaxError( "Function has a return type but does not have a return statement" ) return ret
def taichi_ast_generator(): if self.runtime.inside_kernel: raise TaichiSyntaxError( "Kernels cannot call other kernels. I.e., nested kernels are not allowed. " "Please check if you have direct/indirect invocation of kernels within kernels. " "Note that some methods provided by the Taichi standard library may invoke kernels, " "and please move their invocations to Python-scope.") self.runtime.inside_kernel = True self.runtime.current_kernel = self try: transform_tree(tree, ctx) if not impl.get_runtime().experimental_real_function: if self.return_type and not ctx.returned: raise TaichiSyntaxError( "Kernel has a return type but does not have a return statement" ) finally: self.runtime.inside_kernel = False self.runtime.current_kernel = None
def func_body(): ctx.ast_builder = fn.ast_builder() transform_tree(tree, ctx)
def do_compile(self, key, args): tree, ctx = _get_tree_and_ctx(self, is_kernel=False, args=args) self.compiled[key.instance_id] = lambda: transform_tree(tree, ctx) self.taichi_functions[key.instance_id] = _ti_core.create_function(key) self.taichi_functions[key.instance_id].set_function_body( self.compiled[key.instance_id])