cornell-zhang/heterocl

Unable to parse complex hcl.select for different codegens

Closed this issue · 3 comments

test_select.zip

HCL fails to generate code for complex hcl.select conditions such as the below one for vhls, ihls, and aocl backend.

src = hcl.select(use_imm == 1, hcl.cast(hcl.Int(16), (c[i] + b[i])), 
                                           hcl.cast(hcl.Int(32), (c[i] - b[i]))
                                           )
d[i] = hcl.select(dst >= (-1 * src),
                    hcl.select(dst <= src, a[i], src),
                    (-1 * src))

The error message is below

Traceback (most recent call last):
  File "test_select.py", line 26, in <module>
    f = top()
  File "test_select.py", line 24, in top
    return hcl.build(s, target="vhls")
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/api.py", line 337, in build
    return _build(schedule.sch, new_inputs, target=target, name=name, stmt=stmt, schedule_name=schedule.name)
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/tvm/build_module.py", line 577, in build
    return build_fpga_kernel(sch, args, target.target_name, name=name, schedule_name=schedule_name)
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/tvm/build_module.py", line 436, in build_fpga_kernel
    ret = builder(fdevice)
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/tvm/_ffi/function.py", line 280, in my_api_func
    return flocal(*args)
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/tvm/_ffi/_ctypes/function.py", line 183, in __call__
    ctypes.byref(ret_val), ctypes.byref(ret_tcode)))
  File "/home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/heterocl/tvm/_ffi/base.py", line 66, in check_call
    raise TVMError(py_str(_LIB.TVMGetLastError()))
heterocl.tvm._ffi.base.TVMError: [21:51:53] src/codegen/codegen_c.cc:49: unknown type of select((select((scalar0[0] == 1), int32(int16((int33(c[i]) + int33(b[i])))), int32((int33(c[i]) - int33(b[i])))) < int32(((int33(c[i]) + int33(b[i]))*(int33)2))), select((scalar0[0] == 1), int32(int16((int33(c[i]) + int33(b[i])))), int32((int33(c[i]) - int33(b[i])))), a[i])
Stack trace returned 10 entries:
[bt] (0) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(dmlc::StackTrace()+0x3c) [0x7f291980e31c]
[bt] (1) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(dmlc::LogMessageFatal::~LogMessageFatal()+0x18) [0x7f291980e668]
[bt] (2) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::ExtractDType(Halide::Expr, bool&)+0x3fa) [0x7f2919a2ae5a]
[bt] (3) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::CodeGenC::VisitExpr_(Halide::Internal::Select const*, std::ostream&)+0xee) [0x7f2919a3184e]
[bt] (4) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::IRFunctor<void (TVM::NodeRef const&, TVM::ir::ExprFunctor<void (Halide::Expr const&, std::ostream&)>*, std::ostream&)>::operator()(TVM::NodeRef const&, TVM::ir::ExprFunctor<void (Halide::Expr const&, std::ostream&)>*, std::ostream&) const+0x69) [0x7f2919a0e859]
[bt] (5) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::CodeGenC::PrintExpr(Halide::Expr const&, std::ostream&)+0x2ce) [0x7f2919a2c97e]
[bt] (6) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::CodeGenC::PrintExpr(Halide::Expr const&)+0x15a) [0x7f2919a39eba]
[bt] (7) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::CodeGenC::VisitStmt_(Halide::Internal::Store const*)+0x494) [0x7f2919a327b4]
[bt] (8) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::codegen::CodeGenVivadoHLS::VisitStmt_(Halide::Internal::Store const*)+0x763) [0x7f2919a93bb3]
[bt] (9) /home/dp638/.local/lib/python3.7/site-packages/heterocl-0.3-py3.7.egg/lib/libhcl.so(TVM::IRFunctor<void (TVM::NodeRef const&, TVM::ir::StmtFunctor<void (Halide::Internal::Stmt const&)>*)>::operator()(TVM::NodeRef const&, TVM::ir::StmtFunctor<void (Halide::Internal::Stmt const&)>*) const+0x60) [0x7f2919a08da0]

However when hcl.select is refactored via hcl.if_/hcl.elif_ such as below it works

with hcl.if_(use_imm == 1):
                src = hcl.cast(hcl.Int(16), (c[i] + b[i]))
            with hcl.else_():
                src = hcl.cast(hcl.Int(32), (c[i] - b[i]))

            dst = hcl.cast(hcl.Int(32), (2 * (c[i] + b[i])))
with hcl.if_(dst >= (-1 * src)):
                with hcl.if_(dst <= src):
                    d[i] = a[i]
                with hcl.else_():
                    d[i] = src
            with hcl.else_():
                d[i] = (-1 * src)

However, it increases the work on the part of the designer.

How to reproduce: Just uncomment the commented codes in the attached Python file (inside the zip) and run python test_select.py. The file has all necessary print statements.

@zzzDavid you will fix this in your PR, right?

Yes, I added support for nested hcl.select conditions in my PR (SystemC backend). I'll add tests for such cases

Will be solved with #375