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
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)
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""" )
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
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))
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
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
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
def deactivate_all(): warning( """'ti.root.deactivate_all()' would deactivate all finalized snodes.""" ) ti.deactivate_all_snodes()
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)
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)