.. function:: ti.var(dt, shape = None, offset = None) :parameter dt: (DataType) type of the tensor element :parameter shape: (optional, scalar or tuple) the shape of tensor :parameter offset: (optional, scalar or tuple) see :ref:`offset` For example, this creates a *dense* tensor with four ``int32`` as elements: :: x = ti.var(ti.i32, shape=4) This creates a 4x3 *dense* tensor with ``float32`` elements: :: x = ti.var(ti.f32, shape=(4, 3)) If shape is ``()`` (empty tuple), then a 0-D tensor (scalar) is created: :: x = ti.var(ti.f32, shape=()) Then access it by passing ``None`` as index: :: x[None] = 2 If shape is **not provided** or ``None``, the user must manually ``place`` it afterwards: :: x = ti.var(ti.f32) ti.root.dense(ti.ij, (4, 3)).place(x) # equivalent to: x = ti.var(ti.f32, shape=(4, 3))
Note
Not providing shape
allows you to place the tensor in a layout other than the default dense, see :ref:`layout` for more details.
Warning
All variables should be created and placed before any kernel invocation or any of them accessed from python-scope. For example:
x = ti.var(ti.f32)
x[None] = 1 # ERROR: x not placed!
x = ti.var(ti.f32, shape=())
@ti.kernel
def func():
x[None] = 1
func()
y = ti.var(ti.f32, shape=())
# ERROR: cannot create tensor after kernel invocation!
x = ti.var(ti.f32, shape=())
x[None] = 1
y = ti.var(ti.f32, shape=())
# ERROR: cannot create tensor after any tensor accesses from the Python-scope!
You can access an element of the Taichi tensor by an index or indices.
.. attribute:: a[p, q, ...] :parameter a: (Tensor) the tensor of scalars :parameter p: (scalar) index of the first tensor dimension :parameter q: (scalar) index of the second tensor dimension :return: (scalar) the element at ``[p, q, ...]`` This extracts the element value at index ``[3, 4]`` of tensor ``a``: :: x = a[3, 4] This sets the element value at index ``2`` of 1D tensor ``b`` to ``5``: :: b[2] = 5 .. note :: In Python, x[(exp1, exp2, ..., expN)] is equivalent to x[exp1, exp2, ..., expN]; the latter is just syntactic sugar for the former. .. note :: The returned value can also be ``Vector`` / ``Matrix`` if ``a`` is a tensor of vector / matrix, see :ref:`vector` for more details.
.. attribute:: a.shape :parameter a: (Tensor) the tensor :return: (tuple) the shape of tensor ``a`` :: x = ti.var(ti.i32, (6, 5)) x.shape # (6, 5) y = ti.var(ti.i32, 6) y.shape # (6,) z = ti.var(ti.i32, ()) z.shape # ()
.. attribute:: a.dtype :parameter a: (Tensor) the tensor :return: (DataType) the data type of ``a`` :: x = ti.var(ti.i32, (2, 3)) x.dtype # ti.i32
.. function:: a.parent(n = 1) :parameter a: (Tensor) the tensor :parameter n: (optional, scalar) the number of parent steps, i.e. ``n=1`` for parent, ``n=2`` grandparent, etc. :return: (SNode) the parent of ``a``'s containing SNode :: x = ti.var(ti.i32) y = ti.var(ti.i32) blk1 = ti.root.dense(ti.ij, (6, 5)) blk2 = blk1.dense(ti.ij, (3, 2)) blk1.place(x) blk2.place(y) x.parent() # blk1 y.parent() # blk2 y.parent(2) # blk1 See :ref:`snode` for more details.