开发者工具

This section provides a detailed description of some commonly used utilities for Taichi developers.

日志

Taichi uses spdlog as its logging system. Logs can have different levels, from low to high, they are:

trace
debug
info
warn
error

The higher the level is, the more critical the message is.

The default logging level is info. You may override the default logging level by:

  1. Setting the environment variable like export TI_LOG_LEVEL=warn.
  2. Setting the log level from Python side: ti.set_logging_level(ti.WARN).

In Python, you may write logs using the ti.* interface:

# Python
ti.trace("Hello world!")
ti.debug("Hello world!")
ti.info("Hello world!")
ti.warn("Hello world!")
ti.error("Hello world!")

In C++, you may write logs using the TI_* interface:

// C++
TI_TRACE("Hello world!");
TI_DEBUG("Hello world!");
TI_INFO("Hello world!");
TI_WARN("Hello world!");
TI_ERROR("Hello world!");

If one raises a message of the level error, Taichi will be terminated immediately and result in a RuntimeError on Python side.

int func(void *p) {
  if (p == nullptr)
    TI_ERROR("The pointer cannot be null!");

  // will not reach here if p == nullptr
  do_something(p);
}

注解

For people from Linux kernels, TI_ERROR is just panic.

You may also simplify the above code by using TI_ASSERT:

int func(void *p) {
  TI_ASSERT_INFO(p != nullptr, "The pointer cannot be null!");
  // or
  // TI_ASSERT(p != nullptr);

  // will not reach here if p == nullptr
  do_something(p);
}

基准测试和回归测试

  • 运行 ti benchmark 以基准模式运行测试。 这将记录 ti test 的性能,并将其保存在 benchmarks/output 中。
  • Run ti regression to show the difference between the previous result in benchmarks/baseline. And you can see if the performance is increasing or decreasing after your commits. This is really helpful when your work is related to IR optimizations.
  • Run ti baseline to save the benchmark result to benchmarks/baseline for future comparison, this may be executed on performance-related PRs, before they are merged into master.

例如,这是启用常数折叠优化传递后 ti regression 输出的一部分:

linalg__________________polar_decomp______________________________
codegen_offloaded_tasks                       37 ->    39    +5.4%
codegen_statements                          3179 ->  3162    -0.5%
codegen_kernel_statements                   2819 ->  2788    -1.1%
codegen_evaluator_statements                   0 ->    14    +inf%

linalg__________________init_matrix_from_vectors__________________
codegen_offloaded_tasks                       37 ->    39    +5.4%
codegen_statements                          3180 ->  3163    -0.5%
codegen_kernel_statements                   2820 ->  2789    -1.1%
codegen_evaluator_statements                   0 ->    14    +inf%

注解

Currently ti benchmark only supports benchmarking number-of-statements, no time benchmarking is included since it depends on hardware performance and therefore hard to compare if the baseline is from another machine. We are to purchase a fixed-performance machine as a time benchmark server at some point. Discussion at: https://github.com/taichi-dev/taichi/issue/948

The suggested workflow for the performance-related PR author to run the regression tests is:

  • Run ti benchmark && ti baseline in master to save the current performance as a baseline.
  • 运行 git checkout -b your-branch-name (分支名称).
  • 尝试解决问题(第一阶段)。
  • 运行 ti benchmark && ti regression 获取结果。
  • (结果不理想)继续优化直至结果理想。
  • (If result OK) Run ti baseline to save stage 1 performance as a baseline.
  • 继续进行第二,第三阶段,同时以上的工作流程也同样适用。

程序崩溃时触发GDB(仅限于Linux操作系统)

# Python
ti.set_gdb_trigger(True)

// C++
CoreState::set_trigger_gdb_when_crash(true);

# Shell
export TI_GDB_TRIGGER=1

注解

使用 gdb 快速定位段错误 (segmentation fault) 和断言错误 (assertion failure): 在Taichi 崩溃时,gdb 会被触发并附着到当前的线程上。您可能需要输入和 sudo 超级用户权限相关的密码来允许 gdb 附着到当前的线程上。再输入 gdb 之后, 您可以使用 btbacktrace)指令检查堆的回溯,从而定位产生错误的代码的具体行数。

Code coverage

To ensure that our tests covered every situation, we need to have coverage report. That is, to detect how many percents of code lines in is executed in test.

  • Generally, the higher the coverage percentage is, the stronger our tests are.
  • When making a PR, we want to ensure that it comes with corresponding tests. Or code coverage will decrease.
  • Code coverage statuses are visible at Codecov.
  • Currently, Taichi is only set up for Python code coverage report, not for C++ yet.
ti test -C       # run tests and save results to .coverage
coverage report  # generate a coverage report on terminal output
coverage html    # generate a HTML form report in htmlcov/index.html

接口系统(遗留)

打印所有接口和单位

ti.core.print_all_units()

序列化(遗留)

Taichi的序列化模块可以允许你将对象序列化/反序列化成二进制字符串。

You can use TI_IO macros to explicitly define fields necessary in Taichi.

// TI_IO_DEF
struct Particle {
    Vector3f position, velocity;
    real mass;
    string name;

    TI_IO_DEF(position, velocity, mass, name);
}

// TI_IO_DECL
struct Particle {
    Vector3f position, velocity;
    real mass;
    bool has_name
    string name;

    TI_IO_DECL() {
        TI_IO(position);
        TI_IO(velocity);
        TI_IO(mass);
        TI_IO(has_name);
        // More flexibility:
        if (has_name) {
            TI_IO(name);
        }
    }
}

// TI_IO_DEF_VIRT();

进展通知(遗留)

当任务完成或崩溃时,taichi消息传递程序可以将邮件发送到 $TI_MONITOR_EMAIL 。 要启用的话:

from taichi.tools import messenger
messenger.enable(task_id='test')