Skip to content

Commit

Permalink
well doc merge
Browse files Browse the repository at this point in the history
  • Loading branch information
archibate committed Jun 27, 2020
2 parents 809a7d2 + 22dc529 commit 6590d0f
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 2 deletions.
84 changes: 84 additions & 0 deletions docs/debugging.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,87 @@ For example:
def is_odd(x: ti.template()):
ti.static_assert(x.data_type() == ti.i32, "is_odd() is only supported for i32")
return x % 2 == 1
Tips for debugging
------------------

Debugging a Taichi program can be hard even with the builtin tools above.
Taichi developers are currently devoting themselves in improving error messages and warnings
to help user find potential BUGs in their programs.

Here we collected some common BUGs that one might encounter with a Taichi program:

Static typing system
++++++++++++++++++++

Taichi pertend that it's a dynamical-typed language like Python, but it's actually a
statically-typed language which will be translated into high performance CPU/GPU instructions.

So the code behavior in Taichi-scope is actually very different from Python-scope!

Type of a variable is simply **determined at its first initialization and never changes later**.

Although static-type provides better performance and simplicity, but may leads to BUGs if
users not distinguished Taichi-scope from Python-scope, e.g.:

.. code-block:: python
@ti.kernel
def buggy():
ret = 0 # 0 is a integer, so `ret` is typed as int32
for i in range(3):
ret += 0.1 * i # i32 += f32, the result is still stored in int32!
print(ret) # will shows 0
buggy()
The codes above shows a common BUG due to the limitation of the static-type system.
The Taichi compiler should shows a warning like:

.. code-block:: none
[W 06/27/20 21:43:51.853] [type_check.cpp:visit@66] [$19] Atomic add (float32 to int32) may lose precision.
This means that it can not store a float32 result to int32.
The solution is to type ``ret`` as float32 at the first place:

.. code-block:: python
@ti.kernel
def not_buggy():
ret = 0.0 # 0 is a floating point number, so `ret` is typed as float32
for i in range(3):
ret += 0.1 * i # f32 += f32, OK!!
print(ret) # will shows 0.6
not_buggy()
`@archibate <https://github.com/archibate>`_'s personal suggestion to prevent issues like this:

* Recall the ``float ret = 0;`` in C/C++, always use ``ret = float(0)`` on **initialization**,
and ``ret = int(0)`` for integers. So that you are always clear of what type every variable.

Advanced Optimization
+++++++++++++++++++++

Taichi has a advanced optimization engine to make your Taichi kernel to be as fast as it could.
But like the ``gcc -O3`` does, sometimes advanced optimization can leads to BUGs as it tried
too hard, including runtime errors like:

```RuntimeError: [verify.cpp:basic_verify@40] stmt 8 cannot have operand 7.```

You may use ``ti.core.toggle_advance_optimization(False)`` to turn off advanced
optimization and see if the issue still exists:

.. code-block:: python
import taichi as ti
ti.init()
ti.core.toggle_advance_optimization()
...
If that fixed the issue, please report this BUG on `GitHub <https://github.com/taichi-dev/taichi/issues/new?labels=potential+bug&template=bug_report.md>`_ to help us improve, if you would like to.
2 changes: 1 addition & 1 deletion python/taichi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from taichi.misc import *
from taichi.misc.gui import GUI
from taichi.misc.np2ply import PLYWriter
from taichi.misc.image import imread, imwrite, imshow
from taichi.misc.image import *
from taichi.misc.task import Task
from taichi.misc.test import *
from taichi.misc import settings as settings
Expand Down
3 changes: 3 additions & 0 deletions python/taichi/lang/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ def get_tape(self, loss=None):
def sync(self):
self.materialize()
self.prog.synchronize()
# print's in kernel won't take effect until ti.sync(), discussion:
# https://github.com/taichi-dev/taichi/pull/1303#discussion_r444897102
print(taichi_lang_core.pop_python_print_buffer(), end='')


pytaichi = PyTaichi()
Expand Down
3 changes: 2 additions & 1 deletion taichi/backends/opengl/opengl_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "taichi/program/kernel.h"
#include "taichi/program/program.h"
#include "taichi/util/environ_config.h"
#include "taichi/python/print_buffer.h"
#include "taichi/backends/opengl/runtime.h"

#ifdef TI_WITH_OPENGL
Expand Down Expand Up @@ -487,7 +488,7 @@ struct CompiledProgram::Impl {
TI_WARN("[glsl] Unexpected serialization type: {}, ignoring", type);
break;
};
std::cout << str;
py_cout << str;
}
}
rt_buf->msg_count = 0;
Expand Down
6 changes: 6 additions & 0 deletions taichi/python/export_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "taichi/common/task.h"
#include "taichi/math/math.h"
#include "taichi/python/exception.h"
#include "taichi/python/print_buffer.h"
#include "taichi/python/export.h"
#include "taichi/system/benchmark.h"
#include "taichi/system/profiler.h"
Expand All @@ -20,6 +21,8 @@

TI_NAMESPACE_BEGIN

PythonPrintBuffer py_cout;

Config config_from_py_dict(py::dict &c) {
Config config;
for (auto item : c) {
Expand Down Expand Up @@ -153,6 +156,9 @@ void export_misc(py::module &m) {
}
printf("test was successful.\n");
});
m.def("pop_python_print_buffer", []() {
return py_cout.pop_content();
});
m.def("with_cuda", is_cuda_api_available);
m.def("with_metal", taichi::lang::metal::is_metal_api_available);
m.def("with_opengl", taichi::lang::opengl::is_opengl_api_available);
Expand Down
25 changes: 25 additions & 0 deletions taichi/python/print_buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <sstream>

TI_NAMESPACE_BEGIN

struct PythonPrintBuffer {
/* holds kernel print result before switching back to python */
std::stringstream ss;

template <typename T>
PythonPrintBuffer &operator<<(const T &t) {
ss << t;
return *this;
}
std::string pop_content() {
auto ret = ss.str();
ss = std::stringstream();
return ret;
}
};

extern PythonPrintBuffer py_cout;

TI_NAMESPACE_END

0 comments on commit 6590d0f

Please sign in to comment.