diff --git a/docs/lang/articles/basic/sparse.md b/docs/lang/articles/basic/sparse.md index 914ab04b84983..d3a1c8730cef1 100644 --- a/docs/lang/articles/basic/sparse.md +++ b/docs/lang/articles/basic/sparse.md @@ -44,7 +44,9 @@ In Taichi, programmers can compose data structures similar to VDB and SPGrid wit :::note -**Backend compatibility**: The LLVM backends (CPU/CUDA) and the Metal backend offer the full functionality of computation on spatially sparse data structures. +**Backend compatibility**: The LLVM-based backends (CPU/CUDA) offer the full functionality for performing computations on spatially sparse data structures. +Using sparse data structures on the Metal backend is now deprecated. The support for Dynamic SNode has been removed in v1.3.0, +and the support for Pointer/Bitmasked SNode will be removed in v1.4.0. ::: @@ -170,31 +172,56 @@ The bitmasked SNodes are like dense SNodes with auxiliary activity values. ### Dynamic SNode -To support variable-length fields, Taichi provides dynamic SNodes. The code snippet below first creates a 5x1 dense block (line 2). Then each cell of the dense block contains a variable-length dynamic container (line 3). The maximum length of the dynamic container is 5. In the `make_lists()` function, you can use `ti.append()` to add a value to the end of a dynamic SNode. `x.parent()` is the same as `pixel`. The dense field `l` stores the length of each dynamic SNode. +To support variable-length fields, Taichi provides dynamic SNodes. -```python {3} title=dynamic.py -x = ti.field(ti.i32) -block = ti.root.dense(ti.i, 5) -pixel = block.dynamic(ti.j, 5) -pixel.place(x) +The first argument of `dynamic` is the axis, the second argument is the maximum length, +and the third argument (optional) is the `chunk_size`. + +The `chunk_size` specifies how much space the dynamic SNode allocates when the previously-allocated space runs out. +For example, with `chunk_size=4`, the dynamic SNode allocates the space for four elements when the first element is appended, and +allocates space for another four when the 5th (, 9th, 13th...) element is appended. + +You can use `x[i].append(...)` to append an element, +use `x[i].length()` to get the length, and use `x[i].deactivate()` to clear the list. + +The code snippet below creates a struct field that stores pairs of `(i16, i64)`. +The `i` axis is a dense SNode, and the `j` axis is a dynamic SNode. + +```python {5,13,15,20} title=dynamic.py +pair = ti.types.struct(a=ti.i16, b=ti.i64) +pair_field = pair.field() + +block = ti.root.dense(ti.i, 4) +pixel = block.dynamic(ti.j, 100, chunk_size=4) +pixel.place(pair_field) l = ti.field(ti.i32) ti.root.dense(ti.i, 5).place(l) @ti.kernel -def make_lists(): - for i in range(5): - for j in range(i): - ti.append(x.parent(), i, j * j) # ti.append(pixel, i, j * j) - l[i] = ti.length(x.parent(), i) # [0, 1, 2, 3, 4] +def dynamic_pair(): + for i in range(4): + pair_field[i].deactivate() + for j in range(i * i): + pair_field[i].append(pair(i, j + 1)) + # pair_field = [[], + # [(1, 1)], + # [(2, 1), (2, 2), (2, 3), (2, 4)], + # [(3, 1), (3, 2), ... , (3, 8), (3, 9)]] + l[i] = pair_field[i].length() # l = [0, 1, 4, 9] ``` -