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] [cc] Doc the workflow for exporting Taichi kernels to C99 source #1756

Merged
merged 16 commits into from
Sep 3, 2020
Merged
22 changes: 11 additions & 11 deletions docs/atomic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,16 @@ Below is a list of all explicit atomic operations:

Supported atomic operations on each backend:

+----------+-----------+-----------+---------+
| type | CPU/CUDA | OpenGL | Metal |
+==========+===========+===========+=========+
| ``i32`` | OK | OK | OK |
+----------+-----------+-----------+---------+
| ``f32`` | OK | OK | OK |
+----------+-----------+-----------+---------+
| ``i64`` | OK | EXT | N/A |
+----------+-----------+-----------+---------+
| ``f64`` | OK | EXT | N/A |
+----------+-----------+-----------+---------+
+------+-----------+-----------+---------+----------+
| 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)
212 changes: 212 additions & 0 deletions docs/export_kernels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
Export Taichi kernels to C source
=================================

The C backend of Taichi allows you to **export Taichi kernels to C source**.

The exported Taichi program consists purely of C99 compatible sources and does not require Python. This allows you use the exported sources in a C/C++ project, or even call them from Javascript via Emscripten.
archibate marked this conversation as resolved.
Show resolved Hide resolved

Each C function corresponds to a Taichi kernel.
archibate marked this conversation as resolved.
Show resolved Hide resolved
For example, ``Tk_init_c6_0()`` may correspond to ``init()`` in ``mpm88.py``.

Only the exported source is needed when copying or moving around the code, all of the required Taichi runtimes are
included in that single C source file.
archibate marked this conversation as resolved.
Show resolved Hide resolved

For example, this also allows commercial users to distribute their Taichi program in
binary format by linking this file with their project.
archibate marked this conversation as resolved.
Show resolved Hide resolved

.. warning::

Currently, this feature is only officially supported on the C backend which is only released on **Linux** at this moment.
rexwangcc marked this conversation as resolved.
Show resolved Hide resolved
archibate marked this conversation as resolved.
Show resolved Hide resolved


The workflow of exporting
-------------------------

Use ``ti.core.start_recording`` in the Taichi program you want to export.

Suppose you want to export `examples/mpm88.py <https://github.com/taichi-dev/taichi/blob/master/examples/mpm88.py>`_, here is the workflow:

Export YAML
+++++++++++

First, modify ``mpm88.py`` as shown below:

.. code-block:: python

import taichi as ti

ti.core.start_recording('mpm88.yml')
ti.init(arch=ti.cc)

... # your program

And run it. Close the GUI window once particles are shown up correctly.
archibate marked this conversation as resolved.
Show resolved Hide resolved

This will save all the kernels in ``mpm88.py`` to ``mpm88.yml``:

.. code-block:: yaml

- action: "compile_kernel"
kernel_name: "init_c6_0"
kernel_source: "void Tk_init_c6_0(struct Ti_Context *ti_ctx) {\n for (Ti_i32 tmp0 = 0; tmp0 < 8192...\n"
- action: "launch_kernel"
kernel_name: "init_c6_0"
...

.. note::

Equivalently, you may also specify these two arguments from environment
variables on Unix-like system:

.. code-block:: bash

TI_ARCH=cc TI_ACTION_RECORD=mpm88.yml python mpm88.py

Compose YAML into a single C file
+++++++++++++++++++++++++++++++++

Now all necessary information is saved in ``mpm88.yml``. However, the ``kernel_source``'s are separated one-by-one.
archibate marked this conversation as resolved.
Show resolved Hide resolved
You may want to **compose** the separate kernels into **one single file** in order to distribute it more easily.
archibate marked this conversation as resolved.
Show resolved Hide resolved

We provide a useful tool to do this, type these commands in your console:
archibate marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: bash

python3 -m taichi cc_compose mpm88.yml mpm88.c mpm88.h

This composes all the kernels and runtimes in ``mpm88.yml`` into a single C
source file ``mpm88.c``:

.. code-block:: c

...

Ti_i8 Ti_gtmp[1048576];
union Ti_BitCast Ti_args[8];
Ti_i32 Ti_earg[8 * 8];

struct Ti_Context Ti_ctx = { // statically-allocated context for convenience!
&Ti_root, Ti_gtmp, Ti_args, Ti_earg,
};

void Tk_init_c6_0(struct Ti_Context *ti_ctx) {
for (Ti_i32 tmp0 = 0; tmp0 < 8192; tmp0 += 1) {
Ti_i32 tmp1 = tmp0;
Ti_f32 tmp2 = Ti_rand_f32();
Ti_f32 tmp3 = Ti_rand_f32();
Ti_f32 tmp4 = 0.4;
Ti_f32 tmp5 = tmp2 * tmp4;

...

And a C header file ``mpm88.h`` for declarations of data structures, functions
(kernels) for this file.
archibate marked this conversation as resolved.
Show resolved Hide resolved

.. note::

The generated C source is promised to be C99 compatible.

It should also be functional when being compiled as C++.
archibate marked this conversation as resolved.
Show resolved Hide resolved


Calling the exported kernels
----------------------------

Then, link this file (``mpm88.c``) together with your C/C++ project.
Include the header (``mpm88.h``) to where kernels are to be called.
archibate marked this conversation as resolved.
Show resolved Hide resolved

To call the kernel ``init_c6_0``, for example:
archibate marked this conversation as resolved.
Show resolved Hide resolved

.. code-block:: cpp

#include "mpm88.h"

int main(void) {
...
Tk_init_c6_0(&Ti_ctx);
...
}


Alternatively, if you need multiple Taichi contexts within one program:

.. code-block:: cpp

extern "C" { // if you use mpm88.c instead of renaming it to mpm88.cpp
#include "mpm88.h"
}

class MyRenderer {
...
struct Ti_Context per_renderer_taichi_context;
...
};

MyRenderer::MyRenderer() {
// allocate buffers on your own:
per_renderer_taichi_context.root = malloc(...);
...
Tk_init_c6_0(&per_renderer_taichi_context);
}


Specifying scalar arguments
+++++++++++++++++++++++++++

To specify scalar arguments for kernels:

.. code-block:: cpp

Ti_ctx.args[0].val_f64 = 3.14; // first argument, float64
Ti_ctx.args[1].val_i32 = 233; // second argument, int32
Tk_my_kernel_c8_0(&Ti_ctx);
double ret = Ti_ctx.args[0].val_f64; // return value, float64

printf("my_kernel(3.14, 233) = %lf\n", ret);

Passing external arrays
+++++++++++++++++++++++

To pass external arrays as arguments for kernels:

.. code-block:: cpp

float img[640 * 480 * 3];

Ti_ctx.args[0].ptr_f32 = img; // first argument, float32 pointer to array

// specify the shape of that array:
Ti_ctx.earg[0 * 8 + 0] = 640; // img.shape[0]
Ti_ctx.earg[0 * 8 + 1] = 480; // img.shape[1]
Ti_ctx.earg[0 * 8 + 2] = 3; // img.shape[2]
Tk_matrix_to_ext_arr_c12_0(&Ti_ctx);

// note that the array used in Taichi is row-major:
printf("img[3, 2, 1] = %f\n", img[(3 * 480 + 2) * 3 + 1]);

Taichi.js (WIP)
---------------

Once you have C source generated, you can compile the C source into Javascript
archibate marked this conversation as resolved.
Show resolved Hide resolved
or WASM via Emscripten.

We provide `Taichi.js <https://github.com/taichi-dev/taichi.js>`_ as an
infrastructure for wrapping Taichi kernels for Javascript.
See `its README.md <https://github.com/taichi-dev/taichi.js/blob/master/README.md>`_ for the complete workflow.

Check `this page <https://taichi-dev.github.io/taichi.js>`_ for online demo.
archibate marked this conversation as resolved.
Show resolved Hide resolved

Calling Taichi kernels from Julia (WIP)
---------------------------------------

Once you have C source generated, you can then compile the C source into a
shared object. Then it can be called from other langurages that provides a C
interface, including but not limited to Julia, Matlab, Mathematica, Java, etc.

TODO: WIP.

The export workflow for Metal shaders (WIP)
-------------------------------------------

Actually we also support exporting / dumping Metal shaders for the Apple Metal
backend via the shared API as C backend does. Documentation WIP.
archibate marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 9 additions & 9 deletions docs/hello.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,15 @@ Taichi programs run on either CPUs or GPUs. Initialize Taichi according to your

Supported backends on different platforms:

+----------+------+------+--------+-------+
| platform | CPU | CUDA | OpenGL | Metal |
+==========+======+======+========+=======+
| Windows | OK | OK | OK | N/A |
+----------+------+------+--------+-------+
| Linux | OK | OK | OK | N/A |
+----------+------+------+--------+-------+
| Mac OS X | OK | N/A | N/A | OK |
+----------+------+------+--------+-------+
+----------+------+------+--------+-------+----------+
| platform | CPU | CUDA | OpenGL | Metal | C source |
+==========+======+======+========+=======+==========+
| Windows | OK | OK | OK | N/A | N/A |
+----------+------+------+--------+-------+----------+
| Linux | OK | OK | OK | N/A | OK |
+----------+------+------+--------+-------+----------+
| Mac OS X | OK | N/A | N/A | OK | N/A |
+----------+------+------+--------+-------+----------+

(OK: supported; N/A: not available)

Expand Down
3 changes: 2 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ The Taichi Programming Language
faq
gui
debugging
extension_libraries
export_results
cli_utilities
global_settings
export_kernels
extension_libraries
acknowledgments


Expand Down
18 changes: 18 additions & 0 deletions docs/snode.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ Taichi provides *Structural Nodes (SNodes)* to compose the hierarchy and particu

* dynamic: Variable-length array, with a predefined maximum length. It serves the role of ``std::vector`` in C++ or ``list`` in Python, and can be used to maintain objects (e.g. particles) contained in a block.

.. note::

Supported SNode types on each backend:

+-----------+----------+--------+-------+----------+
| SNode | CPU/CUDA | OpenGL | Metal | C source |
+===========+==========+========+=======+==========+
| dense | OK | OK | OK | OK |
+-----------+----------+--------+-------+----------+
| bitmasked | OK | N/A | OK | N/A |
+-----------+----------+--------+-------+----------+
| pointer | OK | N/A | N/A | N/A |
+-----------+----------+--------+-------+----------+
| dynamic | OK | PAR | N/A | N/A |
+-----------+----------+--------+-------+----------+

(OK: supported; PAR: partial support; N/A: not available)


See :ref:`layout` for more details. ``ti.root`` is the root node of the data structure.

Expand Down
47 changes: 24 additions & 23 deletions docs/type.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,32 @@ Currently, supported basic types in Taichi are
- float64 ``ti.f64``

.. note::

Supported types on each backend:

+------+-----------+-----------+---------+
| type | CPU/CUDA | OpenGL | Metal |
+======+===========+===========+=========+
| i8 | OK | N/A | OK |
+------+-----------+-----------+---------+
| i16 | OK | N/A | OK |
+------+-----------+-----------+---------+
| i32 | OK | OK | OK |
+------+-----------+-----------+---------+
| i64 | OK | EXT | N/A |
+------+-----------+-----------+---------+
| u8 | OK | N/A | OK |
+------+-----------+-----------+---------+
| u16 | OK | N/A | OK |
+------+-----------+-----------+---------+
| u32 | OK | N/A | OK |
+------+-----------+-----------+---------+
| u64 | OK | N/A | N/A |
+------+-----------+-----------+---------+
| f32 | OK | OK | OK |
+------+-----------+-----------+---------+
| f64 | OK | OK | N/A |
+------+-----------+-----------+---------+
+------+-----------+-----------+---------+----------+
| type | CPU/CUDA | OpenGL | Metal | C source |
+======+===========+===========+=========+==========+
| i8 | OK | N/A | OK | OK |
+------+-----------+-----------+---------+----------+
| i16 | OK | N/A | OK | OK |
+------+-----------+-----------+---------+----------+
| i32 | OK | OK | OK | OK |
+------+-----------+-----------+---------+----------+
| i64 | OK | EXT | N/A | OK |
+------+-----------+-----------+---------+----------+
| u8 | OK | N/A | OK | OK |
+------+-----------+-----------+---------+----------+
| u16 | OK | N/A | OK | OK |
+------+-----------+-----------+---------+----------+
| u32 | OK | N/A | OK | OK |
+------+-----------+-----------+---------+----------+
| u64 | OK | N/A | N/A | OK |
+------+-----------+-----------+---------+----------+
| f32 | OK | OK | OK | OK |
+------+-----------+-----------+---------+----------+
| f64 | OK | OK | N/A | OK |
+------+-----------+-----------+---------+----------+

(OK: supported, EXT: require extension, N/A: not available)

Expand Down
Loading