Structural nodes (SNodes)¶
After writing the computation code, the user needs to specify the internal data structure hierarchy. Specifying a data structure includes choices at both the macro level, dictating how the data structure components nest with each other and the way they represent sparsity, and the micro level, dictating how data are grouped together (e.g. structure of arrays vs. array of structures). Taichi provides Structural Nodes (SNodes) to compose the hierarchy and particular properties. These constructs and their semantics are listed below:
- dense: A fixed-length contiguous array.
- bitmasked: This is similar to dense, but it also uses a mask to maintain sparsity information, one bit per child.
- pointer: Store pointers instead of the whole structure to save memory and maintain sparsity.
- dynamic: Variable-length array, with a predefined maximum length. It serves the role of
std::vectorin C++ orlistin Python, and can be used to maintain objects (e.g. particles) contained in a block.
See Advanced dense layouts for more details. ti.root is the root node of the data structure.
-
snode.place(x, ...)¶ 参数: - snode – (SNode) where to place
- x – (tensor) tensor(s) to be placed
返回: (SNode) the
snodeitselfThe following code places two 0-D tensors named
xandy:x = ti.var(dt=ti.i32) y = ti.var(dt=ti.f32) ti.root.place(x, y) assert x.snode() == y.snode()
-
tensor.shape()¶ 参数: tensor – (Tensor) 返回: (tuple of integers) the shape of tensor Equivalent to
tensor.snode().shape.For example,
ti.root.dense(ti.ijk, (3, 5, 4)).place(x) x.shape # returns (3, 5, 4)
-
tensor.snode()¶ 参数: tensor – (Tensor) 返回: (SNode) the structual node where tensoris placedx = ti.var(dt=ti.i32) y = ti.var(dt=ti.f32) ti.root.place(x, y) x.snode()
-
snode.shape()¶ 参数: snode – (SNode) 返回: (tuple) the size of node along that axis blk1 = ti.root blk2 = blk1.dense(ti.i, 3) blk3 = blk2.dense(ti.jk, (5, 2)) blk4 = blk3.dense(ti.k, 2) blk1.shape # () blk2.shape # (3, ) blk3.shape # (3, 5, 2) blk4.shape # (3, 5, 4)
-
snode.parent(n = 1)¶ 参数: - snode – (SNode)
- n – (optional, scalar) the number of steps, i.e.
n=1for parent,n=2grandparent, etc.
返回: (SNode) the parent node of
snodeblk1 = ti.root.dense(ti.i, 8) blk2 = blk1.dense(ti.j, 4) blk3 = blk2.bitmasked(ti.k, 6) blk1.parent() # ti.root blk2.parent() # blk1 blk3.parent() # blk2 blk3.parent(1) # blk2 blk3.parent(2) # blk1 blk3.parent(3) # ti.root blk3.parent(4) # None
Node types¶
-
snode.dense(indices, shape)¶ 参数: - snode – (SNode) parent node where the child is derived from
- indices – (Index or Indices) indices used for this node
- shape – (scalar or tuple) shape the tensor of vectors
返回: (SNode) the derived child node
The following code places a 1-D tensor of size
3:x = ti.var(dt=ti.i32) ti.root.dense(ti.i, 3).place(x)
The following code places a 2-D tensor of shape
(3, 4):x = ti.var(dt=ti.i32) ti.root.dense(ti.ij, (3, 4)).place(x)
注解
If
shapeis a scalar and there are multiple indices, thenshapewill be automatically expanded to fit the number of indices. For example,snode.dense(ti.ijk, 3)
is equivalent to
snode.dense(ti.ijk, (3, 3, 3))
-
snode.dynamic(index, size, chunk_size = None)¶ 参数: - snode – (SNode) parent node where the child is derived from
- index – (Index) the
dynamicnode indices - size – (scalar) the maximum size of the dynamic node
- chunk_size – (optional, scalar) the number of elements in each dynamic memory allocation chunk
返回: (SNode) the derived child node
dynamicnodes acts likestd::vectorin C++ orlistin Python. Taichi’s dynamic memory allocation system allocates its memory on the fly.The following places a 1-D dynamic tensor of maximum size
16:ti.root.dynamic(ti.i, 16).place(x)
-
snode.bitmasked()¶
-
snode.pointer()¶
-
snode.hash()¶ TODO: add descriptions here
Working with dynamic SNodes¶
-
ti.length(snode, indices)¶ 参数: - snode – (SNode, dynamic)
- indices – (scalar or tuple of scalars) the
dynamicnode indices
返回: (int32) the current size of the dynamic node
-
ti.append(snode, indices, val)¶ 参数: - snode – (SNode, dynamic)
- indices – (scalar or tuple of scalars) the
dynamicnode indices - val – (depends on SNode data type) value to store
返回: (int32) the size of the dynamic node, before appending
Inserts
valinto thedynamicnode with indicesindices.
Taichi tensors like powers of two¶
Non-power-of-two tensor dimensions are promoted into powers of two and thus these tensors will occupy more virtual address space.
For example, a (dense) tensor of size (18, 65) will be materialized as (32, 128).