From fcd2c7c43a769adc3ae6711ba221febdaf8fce48 Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Sat, 18 Jul 2020 20:55:36 +0800 Subject: [PATCH 01/10] [Doc] Replace all ti.var->ti.field (#1515) --- docs/compilation.rst | 4 ++-- docs/debugging.rst | 6 +++--- docs/export_results.rst | 8 ++++---- docs/external.rst | 4 ++-- docs/gui.rst | 8 ++++---- docs/hello.rst | 8 ++++---- docs/internal.rst | 8 ++++---- docs/layout.rst | 30 +++++++++++++++--------------- docs/matrix.rst | 2 +- docs/odop.rst | 6 +++--- docs/offset.rst | 6 +++--- docs/profiler.rst | 4 ++-- docs/scalar_tensor.rst | 40 ++++++++++++++++++++-------------------- docs/snode.rst | 12 ++++++------ docs/vector.rst | 2 +- 15 files changed, 74 insertions(+), 74 deletions(-) diff --git a/docs/compilation.rst b/docs/compilation.rst index 88aa3f6d82236..fe90bbe9e2bf4 100644 --- a/docs/compilation.rst +++ b/docs/compilation.rst @@ -30,8 +30,8 @@ We allocate two 1D tensors to simplify discussion: .. code-block:: python - x = ti.var(dt=ti.f32, shape=128) - y = ti.var(dt=ti.f32, shape=16) + x = ti.field(dt=ti.f32, shape=128) + y = ti.field(dt=ti.f32, shape=16) Kernel registration diff --git a/docs/debugging.rst b/docs/debugging.rst index f2daef87dd6ea..e17686bfa4dc9 100644 --- a/docs/debugging.rst +++ b/docs/debugging.rst @@ -85,7 +85,7 @@ For now, Taichi-scope ``print`` supports string, scalar, vector, and matrix expr import taichi as ti ti.init(arch=ti.cpu) - a = ti.var(ti.f32, 4) + a = ti.field(ti.f32, 4) @ti.kernel @@ -107,7 +107,7 @@ It is similar to Python-scope ``print``. .. code-block:: python - x = ti.var(ti.f32, (2, 3)) + x = ti.field(ti.f32, (2, 3)) y = 1 @ti.kernel @@ -140,7 +140,7 @@ For performance reason, ``assert`` only works when ``debug`` mode is on, For exa ti.init(arch=ti.cpu, debug=True) - x = ti.var(ti.f32, 128) + x = ti.field(ti.f32, 128) @ti.kernel def do_sqrt_all(): diff --git a/docs/export_results.rst b/docs/export_results.rst index 2fb98eb5ef587..6e60cc59fe6b1 100644 --- a/docs/export_results.rst +++ b/docs/export_results.rst @@ -26,7 +26,7 @@ Export images using ``ti.GUI.show`` ti.init() - pixels = ti.var(ti.u8, shape=(512, 512, 3)) + pixels = ti.field(ti.u8, shape=(512, 512, 3)) @ti.kernel def paint(): @@ -57,7 +57,7 @@ To save images without invoking ``ti.GUI.show(filename)``, use ``ti.imwrite(file ti.init() - pixels = ti.var(ti.u8, shape=(512, 512, 3)) + pixels = ti.field(ti.u8, shape=(512, 512, 3)) @ti.kernel def set_pixels(): @@ -69,7 +69,7 @@ To save images without invoking ``ti.GUI.show(filename)``, use ``ti.imwrite(file ti.imwrite(pixels.to_numpy(), filename) print(f'The image has been saved to {filename}') -- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix``, ``ti.Vector``, ``ti.var``) and numpy tensors ``np.ndarray``. +- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix``, ``ti.Vector``, ``ti.field``) and numpy tensors ``np.ndarray``. - Same as above ``ti.GUI.show(filename)``, the image format (``png``, ``jpg`` and ``bmp``) is also controlled by the suffix of ``filename`` in ``ti.imwrite(filename)``. - Meanwhile, the resulted image type (grayscale, RGB, or RGBA) is determined by **the number of channels in the input tensor**, i.e., the length of the third dimension (``tensor.shape[2]``). - In other words, a tensor that has shape ``(w, h)`` or ``(w, h, 1)`` will be exported as a grayscale image. @@ -96,7 +96,7 @@ Export videos ti.init() - pixels = ti.var(ti.u8, shape=(512, 512, 3)) + pixels = ti.field(ti.u8, shape=(512, 512, 3)) @ti.kernel def paint(): diff --git a/docs/external.rst b/docs/external.rst index 64633a63f9184..988619e725681 100644 --- a/docs/external.rst +++ b/docs/external.rst @@ -21,7 +21,7 @@ Use ``to_numpy``/``from_numpy``/``to_torch``/``from_torch``: m = 7 # Taichi tensors - val = ti.var(ti.i32, shape=(n, m)) + val = ti.field(ti.i32, shape=(n, m)) vec = ti.Vector(3, dt=ti.i32, shape=(n, m)) mat = ti.Matrix(3, 4, dt=ti.i32, shape=(n, m)) @@ -74,7 +74,7 @@ Note that struct-for's on external arrays are not supported. n = 4 m = 7 - val = ti.var(ti.i32, shape=(n, m)) + val = ti.field(ti.i32, shape=(n, m)) @ti.kernel def test_numpy(arr: ti.ext_arr()): diff --git a/docs/gui.rst b/docs/gui.rst index 394b68613c358..d6981d61a0579 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -63,9 +63,9 @@ Paint on a window If the window size is ``(x, y)``, then ``img`` must be one of: - * ``ti.var(shape=(x, y))``, a grey-scale image + * ``ti.field(shape=(x, y))``, a grey-scale image - * ``ti.var(shape=(x, y, 3))``, where `3` is for ``(r, g, b)`` channels + * ``ti.field(shape=(x, y, 3))``, where `3` is for ``(r, g, b)`` channels * ``ti.Vector(3, shape=(x, y))`` (see :ref:`vector`) @@ -387,7 +387,7 @@ Image I/O :parameter img: (Matrix or Expr) the image you want to export :parameter filename: (string) the location you want to save to - Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix``, ``ti.Vector``, or ``ti.var``) to a specified location ``filename``. + Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix``, ``ti.Vector``, or ``ti.field``) to a specified location ``filename``. Same as ``ti.GUI.show(filename)``, the format of the exported image is determined by **the suffix of** ``filename`` as well. Now ``ti.imwrite`` supports exporting images to ``png``, ``img`` and ``jpg`` and we recommend using ``png``. @@ -401,7 +401,7 @@ Image I/O shape = (512, 512) type = ti.u8 - pixels = ti.var(dt=type, shape=shape) + pixels = ti.field(dt=type, shape=shape) @ti.kernel def draw(): diff --git a/docs/hello.rst b/docs/hello.rst index 9b9e9c23743f4..2cfadf8314bcd 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -17,7 +17,7 @@ Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) ti.init(arch=ti.gpu) n = 320 - pixels = ti.var(dt=ti.f32, shape=(n * 2, n)) + pixels = ti.field(dt=ti.f32, shape=(n * 2, n)) @ti.func @@ -107,7 +107,7 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your Taichi is a data-oriented programming language where dense or spatially-sparse tensors are the first-class citizens. See :ref:`sparse` for more details on sparse tensors. -In the code above, ``pixels = ti.var(dt=ti.f32, shape=(n * 2, n))`` allocates a 2D dense tensor named ``pixels`` of +In the code above, ``pixels = ti.field(dt=ti.f32, shape=(n * 2, n))`` allocates a 2D dense tensor named ``pixels`` of size ``(640, 320)`` and element data type ``ti.f32`` (i.e. ``float`` in C). Functions and kernels @@ -247,7 +247,7 @@ For example, to access a single pixel of the rendered image in Python-scope, sim .. code-block:: python import taichi as ti - pixels = ti.var(ti.f32, (1024, 512)) + pixels = ti.field(ti.f32, (1024, 512)) pixels[42, 11] = 0.7 # store data into pixels print(pixels[42, 11]) # prints 0.7 @@ -262,7 +262,7 @@ So that you can also use your favorite Python packages (e.g. ``numpy``, ``pytorc .. code-block:: python import taichi as ti - pixels = ti.var(ti.f32, (1024, 512)) + pixels = ti.field(ti.f32, (1024, 512)) import numpy as np arr = np.random.rand(1024, 512) diff --git a/docs/internal.rst b/docs/internal.rst index b7a949d3fdd1d..37c54bd75bcad 100644 --- a/docs/internal.rst +++ b/docs/internal.rst @@ -31,7 +31,7 @@ For example, ti.init(print_ir=True) - x = ti.var(ti.i32) + x = ti.field(ti.i32) ti.root.dense(ti.i, 4).bitmasked(ti.i, 4).place(x) @ti.kernel @@ -156,7 +156,7 @@ correspond to? Each ``SNode`` can have a different virtual-to-physical mapping. ``physical_index_position[i] == -1`` means the ``i``-th virtual index does not corrspond to any physical index in this ``SNode``. -``SNode`` s in handy dense tensors (i.e., ``a = ti.var(ti.i32, shape=(128, 256, 512))``) +``SNode`` s in handy dense tensors (i.e., ``a = ti.field(ti.i32, shape=(128, 256, 512))``) have **trivial** virtual-to-physical mapping, e.g. ``physical_index_position[i] = i``. However, more complex data layouts, such as column-major 2D tensors can lead to ``SNodes`` with @@ -164,9 +164,9 @@ However, more complex data layouts, such as column-major 2D tensors can lead to .. code-block:: python - a = ti.var(ti.f32, shape=(128, 32, 8)) + a = ti.field(ti.f32, shape=(128, 32, 8)) - b = ti.var(ti.f32) + b = ti.field(ti.f32) ti.root.dense(ti.j, 32).dense(ti.i, 16).place(b) ti.get_runtime().materialize() diff --git a/docs/layout.rst b/docs/layout.rst index eb1216144e9ac..2a6e30d294d78 100644 --- a/docs/layout.rst +++ b/docs/layout.rst @@ -6,7 +6,7 @@ Advanced dense layouts Tensors (:ref:`scalar_tensor`) can be *placed* in a specific shape and *layout*. Defining a proper layout can be critical to performance, especially for memory-bound applications. A carefully designed data layout can significantly improve cache/TLB-hit rates and cacheline utilization. Although when performance is not the first priority, you probably don't have to worry about it. -In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating tensors using ``ti.var/Vector/Matrix``), +In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating tensors using ``ti.field/Vector/Matrix``), and then migrate to more advanced layouts using the ``ti.root.X`` syntax if necessary. Taichi decouples algorithms from data layouts, and the Taichi compiler automatically optimizes data accesses on a specific data layout. These Taichi features allow programmers to quickly experiment with different data layouts and figure out the most efficient one on a specific task and computer architecture. @@ -19,28 +19,28 @@ For example, this declares a 0-D tensor: .. code-block:: python - x = ti.var(ti.f32) + x = ti.field(ti.f32) ti.root.place(x) # is equivalent to: - x = ti.var(ti.f32, shape=()) + x = ti.field(ti.f32, shape=()) This declares a 1D tensor of size ``3``: .. code-block:: python - x = ti.var(ti.f32) + x = ti.field(ti.f32) ti.root.dense(ti.i, 3).place(x) # is equivalent to: - x = ti.var(ti.f32, shape=3) + x = ti.field(ti.f32, shape=3) This declares a 2D tensor of shape ``(3, 4)``: .. code-block:: python - x = ti.var(ti.f32) + x = ti.field(ti.f32) ti.root.dense(ti.ij, (3, 4)).place(x) # is equivalent to: - x = ti.var(ti.f32, shape=(3, 4)) + x = ti.field(ti.f32, shape=(3, 4)) You may wonder, why not simply specify the ``shape`` of the tensor? Why bother using the more complex version? Good question, let go forward and figure out why. @@ -137,8 +137,8 @@ Take a simple 1D wave equation solver for example: .. code-block:: python N = 200000 - pos = ti.var(ti.f32) - vel = ti.var(ti.f32) + pos = ti.field(ti.f32) + vel = ti.field(ti.f32) ti.root.dense(ti.i, N).place(pos) ti.root.dense(ti.i, N).place(vel) @@ -161,11 +161,11 @@ Then ``vel[i]`` is placed right next to ``pos[i]``, this can increase the cache- Flat layouts versus hierarchical layouts ---------------------------------------- -By default, when allocating a ``ti.var``, it follows the simplest data layout. +By default, when allocating a ``ti.field``, it follows the simplest data layout. .. code-block:: python - val = ti.var(ti.f32, shape=(32, 64, 128)) + val = ti.field(ti.f32, shape=(32, 64, 128)) # C++ equivalent: float val[32][64][128] However, at times this data layout can be suboptimal for certain types of computer graphics tasks. @@ -175,7 +175,7 @@ A better layout might be .. code-block:: python - val = ti.var(ti.f32) + val = ti.field(ti.f32) ti.root.dense(ti.ijk, (8, 16, 32)).dense(ti.ijk, (4, 4, 4)).place(val) This organizes ``val`` in ``4x4x4`` blocks, so that with high probability ``val[i, j, k]`` and its neighbours are close to each other (i.e., in the same cacheline or memory page). @@ -205,21 +205,21 @@ Examples .. code-block:: python - A = ti.var(ti.f32) + A = ti.field(ti.f32) ti.root.dense(ti.ij, (256, 256)).place(A) 2D matrix, column-major .. code-block:: python - A = ti.var(ti.f32) + A = ti.field(ti.f32) ti.root.dense(ti.ji, (256, 256)).place(A) # Note ti.ji instead of ti.ij `8x8` blocked 2D array of size `1024x1024` .. code-block:: python - density = ti.var(ti.f32) + density = ti.field(ti.f32) ti.root.dense(ti.ij, (128, 128)).dense(ti.ij, (8, 8)).place(density) diff --git a/docs/matrix.rst b/docs/matrix.rst index 01618f20d6e64..01c7df1e524ac 100644 --- a/docs/matrix.rst +++ b/docs/matrix.rst @@ -42,7 +42,7 @@ As global tensors of matrices .. note:: - In Python-scope, ``ti.var`` declares :ref:`scalar_tensor`, while ``ti.Matrix`` declares tensors of matrices. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Matrix`` declares tensors of matrices. As a temporary local variable diff --git a/docs/odop.rst b/docs/odop.rst index ea6d08df24679..996ed978c3774 100644 --- a/docs/odop.rst +++ b/docs/odop.rst @@ -22,8 +22,8 @@ A brief example: def __init__(self, n, m, increment): self.n = n self.m = m - self.val = ti.var(ti.f32) - self.total = ti.var(ti.f32) + self.val = ti.field(ti.f32) + self.total = ti.field(ti.f32) self.increment = increment ti.root.dense(ti.ij, (self.n, self.m)).place(self.val) ti.root.place(self.total) @@ -50,7 +50,7 @@ A brief example: arr = Array2D(128, 128, 3) - double_total = ti.var(ti.f32, shape=()) + double_total = ti.field(ti.f32, shape=()) ti.root.lazy_grad() diff --git a/docs/offset.rst b/docs/offset.rst index 6a7911c56537c..c2b32feb54bf8 100644 --- a/docs/offset.rst +++ b/docs/offset.rst @@ -27,6 +27,6 @@ In this way, the tensor's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusi b = ti.Vector(3, dt=ti.f32, shape=(16, 32, 64), offset=(7, 3, -4)) # Works! c = ti.Matrix(2, 1, dt=ti.f32, shape=None, offset=(32,)) # AssertionError d = ti.Matrix(3, 2, dt=ti.f32, shape=(32, 32), offset=(-16, )) # AssertionError - e = ti.var(dt=ti.i32, shape=16, offset=-16) # Works! - f = ti.var(dt=ti.i32, shape=None, offset=-16) # AssertionError - g = ti.var(dt=ti.i32, shape=(16, 32), offset=-16) # AssertionError + e = ti.field(dt=ti.i32, shape=16, offset=-16) # Works! + f = ti.field(dt=ti.i32, shape=None, offset=-16) # AssertionError + g = ti.field(dt=ti.i32, shape=(16, 32), offset=-16) # AssertionError diff --git a/docs/profiler.rst b/docs/profiler.rst index f0295de1500b1..a604a4e756f25 100644 --- a/docs/profiler.rst +++ b/docs/profiler.rst @@ -16,7 +16,7 @@ ScopedProfiler import taichi as ti ti.init(arch=ti.cpu) - var = ti.var(ti.f32, shape=1) + var = ti.field(ti.f32, shape=1) @ti.kernel @@ -48,7 +48,7 @@ KernelProfiler import taichi as ti ti.init(ti.cpu, kernel_profiler=True) - var = ti.var(ti.f32, shape=1) + var = ti.field(ti.f32, shape=1) @ti.kernel diff --git a/docs/scalar_tensor.rst b/docs/scalar_tensor.rst index db27b56e62939..70bcd284e1220 100644 --- a/docs/scalar_tensor.rst +++ b/docs/scalar_tensor.rst @@ -7,7 +7,7 @@ Tensors of scalars Declaration ----------- -.. function:: ti.var(dt, shape = None, offset = None) +.. function:: ti.field(dt, shape = None, offset = None) :parameter dt: (DataType) type of the tensor element :parameter shape: (optional, scalar or tuple) the shape of tensor @@ -16,17 +16,17 @@ Declaration For example, this creates a *dense* tensor with four ``int32`` as elements: :: - x = ti.var(ti.i32, shape=4) + x = ti.field(ti.i32, shape=4) This creates a 4x3 *dense* tensor with ``float32`` elements: :: - x = ti.var(ti.f32, shape=(4, 3)) + x = ti.field(ti.f32, shape=(4, 3)) If shape is ``()`` (empty tuple), then a 0-D tensor (scalar) is created: :: - x = ti.var(ti.f32, shape=()) + x = ti.field(ti.f32, shape=()) Then access it by passing ``None`` as index: :: @@ -36,9 +36,9 @@ Declaration If shape is **not provided** or ``None``, the user must manually ``place`` it afterwards: :: - x = ti.var(ti.f32) + x = ti.field(ti.f32) ti.root.dense(ti.ij, (4, 3)).place(x) - # equivalent to: x = ti.var(ti.f32, shape=(4, 3)) + # equivalent to: x = ti.field(ti.f32, shape=(4, 3)) .. note:: @@ -51,25 +51,25 @@ Declaration .. code-block:: python - x = ti.var(ti.f32) + x = ti.field(ti.f32) x[None] = 1 # ERROR: x not placed! .. code-block:: python - x = ti.var(ti.f32, shape=()) + x = ti.field(ti.f32, shape=()) @ti.kernel def func(): x[None] = 1 func() - y = ti.var(ti.f32, shape=()) + y = ti.field(ti.f32, shape=()) # ERROR: cannot create tensor after kernel invocation! .. code-block:: python - x = ti.var(ti.f32, shape=()) + x = ti.field(ti.f32, shape=()) x[None] = 1 - y = ti.var(ti.f32, shape=()) + y = ti.field(ti.f32, shape=()) # ERROR: cannot create tensor after any tensor accesses from the Python-scope! @@ -114,13 +114,13 @@ Meta data :: - x = ti.var(ti.i32, (6, 5)) + x = ti.field(ti.i32, (6, 5)) x.dim() # 2 - y = ti.var(ti.i32, 6) + y = ti.field(ti.i32, 6) y.dim() # 1 - z = ti.var(ti.i32, ()) + z = ti.field(ti.i32, ()) z.dim() # 0 @@ -131,13 +131,13 @@ Meta data :: - x = ti.var(ti.i32, (6, 5)) + x = ti.field(ti.i32, (6, 5)) x.shape() # (6, 5) - y = ti.var(ti.i32, 6) + y = ti.field(ti.i32, 6) y.shape() # (6,) - z = ti.var(ti.i32, ()) + z = ti.field(ti.i32, ()) z.shape() # () @@ -148,7 +148,7 @@ Meta data :: - x = ti.var(ti.i32, (2, 3)) + x = ti.field(ti.i32, (2, 3)) x.data_type() # ti.i32 @@ -160,8 +160,8 @@ Meta data :: - x = ti.var(ti.i32) - y = ti.var(ti.i32) + x = ti.field(ti.i32) + y = ti.field(ti.i32) blk1 = ti.root.dense(ti.ij, (6, 5)) blk2 = blk1.dense(ti.ij, (3, 2)) blk1.place(x) diff --git a/docs/snode.rst b/docs/snode.rst index f1ac731e15604..6ac5f5ed2ad46 100644 --- a/docs/snode.rst +++ b/docs/snode.rst @@ -27,8 +27,8 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str :: - x = ti.var(dt=ti.i32) - y = ti.var(dt=ti.f32) + x = ti.field(dt=ti.i32) + y = ti.field(dt=ti.f32) ti.root.place(x, y) assert x.snode() == y.snode() @@ -68,8 +68,8 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str :: - x = ti.var(dt=ti.i32) - y = ti.var(dt=ti.f32) + x = ti.field(dt=ti.i32) + y = ti.field(dt=ti.f32) ti.root.place(x, y) x.snode() @@ -135,14 +135,14 @@ Node types :: - x = ti.var(dt=ti.i32) + x = ti.field(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) + x = ti.field(dt=ti.i32) ti.root.dense(ti.ij, (3, 4)).place(x) .. note:: diff --git a/docs/vector.rst b/docs/vector.rst index 0c58a107fdf09..665b18144bb92 100644 --- a/docs/vector.rst +++ b/docs/vector.rst @@ -31,7 +31,7 @@ As global tensors of vectors .. note:: - In Python-scope, ``ti.var`` declares :ref:`scalar_tensor`, while ``ti.Vector`` declares tensors of vectors. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Vector`` declares tensors of vectors. As a temporary local variable From 0d5238eab2d0e134ed0ada553e3bd20a4c2d15a2 Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Tue, 21 Jul 2020 00:11:08 +0800 Subject: [PATCH 02/10] [Doc] Update all global tensor ti.Vector to ti.Vector.field (#1539) * uptate * update * update * update --- docs/export_results.rst | 6 +++--- docs/external.rst | 2 +- docs/gui.rst | 4 ++-- docs/layout.rst | 8 ++++---- docs/matrix.rst | 2 +- docs/offset.rst | 2 +- docs/vector.rst | 8 ++++---- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/export_results.rst b/docs/export_results.rst index 6e60cc59fe6b1..fa5713ed74134 100644 --- a/docs/export_results.rst +++ b/docs/export_results.rst @@ -69,7 +69,7 @@ To save images without invoking ``ti.GUI.show(filename)``, use ``ti.imwrite(file ti.imwrite(pixels.to_numpy(), filename) print(f'The image has been saved to {filename}') -- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix``, ``ti.Vector``, ``ti.field``) and numpy tensors ``np.ndarray``. +- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix``, ``ti.Vector.field``, ``ti.field``) and numpy tensors ``np.ndarray``. - Same as above ``ti.GUI.show(filename)``, the image format (``png``, ``jpg`` and ``bmp``) is also controlled by the suffix of ``filename`` in ``ti.imwrite(filename)``. - Meanwhile, the resulted image type (grayscale, RGB, or RGBA) is determined by **the number of channels in the input tensor**, i.e., the length of the third dimension (``tensor.shape[2]``). - In other words, a tensor that has shape ``(w, h)`` or ``(w, h, 1)`` will be exported as a grayscale image. @@ -190,8 +190,8 @@ Export PLY files ti.init(arch=ti.cpu) num_vertices = 1000 - pos = ti.Vector(3, dt=ti.f32, shape=(10, 10, 10)) - rgba = ti.Vector(4, dt=ti.f32, shape=(10, 10, 10)) + pos = ti.Vector.field(3, dtype=ti.f32, shape=(10, 10, 10)) + rgba = ti.Vector.field(4, dtype=ti.f32, shape=(10, 10, 10)) @ti.kernel diff --git a/docs/external.rst b/docs/external.rst index 988619e725681..18e2975a04b6f 100644 --- a/docs/external.rst +++ b/docs/external.rst @@ -22,7 +22,7 @@ Use ``to_numpy``/``from_numpy``/``to_torch``/``from_torch``: # Taichi tensors val = ti.field(ti.i32, shape=(n, m)) - vec = ti.Vector(3, dt=ti.i32, shape=(n, m)) + vec = ti.Vector.field(3, dtype=ti.i32, shape=(n, m)) mat = ti.Matrix(3, 4, dt=ti.i32, shape=(n, m)) # Scalar diff --git a/docs/gui.rst b/docs/gui.rst index d6981d61a0579..205e464796906 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -67,7 +67,7 @@ Paint on a window * ``ti.field(shape=(x, y, 3))``, where `3` is for ``(r, g, b)`` channels - * ``ti.Vector(3, shape=(x, y))`` (see :ref:`vector`) + * ``ti.Vector.field(3, shape=(x, y))`` (see :ref:`vector`) * ``np.ndarray(shape=(x, y))`` @@ -387,7 +387,7 @@ Image I/O :parameter img: (Matrix or Expr) the image you want to export :parameter filename: (string) the location you want to save to - Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix``, ``ti.Vector``, or ``ti.field``) to a specified location ``filename``. + Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix``, ``ti.Vector.field``, or ``ti.field``) to a specified location ``filename``. Same as ``ti.GUI.show(filename)``, the format of the exported image is determined by **the suffix of** ``filename`` as well. Now ``ti.imwrite`` supports exporting images to ``png``, ``img`` and ``jpg`` and we recommend using ``png``. diff --git a/docs/layout.rst b/docs/layout.rst index 2a6e30d294d78..f77e921212c83 100644 --- a/docs/layout.rst +++ b/docs/layout.rst @@ -227,8 +227,8 @@ Examples .. code-block:: python - pos = ti.Vector(3, dt=ti.f32) - vel = ti.Vector(3, dt=ti.f32) + pos = ti.Vector.field(3, dtype=ti.f32) + vel = ti.Vector.field(3, dtype=ti.f32) ti.root.dense(ti.i, 1024).place(pos, vel) # equivalent to ti.root.dense(ti.i, 1024).place(pos(0), pos(1), pos(2), vel(0), vel(1), vel(2)) @@ -237,8 +237,8 @@ Examples .. code-block:: python - pos = ti.Vector(3, dt=ti.f32) - vel = ti.Vector(3, dt=ti.f32) + pos = ti.Vector.field(3, dtype=ti.f32) + vel = ti.Vector.field(3, dtype=ti.f32) for i in range(3): ti.root.dense(ti.i, 1024).place(pos(i)) for i in range(3): diff --git a/docs/matrix.rst b/docs/matrix.rst index 01c7df1e524ac..0bad2057d5db0 100644 --- a/docs/matrix.rst +++ b/docs/matrix.rst @@ -6,7 +6,7 @@ Matrices - ``ti.Matrix`` is for small matrices (e.g. `3x3`) only. If you have `64x64` matrices, you should consider using a 2D tensor of scalars. - ``ti.Vector`` is the same as ``ti.Matrix``, except that it has only one column. - Differentiate element-wise product ``*`` and matrix product ``@``. -- ``ti.Vector(n, dt=ti.f32)`` or ``ti.Matrix(n, m, dt=ti.f32)`` to create tensors of vectors/matrices. +- ``ti.Vector.field(n, dtype=ti.f32)`` or ``ti.Matrix(n, m, dt=ti.f32)`` to create tensors of vectors/matrices. - ``A.transpose()`` - ``R, S = ti.polar_decompose(A, ti.f32)`` - ``U, sigma, V = ti.svd(A, ti.f32)`` (Note that ``sigma`` is a ``3x3`` diagonal matrix) diff --git a/docs/offset.rst b/docs/offset.rst index c2b32feb54bf8..d5e9f7d78f5d4 100644 --- a/docs/offset.rst +++ b/docs/offset.rst @@ -24,7 +24,7 @@ In this way, the tensor's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusi .. code-block:: python a = ti.Matrix(2, 3, dt=ti.f32, shape=(32,), offset=(-16, )) # Works! - b = ti.Vector(3, dt=ti.f32, shape=(16, 32, 64), offset=(7, 3, -4)) # Works! + b = ti.Vector.field(3, dtype=ti.f32, shape=(16, 32, 64), offset=(7, 3, -4)) # Works! c = ti.Matrix(2, 1, dt=ti.f32, shape=None, offset=(32,)) # AssertionError d = ti.Matrix(3, 2, dt=ti.f32, shape=(32, 32), offset=(-16, )) # AssertionError e = ti.field(dt=ti.i32, shape=16, offset=-16) # Works! diff --git a/docs/vector.rst b/docs/vector.rst index 06cd7cb12d34e..578581599ac9f 100644 --- a/docs/vector.rst +++ b/docs/vector.rst @@ -16,7 +16,7 @@ Declaration As global tensors of vectors ++++++++++++++++++++++++++++ -.. function:: ti.Vector.var(n, dt, shape = None, offset = None) +.. function:: ti.Vector.field(n, dt, shape = None, offset = None) :parameter n: (scalar) the number of components in the vector :parameter dt: (DataType) data type of the components @@ -27,11 +27,11 @@ As global tensors of vectors :: # Python-scope - a = ti.Vector.var(3, dt=ti.f32, shape=(5, 4)) + a = ti.Vector.field(3, dtype=ti.f32, shape=(5, 4)) .. note:: - In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Vector`` declares tensors of vectors. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Vector.field`` declares tensors of vectors. As a temporary local variable @@ -236,7 +236,7 @@ Metadata :: # Python-scope - a = ti.Vector.var(3, dt=ti.f32, shape=()) + a = ti.Vector.field(3, dtype=ti.f32, shape=()) a.n # 3 TODO: add element wise operations docs From 81b5aaa337f6f09cff94d472d9c54b0c5a084849 Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Wed, 22 Jul 2020 02:12:13 +0800 Subject: [PATCH 03/10] [Doc] Replace ti.Matrix to ti.Matrix.field in the documents (#1552) * replace ti.Matrix * update --- docs/export_results.rst | 2 +- docs/external.rst | 2 +- docs/gui.rst | 4 ++-- docs/matrix.rst | 8 ++++---- docs/offset.rst | 6 +++--- docs/tensor_matrix.rst | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/export_results.rst b/docs/export_results.rst index fa5713ed74134..48f5d6a1c7bc3 100644 --- a/docs/export_results.rst +++ b/docs/export_results.rst @@ -69,7 +69,7 @@ To save images without invoking ``ti.GUI.show(filename)``, use ``ti.imwrite(file ti.imwrite(pixels.to_numpy(), filename) print(f'The image has been saved to {filename}') -- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix``, ``ti.Vector.field``, ``ti.field``) and numpy tensors ``np.ndarray``. +- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix.field``, ``ti.Vector.field``, ``ti.field``) and numpy tensors ``np.ndarray``. - Same as above ``ti.GUI.show(filename)``, the image format (``png``, ``jpg`` and ``bmp``) is also controlled by the suffix of ``filename`` in ``ti.imwrite(filename)``. - Meanwhile, the resulted image type (grayscale, RGB, or RGBA) is determined by **the number of channels in the input tensor**, i.e., the length of the third dimension (``tensor.shape[2]``). - In other words, a tensor that has shape ``(w, h)`` or ``(w, h, 1)`` will be exported as a grayscale image. diff --git a/docs/external.rst b/docs/external.rst index 18e2975a04b6f..5f0e0bc2bb642 100644 --- a/docs/external.rst +++ b/docs/external.rst @@ -23,7 +23,7 @@ Use ``to_numpy``/``from_numpy``/``to_torch``/``from_torch``: # Taichi tensors val = ti.field(ti.i32, shape=(n, m)) vec = ti.Vector.field(3, dtype=ti.i32, shape=(n, m)) - mat = ti.Matrix(3, 4, dt=ti.i32, shape=(n, m)) + mat = ti.Matrix.field(3, 4, dtype=ti.i32, shape=(n, m)) # Scalar arr = np.ones(shape=(n, m), dtype=np.int32) diff --git a/docs/gui.rst b/docs/gui.rst index 205e464796906..be4922ebe9010 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -387,7 +387,7 @@ Image I/O :parameter img: (Matrix or Expr) the image you want to export :parameter filename: (string) the location you want to save to - Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix``, ``ti.Vector.field``, or ``ti.field``) to a specified location ``filename``. + Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix.field``, ``ti.Vector.field``, or ``ti.field``) to a specified location ``filename``. Same as ``ti.GUI.show(filename)``, the format of the exported image is determined by **the suffix of** ``filename`` as well. Now ``ti.imwrite`` supports exporting images to ``png``, ``img`` and ``jpg`` and we recommend using ``png``. @@ -431,7 +431,7 @@ Image I/O shape = (512, 512) channels = 3 type = ti.f32 - pixels = ti.Matrix(channels, dt=type, shape=shape) + pixels = ti.Matrix.field(channels, dtype=type, shape=shape) @ti.kernel def draw(): diff --git a/docs/matrix.rst b/docs/matrix.rst index 0bad2057d5db0..d3d1781e3ceda 100644 --- a/docs/matrix.rst +++ b/docs/matrix.rst @@ -6,7 +6,7 @@ Matrices - ``ti.Matrix`` is for small matrices (e.g. `3x3`) only. If you have `64x64` matrices, you should consider using a 2D tensor of scalars. - ``ti.Vector`` is the same as ``ti.Matrix``, except that it has only one column. - Differentiate element-wise product ``*`` and matrix product ``@``. -- ``ti.Vector.field(n, dtype=ti.f32)`` or ``ti.Matrix(n, m, dt=ti.f32)`` to create tensors of vectors/matrices. +- ``ti.Vector.field(n, dtype=ti.f32)`` or ``ti.Matrix.field(n, m, dtype=ti.f32)`` to create tensors of vectors/matrices. - ``A.transpose()`` - ``R, S = ti.polar_decompose(A, ti.f32)`` - ``U, sigma, V = ti.svd(A, ti.f32)`` (Note that ``sigma`` is a ``3x3`` diagonal matrix) @@ -26,7 +26,7 @@ Declaration As global tensors of matrices +++++++++++++++++++++++++++++ -.. function:: ti.Matrix.var(n, m, dt, shape = None, offset = None) +.. function:: ti.Matrix.field(n, m, dtype, shape = None, offset = None) :parameter n: (scalar) the number of rows in the matrix :parameter m: (scalar) the number of columns in the matrix @@ -38,11 +38,11 @@ As global tensors of matrices :: # Python-scope - a = ti.Matrix.var(3, 3, dt=ti.f32, shape=(5, 4)) + a = ti.Matrix.field(3, 3, dtype=ti.f32, shape=(5, 4)) .. note:: - In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Matrix`` declares tensors of matrices. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Matrix.field`` declares tensors of matrices. As a temporary local variable diff --git a/docs/offset.rst b/docs/offset.rst index d5e9f7d78f5d4..8c011ee9807d5 100644 --- a/docs/offset.rst +++ b/docs/offset.rst @@ -23,10 +23,10 @@ In this way, the tensor's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusi .. code-block:: python - a = ti.Matrix(2, 3, dt=ti.f32, shape=(32,), offset=(-16, )) # Works! + a = ti.Matrix.field(2, 3, dtype=ti.f32, shape=(32,), offset=(-16, )) # Works! b = ti.Vector.field(3, dtype=ti.f32, shape=(16, 32, 64), offset=(7, 3, -4)) # Works! - c = ti.Matrix(2, 1, dt=ti.f32, shape=None, offset=(32,)) # AssertionError - d = ti.Matrix(3, 2, dt=ti.f32, shape=(32, 32), offset=(-16, )) # AssertionError + c = ti.Matrix.field(2, 1, dtype=ti.f32, shape=None, offset=(32,)) # AssertionError + d = ti.Matrix.field(3, 2, dtype=ti.f32, shape=(32, 32), offset=(-16, )) # AssertionError e = ti.field(dt=ti.i32, shape=16, offset=-16) # Works! f = ti.field(dt=ti.i32, shape=None, offset=-16) # AssertionError g = ti.field(dt=ti.i32, shape=(16, 32), offset=-16) # AssertionError diff --git a/docs/tensor_matrix.rst b/docs/tensor_matrix.rst index 12c450218877b..c1b1f814937fa 100644 --- a/docs/tensor_matrix.rst +++ b/docs/tensor_matrix.rst @@ -31,7 +31,7 @@ Tensors of matrices ------------------- Tensor elements can also be matrices. -Suppose you have a ``128 x 64`` tensor called ``A``, each element containing a ``3 x 2`` matrix. To allocate a ``128 x 64`` tensor of ``3 x 2`` matrix, use the statement ``A = ti.Matrix(3, 2, dt=ti.f32, shape=(128, 64))``. +Suppose you have a ``128 x 64`` tensor called ``A``, each element containing a ``3 x 2`` matrix. To allocate a ``128 x 64`` tensor of ``3 x 2`` matrix, use the statement ``A = ti.Matrix.field(3, 2, dtype=ti.f32, shape=(128, 64))``. * If you want to get the matrix of grid node ``i, j``, please use ``mat = A[i, j]``. ``mat`` is simply a ``3 x 2`` matrix * To get the element on the first row and second column of that matrix, use ``mat[0, 1]`` or ``A[i, j][0, 1]``. @@ -50,5 +50,5 @@ For example, ``2x1``, ``3x3``, ``4x4`` matrices are fine, yet ``32x6`` is probab Due to the unrolling mechanisms, operating on large matrices (e.g. ``32x128``) can lead to very long compilation time and low performance. If you have a dimension that is too large (e.g. ``64``), it's better to declare a tensor of size ``64``. -E.g., instead of declaring ``ti.Matrix(64, 32, dt=ti.f32, shape=(3, 2))``, declare ``ti.Matrix(3, 2, dt=ti.f32, shape=(64, 32))``. +E.g., instead of declaring ``ti.Matrix.field(64, 32, dtype=ti.f32, shape=(3, 2))``, declare ``ti.Matrix.field(3, 2, dtype=ti.f32, shape=(64, 32))``. Try to put large dimensions to tensors instead of matrices. From 84e46f09daf8c2afce66f40f09f85088abb99dce Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Thu, 23 Jul 2020 00:06:27 +0800 Subject: [PATCH 04/10] [Doc] Update new allocation APIs' definitions in the documents (#1564) * update API * update --- docs/matrix.rst | 2 +- docs/meta.rst | 8 ++++---- docs/scalar_tensor.rst | 4 ++-- docs/vector.rst | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/matrix.rst b/docs/matrix.rst index d3d1781e3ceda..f225df8e06f08 100644 --- a/docs/matrix.rst +++ b/docs/matrix.rst @@ -30,7 +30,7 @@ As global tensors of matrices :parameter n: (scalar) the number of rows in the matrix :parameter m: (scalar) the number of columns in the matrix - :parameter dt: (DataType) data type of the components + :parameter dtype: (DataType) data type of the components :parameter shape: (optional, scalar or tuple) shape the tensor of vectors, see :ref:`tensor` :parameter offset: (optional, scalar or tuple) see :ref:`offset` diff --git a/docs/meta.rst b/docs/meta.rst index 28f891ab9f376..91a865f863fc0 100644 --- a/docs/meta.rst +++ b/docs/meta.rst @@ -27,10 +27,10 @@ as a type hint to pass a tensor as an argument. For example: for i in x: y[i] = x[i] - a = ti.var(ti.f32, 4) - b = ti.var(ti.f32, 4) - c = ti.var(ti.f32, 12) - d = ti.var(ti.f32, 12) + a = ti.field(ti.f32, 4) + b = ti.field(ti.f32, 4) + c = ti.field(ti.f32, 12) + d = ti.field(ti.f32, 12) copy(a, b) copy(c, d) diff --git a/docs/scalar_tensor.rst b/docs/scalar_tensor.rst index 1a293f477664d..10746b63f0e44 100644 --- a/docs/scalar_tensor.rst +++ b/docs/scalar_tensor.rst @@ -7,9 +7,9 @@ Tensors of scalars Declaration ----------- -.. function:: ti.field(dt, shape = None, offset = None) +.. function:: ti.field(dtype, shape = None, offset = None) - :parameter dt: (DataType) type of the tensor element + :parameter dtype: (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` diff --git a/docs/vector.rst b/docs/vector.rst index 578581599ac9f..1f00d208fa8f8 100644 --- a/docs/vector.rst +++ b/docs/vector.rst @@ -16,10 +16,10 @@ Declaration As global tensors of vectors ++++++++++++++++++++++++++++ -.. function:: ti.Vector.field(n, dt, shape = None, offset = None) +.. function:: ti.Vector.field(n, dtype, shape = None, offset = None) :parameter n: (scalar) the number of components in the vector - :parameter dt: (DataType) data type of the components + :parameter dtype: (DataType) data type of the components :parameter shape: (optional, scalar or tuple) shape the tensor of vectors, see :ref:`tensor` :parameter offset: (optional, scalar or tuple) see :ref:`offset` From 505cfcf3af3829ede31908645befa8945545eb68 Mon Sep 17 00:00:00 2001 From: Xudong Feng Date: Thu, 23 Jul 2020 21:32:01 +0800 Subject: [PATCH 05/10] [Doc] Replace tensor -> field for docs starting with [a-g] (#1563) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update * Apply suggestions from code review Co-authored-by: 彭于斌 <1931127624@qq.com> Co-authored-by: 彭于斌 <1931127624@qq.com> --- docs/compilation.rst | 8 ++++---- docs/debugging.rst | 2 +- docs/differentiable_programming.rst | 6 +++--- docs/export_results.rst | 10 +++++----- docs/external.rst | 6 +++--- docs/faq.rst | 10 +++++----- docs/global_settings.rst | 2 +- docs/gui.rst | 16 ++++++++-------- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/compilation.rst b/docs/compilation.rst index fe90bbe9e2bf4..89ac222ebca8b 100644 --- a/docs/compilation.rst +++ b/docs/compilation.rst @@ -21,12 +21,12 @@ Let's consider the following simple kernel: .. code-block:: python @ti.kernel - def add(tensor: ti.template(), delta: ti.i32): - for i in tensor: - tensor[i] += delta + def add(field: ti.template(), delta: ti.i32): + for i in field: + field[i] += delta -We allocate two 1D tensors to simplify discussion: +We allocate two 1D fields to simplify discussion: .. code-block:: python diff --git a/docs/debugging.rst b/docs/debugging.rst index e17686bfa4dc9..efde999c2f3a4 100644 --- a/docs/debugging.rst +++ b/docs/debugging.rst @@ -169,7 +169,7 @@ For example: @ti.func def copy(dst: ti.template(), src: ti.template()): - ti.static_assert(dst.shape == src.shape, "copy() needs src and dst tensors to be same shape") + ti.static_assert(dst.shape == src.shape, "copy() needs src and dst fields to be same shape") for I in ti.grouped(src): dst[I] = src[I] return x % 2 == 1 diff --git a/docs/differentiable_programming.rst b/docs/differentiable_programming.rst index 7bb37146a2652..81c29a90969c0 100644 --- a/docs/differentiable_programming.rst +++ b/docs/differentiable_programming.rst @@ -9,15 +9,15 @@ The `DiffTaichi repo `_ contains 10 d .. note:: Unlike tools such as TensorFlow where **immutable** output buffers are generated, - the **imperative** programming paradigm adopted in Taichi allows programmers to freely modify global tensors. + the **imperative** programming paradigm adopted in Taichi allows programmers to freely modify global fields. To make automatic differentiation well-defined under this setting, we make the following assumption on Taichi programs for differentiable programming: **Global Data Access Rules:** - - If a global tensor element is written more than once, then starting from the second write, the + - If a global field element is written more than once, then starting from the second write, the write **must** come in the form of an atomic add (“accumulation", using ``ti.atomic_add`` or simply ``+=``). - - No read accesses happen to a global tensor element, until its accumulation is done. + - No read accesses happen to a global field element, until its accumulation is done. **Kernel Simplicity Rule:** Kernel body consists of multiple `simply nested` for-loops. I.e., each for-loop can either contain exactly one (nested) for-loop (and no other statements), or a group of statements without loops. diff --git a/docs/export_results.rst b/docs/export_results.rst index 48f5d6a1c7bc3..7952daeb1ecd0 100644 --- a/docs/export_results.rst +++ b/docs/export_results.rst @@ -69,15 +69,15 @@ To save images without invoking ``ti.GUI.show(filename)``, use ``ti.imwrite(file ti.imwrite(pixels.to_numpy(), filename) print(f'The image has been saved to {filename}') -- ``ti.imwrite`` can export Taichi tensors (``ti.Matrix.field``, ``ti.Vector.field``, ``ti.field``) and numpy tensors ``np.ndarray``. +- ``ti.imwrite`` can export Taichi fields (``ti.Matrix.field``, ``ti.Vector.field``, ``ti.field``) and numpy tensors ``np.ndarray``. - Same as above ``ti.GUI.show(filename)``, the image format (``png``, ``jpg`` and ``bmp``) is also controlled by the suffix of ``filename`` in ``ti.imwrite(filename)``. -- Meanwhile, the resulted image type (grayscale, RGB, or RGBA) is determined by **the number of channels in the input tensor**, i.e., the length of the third dimension (``tensor.shape[2]``). -- In other words, a tensor that has shape ``(w, h)`` or ``(w, h, 1)`` will be exported as a grayscale image. -- If you want to export ``RGB`` or ``RGBA`` images instead, the input tensor should have a shape ``(w, h, 3)`` or ``(w, h, 4)`` respectively. +- Meanwhile, the resulted image type (grayscale, RGB, or RGBA) is determined by **the number of channels in the input field**, i.e., the length of the third dimension (``field.shape[2]``). +- In other words, a field that has shape ``(w, h)`` or ``(w, h, 1)`` will be exported as a grayscale image. +- If you want to export ``RGB`` or ``RGBA`` images instead, the input field should have a shape ``(w, h, 3)`` or ``(w, h, 4)`` respectively. .. note:: - All Taichi tensors have their own data types, such as ``ti.u8`` and ``ti.f32``. Different data types can lead to different behaviors of ``ti.imwrite``. Please check out :ref:`gui` for more details. + All Taichi fields have their own data types, such as ``ti.u8`` and ``ti.f32``. Different data types can lead to different behaviors of ``ti.imwrite``. Please check out :ref:`gui` for more details. - Taichi offers other helper functions that read and show images in addition to ``ti.imwrite``. They are also demonstrated in :ref:`gui`. diff --git a/docs/external.rst b/docs/external.rst index 5f0e0bc2bb642..fed86db6be360 100644 --- a/docs/external.rst +++ b/docs/external.rst @@ -5,8 +5,8 @@ Interacting with external arrays **External arrays** refer to ``numpy.ndarray`` or ``torch.Tensor``. -Conversion between Taichi tensors and external arrays ------------------------------------------------------ +Conversion between Taichi fields and external arrays +---------------------------------------------------- Use ``to_numpy``/``from_numpy``/``to_torch``/``from_torch``: @@ -20,7 +20,7 @@ Use ``to_numpy``/``from_numpy``/``to_torch``/``from_torch``: n = 4 m = 7 - # Taichi tensors + # Taichi fields val = ti.field(ti.i32, shape=(n, m)) vec = ti.Vector.field(3, dtype=ti.i32, shape=(n, m)) mat = ti.Matrix.field(3, 4, dtype=ti.i32, shape=(n, m)) diff --git a/docs/faq.rst b/docs/faq.rst index 7cb43f2201192..40c6f31f7e2d8 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -20,9 +20,9 @@ Frequently asked questions for i in range(100): # This loop will not be parallelized ... -**Q:** What's the most convinent way to load images / textures into Taichi tensors? +**Q:** What's the most convinent way to load images / textures into Taichi fields? -**A:** Simply use ``tensor.from_numpy(ti.imread('filename.png'))``. +**A:** Simply use ``field.from_numpy(ti.imread('filename.png'))``. **Q:** Can Taichi co-operate with **other Python packages** like ``matplotlib``? @@ -41,10 +41,10 @@ Frequently asked questions **A:** You may export it with :ref:`export_ply_files` so that you could view it in Houdini or Blender. Or make use the extension library `Taichi THREE ` to render images and update to GUI in real-time. -**Q:** How do I declare a tensor with **dynamic length**? +**Q:** How do I declare a field with **dynamic length**? -**A:** What you want may be the ``dynamic`` SNode, a kind of sparse tensor, see :ref:`dynamic`. - Or simply allocate a dense tensor large enough, and another 0-D tensor ``tensor_len[None]`` for length record. +**A:** What you want may be the ``dynamic`` SNode, a kind of sparse field, see :ref:`dynamic`. + Or simply allocate a dense field large enough, and another 0-D field ``field_len[None]`` for length record. But in fact, the ``dynamic`` SNode could be slower than the latter solution, due to the cost of maintaining the sparsity information. **Q:** Can a user iterate over irregular topologies (e.g., graphs or tetrahedral meshes) instead of regular grids? diff --git a/docs/global_settings.rst b/docs/global_settings.rst index e028b980cb3a4..c8d2bf89820e5 100644 --- a/docs/global_settings.rst +++ b/docs/global_settings.rst @@ -22,7 +22,7 @@ Compilation Runtime ******* -- Restart the entire Taichi system (destroy all tensors and kernels): ``ti.reset()``. +- Restart the entire Taichi system (destroy all fields and kernels): ``ti.reset()``. - To start program in debug mode: ``ti.init(debug=True)`` or ``ti debug your_script.py``. - To disable importing torch on start up: ``export TI_ENABLE_TORCH=0``. diff --git a/docs/gui.rst b/docs/gui.rst index be4922ebe9010..22214a89e85c2 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -53,7 +53,7 @@ Paint on a window .. function:: gui.set_image(img) :parameter gui: (GUI) the window object - :parameter img: (np.array or Tensor) tensor containing the image, see notes below + :parameter img: (np.array or ti.field) field containing the image, see notes below Set an image to display on the window. @@ -387,11 +387,11 @@ Image I/O :parameter img: (Matrix or Expr) the image you want to export :parameter filename: (string) the location you want to save to - Export a ``np.ndarray`` or Taichi tensor (``ti.Matrix.field``, ``ti.Vector.field``, or ``ti.field``) to a specified location ``filename``. + Export a ``np.ndarray`` or Taichi field (``ti.Matrix.field``, ``ti.Vector.field``, or ``ti.field``) to a specified location ``filename``. Same as ``ti.GUI.show(filename)``, the format of the exported image is determined by **the suffix of** ``filename`` as well. Now ``ti.imwrite`` supports exporting images to ``png``, ``img`` and ``jpg`` and we recommend using ``png``. - Please make sure that the input image has **a valid shape**. If you want to export a grayscale image, the input shape of tensor should be ``(height, weight)`` or ``(height, weight, 1)``. For example: + Please make sure that the input image has **a valid shape**. If you want to export a grayscale image, the input shape of field should be ``(height, weight)`` or ``(height, weight, 1)``. For example: .. code-block:: python @@ -412,13 +412,13 @@ Image I/O ti.imwrite(pixels, f"export_u8.png") - Besides, for RGB or RGBA images, ``ti.imwrite`` needs to receive a tensor which has shape ``(height, width, 3)`` and ``(height, width, 4)`` individually. + Besides, for RGB or RGBA images, ``ti.imwrite`` needs to receive a field which has shape ``(height, width, 3)`` and ``(height, width, 4)`` individually. - Generally the value of the pixels on each channel of a ``png`` image is an integar in [0, 255]. For this reason, ``ti.imwrite`` will **cast tensors** which has different datatypes all **into integars between [0, 255]**. As a result, ``ti.imwrite`` has the following requirements for different datatypes of input tensors: + Generally the value of the pixels on each channel of a ``png`` image is an integar in [0, 255]. For this reason, ``ti.imwrite`` will **cast fields** which has different datatypes all **into integars between [0, 255]**. As a result, ``ti.imwrite`` has the following requirements for different datatypes of input fields: - - For float-type (``ti.f16``, ``ti.f32``, etc) input tensors, **the value of each pixel should be float between [0.0, 1.0]**. Otherwise ``ti.imwrite`` will first clip them into [0.0, 1.0]. Then they are multiplied by 256 and casted to integaters ranging from [0, 255]. + - For float-type (``ti.f16``, ``ti.f32``, etc) input fields, **the value of each pixel should be float between [0.0, 1.0]**. Otherwise ``ti.imwrite`` will first clip them into [0.0, 1.0]. Then they are multiplied by 256 and casted to integaters ranging from [0, 255]. - - For int-type (``ti.u8``, ``ti.u16``, etc) input tensors, **the value of each pixel can be any valid integer in its own bounds**. These integers in this tensor will be scaled to [0, 255] by being divided over the upper bound of its basic type accordingly. + - For int-type (``ti.u8``, ``ti.u16``, etc) input fields, **the value of each pixel can be any valid integer in its own bounds**. These integers in this field will be scaled to [0, 255] by being divided over the upper bound of its basic type accordingly. Here is another example: @@ -453,7 +453,7 @@ Image I/O This function loads an image from the target filename and returns it as a ``np.ndarray(dtype=np.uint8)``. - Each value in this returned tensor is an integer in [0, 255]. + Each value in this returned field is an integer in [0, 255]. .. function:: ti.imshow(img, windname) From 728fd3b26f5769a5c5a15b97cea2191b3289a91b Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Sat, 25 Jul 2020 21:06:00 +0800 Subject: [PATCH 06/10] [Doc] Replace tensor by field for files beginning with t to z (#1579) * update * update --- docs/tensor_matrix.rst | 44 +++++++++++++++++++++--------------------- docs/vector.rst | 30 ++++++++++++++-------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/docs/tensor_matrix.rst b/docs/tensor_matrix.rst index c1b1f814937fa..e7e2acf22be00 100644 --- a/docs/tensor_matrix.rst +++ b/docs/tensor_matrix.rst @@ -1,41 +1,41 @@ .. _tensor: -Tensors and matrices -==================== +Fields and matrices +=================== -Tensors are global variables provided by Taichi. Tensors can be either sparse or dense. -An element of a tensor can be either a scalar or a vector/matrix. +Fields are global variables provided by Taichi. Fields can be either sparse or dense. +An element of a field can be either a scalar or a vector/matrix. .. note:: - Although mathematically matrices are treated as 2D tensors, in Taichi, **tensor** and **matrix** are two completely different concepts. - Matrices can be used as tensor elements, so you can have tensors with each element being a matrix. + Although mathematically matrices are treated as 2D fields, in Taichi, **field** and **matrix** are two completely different concepts. + Matrices can be used as field elements, so you can have fields with each element being a matrix. -Tensors of scalars ------------------- -* Every global variable is an N-dimensional tensor. +Fields of scalars +----------------- +* Every global variable is an N-dimensional field. - - Global ``scalars`` are treated as 0-D tensors of scalars. + - Global ``scalars`` are treated as 0-D fields of scalars. -* Tensors are always accessed using indices +* Fields are always accessed using indices - - E.g. ``x[i, j, k]`` if ``x`` is a scalar 3D tensor. - - Even when accessing 0-D tensor ``x``, use ``x[None] = 0`` instead of ``x = 0``. Please **always** use indexing to access entries in tensors. + - E.g. ``x[i, j, k]`` if ``x`` is a scalar 3D field. + - Even when accessing 0-D field ``x``, use ``x[None] = 0`` instead of ``x = 0``. Please **always** use indexing to access entries in fields. -* Tensor values are initially zero. -* Sparse tensors are initially inactive. +* Field values are initially zero. +* Sparse fields are initially inactive. * See :ref:`scalar_tensor` for more details. -Tensors of matrices -------------------- -Tensor elements can also be matrices. +Fields of matrices +------------------ +Field elements can also be matrices. -Suppose you have a ``128 x 64`` tensor called ``A``, each element containing a ``3 x 2`` matrix. To allocate a ``128 x 64`` tensor of ``3 x 2`` matrix, use the statement ``A = ti.Matrix.field(3, 2, dtype=ti.f32, shape=(128, 64))``. +Suppose you have a ``128 x 64`` field called ``A``, each element containing a ``3 x 2`` matrix. To allocate a ``128 x 64`` field of ``3 x 2`` matrix, use the statement ``A = ti.Matrix.field(3, 2, dtype=ti.f32, shape=(128, 64))``. * If you want to get the matrix of grid node ``i, j``, please use ``mat = A[i, j]``. ``mat`` is simply a ``3 x 2`` matrix * To get the element on the first row and second column of that matrix, use ``mat[0, 1]`` or ``A[i, j][0, 1]``. -* As you may have noticed, there are **two** indexing operators ``[]`` when you load an matrix element from a global tensor of matrices: the first is for tensor indexing, the second for matrix indexing. +* As you may have noticed, there are **two** indexing operators ``[]`` when you load an matrix element from a global field of matrices: the first is for field indexing, the second for matrix indexing. * ``ti.Vector`` is simply an alias of ``ti.Matrix``. * See :ref:`matrix` for more on matrices. @@ -49,6 +49,6 @@ For example, ``2x1``, ``3x3``, ``4x4`` matrices are fine, yet ``32x6`` is probab Due to the unrolling mechanisms, operating on large matrices (e.g. ``32x128``) can lead to very long compilation time and low performance. -If you have a dimension that is too large (e.g. ``64``), it's better to declare a tensor of size ``64``. +If you have a dimension that is too large (e.g. ``64``), it's better to declare a field of size ``64``. E.g., instead of declaring ``ti.Matrix.field(64, 32, dtype=ti.f32, shape=(3, 2))``, declare ``ti.Matrix.field(3, 2, dtype=ti.f32, shape=(64, 32))``. -Try to put large dimensions to tensors instead of matrices. +Try to put large dimensions to fields instead of matrices. diff --git a/docs/vector.rst b/docs/vector.rst index 1f00d208fa8f8..401b38f3720f8 100644 --- a/docs/vector.rst +++ b/docs/vector.rst @@ -6,24 +6,24 @@ Vectors A vector in Taichi can have two forms: - as a temporary local variable. An ``n`` component vector consists of ``n`` scalar values. - - as an element of a global tensor. In this case, the tensor is an N-dimensional array of ``n`` component vectors. + - as an element of a global field. In this case, the field is an N-dimensional array of ``n`` component vectors. In fact, ``Vector`` is simply an alias of ``Matrix``, just with ``m = 1``. See :ref:`matrix` and :ref:`tensor` for more details. Declaration ----------- -As global tensors of vectors -++++++++++++++++++++++++++++ +As global fields of vectors ++++++++++++++++++++++++++++ .. function:: ti.Vector.field(n, dtype, shape = None, offset = None) :parameter n: (scalar) the number of components in the vector :parameter dtype: (DataType) data type of the components - :parameter shape: (optional, scalar or tuple) shape the tensor of vectors, see :ref:`tensor` + :parameter shape: (optional, scalar or tuple) shape the field of vectors, see :ref:`tensor` :parameter offset: (optional, scalar or tuple) see :ref:`offset` - For example, this creates a 5x4 tensor of 3 component vectors: + For example, this creates a 5x4 field of 3 component vectors: :: # Python-scope @@ -31,7 +31,7 @@ As global tensors of vectors .. note:: - In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Vector.field`` declares tensors of vectors. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Vector.field`` declares fields of vectors. As a temporary local variable @@ -52,13 +52,13 @@ As a temporary local variable Accessing components -------------------- -As global tensors of vectors -++++++++++++++++++++++++++++ +As global fields of vectors ++++++++++++++++++++++++++++ .. attribute:: a[p, q, ...][i] - :parameter a: (tensor of Vector) the vector - :parameter p: (scalar) index of the first tensor dimension - :parameter q: (scalar) index of the second tensor dimension + :parameter a: (field of Vector) the vector + :parameter p: (scalar) index of the first field dimension + :parameter q: (scalar) index of the second field dimension :parameter i: (scalar) index of the vector component This extracts the first component of vector ``a[6, 3]``: @@ -72,12 +72,12 @@ As global tensors of vectors .. note:: - **Always** use two pairs of square brackets to access scalar elements from tensors of vectors. + **Always** use two pairs of square brackets to access scalar elements from fields of vectors. - - The indices in the first pair of brackets locate the vector inside the tensor of vectors; + - The indices in the first pair of brackets locate the vector inside the field of vectors; - The indices in the second pair of brackets locate the scalar element inside the vector. - For 0-D tensors of vectors, indices in the first pair of brackets should be ``[None]``. + For 0-D fields of vectors, indices in the first pair of brackets should be ``[None]``. @@ -224,7 +224,7 @@ Metadata .. attribute:: a.n - :parameter a: (Vector or tensor of Vector) + :parameter a: (Vector or field of Vector) :return: (scalar) return the dimensionality of vector ``a`` E.g., From 635d36197721f70f226827d5685af17e29f3cf8e Mon Sep 17 00:00:00 2001 From: Xudong Feng Date: Mon, 27 Jul 2020 16:27:28 +0800 Subject: [PATCH 07/10] [Doc] Replace tensor by field for files beginning with o to s (#1578) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update * fix * Apply suggestions from code review Co-authored-by: 彭于斌 <1931127624@qq.com> * Apply suggestions from code review Co-authored-by: 彭于斌 <1931127624@qq.com> Co-authored-by: 彭于斌 <1931127624@qq.com> --- docs/offset.rst | 6 +++--- docs/scalar_tensor.rst | 42 +++++++++++++++++++++--------------------- docs/snode.rst | 34 +++++++++++++++++----------------- docs/syntax_sugars.rst | 12 ++++++------ 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/docs/offset.rst b/docs/offset.rst index 8c011ee9807d5..7ad6c65a4daef 100644 --- a/docs/offset.rst +++ b/docs/offset.rst @@ -3,14 +3,14 @@ Coordinate offsets ================== -- A Taichi tensor can be defined with **coordinate offsets**. The offsets will move tensor bounds so that tensor origins are no longer zero vectors. A typical use case is to support voxels with negative coordinates in physical simulations. +- A Taichi field can be defined with **coordinate offsets**. The offsets will move field bounds so that field origins are no longer zero vectors. A typical use case is to support voxels with negative coordinates in physical simulations. - For example, a matrix of ``32x64`` elements with coordinate offset ``(-16, 8)`` can be defined as the following: .. code-block:: python a = ti.Matrix(2, 2, dt=ti.f32, shape=(32, 64), offset=(-16, 8)) -In this way, the tensor's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusive). +In this way, the field's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusive). .. code-block:: python @@ -19,7 +19,7 @@ In this way, the tensor's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusi a[-16, 64] # upper left corner a[16, 64] # upper right corner -.. note:: The dimensionality of tensor shapes should **be consistent** with that of the offset. Otherwise, a ``AssertionError`` will be raised. +.. note:: The dimensionality of field shapes should **be consistent** with that of the offset. Otherwise, a ``AssertionError`` will be raised. .. code-block:: python diff --git a/docs/scalar_tensor.rst b/docs/scalar_tensor.rst index 10746b63f0e44..68ded2915031f 100644 --- a/docs/scalar_tensor.rst +++ b/docs/scalar_tensor.rst @@ -1,7 +1,7 @@ .. _scalar_tensor: -Tensors of scalars -================== +Fields of scalars +================= Declaration @@ -9,21 +9,21 @@ Declaration .. function:: ti.field(dtype, shape = None, offset = None) - :parameter dtype: (DataType) type of the tensor element - :parameter shape: (optional, scalar or tuple) the shape of tensor + :parameter dtype: (DataType) type of the field element + :parameter shape: (optional, scalar or tuple) the shape of field :parameter offset: (optional, scalar or tuple) see :ref:`offset` - For example, this creates a *dense* tensor with four ``int32`` as elements: + For example, this creates a *dense* field with four ``int32`` as elements: :: x = ti.field(ti.i32, shape=4) - This creates a 4x3 *dense* tensor with ``float32`` elements: + This creates a 4x3 *dense* field with ``float32`` elements: :: x = ti.field(ti.f32, shape=(4, 3)) - If shape is ``()`` (empty tuple), then a 0-D tensor (scalar) is created: + If shape is ``()`` (empty tuple), then a 0-D field (scalar) is created: :: x = ti.field(ti.f32, shape=()) @@ -42,7 +42,7 @@ Declaration .. note:: - Not providing ``shape`` allows you to *place* the tensor in a layout other than the default *dense*, see :ref:`layout` for more details. + Not providing ``shape`` allows you to *place* the field in a layout other than the default *dense*, see :ref:`layout` for more details. .. warning:: @@ -63,34 +63,34 @@ Declaration func() y = ti.field(ti.f32, shape=()) - # ERROR: cannot create tensor after kernel invocation! + # ERROR: cannot create fields after kernel invocation! .. code-block:: python x = ti.field(ti.f32, shape=()) x[None] = 1 y = ti.field(ti.f32, shape=()) - # ERROR: cannot create tensor after any tensor accesses from the Python-scope! + # ERROR: cannot create fields after any field accesses from the Python-scope! Accessing components -------------------- -You can access an element of the Taichi tensor by an index or indices. +You can access an element of the Taichi field 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 + :parameter a: (ti.field) the field of scalars + :parameter p: (scalar) index of the first field dimension + :parameter q: (scalar) index of the second field dimension :return: (scalar) the element at ``[p, q, ...]`` - This extracts the element value at index ``[3, 4]`` of tensor ``a``: + This extracts the element value at index ``[3, 4]`` of field ``a``: :: x = a[3, 4] - This sets the element value at index ``2`` of 1D tensor ``b`` to ``5``: + This sets the element value at index ``2`` of 1D field ``b`` to ``5``: :: b[2] = 5 @@ -101,7 +101,7 @@ You can access an element of the Taichi tensor by an index or indices. .. note :: - The returned value can also be ``Vector`` / ``Matrix`` if ``a`` is a tensor of vector / matrix, see :ref:`vector` for more details. + The returned value can also be ``Vector`` / ``Matrix`` if ``a`` is a field of vector / matrix, see :ref:`vector` for more details. Meta data @@ -110,8 +110,8 @@ Meta data .. attribute:: a.shape - :parameter a: (Tensor) the tensor - :return: (tuple) the shape of tensor ``a`` + :parameter a: (ti.field) the field + :return: (tuple) the shape of field ``a`` :: @@ -127,7 +127,7 @@ Meta data .. function:: a.dtype - :parameter a: (Tensor) the tensor + :parameter a: (ti.field) the field :return: (DataType) the data type of ``a`` :: @@ -138,7 +138,7 @@ Meta data .. function:: a.parent(n = 1) - :parameter a: (Tensor) the tensor + :parameter a: (ti.field) the field :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 diff --git a/docs/snode.rst b/docs/snode.rst index c63dadaec20f7..c6be97119a1bf 100644 --- a/docs/snode.rst +++ b/docs/snode.rst @@ -20,10 +20,10 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str .. function:: snode.place(x, ...) :parameter snode: (SNode) where to place - :parameter x: (tensor) tensor(s) to be placed + :parameter a: (ti.field) field(s) to be placed :return: (SNode) the ``snode`` itself - The following code places two 0-D tensors named ``x`` and ``y``: + The following code places two 0-D fields named ``x`` and ``y``: :: @@ -33,12 +33,12 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str assert x.snode() == y.snode() -.. function:: tensor.shape +.. function:: field.shape - :parameter tensor: (Tensor) - :return: (tuple of integers) the shape of tensor + :parameter a: (ti.field) + :return: (tuple of integers) the shape of field - Equivalent to ``tensor.snode().shape``. + Equivalent to ``field.snode().shape``. For example, @@ -48,10 +48,10 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str x.shape # returns (3, 5, 4) -.. function:: tensor.snode() +.. function:: field.snode() - :parameter tensor: (Tensor) - :return: (SNode) the structual node where ``tensor`` is placed + :parameter a: (ti.field) + :return: (SNode) the structual node where ``field`` is placed :: @@ -106,17 +106,17 @@ Node types :parameter snode: (SNode) parent node where the child is derived from :parameter indices: (Index or Indices) indices used for this node - :parameter shape: (scalar or tuple) shape the tensor of vectors + :parameter shape: (scalar or tuple) shape the field of vectors :return: (SNode) the derived child node - The following code places a 1-D tensor of size ``3``: + The following code places a 1-D field of size ``3``: :: x = ti.field(dt=ti.i32) ti.root.dense(ti.i, 3).place(x) - The following code places a 2-D tensor of shape ``(3, 4)``: + The following code places a 2-D field of shape ``(3, 4)``: :: @@ -150,7 +150,7 @@ Node types ``dynamic`` nodes acts like ``std::vector`` in C++ or ``list`` in 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``: + The following places a 1-D dynamic field of maximum size ``16``: :: @@ -186,11 +186,11 @@ Working with ``dynamic`` SNodes Inserts ``val`` into the ``dynamic`` node with indices ``indices``. -Taichi tensors like powers of two ---------------------------------- +Taichi fields 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)``. +Non-power-of-two field dimensions are promoted into powers of two and thus these fields will occupy more virtual address space. +For example, a (dense) field of size ``(18, 65)`` will be materialized as ``(32, 128)``. Indices diff --git a/docs/syntax_sugars.rst b/docs/syntax_sugars.rst index 53c5d4bbfd672..94572560e4319 100644 --- a/docs/syntax_sugars.rst +++ b/docs/syntax_sugars.rst @@ -12,16 +12,16 @@ For example, consider the simple kernel: @ti.kernel def my_kernel(): - for i, j in tensor_a: - tensor_b[i, j] = some_function(tensor_a[i, j]) + for i, j in field_a: + field_b[i, j] = some_function(field_a[i, j]) -The tensors and function be aliased to new names with ``ti.static``: +The fields and function be aliased to new names with ``ti.static``: .. code-block:: python @ti.kernel def my_kernel(): - a, b, fun = ti.static(tensor_a, tensor_b, some_function) + a, b, fun = ti.static(field_a, field_b, some_function) for i,j in a: b[i,j] = fun(a[i,j]) @@ -29,7 +29,7 @@ The tensors and function be aliased to new names with ``ti.static``: Aliases can also be created for class members and methods, which can help prevent cluttering objective data-oriented programming code with ``self``. -For example, consider class kernel to compute the 2-D laplacian of some tensor: +For example, consider class kernel to compute the 2-D laplacian of some field: .. code-block:: python @@ -54,4 +54,4 @@ Using ``ti.static()``, it can be simplified to: ``ti.static`` can also be used in combination with ``if`` (compile-time branching) and ``for`` (compile-time unrolling). See :ref:`meta` for more details. - Here, we are using it for *compile-time const values*, i.e. the **tensor/function handles** are constants at compile time. + Here, we are using it for *compile-time const values*, i.e. the **field/function handles** are constants at compile time. From 153a3d3518c7794e8a03733f316bd876c26fbaf6 Mon Sep 17 00:00:00 2001 From: Xudong Feng <1009694460@qq.com> Date: Mon, 27 Jul 2020 22:28:51 +0800 Subject: [PATCH 08/10] [Doc] Replace tensor by field for files beginning with h to m (#1577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * replace * fix * fix * fix * fix * [skip ci] Update docs/meta.rst Co-authored-by: 彭于斌 <1931127624@qq.com> --- docs/hello.rst | 22 +++++++++++----------- docs/internal.rst | 10 +++++----- docs/layout.rst | 30 +++++++++++++++--------------- docs/matrix.rst | 32 ++++++++++++++++---------------- docs/meta.rst | 26 +++++++++++++------------- 5 files changed, 60 insertions(+), 60 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 2cfadf8314bcd..5d67fe1974ade 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -95,19 +95,19 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your .. note:: When used with the CUDA backend on Windows or ARM devices (e.g. NVIDIA Jetson), - Taichi by default allocates 1 GB GPU memory for tensor storage. You can override this behavior by initializing with + Taichi by default allocates 1 GB GPU memory for field storage. You can override this behavior by initializing with ``ti.init(arch=ti.cuda, device_memory_GB=3.4)`` to allocate ``3.4`` GB GPU memory, or ``ti.init(arch=ti.cuda, device_memory_fraction=0.3)`` to allocate ``30%`` of the total GPU memory. On other platforms, Taichi will make use of its on-demand memory allocator to adaptively allocate memory. -(Sparse) tensors ----------------- +(Sparse) fields +--------------- -Taichi is a data-oriented programming language where dense or spatially-sparse tensors are the first-class citizens. -See :ref:`sparse` for more details on sparse tensors. +Taichi is a data-oriented programming language where dense or spatially-sparse fields are the first-class citizens. +See :ref:`sparse` for more details on sparse fields. -In the code above, ``pixels = ti.field(dt=ti.f32, shape=(n * 2, n))`` allocates a 2D dense tensor named ``pixels`` of +In the code above, ``pixels = ti.field(dt=ti.f32, shape=(n * 2, n))`` allocates a 2D dense field named ``pixels`` of size ``(640, 320)`` and element data type ``ti.f32`` (i.e. ``float`` in C). Functions and kernels @@ -178,12 +178,12 @@ when used at the outermost scope. Range-for loops can be nested. for i in range(10): # Serial :-( ... -**Struct-for loops** are particularly useful when iterating over (sparse) tensor elements. +**Struct-for loops** are particularly useful when iterating over (sparse) field elements. In the code above, ``for i, j in pixels`` loops over all the pixel coordinates, i.e. ``(0, 0), (0, 1), (0, 2), ... , (0, 319), (1, 0), ..., (639, 319)``. .. note:: - Struct-for is the key to :ref:`sparse` in Taichi, as it will only loop over active elements in a sparse tensor. In dense tensors, all elements are active. + Struct-for is the key to :ref:`sparse` in Taichi, as it will only loop over active elements in a sparse field. In dense fields, all elements are active. .. warning:: @@ -241,7 +241,7 @@ Python-scope data access ++++++++++++++++++++++++ Everything outside Taichi-scopes (``ti.func`` and ``ti.kernel``) is simply Python code. -In Python-scopes, you can access Taichi tensor elements using plain indexing syntax. +In Python-scopes, you can access Taichi field elements using plain indexing syntax. For example, to access a single pixel of the rendered image in Python-scope, simply use: .. code-block:: python @@ -256,7 +256,7 @@ For example, to access a single pixel of the rendered image in Python-scope, sim Sharing data with other packages ++++++++++++++++++++++++++++++++ -Taichi provides helper functions such as ``from_numpy`` and ``to_numpy`` for transfer data between Taichi tensors and NumPy arrays, +Taichi provides helper functions such as ``from_numpy`` and ``to_numpy`` for transfer data between Taichi fields and NumPy arrays, So that you can also use your favorite Python packages (e.g. ``numpy``, ``pytorch``, ``matplotlib``) together with Taichi. e.g.: .. code-block:: python @@ -266,7 +266,7 @@ So that you can also use your favorite Python packages (e.g. ``numpy``, ``pytorc import numpy as np arr = np.random.rand(1024, 512) - pixels.from_numpy(arr) # load numpy data into taichi tensors + pixels.from_numpy(arr) # load numpy data into taichi fields import matplotlib.pyplot as plt arr = pixels.to_numpy() # store taichi data into numpy arrays diff --git a/docs/internal.rst b/docs/internal.rst index 37c54bd75bcad..45ef9e49ddb07 100644 --- a/docs/internal.rst +++ b/docs/internal.rst @@ -130,15 +130,15 @@ However, this design has drawbacks as well: * Taichi kernels must parse-able by Python parsers. This means Taichi syntax cannot go beyond Python syntax. - * For example, indexing is always needed when accessing elements in Taichi tensors, even if the tensor is 0D. Use ``x[None] = 123`` to set the value in ``x`` if ``x`` is 0D. This is because ``x = 123`` will set ``x`` itself (instead of its containing value) to be the constant ``123`` in python syntax, and, unfortunately, we cannot modify this behavior. + * For example, indexing is always needed when accessing elements in Taichi fields, even if the fields is 0D. Use ``x[None] = 123`` to set the value in ``x`` if ``x`` is 0D. This is because ``x = 123`` will set ``x`` itself (instead of its containing value) to be the constant ``123`` in python syntax, and, unfortunately, we cannot modify this behavior. -* Python has relatively low performance. This can cause a performance issue when initializing large Taichi tensors with pure python scripts. A Taichi kernel should be used to initialize a huge tensor. +* Python has relatively low performance. This can cause a performance issue when initializing large Taichi fields with pure python scripts. A Taichi kernel should be used to initialize a huge fields. Virtual indices v.s. physical indices ------------------------------------- -In Taichi, *virtual indices* are used to locate elements in tensors, and *physical indices* +In Taichi, *virtual indices* are used to locate elements in fields, and *physical indices* are used to specify data layouts in memory. For example, @@ -156,10 +156,10 @@ correspond to? Each ``SNode`` can have a different virtual-to-physical mapping. ``physical_index_position[i] == -1`` means the ``i``-th virtual index does not corrspond to any physical index in this ``SNode``. -``SNode`` s in handy dense tensors (i.e., ``a = ti.field(ti.i32, shape=(128, 256, 512))``) +``SNode`` s in handy dense fields (i.e., ``a = ti.field(ti.i32, shape=(128, 256, 512))``) have **trivial** virtual-to-physical mapping, e.g. ``physical_index_position[i] = i``. -However, more complex data layouts, such as column-major 2D tensors can lead to ``SNodes`` with +However, more complex data layouts, such as column-major 2D fields can lead to ``SNodes`` with ``physical_index_position[0] = 1`` and ``physical_index_position[1] = 0``. .. code-block:: python diff --git a/docs/layout.rst b/docs/layout.rst index f77e921212c83..132821de7fae8 100644 --- a/docs/layout.rst +++ b/docs/layout.rst @@ -3,10 +3,10 @@ Advanced dense layouts ====================== -Tensors (:ref:`scalar_tensor`) can be *placed* in a specific shape and *layout*. +Fields (:ref:`scalar_tensor`) can be *placed* in a specific shape and *layout*. Defining a proper layout can be critical to performance, especially for memory-bound applications. A carefully designed data layout can significantly improve cache/TLB-hit rates and cacheline utilization. Although when performance is not the first priority, you probably don't have to worry about it. -In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating tensors using ``ti.field/Vector/Matrix``), +In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating fields using ``ti.field/Vector/Matrix``), and then migrate to more advanced layouts using the ``ti.root.X`` syntax if necessary. Taichi decouples algorithms from data layouts, and the Taichi compiler automatically optimizes data accesses on a specific data layout. These Taichi features allow programmers to quickly experiment with different data layouts and figure out the most efficient one on a specific task and computer architecture. @@ -15,7 +15,7 @@ Taichi decouples algorithms from data layouts, and the Taichi compiler automatic From ``shape`` to ``ti.root.X`` ------------------------------- -For example, this declares a 0-D tensor: +For example, this declares a 0-D field: .. code-block:: python @@ -24,7 +24,7 @@ For example, this declares a 0-D tensor: # is equivalent to: x = ti.field(ti.f32, shape=()) -This declares a 1D tensor of size ``3``: +This declares a 1D field of size ``3``: .. code-block:: python @@ -33,7 +33,7 @@ This declares a 1D tensor of size ``3``: # is equivalent to: x = ti.field(ti.f32, shape=3) -This declares a 2D tensor of shape ``(3, 4)``: +This declares a 2D field of shape ``(3, 4)``: .. code-block:: python @@ -42,7 +42,7 @@ This declares a 2D tensor of shape ``(3, 4)``: # is equivalent to: x = ti.field(ti.f32, shape=(3, 4)) -You may wonder, why not simply specify the ``shape`` of the tensor? Why bother using the more complex version? +You may wonder, why not simply specify the ``shape`` of the field? Why bother using the more complex version? Good question, let go forward and figure out why. @@ -51,10 +51,10 @@ Row-major versus column-major Let's start with the simplest layout. -Since address spaces are linear in modern computers, for 1D Taichi tensors, the address of the ``i``-th element is simply ``i``. +Since address spaces are linear in modern computers, for 1D Taichi fields, the address of the ``i``-th element is simply ``i``. -To store a multi-dimensional tensor, however, it has to be flattened, in order to fit into the 1D address space. -For example, to store a 2D tensor of size ``(3, 2)``, there are two ways to do this: +To store a multi-dimensional field, however, it has to be flattened, in order to fit into the 1D address space. +For example, to store a 2D field of size ``(3, 2)``, there are two ways to do this: 1. The address of ``(i, j)``-th is ``base + i * 2 + j`` (row-major). @@ -98,9 +98,9 @@ See? ``x`` first increases the first index (i.e. row-major), while ``y`` first i Array of Structures (AoS), Structure of Arrays (SoA) ---------------------------------------------------- -Tensors of same size can be placed together. +Fields of same size can be placed together. -For example, this places two 1D tensors of size ``3`` (array of structure, AoS): +For example, this places two 1D fields of size ``3`` (array of structure, AoS): .. code-block:: python @@ -113,7 +113,7 @@ Their memory layout: # address low ............. address high # x[0] y[0] | x[1] y[1] | x[2] y[2] -In contrast, this places two tensor placed separately (structure of array, SoA): +In contrast, this places two field placed separately (structure of array, SoA): .. code-block:: python @@ -129,7 +129,7 @@ Now, their memory layout: Normally, you don't have to worry about the performance nuances between different layouts, and should just define the simplest layout as a start. -However, locality sometimes have a significant impact on the performance, especially when the tensor is huge. +However, locality sometimes have a significant impact on the performance, especially when the field is huge. **To improve spatial locality of memory accesses (i.e. cache hit rate / cacheline utilization), it's sometimes helpful to place the data elements within relatively close storage locations if they are often accessed together.** Take a simple 1D wave equation solver for example: @@ -184,7 +184,7 @@ This organizes ``val`` in ``4x4x4`` blocks, so that with high probability ``val[ Struct-fors on advanced dense data layouts ------------------------------------------ -Struct-fors on nested dense data structures will automatically follow their data order in memory. For example, if 2D scalar tensor ``A`` is stored in row-major order, +Struct-fors on nested dense data structures will automatically follow their data order in memory. For example, if 2D scalar field ``A`` is stored in row-major order, .. code-block:: python @@ -195,7 +195,7 @@ will iterate over elements of ``A`` following row-major order. If ``A`` is colum If ``A`` is hierarchical, it will be iterated level by level. This maximizes the memory bandwidth utilization in most cases. -Struct-for loops on sparse tensors follow the same philosophy, and will be discussed further in :ref:`sparse`. +Struct-for loops on sparse fields follow the same philosophy, and will be discussed further in :ref:`sparse`. Examples diff --git a/docs/matrix.rst b/docs/matrix.rst index f225df8e06f08..5733da5e293cb 100644 --- a/docs/matrix.rst +++ b/docs/matrix.rst @@ -3,10 +3,10 @@ Matrices ======== -- ``ti.Matrix`` is for small matrices (e.g. `3x3`) only. If you have `64x64` matrices, you should consider using a 2D tensor of scalars. +- ``ti.Matrix`` is for small matrices (e.g. `3x3`) only. If you have `64x64` matrices, you should consider using a 2D field of scalars. - ``ti.Vector`` is the same as ``ti.Matrix``, except that it has only one column. - Differentiate element-wise product ``*`` and matrix product ``@``. -- ``ti.Vector.field(n, dtype=ti.f32)`` or ``ti.Matrix.field(n, m, dtype=ti.f32)`` to create tensors of vectors/matrices. +- ``ti.Vector.field(n, dtype=ti.f32)`` or ``ti.Matrix.field(n, m, dtype=ti.f32)`` to create fields of vectors/matrices. - ``A.transpose()`` - ``R, S = ti.polar_decompose(A, ti.f32)`` - ``U, sigma, V = ti.svd(A, ti.f32)`` (Note that ``sigma`` is a ``3x3`` diagonal matrix) @@ -18,23 +18,23 @@ TODO: doc here better like Vector. WIP A matrix in Taichi can have two forms: - as a temporary local variable. An ``n by m`` matrix consists of ``n * m`` scalar values. - - as a an element of a global tensor. In this case, the tensor is an N-dimensional array of ``n by m`` matrices. + - as a an element of a global field. In this case, the field is an N-dimensional array of ``n by m`` matrices. Declaration ----------- -As global tensors of matrices -+++++++++++++++++++++++++++++ +As global fields of matrices +++++++++++++++++++++++++++++ .. function:: ti.Matrix.field(n, m, dtype, shape = None, offset = None) :parameter n: (scalar) the number of rows in the matrix :parameter m: (scalar) the number of columns in the matrix :parameter dtype: (DataType) data type of the components - :parameter shape: (optional, scalar or tuple) shape the tensor of vectors, see :ref:`tensor` + :parameter shape: (optional, scalar or tuple) shape the field of vectors, see :ref:`tensor` :parameter offset: (optional, scalar or tuple) see :ref:`offset` - For example, this creates a 5x4 tensor of 3x3 matrices: + For example, this creates a 5x4 field of 3x3 matrices: :: # Python-scope @@ -42,7 +42,7 @@ As global tensors of matrices .. note:: - In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Matrix.field`` declares tensors of matrices. + In Python-scope, ``ti.field`` declares :ref:`scalar_tensor`, while ``ti.Matrix.field`` declares fields of matrices. As a temporary local variable @@ -90,13 +90,13 @@ As a temporary local variable Accessing components -------------------- -As global tensors of vectors -++++++++++++++++++++++++++++ +As global fields of vectors ++++++++++++++++++++++++++++ .. attribute:: a[p, q, ...][i, j] - :parameter a: (tensor of matrices) the tensor of matrices - :parameter p: (scalar) index of the first tensor dimension - :parameter q: (scalar) index of the second tensor dimension + :parameter a: (field of matrices) the field of matrices + :parameter p: (scalar) index of the first field dimension + :parameter q: (scalar) index of the second field dimension :parameter i: (scalar) row index of the matrix :parameter j: (scalar) column index of the matrix @@ -111,12 +111,12 @@ As global tensors of vectors .. note:: - **Always** use two pair of square brackets to access scalar elements from tensors of matrices. + **Always** use two pair of square brackets to access scalar elements from fields of matrices. - - The indices in the first pair of brackets locate the matrix inside the tensor of matrices; + - The indices in the first pair of brackets locate the matrix inside the field of matrices; - The indices in the second pair of brackets locate the scalar element inside the matrix. - For 0-D tensors of matrices, indices in the first pair of brackets should be ``[None]``. + For 0-D fields of matrices, indices in the first pair of brackets should be ``[None]``. diff --git a/docs/meta.rst b/docs/meta.rst index 91a865f863fc0..5f3a3e4891bec 100644 --- a/docs/meta.rst +++ b/docs/meta.rst @@ -18,7 +18,7 @@ Template metaprogramming ------------------------ You may use ``ti.template()`` -as a type hint to pass a tensor as an argument. For example: +as a type hint to pass a field as an argument. For example: .. code-block:: python @@ -43,7 +43,7 @@ Dimensionality-independent programming using grouped indices ------------------------------------------------------------ However, the ``copy`` template shown above is not perfect. For example, it can only be -used to copy 1D tensors. What if we want to copy 2D tensors? Do we have to write +used to copy 1D fields. What if we want to copy 2D fields? Do we have to write another kernel? .. code-block:: python @@ -72,7 +72,7 @@ For example: @ti.kernel def array_op(x: ti.template(), y: ti.template()): - # if tensor x is 2D: + # if field x is 2D: for I in ti.grouped(x): # I is simply a 2D vector with data type i32 y[I + ti.Vector([0, 1])] = I[0] + I[1] @@ -81,26 +81,26 @@ For example: y[i, j + 1] = i + j -Tensor metadata ---------------- +Field metadata +-------------- -Sometimes it is useful to get the data type (``tensor.dtype``) and shape (``tensor.shape``) of tensors. +Sometimes it is useful to get the data type (``field.dtype``) and shape (``field.shape``) of fields. These attributes can be accessed in both Taichi- and Python-scopes. .. code-block:: python @ti.func - def print_tensor_info(x: ti.template()): - print('Tensor dimensionality is', len(x.shape)) + def print_field_info(x: ti.template()): + print('Field dimensionality is', len(x.shape)) for i in ti.static(range(len(x.shape))): print('Size alone dimension', i, 'is', x.shape[i]) - ti.static_print('Tensor data type is', x.dtype) + ti.static_print('Field data type is', x.dtype) See :ref:`scalar_tensor` for more details. .. note:: - For sparse tensors, the full domain shape will be returned. + For sparse fields, the full domain shape will be returned. Matrix & vector metadata @@ -168,9 +168,9 @@ When to use for loops with ``ti.static`` There are several reasons why ``ti.static`` for loops should be used. - Loop unrolling for performance. - - Loop over vector/matrix elements. Indices into Taichi matrices must be a compile-time constant. Indexing into taichi tensors can be run-time variables. For example, if ``x`` is a 1-D tensor of 3D vector, accessed as ``x[tensor_index][matrix index]``. The first index can be variable, yet the second must be a constant. + - Loop over vector/matrix elements. Indices into Taichi matrices must be a compile-time constant. Indexing into taichi fields can be run-time variables. For example, if ``x`` is a 1-D field of 3D vector, accessed as ``x[field_index][matrix_index]``. The first index can be variable, yet the second must be a constant. -For example, code for resetting this tensor of vectors should be +For example, code for resetting this field of vectors should be .. code-block:: python @@ -179,5 +179,5 @@ For example, code for resetting this tensor of vectors should be for i in x: for j in ti.static(range(x.n)): # The inner loop must be unrolled since j is a vector index instead - # of a global tensor index. + # of a global field index. x[i][j] = 0 From 19b0eb98b0966604435c9f3903a88e49f1d9dba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BA=8E=E6=96=8C?= <1931127624@qq.com> Date: Mon, 3 Aug 2020 12:26:32 +0800 Subject: [PATCH 09/10] [skip ci] Apply suggestions from code review Co-authored-by: Xudong Feng <1009694460@qq.com> --- docs/compilation.rst | 4 ++-- docs/gui.rst | 2 +- docs/hello.rst | 4 ++-- docs/offset.rst | 8 ++++---- docs/snode.rst | 12 ++++++------ 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/compilation.rst b/docs/compilation.rst index 89ac222ebca8b..684fde8d283e8 100644 --- a/docs/compilation.rst +++ b/docs/compilation.rst @@ -30,8 +30,8 @@ We allocate two 1D fields to simplify discussion: .. code-block:: python - x = ti.field(dt=ti.f32, shape=128) - y = ti.field(dt=ti.f32, shape=16) + x = ti.field(dtype=ti.f32, shape=128) + y = ti.field(dtype=ti.f32, shape=16) Kernel registration diff --git a/docs/gui.rst b/docs/gui.rst index 22214a89e85c2..bd6bbe1018fb5 100644 --- a/docs/gui.rst +++ b/docs/gui.rst @@ -401,7 +401,7 @@ Image I/O shape = (512, 512) type = ti.u8 - pixels = ti.field(dt=type, shape=shape) + pixels = ti.field(dtype=type, shape=shape) @ti.kernel def draw(): diff --git a/docs/hello.rst b/docs/hello.rst index 5d67fe1974ade..510146cc5ca0d 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -17,7 +17,7 @@ Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) ti.init(arch=ti.gpu) n = 320 - pixels = ti.field(dt=ti.f32, shape=(n * 2, n)) + pixels = ti.field(dtype=ti.f32, shape=(n * 2, n)) @ti.func @@ -107,7 +107,7 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your Taichi is a data-oriented programming language where dense or spatially-sparse fields are the first-class citizens. See :ref:`sparse` for more details on sparse fields. -In the code above, ``pixels = ti.field(dt=ti.f32, shape=(n * 2, n))`` allocates a 2D dense field named ``pixels`` of +In the code above, ``pixels = ti.field(dtype=ti.f32, shape=(n * 2, n))`` allocates a 2D dense field named ``pixels`` of size ``(640, 320)`` and element data type ``ti.f32`` (i.e. ``float`` in C). Functions and kernels diff --git a/docs/offset.rst b/docs/offset.rst index 7ad6c65a4daef..9ca924e3a7c9d 100644 --- a/docs/offset.rst +++ b/docs/offset.rst @@ -8,7 +8,7 @@ Coordinate offsets .. code-block:: python - a = ti.Matrix(2, 2, dt=ti.f32, shape=(32, 64), offset=(-16, 8)) + a = ti.Matrix(2, 2, dtype=ti.f32, shape=(32, 64), offset=(-16, 8)) In this way, the field's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusive). @@ -27,6 +27,6 @@ In this way, the field's indices are from ``(-16, 8)`` to ``(16, 72)`` (exclusiv b = ti.Vector.field(3, dtype=ti.f32, shape=(16, 32, 64), offset=(7, 3, -4)) # Works! c = ti.Matrix.field(2, 1, dtype=ti.f32, shape=None, offset=(32,)) # AssertionError d = ti.Matrix.field(3, 2, dtype=ti.f32, shape=(32, 32), offset=(-16, )) # AssertionError - e = ti.field(dt=ti.i32, shape=16, offset=-16) # Works! - f = ti.field(dt=ti.i32, shape=None, offset=-16) # AssertionError - g = ti.field(dt=ti.i32, shape=(16, 32), offset=-16) # AssertionError + e = ti.field(dtype=ti.i32, shape=16, offset=-16) # Works! + f = ti.field(dtype=ti.i32, shape=None, offset=-16) # AssertionError + g = ti.field(dtype=ti.i32, shape=(16, 32), offset=-16) # AssertionError diff --git a/docs/snode.rst b/docs/snode.rst index c6be97119a1bf..0bbbc67dc0dec 100644 --- a/docs/snode.rst +++ b/docs/snode.rst @@ -27,8 +27,8 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str :: - x = ti.field(dt=ti.i32) - y = ti.field(dt=ti.f32) + x = ti.field(dtype=ti.i32) + y = ti.field(dtype=ti.f32) ti.root.place(x, y) assert x.snode() == y.snode() @@ -55,8 +55,8 @@ See :ref:`layout` for more details. ``ti.root`` is the root node of the data str :: - x = ti.field(dt=ti.i32) - y = ti.field(dt=ti.f32) + x = ti.field(dtype=ti.i32) + y = ti.field(dtype=ti.f32) ti.root.place(x, y) x.snode() @@ -113,14 +113,14 @@ Node types :: - x = ti.field(dt=ti.i32) + x = ti.field(dtype=ti.i32) ti.root.dense(ti.i, 3).place(x) The following code places a 2-D field of shape ``(3, 4)``: :: - x = ti.field(dt=ti.i32) + x = ti.field(dtype=ti.i32) ti.root.dense(ti.ij, (3, 4)).place(x) .. note:: From 834942e4015d5ea63ceeef41a4ed6226351964ac Mon Sep 17 00:00:00 2001 From: Yuanming Hu Date: Tue, 4 Aug 2020 10:35:18 -0400 Subject: [PATCH 10/10] [skip ci] Update docs/layout.rst --- docs/layout.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/layout.rst b/docs/layout.rst index 132821de7fae8..8904fd928701c 100644 --- a/docs/layout.rst +++ b/docs/layout.rst @@ -6,7 +6,7 @@ Advanced dense layouts Fields (:ref:`scalar_tensor`) can be *placed* in a specific shape and *layout*. Defining a proper layout can be critical to performance, especially for memory-bound applications. A carefully designed data layout can significantly improve cache/TLB-hit rates and cacheline utilization. Although when performance is not the first priority, you probably don't have to worry about it. -In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating fields using ``ti.field/Vector/Matrix``), +In Taichi, the layout is defined in a recursive manner. See :ref:`snode` for more details about how this works. We suggest starting with the default layout specification (simply by specifying ``shape`` when creating fields using ``ti.field/ti.Vector.field/ti.Matrix.field``), and then migrate to more advanced layouts using the ``ti.root.X`` syntax if necessary. Taichi decouples algorithms from data layouts, and the Taichi compiler automatically optimizes data accesses on a specific data layout. These Taichi features allow programmers to quickly experiment with different data layouts and figure out the most efficient one on a specific task and computer architecture.