From bcead488cce5a5da3c13cc1e24bc7f59d0b29101 Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Fri, 24 Jul 2020 22:38:44 +0800 Subject: [PATCH 01/18] [skip ci] [Doc] [refactor] Improve syntax.rst, type.rst --- docs/hello.rst | 29 +++--- docs/syntax.rst | 239 ++++++++++++++++++++++++++++++++++++++---------- docs/type.rst | 110 ++++++++++++++++++---- 3 files changed, 300 insertions(+), 78 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 9b9e9c23743f4..1f6481391651f 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -46,17 +46,21 @@ Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) Let's dive into this simple Taichi program. + import taichi as ti ------------------- + Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other Python packages in conjunction with Taichi. + Portability ----------- -Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your hardware platform as follows: +Taichi programs run on either CPUs or GPUs. +Initialize Taichi according to your hardware platform as follows: .. code-block:: python @@ -65,7 +69,7 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your # Run on GPU, with the NVIDIA CUDA backend ti.init(arch=ti.cuda) - # Run on GPU, with the OpenGL backend + # Run on GPU, with the OpenGL compute shader backend ti.init(arch=ti.opengl) # Run on GPU, with the Apple Metal backend, if you are on OS X ti.init(arch=ti.metal) @@ -74,6 +78,7 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your ti.init(arch=ti.cpu) .. note:: + Supported backends on different platforms: +----------+------+------+--------+-------+ @@ -101,33 +106,35 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your On other platforms, Taichi will make use of its on-demand memory allocator to adaptively allocate memory. -(Sparse) tensors ----------------- +Tensors +------- -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 **tensors** are the first-class citizens. In the code above, ``pixels = ti.var(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). +size ``(640, 320)`` with data type ``ti.f32`` (32-bit floating-point number). + Functions and kernels --------------------- Computation resides in Taichi **kernels**. Kernel arguments must be type-hinted. -The language used in Taichi kernels and functions looks exactly like Python, yet the Taichi frontend compiler converts it +The language used in Taichi kernels and functions looks much like Python, yet the Taichi frontend compiler converts it into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. Taichi **functions**, which can be called by Taichi kernels and other Taichi functions, should be defined with the keyword ``ti.func``. .. note:: - **Taichi-scopes v.s. Python-scopes**: everything decorated with ``ti.kernel`` and ``ti.func`` is in Taichi-scope, which will be compiled by the Taichi compiler. - Everything else is in Python-scopes. They are simply Python code. + **Taichi-scopes v.s. Python-scopes**: everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope, which will be compiled by the Taichi compiler. + + Everything else is in Python-scopes. They are simply Python native code. .. warning:: Taichi kernels must be called in the Python-scope. I.e., **nested kernels are not supported**. - Nested functions are allowed. **Recursive functions are not supported for now**. + + But nested functions are allowed. **Recursive functions are not supported for now**. Taichi functions can only be called in Taichi-scope. diff --git a/docs/syntax.rst b/docs/syntax.rst index 6ba74de0fc59d..9a546b95564de 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -1,29 +1,103 @@ Syntax ====== +Taichi-scope vs Python-scope +---------------------------- + +Codes decorated by ``@ti.kernel`` or ``@ti.func`` is the **Taichi-scope**. + +They are to be compiled and executed on CPU or GPU devices with high +parallelization performance, on the cost of less flexibility. + +.. note:: + + For people from CUDA, Taichi-scope = **device** side. + +Codes outside ``@ti.kernel`` or ``@ti.func`` is the **Python-scope**. + +They are not compiled by the Taichi compiler and have lower performance +but with a richer type system and better flexibility. + +.. note:: + + For people from CUDA, Python-scope = **host** side. + Kernels ------- -Kernel arguments must be type-hinted. Kernels can have at most 8 parameters, e.g., +A Python function decorated by ``@ti.kernel`` is a **Taichi kernel**: + +.. code-block:: python + + @ti.kernel + def my_kern(): + ... + + my_kern() + + +Kernels are to be called from **Python-scope**. + +.. note:: + + For people from CUDA, Taichi functions = ``__global__``. + +Arguments +********* + +Kernels can have at most 8 parameters so that you can pass values from +Python-scope to Taichi-scope easily. + +Kernel arguments must be type-hinted: .. code-block:: python @ti.kernel - def print_xy(x: ti.i32, y: ti.f32): + def my_kern(x: ti.i32, y: ti.f64): print(x + y) + my_kern(2, 3.3) # prints: 5.3 + +.. note:: + + For now, we only support scalars as arguments. Specifying ``ti.Matrix`` or ``ti.Vector`` as argument is not supported. For example: + + .. code-block:: python + + @ti.kernel + def bad_kernel(v: ti.Vector): + ... + + @ti.kernel + def good_kernel(vx: ti.f32, vy: ti.f32): + v = ti.Vector([vx, vy]) + ... + + +Return value +************ + +A kernel may or may not have a **scalar** return value. +The type of return value must be hinted: + +.. code-block:: python + + @ti.kernel + def my_kern() -> ti.f32: + return 233.33 + + print(my_kern()) # 233.33 + -A kernel can have a **scalar** return value. If a kernel has a return value, it must be type-hinted. The return value will be automatically cast into the hinted type. e.g., .. code-block:: python @ti.kernel - def add_xy(x: ti.f32, y: ti.f32) -> ti.i32: - return x + y # same as: ti.cast(x + y, ti.i32) + def add_xy() -> ti.i32: # int32 + return 233.33 - res = add_xy(2.3, 1.1) - print(res) # 3, since return type is ti.i32 + print(my_kern()) # 233, since return type is ti.i32 .. note:: @@ -43,74 +117,111 @@ The return value will be automatically cast into the hinted type. e.g., return x, y # Error -We also support **template arguments** (see :ref:`template_metaprogramming`) and **external array arguments** (see :ref:`external`) in Taichi kernels. +Advanced arguments +****************** -.. warning:: +We also support **template arguments** (see :ref:`template_metaprogramming`) and **external array arguments** (see :ref:`external`) in Taichi kernels. Use ``ti.template()`` or ``ti.ext_arr()`` as their type-hints respectively. + +.. note:: When using differentiable programming, there are a few more constraints on kernel structures. See the **Kernel Simplicity Rule** in :ref:`differentiable`. Also, please do not use kernel return values in differentiable programming, since the return value will not be tracked by automatic differentiation. Instead, store the result into a global variable (e.g. ``loss[None]``). + Functions --------- -Use ``@ti.func`` to decorate your Taichi functions. These functions are callable only in `Taichi`-scope. Do not call them in `Python`-scopes. +A Python function decorated by ``@ti.func`` is a **Taichi function**: .. code-block:: python - @ti.func - def laplacian(t, i, j): - return inv_dx2 * ( - -4 * p[t, i, j] + p[t, i, j - 1] + p[t, i, j + 1] + p[t, i + 1, j] + - p[t, i - 1, j]) + @ti.func + def my_func(): + ... - @ti.kernel - def fdtd(t: ti.i32): - for i in range(n_grid): # Parallelized - for j in range(n_grid): # Serial loops in each parallel threads - laplacian_p = laplacian(t - 2, i, j) - laplacian_q = laplacian(t - 1, i, j) - p[t, i, j] = 2 * p[t - 1, i, j] + ( - c * c * dt * dt + c * alpha * dt) * laplacian_q - p[ - t - 2, i, j] - c * alpha * dt * laplacian_p + @ti.kernel + def my_kern(): + ... + my_func() # call functions from Taichi-scope + ... + my_kern() # call kernels from Python-scope -.. warning:: - Functions with multiple ``return`` statements are not supported for now. Use a **local** variable to store the results, so that you end up with only one ``return`` statement: +Functions are to be called from **Taichi-scope**. - .. code-block:: python +.. note:: - # Bad function - two return statements - @ti.func - def safe_sqrt(x): - if x >= 0: - return ti.sqrt(x) - else: - return 0.0 + For people from CUDA, Taichi functions = ``__device__``. - # Good function - single return statement - @ti.func - def safe_sqrt(x): - rst = 0.0 - if x >= 0: - rst = ti.sqrt(x) - else: - rst = 0.0 - return rst +.. note:: -.. warning:: + Functions can be nested. - Currently, all functions are force-inlined. Therefore, no recursion is allowed. +Arguments and return values +*************************** -.. note:: +Functions can have multiple arguments and return values. +Unlike kernel, function arguments don't need to be type-hinted: + +.. code-block:: python + + @ti.func + def my_add(x, y): + return x + y + + + @ti.kernel + def my_kern(): + ... + ret = my_add(2, 3.3) + print(ret) # 5.3 + ... + + +Function arguments are passed by value, changes made inside function scope +won't affect the outside value in the caller: + +.. code-block:: python + + @ti.func + def my_func(x): + x = x + 1 # won't change the original value of x + + + @ti.kernel + def my_kern(): + ... + x = 233 + my_func(x) + print(x) # 233 + ... + + +You may use ``ti.template()`` as type-hint to force arguments to be passed by +reference: + +.. code-block:: python + + @ti.func + def my_func(x: ti.template()): + x = x + 1 # will change the original value of x + + + @ti.kernel + def my_kern(): + ... + x = 233 + my_func(x) + print(x) # 234 + ... - Function arguments are passed by value. .. note:: - Unlike functions, **kernels do not support vectors or matrices as arguments**: + Unlike kernels, functions **do support vectors or matrices as arguments and return values**: .. code-block:: python @@ -126,11 +237,41 @@ Use ``@ti.func`` to decorate your Taichi functions. These functions are callable p += d * t ... +.. warning:: + + Functions with multiple ``return`` statements are not supported for now. Use a **local** variable to store the results, so that you end up with only one ``return`` statement: + + .. code-block:: python + + # Bad function - two return statements + @ti.func + def safe_sqrt(x): + if x >= 0: + return ti.sqrt(x) + else: + return 0.0 + + # Good function - single return statement + @ti.func + def safe_sqrt(x): + ret = 0.0 + if x >= 0: + ret = ti.sqrt(x) + else: + ret = 0.0 + return ret + + +.. warning:: + + Currently, all functions are force-inlined. Therefore, no recursion is allowed. + Scalar arithmetics ------------------ -Supported scalar functions: + +Currently supported scalar functions: .. function:: ti.sin(x) .. function:: ti.cos(x) diff --git a/docs/type.rst b/docs/type.rst index 0f01ec8745852..aa465214b1b9e 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -1,8 +1,33 @@ Type system =========== +Taichi supports many kind of data types, the type name is recognized as +a *prefix character* + a *digital number*. + +The *prefix character* can be one of: + +- ``i`` for signed integers, e.g. 233, -666 +- ``u`` for unsigned integers, e.g. 233, 666 +- ``f`` for floating point numbers, e.g. 2.33, 1e-4 + +The *digital number* can be one of: + +- ``8`` +- ``16`` +- ``32`` +- ``64`` + +It represents how much **bits** is used in storing the data. +The larger the bit number, the higher precision is. + +For example, the two most commonly used types: + +- ``i32`` represents a 32-bit signed integer. +- ``f32`` represents a 32-bit floating pointer number. + Supported types --------------- + Currently, supported basic types in Taichi are - int8 ``ti.i8`` @@ -46,13 +71,21 @@ Currently, supported basic types in Taichi are (OK: supported, EXT: require extension, N/A: not available) -Boolean types should be represented using ``ti.i32``. +.. note:: -Binary operations on different types will give you a promoted type, following the C programming language, e.g. + Boolean types should be represented using ``ti.i32``. -- ``i32 + f32 = f32`` -- ``f32 + f64 = f64`` -- ``i32 + i64 = i64`` + + +Type promotion +-------------- + +Binary operations on different types will give you a promoted type, following the C programming language, e.g.: + +- ``i32 + f32 = f32`` (integer + float = float) +- ``i32 + i64 = i64`` (less-bits + more-bits = lamore-bits) + +Basically it will try to choose the least precise type to contain the result value. .. _default_precisions: @@ -62,6 +95,7 @@ Default precisions By default, numerical literals have 32-bit precisions. For example, ``42`` has type ``ti.i32`` and ``3.14`` has type ``ti.f32``. + Default integer and float-point precisions (``default_ip`` and ``default_fp``) can be specified when initializing Taichi: .. code-block:: python @@ -76,24 +110,64 @@ Default integer and float-point precisions (``default_ip`` and ``default_fp``) c Type casts ---------- -Use ``ti.cast`` to cast scalar values. +Implicit casts +**************** + +WARNING: The type of a variable is **determinated on it's initialization**. + +When a *wide* variable is assigned with a *narrow* type, it will be +implicitly promoted to the *wide* type and no warning will be raised: .. code-block:: python - a = 1.4 - b = ti.cast(a, ti.i32) - c = ti.cast(b, ti.f32) + a = 1.7 + a = 1 + print(a) # 1.0 - # Equivalently, use ``int()`` and ``float()`` - # to convert values to default float-point/integer types - b = int(a) - c = float(b) +When a *narrow* variable is assigned with a *wide* type, it will be +implicitly casted into the *narrow* type and Taichi will raise a warning: - # Element-wise casts in matrices - mat = ti.Matrix([[3.0, 0.0], [0.3, 0.1]]) - mat_int = mat.cast(int) - mat_int2 = mat.cast(ti.i32) +.. code-block:: python + + a = 1 + a = 1.7 + print(a) # 1 + +Explicit casts +************** + +You may use ``ti.cast`` to explicitly cast scalar values between different types: + +.. code-block:: python + + a = 1.7 + b = ti.cast(a, ti.i32) # 1 + c = ti.cast(b, ti.f32) # 1.0 + +Equivalently, use ``int()`` and ``float()`` to convert values to default float-point/integer types: + +.. code-block:: python + + a = 1.7 + b = int(a) # 1 + c = float(a) # 1.0 + +Casting vector / matrix elements +******************************** + +Type cast applied to vectors / matrices are element-wise: + +.. code-block:: python + + u = ti.Vector([2.3, 4.7]) + v = int(u) # ti.Vector([2, 4]) + +Bit casting +*********** Use ``ti.bit_cast`` to bit-cast a value into another data type. The underlying bits will be preserved in this cast. The new type must have the same width as the the old type. -For example, bit-casting ``i32`` to ``f64`` is not allowed. Use this operation with caution. + +.. code-block:: + + For people from C++, ``ti.bit_cast`` is equivalent to ``reinterpret_cast``. From 4c5a25034cb466600a1adc0605946535b3e6d368 Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Fri, 24 Jul 2020 22:48:10 +0800 Subject: [PATCH 02/18] [skip ci] fix typo --- docs/syntax.rst | 7 +++++-- docs/type.rst | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/syntax.rst b/docs/syntax.rst index 9a546b95564de..69c9d2f26a556 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -13,6 +13,7 @@ parallelization performance, on the cost of less flexibility. For people from CUDA, Taichi-scope = **device** side. + Codes outside ``@ti.kernel`` or ``@ti.func`` is the **Python-scope**. They are not compiled by the Taichi compiler and have lower performance @@ -22,6 +23,7 @@ but with a richer type system and better flexibility. For people from CUDA, Python-scope = **host** side. + Kernels ------- @@ -40,7 +42,8 @@ Kernels are to be called from **Python-scope**. .. note:: - For people from CUDA, Taichi functions = ``__global__``. + For people from CUDA, Taichi kernels = ``__global__``. + Arguments ********* @@ -102,7 +105,7 @@ The return value will be automatically cast into the hinted type. e.g., .. note:: - For now, we only support one scalar as return value. Returning ``ti.Matrix`` or ``ti.Vector`` is not supported. Python-style tuple return is not supported either. For example: + For now, kernels only support one scalar as return value. Returning ``ti.Matrix`` or ``ti.Vector`` is not supported. Python-style tuple return is not supported either. For example: .. code-block:: python diff --git a/docs/type.rst b/docs/type.rst index aa465214b1b9e..d177a61cf188c 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -73,7 +73,7 @@ Currently, supported basic types in Taichi are .. note:: - Boolean types should be represented using ``ti.i32``. + Boolean types are represented using ``ti.i32``. From 7bb418ae02c55b0cf533c1dcdc7a02cd57296103 Mon Sep 17 00:00:00 2001 From: Taichi Gardener Date: Fri, 24 Jul 2020 10:49:22 -0400 Subject: [PATCH 03/18] [skip ci] enforce code format --- docs/syntax.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/syntax.rst b/docs/syntax.rst index 69c9d2f26a556..a4ab2ca093b97 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -175,7 +175,7 @@ Unlike kernel, function arguments don't need to be type-hinted: def my_add(x, y): return x + y - + @ti.kernel def my_kern(): ... @@ -193,7 +193,7 @@ won't affect the outside value in the caller: def my_func(x): x = x + 1 # won't change the original value of x - + @ti.kernel def my_kern(): ... @@ -212,7 +212,7 @@ reference: def my_func(x: ti.template()): x = x + 1 # will change the original value of x - + @ti.kernel def my_kern(): ... From ba31b15759ce5e26747091c16b4f5f04d09a6bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BA=8E=E6=96=8C?= <1931127624@qq.com> Date: Sat, 25 Jul 2020 14:17:11 +0800 Subject: [PATCH 04/18] [skip ci] Apply suggestions from code review Co-authored-by: Xiao Zhai <7610945+TroyZhai@users.noreply.github.com> --- docs/hello.rst | 2 +- docs/syntax.rst | 10 +++++----- docs/type.rst | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 1f6481391651f..3d7a90981d833 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -126,7 +126,7 @@ Taichi **functions**, which can be called by Taichi kernels and other Taichi fun .. note:: - **Taichi-scopes v.s. Python-scopes**: everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope, which will be compiled by the Taichi compiler. + **Taichi-scopes v.s. Python-scopes**: everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope and hence will be compiled by the Taichi compiler. Everything else is in Python-scopes. They are simply Python native code. diff --git a/docs/syntax.rst b/docs/syntax.rst index a4ab2ca093b97..68235c1f685dd 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -42,7 +42,7 @@ Kernels are to be called from **Python-scope**. .. note:: - For people from CUDA, Taichi kernels = ``__global__``. + For people from CUDA, Taichi kernels = ``__global__`` functions. Arguments @@ -81,7 +81,7 @@ Return value ************ A kernel may or may not have a **scalar** return value. -The type of return value must be hinted: +If it does, the type of return value must be hinted: .. code-block:: python @@ -105,7 +105,7 @@ The return value will be automatically cast into the hinted type. e.g., .. note:: - For now, kernels only support one scalar as return value. Returning ``ti.Matrix`` or ``ti.Vector`` is not supported. Python-style tuple return is not supported either. For example: + For now, a kernel can only have one scalar return value. Returning ``ti.Matrix`` or ``ti.Vector`` is not supported. Python-style tuple return is not supported either. For example: .. code-block:: python @@ -156,7 +156,7 @@ Functions are to be called from **Taichi-scope**. .. note:: - For people from CUDA, Taichi functions = ``__device__``. + For people from CUDA, Taichi functions = ``__device__`` functions. .. note:: @@ -167,7 +167,7 @@ Arguments and return values *************************** Functions can have multiple arguments and return values. -Unlike kernel, function arguments don't need to be type-hinted: +Unlike kernels, arguments in functions don't need to be type-hinted: .. code-block:: python diff --git a/docs/type.rst b/docs/type.rst index d177a61cf188c..49349ca6e49b6 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -1,7 +1,7 @@ Type system =========== -Taichi supports many kind of data types, the type name is recognized as +Taichi supports many data types. The type name is recognized as a *prefix character* + a *digital number*. The *prefix character* can be one of: @@ -17,8 +17,8 @@ The *digital number* can be one of: - ``32`` - ``64`` -It represents how much **bits** is used in storing the data. -The larger the bit number, the higher precision is. +It represents how many **bits** are used in storing the data. +The larger the bit number, the higher the precision is. For example, the two most commonly used types: @@ -80,7 +80,7 @@ Currently, supported basic types in Taichi are Type promotion -------------- -Binary operations on different types will give you a promoted type, following the C programming language, e.g.: +Binary operations on different types will give you a promoted type, following the C programming language convention, e.g.: - ``i32 + f32 = f32`` (integer + float = float) - ``i32 + i64 = i64`` (less-bits + more-bits = lamore-bits) @@ -155,7 +155,7 @@ Equivalently, use ``int()`` and ``float()`` to convert values to default float-p Casting vector / matrix elements ******************************** -Type cast applied to vectors / matrices are element-wise: +Type casts applied to vectors/matrices are element-wise: .. code-block:: python From 7fce28a227c054d5a8551400a4d674cb9740b1b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BA=8E=E6=96=8C?= <1931127624@qq.com> Date: Sat, 25 Jul 2020 14:50:46 +0800 Subject: [PATCH 05/18] [skip ci] Apply suggestions from code review --- docs/hello.rst | 3 +-- docs/syntax.rst | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 3d7a90981d833..266152d9e13d3 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -133,8 +133,7 @@ Taichi **functions**, which can be called by Taichi kernels and other Taichi fun .. warning:: Taichi kernels must be called in the Python-scope. I.e., **nested kernels are not supported**. - - But nested functions are allowed. **Recursive functions are not supported for now**. + Nested functions are allowed. **Recursive functions are not supported for now**. Taichi functions can only be called in Taichi-scope. diff --git a/docs/syntax.rst b/docs/syntax.rst index 68235c1f685dd..54a19740ff81a 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -4,7 +4,7 @@ Syntax Taichi-scope vs Python-scope ---------------------------- -Codes decorated by ``@ti.kernel`` or ``@ti.func`` is the **Taichi-scope**. +Code decorated by ``@ti.kernel`` or ``@ti.func`` is in the **Taichi-scope**. They are to be compiled and executed on CPU or GPU devices with high parallelization performance, on the cost of less flexibility. @@ -14,7 +14,7 @@ parallelization performance, on the cost of less flexibility. For people from CUDA, Taichi-scope = **device** side. -Codes outside ``@ti.kernel`` or ``@ti.func`` is the **Python-scope**. +Code outside ``@ti.kernel`` or ``@ti.func`` is in the **Python-scope**. They are not compiled by the Taichi compiler and have lower performance but with a richer type system and better flexibility. @@ -38,7 +38,7 @@ A Python function decorated by ``@ti.kernel`` is a **Taichi kernel**: my_kern() -Kernels are to be called from **Python-scope**. +Kernels should be called from **Python-scope**. .. note:: @@ -152,7 +152,7 @@ A Python function decorated by ``@ti.func`` is a **Taichi function**: my_kern() # call kernels from Python-scope -Functions are to be called from **Taichi-scope**. +Taichi functions can only be called from **Taichi-scope**. .. note:: From a816e2f705df15d19d654dd953a823d3214beb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BA=8E=E6=96=8C?= <1931127624@qq.com> Date: Sat, 25 Jul 2020 14:55:23 +0800 Subject: [PATCH 06/18] [skip ci] Apply suggestions from code review --- docs/syntax.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/syntax.rst b/docs/syntax.rst index 54a19740ff81a..585090cc3ee10 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -160,7 +160,11 @@ Taichi functions can only be called from **Taichi-scope**. .. note:: - Functions can be nested. + Taichi functions can be nested. + +.. warning:: + + Currently, all functions are force-inlined. Therefore, no recursion is allowed. Arguments and return values @@ -265,12 +269,6 @@ reference: return ret -.. warning:: - - Currently, all functions are force-inlined. Therefore, no recursion is allowed. - - - Scalar arithmetics ------------------ From 1f1d7db009d856ba34add9d04a082c70ec59004c Mon Sep 17 00:00:00 2001 From: Taichi Gardener Date: Sat, 25 Jul 2020 02:55:38 -0400 Subject: [PATCH 07/18] [skip ci] enforce code format --- docs/syntax.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/syntax.rst b/docs/syntax.rst index 585090cc3ee10..146411dec44ef 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -161,7 +161,7 @@ Taichi functions can only be called from **Taichi-scope**. .. note:: Taichi functions can be nested. - + .. warning:: Currently, all functions are force-inlined. Therefore, no recursion is allowed. From c4d823ac42871a3c2a54499fdcb1578352cb12dc Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Sat, 25 Jul 2020 15:31:45 +0800 Subject: [PATCH 08/18] [skip ci] minor --- docs/type.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/type.rst b/docs/type.rst index 49349ca6e49b6..3032c467ba37a 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -111,7 +111,7 @@ Type casts ---------- Implicit casts -**************** +************** WARNING: The type of a variable is **determinated on it's initialization**. From dd612239ee3345468f1cca19fff2a3e5c7bf6d0f Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Sat, 25 Jul 2020 18:23:52 +0800 Subject: [PATCH 09/18] [skip ci] apply concern --- docs/hello.rst | 8 ++------ docs/index.rst | 2 +- docs/syntax.rst | 31 +++++++++++++++++-------------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 266152d9e13d3..61c3bbc210fde 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -3,8 +3,7 @@ Hello, world! We introduce the Taichi programming language through a very basic `fractal` example. -Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) will give you an animation of -`Julia set `_: +Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) will give you an animation of `Julia set `_: .. image:: https://github.com/yuanming-hu/public_files/raw/master/graphics/taichi/fractal.gif @@ -50,10 +49,7 @@ Let's dive into this simple Taichi program. import taichi as ti ------------------- -Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, -we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with -minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other -Python packages in conjunction with Taichi. +Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other Python packages in conjunction with Taichi. Portability diff --git a/docs/index.rst b/docs/index.rst index 1e8ae8417d172..02dfce8d1556c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,10 +38,10 @@ The Taichi Programming Language meta layout sparse - offset differentiable_programming odop compilation + offset syntax_sugars diff --git a/docs/syntax.rst b/docs/syntax.rst index 585090cc3ee10..b8fa547d3934c 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -32,10 +32,10 @@ A Python function decorated by ``@ti.kernel`` is a **Taichi kernel**: .. code-block:: python @ti.kernel - def my_kern(): + def my_kernel(): ... - my_kern() + my_kernel() Kernels should be called from **Python-scope**. @@ -56,10 +56,10 @@ Kernel arguments must be type-hinted: .. code-block:: python @ti.kernel - def my_kern(x: ti.i32, y: ti.f64): + def my_kernel(x: ti.i32, y: ti.f64): print(x + y) - my_kern(2, 3.3) # prints: 5.3 + my_kernel(2, 3.3) # prints: 5.3 .. note:: @@ -86,10 +86,10 @@ If it does, the type of return value must be hinted: .. code-block:: python @ti.kernel - def my_kern() -> ti.f32: + def my_kernel() -> ti.f32: return 233.33 - print(my_kern()) # 233.33 + print(my_kernel()) # 233.33 The return value will be automatically cast into the hinted type. e.g., @@ -100,7 +100,7 @@ The return value will be automatically cast into the hinted type. e.g., def add_xy() -> ti.i32: # int32 return 233.33 - print(my_kern()) # 233, since return type is ti.i32 + print(my_kernel()) # 233, since return type is ti.i32 .. note:: @@ -144,15 +144,15 @@ A Python function decorated by ``@ti.func`` is a **Taichi function**: ... @ti.kernel - def my_kern(): + def my_kernel(): ... my_func() # call functions from Taichi-scope ... - my_kern() # call kernels from Python-scope + my_kernel() # call kernels from Python-scope -Taichi functions can only be called from **Taichi-scope**. +Taichi functions should be called from **Taichi-scope**. .. note:: @@ -161,7 +161,7 @@ Taichi functions can only be called from **Taichi-scope**. .. note:: Taichi functions can be nested. - + .. warning:: Currently, all functions are force-inlined. Therefore, no recursion is allowed. @@ -181,7 +181,7 @@ Unlike kernels, arguments in functions don't need to be type-hinted: @ti.kernel - def my_kern(): + def my_kernel(): ... ret = my_add(2, 3.3) print(ret) # 5.3 @@ -199,7 +199,7 @@ won't affect the outside value in the caller: @ti.kernel - def my_kern(): + def my_kernel(): ... x = 233 my_func(x) @@ -207,6 +207,9 @@ won't affect the outside value in the caller: ... +Advanced arguments +****************** + You may use ``ti.template()`` as type-hint to force arguments to be passed by reference: @@ -218,7 +221,7 @@ reference: @ti.kernel - def my_kern(): + def my_kernel(): ... x = 233 my_func(x) From 94079324634632e57f2299a1cf6ee274af91605c 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, 27 Jul 2020 16:39:19 +0800 Subject: [PATCH 10/18] [skip ci] app --- docs/hello.rst | 6 ++++-- docs/type.rst | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index 61c3bbc210fde..fba4425c924fc 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -114,11 +114,13 @@ size ``(640, 320)`` with data type ``ti.f32`` (32-bit floating-point number). Functions and kernels --------------------- -Computation resides in Taichi **kernels**. Kernel arguments must be type-hinted. +Computation resides in Taichi **kernels**, which is defined with the decorator ``@ti.kernel``. +Kernel arguments must be type-hinted (if any). The language used in Taichi kernels and functions looks much like Python, yet the Taichi frontend compiler converts it into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. -Taichi **functions**, which can be called by Taichi kernels and other Taichi functions, should be defined with the keyword ``ti.func``. +Taichi **functions** are defined with the decorator ``@ti.func``. +They can be called by Taichi kernels and other Taichi functions. .. note:: diff --git a/docs/type.rst b/docs/type.rst index 3032c467ba37a..fa7deb90ffd6b 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -161,6 +161,8 @@ Type casts applied to vectors/matrices are element-wise: u = ti.Vector([2.3, 4.7]) v = int(u) # ti.Vector([2, 4]) + # equivalent to: + v = ti.cast(u, ti.i32) # ti.Vector([2, 4]) Bit casting *********** From 49a5287ca8af5a1751e908d501f9af7c81c4d22d Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Mon, 27 Jul 2020 16:42:59 +0800 Subject: [PATCH 11/18] [skip ci] rev --- docs/hello.rst | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index fba4425c924fc..fb55c333a44af 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -3,7 +3,8 @@ Hello, world! We introduce the Taichi programming language through a very basic `fractal` example. -Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) will give you an animation of `Julia set `_: +Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) will give you an animation of +`Julia set `_: .. image:: https://github.com/yuanming-hu/public_files/raw/master/graphics/taichi/fractal.gif @@ -49,14 +50,16 @@ Let's dive into this simple Taichi program. import taichi as ti ------------------- -Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other Python packages in conjunction with Taichi. +Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, +we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with +minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other +Python packages in conjunction with Taichi. Portability ----------- -Taichi programs run on either CPUs or GPUs. -Initialize Taichi according to your hardware platform as follows: +Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your hardware platform as follows: .. code-block:: python @@ -65,7 +68,7 @@ Initialize Taichi according to your hardware platform as follows: # Run on GPU, with the NVIDIA CUDA backend ti.init(arch=ti.cuda) - # Run on GPU, with the OpenGL compute shader backend + # Run on GPU, with the OpenGL backend ti.init(arch=ti.opengl) # Run on GPU, with the Apple Metal backend, if you are on OS X ti.init(arch=ti.metal) @@ -105,10 +108,12 @@ Initialize Taichi according to your hardware platform as follows: Tensors ------- -Taichi is a data-oriented programming language where **tensors** are the first-class citizens. +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 -size ``(640, 320)`` with data type ``ti.f32`` (32-bit floating-point number). +size ``(640, 320)`` and element data type ``ti.f32`` (i.e. ``float`` in C). Functions and kernels @@ -116,7 +121,7 @@ Functions and kernels Computation resides in Taichi **kernels**, which is defined with the decorator ``@ti.kernel``. Kernel arguments must be type-hinted (if any). -The language used in Taichi kernels and functions looks much like Python, yet the Taichi frontend compiler converts it +The language used in Taichi kernels and functions looks exactly like Python, yet the Taichi frontend compiler converts it into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. Taichi **functions** are defined with the decorator ``@ti.func``. From 1e86b202583370260039cad12b84e9f1408bb1ee Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Fri, 31 Jul 2020 15:40:17 +0800 Subject: [PATCH 12/18] nit --- docs/hello.rst | 22 +++++++++++----------- docs/index.rst | 2 +- docs/syntax.rst | 2 +- docs/type.rst | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index fb55c333a44af..8c5a9916d2868 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -46,16 +46,13 @@ Running the Taichi code below (``python3 fractal.py`` or ``ti example fractal``) Let's dive into this simple Taichi program. - import taichi as ti ------------------- - Taichi is a domain-specific language (DSL) embedded in Python. To make Taichi as easy to use as a Python package, we have done heavy engineering with this goal in mind - letting every Python programmer write Taichi programs with minimal learning effort. You can even use your favorite Python package management system, Python IDEs and other Python packages in conjunction with Taichi. - Portability ----------- @@ -109,27 +106,30 @@ Tensors ------- 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. +See :ref:`scalar_tensor` for more details on tensors. In the code above, ``pixels = ti.var(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 --------------------- -Computation resides in Taichi **kernels**, which is defined with the decorator ``@ti.kernel``. +Computation resides in Taichi **kernels** and Taichi **functions**. + +Taichi **kernels** are defined with the decorator ``@ti.kernel``. Kernel arguments must be type-hinted (if any). -The language used in Taichi kernels and functions looks exactly like Python, yet the Taichi frontend compiler converts it -into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. Taichi **functions** are defined with the decorator ``@ti.func``. -They can be called by Taichi kernels and other Taichi functions. +They can be called by Taichi kernels or other Taichi functions. + +The language used in Taichi kernels and functions looks exactly like Python, yet the Taichi frontend compiler converts it into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. .. note:: - **Taichi-scopes v.s. Python-scopes**: everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope and hence will be compiled by the Taichi compiler. + **Taichi-scopes v.s. Python-scopes**: + + Everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope + and hence will be compiled by the Taichi compiler. Everything else is in Python-scopes. They are simply Python native code. diff --git a/docs/index.rst b/docs/index.rst index 02dfce8d1556c..1e8ae8417d172 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -38,10 +38,10 @@ The Taichi Programming Language meta layout sparse + offset differentiable_programming odop compilation - offset syntax_sugars diff --git a/docs/syntax.rst b/docs/syntax.rst index 0315e47c39693..63225b74c46fc 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -56,7 +56,7 @@ Kernel arguments must be type-hinted: .. code-block:: python @ti.kernel - def my_kernel(x: ti.i32, y: ti.f64): + def my_kernel(x: ti.i32, y: ti.f32): print(x + y) my_kernel(2, 3.3) # prints: 5.3 diff --git a/docs/type.rst b/docs/type.rst index fa7deb90ffd6b..0173b74f2fda1 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -83,9 +83,9 @@ Type promotion Binary operations on different types will give you a promoted type, following the C programming language convention, e.g.: - ``i32 + f32 = f32`` (integer + float = float) -- ``i32 + i64 = i64`` (less-bits + more-bits = lamore-bits) +- ``i32 + i64 = i64`` (less-bits + more-bits = more-bits) -Basically it will try to choose the least precise type to contain the result value. +Basically it will try to choose the more precise type to contain the result value. .. _default_precisions: From a9866750d0c91991bc4511b0b238cf4f9b5ecf1a Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Fri, 31 Jul 2020 15:40:38 +0800 Subject: [PATCH 13/18] [skip ci] revert type.rst --- docs/type.rst | 112 ++++++++------------------------------------------ 1 file changed, 18 insertions(+), 94 deletions(-) diff --git a/docs/type.rst b/docs/type.rst index 0173b74f2fda1..0f01ec8745852 100644 --- a/docs/type.rst +++ b/docs/type.rst @@ -1,33 +1,8 @@ Type system =========== -Taichi supports many data types. The type name is recognized as -a *prefix character* + a *digital number*. - -The *prefix character* can be one of: - -- ``i`` for signed integers, e.g. 233, -666 -- ``u`` for unsigned integers, e.g. 233, 666 -- ``f`` for floating point numbers, e.g. 2.33, 1e-4 - -The *digital number* can be one of: - -- ``8`` -- ``16`` -- ``32`` -- ``64`` - -It represents how many **bits** are used in storing the data. -The larger the bit number, the higher the precision is. - -For example, the two most commonly used types: - -- ``i32`` represents a 32-bit signed integer. -- ``f32`` represents a 32-bit floating pointer number. - Supported types --------------- - Currently, supported basic types in Taichi are - int8 ``ti.i8`` @@ -71,21 +46,13 @@ Currently, supported basic types in Taichi are (OK: supported, EXT: require extension, N/A: not available) -.. note:: +Boolean types should be represented using ``ti.i32``. - Boolean types are represented using ``ti.i32``. +Binary operations on different types will give you a promoted type, following the C programming language, e.g. - - -Type promotion --------------- - -Binary operations on different types will give you a promoted type, following the C programming language convention, e.g.: - -- ``i32 + f32 = f32`` (integer + float = float) -- ``i32 + i64 = i64`` (less-bits + more-bits = more-bits) - -Basically it will try to choose the more precise type to contain the result value. +- ``i32 + f32 = f32`` +- ``f32 + f64 = f64`` +- ``i32 + i64 = i64`` .. _default_precisions: @@ -95,7 +62,6 @@ Default precisions By default, numerical literals have 32-bit precisions. For example, ``42`` has type ``ti.i32`` and ``3.14`` has type ``ti.f32``. - Default integer and float-point precisions (``default_ip`` and ``default_fp``) can be specified when initializing Taichi: .. code-block:: python @@ -110,66 +76,24 @@ Default integer and float-point precisions (``default_ip`` and ``default_fp``) c Type casts ---------- -Implicit casts -************** - -WARNING: The type of a variable is **determinated on it's initialization**. - -When a *wide* variable is assigned with a *narrow* type, it will be -implicitly promoted to the *wide* type and no warning will be raised: +Use ``ti.cast`` to cast scalar values. .. code-block:: python - a = 1.7 - a = 1 - print(a) # 1.0 + a = 1.4 + b = ti.cast(a, ti.i32) + c = ti.cast(b, ti.f32) -When a *narrow* variable is assigned with a *wide* type, it will be -implicitly casted into the *narrow* type and Taichi will raise a warning: + # Equivalently, use ``int()`` and ``float()`` + # to convert values to default float-point/integer types + b = int(a) + c = float(b) -.. code-block:: python - - a = 1 - a = 1.7 - print(a) # 1 - -Explicit casts -************** - -You may use ``ti.cast`` to explicitly cast scalar values between different types: - -.. code-block:: python - - a = 1.7 - b = ti.cast(a, ti.i32) # 1 - c = ti.cast(b, ti.f32) # 1.0 - -Equivalently, use ``int()`` and ``float()`` to convert values to default float-point/integer types: - -.. code-block:: python - - a = 1.7 - b = int(a) # 1 - c = float(a) # 1.0 - -Casting vector / matrix elements -******************************** - -Type casts applied to vectors/matrices are element-wise: - -.. code-block:: python - - u = ti.Vector([2.3, 4.7]) - v = int(u) # ti.Vector([2, 4]) - # equivalent to: - v = ti.cast(u, ti.i32) # ti.Vector([2, 4]) - -Bit casting -*********** + # Element-wise casts in matrices + mat = ti.Matrix([[3.0, 0.0], [0.3, 0.1]]) + mat_int = mat.cast(int) + mat_int2 = mat.cast(ti.i32) Use ``ti.bit_cast`` to bit-cast a value into another data type. The underlying bits will be preserved in this cast. The new type must have the same width as the the old type. - -.. code-block:: - - For people from C++, ``ti.bit_cast`` is equivalent to ``reinterpret_cast``. +For example, bit-casting ``i32`` to ``f64`` is not allowed. Use this operation with caution. From 6aeeb7da66024e2bb5336962d8a99dee52f71aa1 Mon Sep 17 00:00:00 2001 From: Taichi Gardener Date: Sun, 9 Aug 2020 23:19:55 -0400 Subject: [PATCH 14/18] [skip ci] enforce code format --- docs/hello.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hello.rst b/docs/hello.rst index 437a89f7c339b..e95fd28f973dc 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -127,7 +127,7 @@ The language used in Taichi kernels and functions looks exactly like Python, yet .. note:: **Taichi-scopes v.s. Python-scopes**: - + Everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope and hence will be compiled by the Taichi compiler. From e101a45eae2b838c50bb113e43a5f1b0481db3ca Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Mon, 10 Aug 2020 12:02:44 +0800 Subject: [PATCH 15/18] TaichiSyntaxError for func --- docs/hello.rst | 17 +++++++++++++---- docs/syntax.rst | 2 +- python/taichi/lang/kernel.py | 10 +++++++--- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index e95fd28f973dc..b68b6ebd3773d 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -117,11 +117,14 @@ Functions and kernels Computation resides in Taichi **kernels** and Taichi **functions**. Taichi **kernels** are defined with the decorator ``@ti.kernel``. +They can be called from Python to perform computation. Kernel arguments must be type-hinted (if any). Taichi **functions** are defined with the decorator ``@ti.func``. They can be called by Taichi kernels or other Taichi functions. +See :ref:`syntax` for more details about Taichi kernels and functions. + The language used in Taichi kernels and functions looks exactly like Python, yet the Taichi frontend compiler converts it into a language that is **compiled, statically-typed, lexically-scoped, parallel and differentiable**. .. note:: @@ -135,12 +138,18 @@ The language used in Taichi kernels and functions looks exactly like Python, yet .. warning:: - Taichi kernels must be called in the Python-scope. I.e., **nested kernels are not supported**. - Nested functions are allowed. **Recursive functions are not supported for now**. + Taichi kernels must be called from the Python-scope. + Taichi functions must be called from the Taichi-scope. + +.. note:: - Taichi functions can only be called in Taichi-scope. + For those who come from the world of CUDA, ``ti.func`` corresponds to ``__device__`` while ``ti.kernel`` corresponds to ``__global__``. + +.. warning:: -For those who come from the world of CUDA, ``ti.func`` corresponds to ``__device__`` while ``ti.kernel`` corresponds to ``__global__``. + **Nested kernels are not supported**. + **Nested functions are allowed**. + **Recursive functions are not supported for now**. Parallel for-loops diff --git a/docs/syntax.rst b/docs/syntax.rst index 63225b74c46fc..c24ec8f34f0d9 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -275,7 +275,7 @@ reference: Scalar arithmetics ------------------ -Currently supported scalar functions: +Supported scalar functions: .. function:: ti.sin(x) .. function:: ti.cos(x) diff --git a/python/taichi/lang/kernel.py b/python/taichi/lang/kernel.py index ee156712cd9b8..978d3e221a13d 100644 --- a/python/taichi/lang/kernel.py +++ b/python/taichi/lang/kernel.py @@ -5,6 +5,7 @@ from .kernel_arguments import * from .util import * from .shell import oinspect, _shell_pop_print +from .exception import TaichiSyntaxError from . import impl import functools @@ -75,8 +76,11 @@ def __init__(self, func, classfunc=False, pyfunc=False): def __call__(self, *args): _taichi_skip_traceback = 1 if not impl.inside_kernel(): - assert self.pyfunc, "Use @ti.pyfunc if you wish to call " \ - "Taichi functions from Python-scope" + if not self.pyfunc: + raise TaichiSyntaxError( + "Taichi functions cannot be called from Python-scope." + " Use @ti.pyfunc if you wish to call Taichi functions " + "from both Python-scope and Taichi-scope.") return self.func(*args) if self.compiled is None: self.do_compile() @@ -364,7 +368,7 @@ def taichi_ast_generator(): _taichi_skip_traceback = 1 if self.runtime.inside_kernel: import taichi as ti - raise ti.TaichiSyntaxError( + raise TaichiSyntaxError( "Kernels cannot call other kernels. I.e., nested kernels are not allowed. Please check if you have direct/indirect invocation of kernels within kernels. Note that some methods provided by the Taichi standard library may invoke kernels, and please move their invocations to Python-scope." ) self.runtime.inside_kernel = True From cb19e3101d14f03fb4a2b330f3f84d069b208902 Mon Sep 17 00:00:00 2001 From: Taichi Gardener Date: Mon, 10 Aug 2020 00:04:04 -0400 Subject: [PATCH 16/18] [skip ci] enforce code format --- python/taichi/lang/kernel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/taichi/lang/kernel.py b/python/taichi/lang/kernel.py index 978d3e221a13d..7457c5141cd45 100644 --- a/python/taichi/lang/kernel.py +++ b/python/taichi/lang/kernel.py @@ -78,9 +78,9 @@ def __call__(self, *args): if not impl.inside_kernel(): if not self.pyfunc: raise TaichiSyntaxError( - "Taichi functions cannot be called from Python-scope." - " Use @ti.pyfunc if you wish to call Taichi functions " - "from both Python-scope and Taichi-scope.") + "Taichi functions cannot be called from Python-scope." + " Use @ti.pyfunc if you wish to call Taichi functions " + "from both Python-scope and Taichi-scope.") return self.func(*args) if self.compiled is None: self.do_compile() From 157a51cabb59131ccbe7d092a74e538a2f178eb4 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, 10 Aug 2020 22:51:50 +0800 Subject: [PATCH 17/18] [skip ci] Apply suggestions from code review Co-authored-by: Danni <38550500+isdanni@users.noreply.github.com> --- docs/hello.rst | 4 ++-- docs/syntax.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/hello.rst b/docs/hello.rst index b68b6ebd3773d..8ee7407161cec 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -134,7 +134,7 @@ The language used in Taichi kernels and functions looks exactly like Python, yet Everything decorated with ``@ti.kernel`` and ``@ti.func`` is in Taichi-scope and hence will be compiled by the Taichi compiler. - Everything else is in Python-scopes. They are simply Python native code. + Everything else is in Python-scope. They are simply Python native code. .. warning:: @@ -148,7 +148,7 @@ The language used in Taichi kernels and functions looks exactly like Python, yet .. warning:: **Nested kernels are not supported**. - **Nested functions are allowed**. + **Nested functions are supported**. **Recursive functions are not supported for now**. diff --git a/docs/syntax.rst b/docs/syntax.rst index c24ec8f34f0d9..584722e442a50 100644 --- a/docs/syntax.rst +++ b/docs/syntax.rst @@ -188,7 +188,7 @@ Unlike kernels, arguments in functions don't need to be type-hinted: ... -Function arguments are passed by value, changes made inside function scope +Function arguments are passed by value. So changes made inside function scope won't affect the outside value in the caller: .. code-block:: python From 4b79e5b91dc94f5bcfc171dceefc285f7ddb5735 Mon Sep 17 00:00:00 2001 From: archibate <1931127624@qq.com> Date: Tue, 11 Aug 2020 23:12:41 +0800 Subject: [PATCH 18/18] [skip ci] misc oft fix --- docs/global_settings.rst | 2 +- docs/hello.rst | 8 +++++--- python/taichi/misc/gui.py | 1 - 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/global_settings.rst b/docs/global_settings.rst index c8d2bf89820e5..e205815b08a40 100644 --- a/docs/global_settings.rst +++ b/docs/global_settings.rst @@ -46,7 +46,7 @@ Specifying ``ti.init`` arguments from environment variables Arguments for ``ti.init`` may also be specified from environment variables. For example: - ``ti.init(arch=ti.cuda)`` is equivalent to ``export TI_ARCH=cuda``. -- ``ti.init(log_level=ti.TRACE)`` is equivalent to ``export TI_ARCH=trace``. +- ``ti.init(log_level=ti.TRACE)`` is equivalent to ``export TI_LOG_LEVEL=trace``. - ``ti.init(debug=True)`` is equivalent to ``export TI_DEBUG=1``. - ``ti.init(use_unified_memory=False)`` is equivalent to ``export TI_USE_UNIFIED_MEMORY=0``. diff --git a/docs/hello.rst b/docs/hello.rst index 8ee7407161cec..c958db016bbed 100644 --- a/docs/hello.rst +++ b/docs/hello.rst @@ -147,9 +147,11 @@ The language used in Taichi kernels and functions looks exactly like Python, yet .. warning:: - **Nested kernels are not supported**. - **Nested functions are supported**. - **Recursive functions are not supported for now**. + Nested kernels are **not supported**. + + Nested functions are **supported**. + + Recursive functions are **not supported for now**. Parallel for-loops diff --git a/python/taichi/misc/gui.py b/python/taichi/misc/gui.py index b36a0132d031d..8cd638bdfc4de 100644 --- a/python/taichi/misc/gui.py +++ b/python/taichi/misc/gui.py @@ -341,7 +341,6 @@ def show(self, file=None): self.core.screenshot(file) self.frame += 1 self.clear() - self.frame += 1 ## Event system