Describe the bug
import taichi as ti
ti.init(print_ir=True)
@ti.kernel
def fill():
for i in range(1):
print(i)
fill()
Log/Screenshots
[Taichi] mode=development
[Taichi] preparing sandbox at /tmp/taichi-q5q3s29d
[Taichi] sandbox prepared
[Taichi] <dev mode>, supported archs: [cpu, cuda, opengl], commit b4b68529, python 3.6.9
[I 05/28/20 22:00:46.405] [compile_to_offloads.cpp:operator()@21] Initial IR:
kernel {
$0 : for @tmp0 in range((cast_value<int32> 0), (cast_value<int32> 1)) {
$1 = eval @tmp0
print %1
}
}
[E 05/28/20 22:00:46.405] Received signal 11 (Segmentation fault)
***********************************
* Taichi Compiler Stack Traceback *
***********************************
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::Logger::error(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::signal_handler(int)
/lib/x86_64-linux-gnu/libc.so.6(+0x3ef20) [0x7f7907462f20]
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::Block::replace_with(taichi::lang::Stmt*, taichi::lang::VecStatement&&, bool)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::LowerAST::visit(taichi::lang::FrontendEvalStmt*)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::LowerAST::visit(taichi::lang::Block*)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::LowerAST::visit(taichi::lang::RangeForStmt*)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::LowerAST::visit(taichi::lang::Block*)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::LowerAST::run(taichi::lang::IRNode*)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::irpass::compile_to_offloads(taichi::lang::IRNode*, taichi::lang::CompileConfig const&, bool, bool, bool, bool, bool)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::Kernel::lower(bool)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::Program::compile(taichi::lang::Kernel&)
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::Kernel::compile()
/tmp/taichi-q5q3s29d/taichi_core.so: taichi::lang::Kernel::operator()()
/tmp/taichi-q5q3s29d/taichi_core.so(+0x70fed4) [0x7f78eca8aed4]
/tmp/taichi-q5q3s29d/taichi_core.so(+0x66998f) [0x7f78ec9e498f]
python3.6(_PyCFunction_FastCallDict+0x154) [0x55ae1509dc54]
python3.6(_PyObject_FastCallDict+0x2bf) [0x55ae1509e06f]
python3.6(_PyObject_Call_Prepend+0x63) [0x55ae150a2aa3]
python3.6(PyObject_Call+0x3e) [0x55ae1509da5e]
python3.6(+0x16b371) [0x55ae150f7371]
python3.6(_PyObject_FastCallDict+0x8b) [0x55ae1509de3b]
python3.6(+0x199c0e) [0x55ae15125c0e]
python3.6(_PyEval_EvalFrameDefault+0x30a) [0x55ae1514875a]
python3.6(PyEval_EvalCodeEx+0x966) [0x55ae15120ff6]
python3.6(+0x1957d4) [0x55ae151217d4]
python3.6(PyObject_Call+0x3e) [0x55ae1509da5e]
python3.6(_PyEval_EvalFrameDefault+0x19e7) [0x55ae15149e37]
python3.6(+0x192e66) [0x55ae1511ee66]
python3.6(_PyFunction_FastCallDict+0x3d8) [0x55ae15120598]
python3.6(_PyObject_FastCallDict+0x26f) [0x55ae1509e01f]
python3.6(_PyObject_Call_Prepend+0x63) [0x55ae150a2aa3]
python3.6(PyObject_Call+0x3e) [0x55ae1509da5e]
python3.6(+0x16b371) [0x55ae150f7371]
python3.6(PyObject_Call+0x3e) [0x55ae1509da5e]
python3.6(_PyEval_EvalFrameDefault+0x19e7) [0x55ae15149e37]
python3.6(+0x193136) [0x55ae1511f136]
python3.6(+0x193ed6) [0x55ae1511fed6]
python3.6(+0x199b95) [0x55ae15125b95]
python3.6(_PyEval_EvalFrameDefault+0x30a) [0x55ae1514875a]
python3.6(PyEval_EvalCodeEx+0x329) [0x55ae151209b9]
python3.6(PyEval_EvalCode+0x1c) [0x55ae1512175c]
python3.6(+0x215744) [0x55ae151a1744]
python3.6(PyRun_FileExFlags+0xa1) [0x55ae151a1b41]
python3.6(PyRun_SimpleFileExFlags+0x1c3) [0x55ae151a1d43]
python3.6(Py_Main+0x613) [0x55ae151a5833]
python3.6(main+0xee) [0x55ae1506f88e]
/lib/x86_64-linux-gnu/libc.so.6: __libc_start_main
python3.6(+0x1c3160) [0x55ae1514f160]
thx, seems print(i * 1) solve the problem?
Btw, what is eval, could you give me more info about this newly added stmt?
I don't see eval if I: print(i) -> x[None] = i.
Is eval expected to be used with loop index? @xumingkuan could you tell me more about what FrontendEvalStmt is used to?
Seems the job of eval is to: convert exprs into stmts.
Thank for making this! Help us a lot.
But note that FrontendPrintStmt still takes Expr as contents, not Stmt *.
That's why we get a seg fault.
Will replace_with segf when stmts.size() == 0?
I just found something potentially dangerous.
Before #1032, there were some code assuming value->stmt is ctx->back_stmt() right after value->ctx():
https://github.com/taichi-dev/taichi/pull/1032/files#diff-545c98e4331981e92caf243d9fde4fb1L896-L897
https://github.com/taichi-dev/taichi/blob/d0b80e11c8b2b02ae31f18edeafa4ba7d90756ed/taichi/ir/ir.cpp#L896-L897
It might be the case, but since in #1032 I made value->stmt possible to be a LoopIndexStmt that is not newly created, the potential bug exposed.
Although the following code is not the same issue,
there's no sound reason for me to use new_statements.back() unless new_statements.size() == 1. Are we using new_statements.back() when new_statements.size() != 1 anywhere, and if the answer is yes, does it work as expected?