예제 #1
0
        def transform_as_kernel():
            # Treat return type
            if node.returns is not None:
                kernel_arguments.decl_ret(ctx.func.return_type)

            for i, arg in enumerate(args.args):
                if isinstance(ctx.func.argument_annotations[i],
                              annotations.template):
                    ctx.create_variable(arg.arg, ctx.global_vars[arg.arg])
                elif isinstance(ctx.func.argument_annotations[i],
                                annotations.sparse_matrix_builder):
                    ctx.create_variable(
                        arg.arg,
                        kernel_arguments.decl_sparse_matrix(
                            to_taichi_type(ctx.arg_features[i])))
                elif isinstance(ctx.func.argument_annotations[i],
                                ndarray_type.NdarrayType):
                    ctx.create_variable(
                        arg.arg,
                        kernel_arguments.decl_ndarray_arg(
                            to_taichi_type(ctx.arg_features[i][0]),
                            ctx.arg_features[i][1], ctx.arg_features[i][2],
                            ctx.arg_features[i][3]))
                elif isinstance(ctx.func.argument_annotations[i], MatrixType):
                    ctx.create_variable(
                        arg.arg,
                        kernel_arguments.decl_matrix_arg(
                            ctx.func.argument_annotations[i]))
                else:
                    ctx.global_vars[
                        arg.arg] = kernel_arguments.decl_scalar_arg(
                            ctx.func.argument_annotations[i])
            # remove original args
            node.args.args = []
예제 #2
0
    def dtype(self):
        """Gets data type of each individual value.

        Returns:
            DataType: Data type of each individual value.
        """
        return to_taichi_type(self.arr.dtype)
예제 #3
0
        def transform_as_kernel():
            # Treat return type
            if node.returns is not None:
                ti.lang.kernel_arguments.decl_scalar_ret(ctx.func.return_type)

            for i, arg in enumerate(args.args):
                if isinstance(ctx.func.argument_annotations[i], ti.template):
                    continue
                elif isinstance(ctx.func.argument_annotations[i],
                                ti.linalg.sparse_matrix_builder):
                    ctx.create_variable(
                        arg.arg, ti.lang.kernel_arguments.decl_sparse_matrix())
                elif isinstance(ctx.func.argument_annotations[i], ti.any_arr):
                    ctx.create_variable(
                        arg.arg,
                        ti.lang.kernel_arguments.decl_any_arr_arg(
                            to_taichi_type(ctx.arg_features[i][0]),
                            ctx.arg_features[i][1], ctx.arg_features[i][2],
                            ctx.arg_features[i][3]))
                else:
                    ctx.global_vars[
                        arg.arg] = ti.lang.kernel_arguments.decl_scalar_arg(
                            ctx.func.argument_annotations[i])
            # remove original args
            node.args.args = []
예제 #4
0
        def transform_as_kernel():
            # Treat return type
            if node.returns is not None:
                ret_init = parse_stmt(
                    'ti.lang.kernel_arguments.decl_scalar_ret(0)')
                ret_init.value.args[0] = node.returns
                ctx.returns = node.returns
                arg_decls.append(ret_init)
                node.returns = None

            for i, arg in enumerate(args.args):
                # Directly pass in template arguments,
                # such as class instances ("self"), fields, SNodes, etc.
                if isinstance(ctx.func.argument_annotations[i], ti.template):
                    continue
                if isinstance(ctx.func.argument_annotations[i],
                              ti.linalg.sparse_matrix_builder):
                    arg_init = parse_stmt(
                        'x = ti.lang.kernel_arguments.decl_sparse_matrix()')
                    arg_init.targets[0].id = arg.arg
                    ctx.create_variable(arg.arg)
                    arg_decls.append(arg_init)
                elif isinstance(ctx.func.argument_annotations[i], ti.any_arr):
                    arg_init = parse_stmt(
                        'x = ti.lang.kernel_arguments.decl_any_arr_arg(0, 0, 0, 0)'
                    )
                    arg_init.targets[0].id = arg.arg
                    ctx.create_variable(arg.arg)
                    array_dt = ctx.arg_features[i][0]
                    array_dim = ctx.arg_features[i][1]
                    array_element_shape = ctx.arg_features[i][2]
                    array_layout = ctx.arg_features[i][3]
                    array_dt = to_taichi_type(array_dt)
                    dt_expr = 'ti.' + ti.core.data_type_name(array_dt)
                    dt = parse_expr(dt_expr)
                    arg_init.value.args[0] = dt
                    arg_init.value.args[1] = parse_expr("{}".format(array_dim))
                    arg_init.value.args[2] = parse_expr(
                        "{}".format(array_element_shape))
                    arg_init.value.args[3] = parse_expr(
                        "ti.{}".format(array_layout))
                    arg_decls.append(arg_init)
                else:
                    arg_init = parse_stmt(
                        'x = ti.lang.kernel_arguments.decl_scalar_arg(0)')
                    arg_init.targets[0].id = arg.arg
                    dt = arg.annotation
                    arg_init.value.args[0] = dt
                    arg_decls.append(arg_init)
            # remove original args
            node.args.args = []
예제 #5
0
 def extract(self, x):
     shape = tuple(x.shape)
     element_dim = len(self.element_shape)
     if len(shape) < element_dim:
         raise ValueError("Invalid argument passed to ti.any_arr()")
     if element_dim > 0:
         if self.layout == Layout.SOA:
             if shape[:element_dim] != self.element_shape:
                 raise ValueError("Invalid argument passed to ti.any_arr()")
         else:
             if shape[-element_dim:] != self.element_shape:
                 raise ValueError("Invalid argument passed to ti.any_arr()")
     return to_taichi_type(
         x.dtype), len(shape), self.element_shape, self.layout
예제 #6
0
 def extract_arg(arg, anno):
     if isinstance(anno, template):
         if isinstance(arg, taichi.lang.snode.SNode):
             return arg.ptr
         if isinstance(arg, taichi.lang.expr.Expr):
             return arg.ptr.get_underlying_ptr_address()
         if isinstance(arg, _ti_core.Expr):
             return arg.get_underlying_ptr_address()
         if isinstance(arg, tuple):
             return tuple(
                 TaichiCallableTemplateMapper.extract_arg(item, anno)
                 for item in arg)
         return arg
     if isinstance(anno, ndarray_type.NdarrayType):
         if isinstance(arg, taichi.lang._ndarray.ScalarNdarray):
             anno._check_element_dim(arg, 0)
             anno._check_element_shape(())
             anno._check_field_dim(len(arg.shape))
             return arg.dtype, len(arg.shape), (), Layout.AOS
         if isinstance(arg, taichi.lang.matrix.VectorNdarray):
             anno._check_element_dim(arg, 1)
             anno._check_element_shape((arg.n, ))
             anno._check_field_dim(len(arg.shape))
             anno._check_layout(arg)
             return arg.dtype, len(arg.shape) + 1, (arg.n, ), arg.layout
         if isinstance(arg, taichi.lang.matrix.MatrixNdarray):
             anno._check_element_dim(arg, 2)
             anno._check_element_shape((arg.n, arg.m))
             anno._check_field_dim(len(arg.shape))
             anno._check_layout(arg)
             return arg.dtype, len(arg.shape) + 2, (arg.n,
                                                    arg.m), arg.layout
         # external arrays
         element_dim = 0 if anno.element_dim is None else anno.element_dim
         layout = Layout.AOS if anno.layout is None else anno.layout
         shape = tuple(arg.shape)
         if len(shape) < element_dim:
             raise ValueError(
                 f"Invalid argument into ti.types.ndarray() - required element_dim={element_dim}, "
                 f"but the argument has only {len(shape)} dimensions")
         element_shape = (
         ) if element_dim == 0 else shape[:
                                          element_dim] if layout == Layout.SOA else shape[
                                              -element_dim:]
         return to_taichi_type(arg.dtype), len(shape), element_shape, layout
     if isinstance(anno, sparse_matrix_builder):
         return arg.dtype
     # Use '#' as a placeholder because other kinds of arguments are not involved in template instantiation
     return '#'
예제 #7
0
파일: kernel_impl.py 프로젝트: galek/taichi
 def extract_arg(arg, anno):
     if isinstance(anno, template):
         if isinstance(arg, taichi.lang.snode.SNode):
             return arg.ptr
         if isinstance(arg, taichi.lang.expr.Expr):
             return arg.ptr.get_underlying_ptr_address()
         if isinstance(arg, _ti_core.Expr):
             return arg.get_underlying_ptr_address()
         if isinstance(arg, tuple):
             return tuple(
                 TaichiCallableTemplateMapper.extract_arg(item, anno)
                 for item in arg)
         return arg
     elif isinstance(anno, any_arr):
         if isinstance(arg, taichi.lang._ndarray.ScalarNdarray):
             anno.check_element_dim(arg, 0)
             return arg.dtype, len(arg.shape), (), Layout.AOS
         if isinstance(arg, taichi.lang.matrix.VectorNdarray):
             anno.check_element_dim(arg, 1)
             anno.check_layout(arg)
             return arg.dtype, len(arg.shape) + 1, (arg.n, ), arg.layout
         if isinstance(arg, taichi.lang.matrix.MatrixNdarray):
             anno.check_element_dim(arg, 2)
             anno.check_layout(arg)
             return arg.dtype, len(arg.shape) + 2, (arg.n,
                                                    arg.m), arg.layout
         # external arrays
         element_dim = 0 if anno.element_dim is None else anno.element_dim
         layout = Layout.AOS if anno.layout is None else anno.layout
         shape = tuple(arg.shape)
         if len(shape) < element_dim:
             raise ValueError(
                 f"Invalid argument into ti.any_arr() - required element_dim={element_dim}, but the argument has only {len(shape)} dimensions"
             )
         element_shape = (
         ) if element_dim == 0 else shape[:
                                          element_dim] if layout == Layout.SOA else shape[
                                              -element_dim:]
         return to_taichi_type(arg.dtype), len(shape), element_shape, layout
     return (type(arg).__name__, )
예제 #8
0
 def extract(self, x):
     return to_taichi_type(x.dtype), len(x.shape)
예제 #9
0
    def visit_FunctionDef(self, node):
        args = node.args
        assert args.vararg is None
        assert args.kwonlyargs == []
        assert args.kw_defaults == []
        assert args.kwarg is None
        import taichi as ti
        if self.is_kernel:  # ti.kernel
            for decorator in node.decorator_list:
                if (isinstance(decorator, ast.Attribute)
                        and isinstance(decorator.value, ast.Name)
                        and decorator.value.id == 'ti'
                        and decorator.attr == 'func'):
                    raise TaichiSyntaxError(
                        "Function definition not allowed in 'ti.kernel'.")
            # Transform as kernel
            arg_decls = []

            # Treat return type
            if node.returns is not None:
                ret_init = self.parse_stmt(
                    'ti.lang.kernel_arguments.decl_scalar_ret(0)')
                ret_init.value.args[0] = node.returns
                self.returns = node.returns
                arg_decls.append(ret_init)
                node.returns = None

            for i, arg in enumerate(args.args):
                # Directly pass in template arguments,
                # such as class instances ("self"), fields, SNodes, etc.
                if isinstance(self.func.arguments[i], ti.template):
                    continue
                import taichi as ti
                if isinstance(self.func.arguments[i], ti.ext_arr):
                    arg_init = self.parse_stmt(
                        'x = ti.lang.kernel_arguments.decl_ext_arr_arg(0, 0)')
                    arg_init.targets[0].id = arg.arg
                    self.create_variable(arg.arg)
                    array_dt = self.arg_features[i][0]
                    array_dim = self.arg_features[i][1]
                    array_dt = to_taichi_type(array_dt)
                    dt_expr = 'ti.' + ti.core.data_type_name(array_dt)
                    dt = self.parse_expr(dt_expr)
                    arg_init.value.args[0] = dt
                    arg_init.value.args[1] = self.parse_expr(
                        "{}".format(array_dim))
                    arg_decls.append(arg_init)
                else:
                    arg_init = self.parse_stmt(
                        'x = ti.lang.kernel_arguments.decl_scalar_arg(0)')
                    arg_init.targets[0].id = arg.arg
                    dt = arg.annotation
                    arg_init.value.args[0] = dt
                    arg_decls.append(arg_init)
            # remove original args
            node.args.args = []

        else:  # ti.func
            for decorator in node.decorator_list:
                if (isinstance(decorator, ast.Attribute)
                        and isinstance(decorator.value, ast.Name)
                        and decorator.value.id == 'ti'
                        and decorator.attr == 'func'):
                    raise TaichiSyntaxError(
                        "Function definition not allowed in 'ti.func'.")
            # Transform as func (all parameters passed by value)
            arg_decls = []
            for i, arg in enumerate(args.args):
                # Directly pass in template arguments,
                # such as class instances ("self"), fields, SNodes, etc.
                if isinstance(self.func.arguments[i], ti.template):
                    continue
                # Create a copy for non-template arguments,
                # so that they are passed by value.
                arg_init = self.parse_stmt('x = ti.expr_init_func(0)')
                arg_init.targets[0].id = arg.arg
                self.create_variable(arg.arg)
                arg_init.value.args[0] = self.parse_expr(arg.arg +
                                                         '_by_value__')
                args.args[i].arg += '_by_value__'
                arg_decls.append(arg_init)

        with self.variable_scope():
            self.generic_visit(node)

        node.body = arg_decls + node.body
        node.body = [self.parse_stmt('import taichi as ti')] + node.body
        return node