示例#1
0
文件: matrix.py 项目: samuela/taichi
    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
示例#2
0
 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))
示例#3
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
        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"
示例#4
0
    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
示例#5
0
    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))
示例#6
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
        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)
示例#7
0
    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))