Beispiel #1
0
    def to_numpy(self, keep_dims=False, as_vector=None, dtype=None):
        """Converts `self` to a numpy array.

        Args:
            keep_dims (bool, optional): Whether to keep the dimension after conversion.
                When keep_dims=True, on an n-D matrix field, the numpy array always has n+2 dims, even for 1x1, 1xn, nx1 matrix fields.
                When keep_dims=False, the resulting numpy array should skip the matrix dims with size 1.
                For example, a 4x1 or 1x4 matrix field with 5x6x7 elements results in an array of shape 5x6x7x4.
            as_vector (bool, deprecated): Whether to make the returned numpy array as a vector, i.e., with shape (n,) rather than (n, 1).
                Note that this argument has been deprecated.
                More discussion about `as_vector`: https://github.com/taichi-dev/taichi/pull/1046#issuecomment-633548858.
            dtype (DataType, optional): The desired data type of returned numpy array.

        Returns:
            numpy.ndarray: The result numpy array.
        """
        if as_vector is not None:
            warning(
                'v.to_numpy(as_vector=True) is deprecated, '
                'please use v.to_numpy() directly instead',
                DeprecationWarning,
                stacklevel=3)
        if dtype is None:
            dtype = to_numpy_type(self.dtype)
        as_vector = self.m == 1 and not keep_dims
        shape_ext = (self.n, ) if as_vector else (self.n, self.m)
        import numpy as np
        arr = np.zeros(self.shape + shape_ext, dtype=dtype)
        from taichi.lang.meta import matrix_to_ext_arr
        matrix_to_ext_arr(self, arr, as_vector)
        ti.sync()
        return arr
Beispiel #2
0
def layout(func):
    assert not pytaichi.materialized, "All layout must be specified before the first kernel launch / data access."
    warning(
        f"@ti.layout will be deprecated in the future, use ti.root directly to specify data layout anytime before the data structure materializes.",
        PendingDeprecationWarning,
        stacklevel=3)
    pytaichi.layout_functions.append(func)
Beispiel #3
0
 def deactivate_all(self):
     """Same as :func:`taichi.lang.snode.SNode.deactivate_all`"""
     if self._finalized:
         self._root.deactivate_all()
     else:
         warning(
             """'deactivate_all()' would do nothing if FieldsBuilder is not finalized"""
         )
Beispiel #4
0
 def finalize(self):
     """Constructs the SNodeTree and finalizes this builder."""
     self._check_not_finalized()
     if self._empty:
         warning("Finalizing an empty FieldsBuilder!")
     _ti_core.finalize_snode_tree(_snode_registry, self._ptr,
                                  impl.get_runtime().prog)
     self._finalized = True
Beispiel #5
0
 def _finalize(self, raise_warning, compile_only):
     self._check_not_finalized()
     if self._empty and raise_warning:
         warning("Finalizing an empty FieldsBuilder!")
     self._finalized = True
     return SNodeTree(
         _ti_core.finalize_snode_tree(_snode_registry, self._ptr,
                                      impl.get_runtime().prog,
                                      compile_only))
Beispiel #6
0
    def finalize(self, raise_warning=True):
        """Constructs the SNodeTree and finalizes this builder.

        Args:
            raise_warning (bool): Raise warning or not."""
        self._check_not_finalized()
        if self._empty and raise_warning:
            warning("Finalizing an empty FieldsBuilder!")
        _ti_core.finalize_snode_tree(_snode_registry, self._ptr,
                                     impl.get_runtime().prog)
        self._finalized = True
Beispiel #7
0
    def to_numpy(self, keep_dims=False, as_vector=None, dtype=None):
        # Discussion: https://github.com/taichi-dev/taichi/pull/1046#issuecomment-633548858
        if as_vector is not None:
            warning(
                'v.to_numpy(as_vector=True) is deprecated, '
                'please use v.to_numpy() directly instead',
                DeprecationWarning,
                stacklevel=3)
        as_vector = self.m == 1 and not keep_dims
        shape_ext = (self.n, ) if as_vector else (self.n, self.m)

        if not self.is_global():
            return np.array(self.entries).reshape(shape_ext)

        if dtype is None:
            dtype = to_numpy_type(self.dtype)
        ret = np.zeros(self.shape + shape_ext, dtype=dtype)
        from taichi.lang.meta import matrix_to_ext_arr
        matrix_to_ext_arr(self, ret, as_vector)
        return ret
Beispiel #8
0
    def to_numpy(self, keep_dims=False, as_vector=None, dtype=None):
        """Convert the taichi matrix to a numpy.ndarray.

        Args:
            keep_dims (bool, optional): Whether keep the dimension after conversion.
                When keep_dims=True, on an n-D matrix field, the numpy array always has n+2 dims, even for 1x1, 1xn, nx1 matrix fields.
                When keep_dims=False, the resulting numpy array should skip the dimensionality with only 1 element, on the matrix shape dimensionalities.
                For example, a 4x1 or 1x4 matrix field with 5x6x7 elements results in an array of shape 5x6x7x4.
            as_vector (bool, deprecated): Make the returned numpy array as a vector i.e., has a shape (n,) rather than (n, 1)
                Note that this argument has been deprecated.
                More discussion about `as_vector`: https://github.com/taichi-dev/taichi/pull/1046#issuecomment-633548858.
            dtype (DataType, optional): The desired data type of returned numpy array.

        Returns:
            numpy.ndarray: The numpy array that converted from the matrix field.

        """
        # Discussion: https://github.com/taichi-dev/taichi/pull/1046#issuecomment-633548858
        if as_vector is not None:
            warning(
                'v.to_numpy(as_vector=True) is deprecated, '
                'please use v.to_numpy() directly instead',
                DeprecationWarning,
                stacklevel=3)
        as_vector = self.m == 1 and not keep_dims
        shape_ext = (self.n, ) if as_vector else (self.n, self.m)

        if not self.is_global():
            return np.array(self.entries).reshape(shape_ext)

        if dtype is None:
            dtype = to_numpy_type(self.dtype)
        ret = np.zeros(self.shape + shape_ext, dtype=dtype)
        from taichi.lang.meta import matrix_to_ext_arr
        matrix_to_ext_arr(self, ret, as_vector)
        return ret
Beispiel #9
0
 def deactivate_all():
     warning(
         """'ti.root.deactivate_all()' would deactivate all finalized snodes."""
     )
     ti.deactivate_all_snodes()
Beispiel #10
0
    def __init__(self,
                 n=1,
                 m=1,
                 dt=None,
                 shape=None,
                 offset=None,
                 empty=False,
                 layout=None,
                 needs_grad=False,
                 keep_raw=False,
                 rows=None,
                 cols=None):
        self.grad = None

        # construct from rows or cols (deprecated)
        if rows is not None or cols is not None:
            warning(
                f"ti.Matrix(rows=[...]) or ti.Matrix(cols=[...]) is deprecated, use ti.Matrix.rows([...]) or ti.Matrix.cols([...]) instead.",
                DeprecationWarning,
                stacklevel=2)
            if rows is not None and cols is not None:
                raise Exception("cannot specify both rows and columns")
            self.dt = dt
            mat = Matrix.cols(cols) if cols is not None else Matrix.rows(rows)
            self.n = mat.n
            self.m = mat.m
            self.entries = mat.entries
            return

        elif empty == True:
            warning(
                f"ti.Matrix(n, m, empty=True) is deprecated, use ti.Matrix.empty(n, m) instead",
                DeprecationWarning,
                stacklevel=2)
            self.dt = dt
            self.entries = [[None] * m for _ in range(n)]
            return

        elif isinstance(n, (list, tuple, np.ndarray)):
            if len(n) == 0:
                mat = []
            elif isinstance(n[0], Matrix):
                raise Exception(
                    'cols/rows required when using list of vectors')
            elif not isinstance(n[0], Iterable):
                if impl.inside_kernel():
                    # wrap potential constants with Expr
                    if keep_raw:
                        mat = [list([x]) for x in n]
                    else:
                        mat = [list([expr.Expr(x)]) for x in n]
                else:
                    mat = [[x] for x in n]
            else:
                mat = [list(r) for r in n]
            self.n = len(mat)
            if len(mat) > 0:
                self.m = len(mat[0])
            else:
                self.m = 1
            self.entries = [x for row in mat for x in row]

        else:
            if dt is None:
                # create a local matrix with specific (n, m)
                self.entries = [impl.expr_init(None) for i in range(n * m)]
                self.n = n
                self.m = m
            else:
                # construct global matrix (deprecated)
                warning(
                    "Declaring global matrices using `ti.Matrix(n, m, dt, shape)` is deprecated, "
                    "use `ti.Matrix.field(n, m, dtype, shape)` instead",
                    DeprecationWarning,
                    stacklevel=2)
                mat = Matrix.field(n=n,
                                   m=m,
                                   dtype=dt,
                                   shape=shape,
                                   offset=offset,
                                   needs_grad=needs_grad,
                                   layout=layout)
                self.n = mat.n
                self.m = mat.m
                self.entries = mat.entries
                self.grad = mat.grad

        if self.n * self.m > 32:
            warning(
                f'Taichi matrices/vectors with {self.n}x{self.m} > 32 entries are not suggested.'
                ' Matrices/vectors will be automatically unrolled at compile-time for performance.'
                ' So the compilation time could be extremely long if the matrix size is too big.'
                ' You may use a field to store a large matrix like this, e.g.:\n'
                f'    x = ti.field(ti.f32, ({self.n}, {self.m})).\n'
                ' See https://taichi.readthedocs.io/en/stable/tensor_matrix.html#matrix-size'
                ' for more details.',
                UserWarning,
                stacklevel=2)
Beispiel #11
0
    def __init__(self,
                 n=1,
                 m=1,
                 dt=None,
                 shape=None,
                 offset=None,
                 empty=False,
                 layout=Layout.AOS,
                 needs_grad=False,
                 keep_raw=False,
                 disable_local_tensor=False,
                 rows=None,
                 cols=None):
        self.local_tensor_proxy = None
        self.any_array_access = None
        self.grad = None

        # construct from rows or cols (deprecated)
        if rows is not None or cols is not None:
            warning(
                f"ti.Matrix(rows=[...]) or ti.Matrix(cols=[...]) is deprecated, use ti.Matrix.rows([...]) or ti.Matrix.cols([...]) instead.",
                DeprecationWarning,
                stacklevel=2)
            if rows is not None and cols is not None:
                raise Exception("cannot specify both rows and columns")
            self.dt = dt
            mat = Matrix.cols(cols) if cols is not None else Matrix.rows(rows)
            self.n = mat.n
            self.m = mat.m
            self.entries = mat.entries
            return

        elif empty == True:
            warning(
                f"ti.Matrix(n, m, empty=True) is deprecated, use ti.Matrix.empty(n, m) instead",
                DeprecationWarning,
                stacklevel=2)
            self.dt = dt
            self.entries = [[None] * m for _ in range(n)]
            return

        elif isinstance(n, (list, tuple, np.ndarray)):
            if len(n) == 0:
                mat = []
            elif isinstance(n[0], Matrix):
                raise Exception(
                    'cols/rows required when using list of vectors')
            elif not isinstance(n[0], Iterable):
                if impl.inside_kernel():
                    # wrap potential constants with Expr
                    if keep_raw:
                        mat = [list([x]) for x in n]
                    else:
                        if in_python_scope(
                        ) or disable_local_tensor or not ti.current_cfg(
                        ).dynamic_index:
                            mat = [list([expr.Expr(x)]) for x in n]
                        else:
                            if not ti.is_extension_supported(
                                    ti.cfg.arch, ti.extension.dynamic_index):
                                raise Exception(
                                    'Backend ' + str(ti.cfg.arch) +
                                    ' doesn\'t support dynamic index')
                            if dt is None:
                                if isinstance(n[0], int):
                                    dt = impl.get_runtime().default_ip
                                elif isinstance(n[0], float):
                                    dt = impl.get_runtime().default_fp
                                else:
                                    raise Exception(
                                        'dt required when using dynamic_index for local tensor'
                                    )
                            self.local_tensor_proxy = impl.expr_init_local_tensor(
                                [len(n)], dt,
                                expr.make_expr_group([expr.Expr(x)
                                                      for x in n]))
                            mat = []
                            for i in range(len(n)):
                                mat.append(
                                    list([
                                        ti.local_subscript_with_offset(
                                            self.local_tensor_proxy, (i, ),
                                            (len(n), ))
                                    ]))
                else:
                    mat = [[x] for x in n]
            else:
                if in_python_scope(
                ) or disable_local_tensor or not ti.current_cfg(
                ).dynamic_index:
                    mat = [list(r) for r in n]
                else:
                    if not ti.is_extension_supported(
                            ti.cfg.arch, ti.extension.dynamic_index):
                        raise Exception('Backend ' + str(ti.cfg.arch) +
                                        ' doesn\'t support dynamic index')
                    if dt is None:
                        if isinstance(n[0][0], int):
                            dt = impl.get_runtime().default_ip
                        elif isinstance(n[0][0], float):
                            dt = impl.get_runtime().default_fp
                        else:
                            raise Exception(
                                'dt required when using dynamic_index for local tensor'
                            )
                    self.local_tensor_proxy = impl.expr_init_local_tensor(
                        [len(n), len(n[0])], dt,
                        expr.make_expr_group(
                            [expr.Expr(x) for row in n for x in row]))
                    mat = []
                    for i in range(len(n)):
                        mat.append([])
                        for j in range(len(n[0])):
                            mat[i].append(
                                ti.local_subscript_with_offset(
                                    self.local_tensor_proxy, (i, j),
                                    (len(n), len(n[0]))))
            self.n = len(mat)
            if len(mat) > 0:
                self.m = len(mat[0])
            else:
                self.m = 1
            self.entries = [x for row in mat for x in row]

        else:
            if dt is None:
                # create a local matrix with specific (n, m)
                self.entries = [impl.expr_init(None) for i in range(n * m)]
                self.n = n
                self.m = m
            else:
                # construct global matrix (deprecated)
                warning(
                    "Declaring global matrices using `ti.Matrix(n, m, dt, shape)` is deprecated, "
                    "use `ti.Matrix.field(n, m, dtype, shape)` instead",
                    DeprecationWarning,
                    stacklevel=2)
                mat = Matrix.field(n=n,
                                   m=m,
                                   dtype=dt,
                                   shape=shape,
                                   offset=offset,
                                   needs_grad=needs_grad,
                                   layout=layout)
                self.n = mat.n
                self.m = mat.m
                self.entries = mat.entries
                self.grad = mat.grad

        if self.n * self.m > 32:
            warning(
                f'Taichi matrices/vectors with {self.n}x{self.m} > 32 entries are not suggested.'
                ' Matrices/vectors will be automatically unrolled at compile-time for performance.'
                ' So the compilation time could be extremely long if the matrix size is too big.'
                ' You may use a field to store a large matrix like this, e.g.:\n'
                f'    x = ti.field(ti.f32, ({self.n}, {self.m})).\n'
                ' See https://taichi.readthedocs.io/en/stable/tensor_matrix.html#matrix-size'
                ' for more details.',
                UserWarning,
                stacklevel=2)