def field(cls, n, m, dtype, shape=None, offset=None, needs_grad=False, layout=None): # TODO(archibate): deprecate layout '''ti.Matrix.field''' self = cls.empty(n, m) self.entries = [] self.n = n self.m = m self.dt = dtype for i in range(n * m): self.entries.append(impl.field(dtype)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is None: assert offset is None, "shape cannot be None when offset is being set" if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) if isinstance(offset, numbers.Number): offset = (offset, ) if offset is not None: assert len(shape) == len( offset ), f'The dimensionality of shape and offset must be the same ({len(shape)} != {len(offset)})' import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e, offset=offset) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad, offset=offset) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list), offset=offset) return self
def place(): dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list))
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 if rows is not None or cols is not None: warnings.warn( 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: warnings.warn( 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] # construct global matrix else: self.entries = [] self.n = n self.m = m self.dt = dt if dt is None: for i in range(n * m): self.entries.append(impl.expr_init(None)) else: assert not impl.inside_kernel() for i in range(n * m): self.entries.append(impl.var(dt)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) if isinstance(offset, numbers.Number): offset = (offset, ) if offset is not None: assert len(shape) == len( offset ), f'The dimensionality of shape and offset must be the same (f{len(shape)} != f{len(offset)})' import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e, offset=offset) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad, offset=offset) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list), offset=offset) else: assert offset is None, f"shape cannot be None when offset is being set"
def field(cls, n, m, dtype, shape=None, offset=None, needs_grad=False, layout=None): # TODO(archibate): deprecate layout '''ti.Matrix.field''' self = cls.empty(n, m) self.entries = [] self.n = n self.m = m self.dt = dtype if isinstance(dtype, (list, tuple, np.ndarray)): # set different dtype for each element in Matrix # see #2135 if m == 1: assert len(np.shape(dtype)) == 1 and len( dtype ) == n, f'Please set correct dtype list for Vector. The shape of dtype list should be ({n}, ) instead of {np.shape(dtype)}' for i in range(n): self.entries.append(impl.field(dtype[i])) else: assert len(np.shape(dtype)) == 2 and len(dtype) == n and len( dtype[0] ) == m, f'Please set correct dtype list for Matrix. The shape of dtype list should be ({n}, {m}) instead of {np.shape(dtype)}' for i in range(n): for j in range(m): self.entries.append(impl.field(dtype[i][j])) else: for _ in range(n * m): self.entries.append(impl.field(dtype)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is None: assert offset is None, "shape cannot be None when offset is being set" if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) if isinstance(offset, numbers.Number): offset = (offset, ) if offset is not None: assert len(shape) == len( offset ), f'The dimensionality of shape and offset must be the same ({len(shape)} != {len(offset)})' import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e, offset=offset) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad, offset=offset) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list), offset=offset) return self
def __init__(self, n=1, m=1, dt=None, shape=None, empty=False, layout=None, needs_grad=False, keep_raw=False, rows=None, cols=None): # TODO: refactor: use multiple initializer like `ti.Matrix.cols([a, b, c])` # and `ti.Matrix.empty(n, m)` instead of ad-hoc `ti.Matrix(cols=[a, b, c])`. self.grad = None if rows is not None or cols is not None: if rows is not None and cols is not None: raise Exception("cannot specify both rows and columns") if cols is not None: rows = cols self.n = len(rows) if isinstance(rows[0], Matrix): for row in rows: assert row.m == 1, "inputs must be vectors, ie. size n by 1" assert row.n == rows[ 0].n, "input vectors must be the same shape" self.m = rows[0].n # l-value copy: self.entries = [row(i) for row in rows for i in range(row.n)] elif isinstance(rows[0], list): for row in rows: assert len(row) == len( rows[0]), "input lists must be the same shape" self.m = len(rows[0]) # l-value copy: self.entries = [x for row in rows for x in row] else: raise Exception( "rows/cols must be list of lists or lists of vectors") if cols is not None: t = self.transpose() self.n = t.n self.m = t.m self.entries = t.entries 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.get_runtime().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: self.entries = [] self.n = n self.m = m self.dt = dt if empty: self.entries = [None] * n * m else: if dt is None: for i in range(n * m): self.entries.append(impl.expr_init(None)) else: assert not impl.inside_kernel() for i in range(n * m): self.entries.append(impl.var(dt)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list))
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 if rows is not None or cols is not None: warnings.warn( 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: warnings.warn( 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] # construct global matrix else: self.entries = [] self.n = n self.m = m self.dt = dt if dt is None: for i in range(n * m): self.entries.append(impl.expr_init(None)) else: assert not impl.inside_kernel() for i in range(n * m): self.entries.append(impl.var(dt)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) if isinstance(offset, numbers.Number): offset = (offset, ) if offset is not None: assert len(shape) == len( offset ), f'The dimensionality of shape and offset must be the same ({len(shape)} != {len(offset)})' import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e, offset=offset) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad, offset=offset) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list), offset=offset) else: assert offset is None, f"shape cannot be None when offset is being set" if self.n * self.m > 32: warnings.warn( 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 tensor to store a large matrix like this, e.g.:\n' f' x = ti.var(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, m=1, dt=None, empty=False, shape=None, layout=None, needs_grad=False, keep_raw=False): self.grad = None if isinstance(n, list): if n == []: mat = [] elif not isinstance(n[0], list): if impl.get_runtime().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 = 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: self.entries = [] self.n = n self.m = m self.dt = dt if empty: self.entries = [None] * n * m else: if dt is None: for i in range(n * m): self.entries.append(impl.expr_init(None)) else: assert not impl.inside_kernel() for i in range(n * m): self.entries.append(impl.var(dt)) self.grad = self.make_grad() if layout is not None: assert shape is not None, 'layout is useless without shape' if shape is not None: if isinstance(shape, numbers.Number): shape = (shape, ) import taichi as ti if layout is None: layout = ti.AOS dim = len(shape) if layout.soa: for i, e in enumerate(self.entries): ti.root.dense(ti.index_nd(dim), shape).place(e) if needs_grad: ti.root.dense(ti.index_nd(dim), shape).place(e.grad) else: var_list = [] for i, e in enumerate(self.entries): var_list.append(e) if needs_grad: for i, e in enumerate(self.entries): var_list.append(e.grad) ti.root.dense(ti.index_nd(dim), shape).place(*tuple(var_list))