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] Add .md documentation #2494

Merged
merged 2 commits into from
Jul 6, 2021
Merged
Show file tree
Hide file tree
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
195 changes: 195 additions & 0 deletions docs/lang/api/arithmetics.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
---
sidebar_position: 4
---

# Scalar operations

## Operators

### Arithmetic operators

| Operation | Result |
| :-------------- | :-------------------------------|
| `-a` | `a`negated |
| `+a` | `a`unchanged |
| `a + b` | sum of `a` and `b` |
| `a - b` | difference of `a` and `b` |
| `a * b` | product of `a` and `b` |
| `a / b` | quotient of `a` and `b` |
| `a // b` | floored quotient of `a` and `b`|
| `a % b` | remainder of `a` / `b` |
| `a ** b` | `a` to the power `b` |

:::note

The `%` operator in Taichi follows the Python style instead of C style,
e.g.,

```python
# In Taichi-scope or Python-scope:
print(2 % 3) # 2
print(-2 % 3) # 1
```

For C-style mod (`%`), please use `ti.raw_mod`:

```python
print(ti.raw_mod(2, 3)) # 2
print(ti.raw_mod(-2, 3)) # -2
```

:::

:::note

Python 3 distinguishes `/` (true division) and `//` (floor division).
For example, `1.0 / 2.0 = 0.5`, `1 / 2 = 0.5`, `1 // 2 = 0`,
`4.2 // 2 = 2`. And Taichi follows the same design:

- **true divisions** on integral types will first cast their
operands to the default float point type.
- **floor divisions** on float-point types will first cast their
operands to the default integer type.

To avoid such implicit casting, you can manually cast your operands to
desired types, using `ti.cast`. Please see
[Default precisions](../articles/basic/type.md#default-precisions) for more details on
default numerical types.
:::

### Logic operators

| Operation | Result |
| :--------------- | :----------- ----------------------------------------|
| `a == b` | if `a` equal `b`, then True, else False |
| `a != b` | if `a` not equal `b`, then True, else False |
| `a > b` | if `a` strictly greater than `b`, then True, else False |
| `a < b` | if `a` strictly less than `b`, then True, else False |
| `a >= b` | if `a` greater than or equal `b`, then True, else False |
| `a <= b` | if `a` less than or equal `b`, then True, else False |
| `not a` | if `a` is False, then True, else False |
| `a or b` | if `a` is False, then `b`, else `a` |
| `a and b` | if `a` is False, then `a`, else `b` |
| `a if cond else b`| if `cond` is True, then `a`, else `b` |

### Bitwise operators
| Operation | Result |
| :--------------- | :----------- ----------------------------------------|
| `~a` | the bits of `a` inverted |
| `a & b`| bitwise and of `a` and `b` |
| `a ^ b`| bitwise exclusive or of `a` and `b` |
| `a \| b`| bitwise or of `a` and `b` |


## Functions

### Trigonometric functions

```python
ti.sin(x)

ti.cos(x)

ti.tan(x)

ti.asin(x)

ti.acos(x)

ti.atan2(x, y)

ti.tanh(x)
```

### Other arithmetic functions

```python
ti.sqrt(x)

ti.rsqrt(x) # A fast version for `1 / ti.sqrt(x)`.

ti.exp(x)

ti.log(x)

ti.floor(x)

ti.ceil(x)
```

### Casting types

```python
ti.cast(x, dtype)
```

See [Type system](../articles/basic/type.md#type-system) for more details.

```python
int(x)
```

A shortcut for `ti.cast(x, int)`.

```python
float(x)
```

A shortcut for `ti.cast(x, float)`.

### Builtin-alike functions

```python
abs(x)

max(x, y, \...)

min(x, y, \...)

pow(x, y) # Same as `x ** y`.
```

### Random number generator

```python
ti.random(dtype = float)
```

## Element-wise arithmetics for vectors and matrices

When these scalar functions are applied on [Matrices](./matrix.md) and [Vectors](./vector.md), they are applied in an element-wise manner. For example:

```python
B = ti.Matrix([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
C = ti.Matrix([[3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])

A = ti.sin(B)
# is equivalent to
for i in ti.static(range(2)):
for j in ti.static(range(3)):
A[i, j] = ti.sin(B[i, j])

A = B ** 2
# is equivalent to
for i in ti.static(range(2)):
for j in ti.static(range(3)):
A[i, j] = B[i, j] ** 2

A = B ** C
# is equivalent to
for i in ti.static(range(2)):
for j in ti.static(range(3)):
A[i, j] = B[i, j] ** C[i, j]

A += 2
# is equivalent to
for i in ti.static(range(2)):
for j in ti.static(range(3)):
A[i, j] += 2

A += B
# is equivalent to
for i in ti.static(range(2)):
for j in ti.static(range(3)):
A[i, j] += B[i, j]
```
94 changes: 94 additions & 0 deletions docs/lang/api/atomic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
sidebar_position: 5
---

# Atomic operations

In Taichi, augmented assignments (e.g., `x[i] += 1`) are automatically
[atomic](https://en.wikipedia.org/wiki/Fetch-and-add).

:::caution

When modifying global variables in parallel, make sure you use atomic
operations. For example, to sum up all the elements in `x`, :

@ti.kernel
def sum():
for i in x:
# Approach 1: OK
total[None] += x[i]

# Approach 2: OK
ti.atomic_add(total[None], x[i])

# Approach 3: Wrong result since the operation is not atomic.
total[None] = total[None] + x[i]

:::

:::note

When atomic operations are applied to local values, the Taichi compiler
will try to demote these operations into their non-atomic counterparts.
:::

Apart from the augmented assignments, explicit atomic operations, such
as `ti.atomic_add`, also do read-modify-write atomically. These
operations additionally return the **old value** of the first argument.

Below is a list of all explicit atomic operations:

::: {.function}
ti.atomic_add(x, y)
:::

::: {.function}
ti.atomic_sub(x, y)

Atomically compute `x + y` or `x - y` and store the result in `x`.

return

: The old value of `x`.

For example, :

x[i] = 3
y[i] = 4
z[i] = ti.atomic_add(x[i], y[i])
# now x[i] = 7, y[i] = 4, z[i] = 3

:::

::: {.function}
ti.atomic_and(x, y)
:::

::: {.function}
ti.atomic_or(x, y)
:::

::: {.function}
ti.atomic_xor(x, y)

Atomically compute `x & y` (bitwise and), `x | y` (bitwise or), or
`x ^ y` (bitwise xor), and store the result in `x`.

return

: The old value of `x`.
:::

:::note

Supported atomic operations on each backend:

| type | CPU/CUDA | OpenGL | Metal | C source |
| ---- | -------- | ------ | ----- | -------- |
| i32 | > OK | > OK | > OK | > OK |
| f32 | > OK | > OK | > OK | > OK |
| i64 | > OK | > EXT | > N/A | > OK |
| f64 | > OK | > EXT | > N/A | > OK |

(OK: supported; EXT: require extension; N/A: not available)
:::
10 changes: 10 additions & 0 deletions docs/lang/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
sidebar_position: 1
---

# API Docs

:::danger WIP Notice
Sorry for the inconvenience, the Taichi API docs are under construction and not in
a stable state yet!
:::
Loading