Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doc] Improve type.rst readability #1618

Merged
merged 5 commits into from
Aug 2, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 124 additions & 22 deletions docs/type.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,33 @@
Type system
===========

Taichi supports common numerical data types. Each type is denoted as
a character indicating its *category* and a number of *precision bits*, e.g., ``i32`` and ``f64``.

The *category* 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``
Expand Down Expand Up @@ -46,54 +71,131 @@ 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::

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.

- ``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 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.


.. _default_precisions:

Default precisions
------------------

By default, numerical literals have 32-bit precisions.
By default, all 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

ti.init(..., default_fp=ti.f32)
ti.init(..., default_fp=ti.f64)
ti.init(default_fp=ti.f32)
ti.init(default_fp=ti.f64)

ti.init(default_ip=ti.i32)
ti.init(default_ip=ti.i64)


Also note that you may use ``float`` or ``int`` in type definitions as aliases
for default precisions, e.g.:

.. code-block:: python

ti.init(default_ip=ti.i64, default_fp=ti.f32)

x = ti.var(float, 5)
y = ti.var(int, 5)
# is equivalent to:
x = ti.var(ti.f32, 5)
y = ti.var(ti.i64, 5)
yuanming-hu marked this conversation as resolved.
Show resolved Hide resolved

def func(a: float) -> int:
...

# is equivalent to:
def func(a: ti.f32) -> ti.i64:
...

ti.init(..., default_ip=ti.i32)
ti.init(..., default_ip=ti.i64)


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 *low-precision* variable is assigned to a *high-precision* variable, it will be
implicitly promoted to the *wide* type and no warning will be raised:

.. code-block:: python

a = 1.7
a = 1
print(a) # 1.0

When a *high-precision* variable is assigned to a *low-precision* type, it will be
implicitly down-cast into the *low-precision* type and Taichi will raise a warning:

.. code-block:: python

a = 1.4
b = ti.cast(a, ti.i32)
c = ti.cast(b, ti.f32)
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

# Equivalently, use ``int()`` and ``float()``
# to convert values to default float-point/integer types
b = int(a)
c = float(b)
a = 1.7
b = ti.cast(a, ti.i32) # 1
c = ti.cast(b, ti.f32) # 1.0

# 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)
Equivalently, use ``int()`` and ``float()`` to convert values to float-point or
integer types of default precisions:

.. code-block:: python

a = 1.7
b = int(a) # 1
c = float(a) # 1.0

Casting vectors and matrices
****************************

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])
# If you are using ti.i32 as default_ip, this is equivalent to:
v = ti.cast(u, ti.i32) # 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.
archibate marked this conversation as resolved.
Show resolved Hide resolved
archibate marked this conversation as resolved.
Show resolved Hide resolved
For example, bit-casting ``i32`` to ``f64`` is not allowed. Use this operation with caution.
yuanming-hu marked this conversation as resolved.
Show resolved Hide resolved

.. code-block::

For people from C++, ``ti.bit_cast`` is equivalent to ``reinterpret_cast``.