cornell-zhang / heterocl

HeteroCL: A Multi-Paradigm Programming Infrastructure for Software-Defined Heterogeneous Computing
https://cornell-zhang.github.io/heterocl/
Apache License 2.0
326 stars 92 forks source link

Bitwise operation causes "unknown intrinsic reinterpret" error #211

Open chhzh123 opened 4 years ago

chhzh123 commented 4 years ago

The following code that performs bitwise AND sequentially causes an "unknown intrinsic reinterpret" error.

A = hcl.placeholder((3,), dtype=hcl.UInt(2), name="A")
out = hcl.compute((3,),
    lambda i: A[i] & 1 & 2,
    dtype=hcl.UInt(2))
s = hcl.create_schedule([A, out])
f = hcl.build(s)
hcl_a = hcl.asarray(np.array([0, 1, 2]), dtype=hcl.UInt(2))
hcl_out = hcl.asarray(np.array([0, 0, 0]), dtype=hcl.UInt(2))
f(hcl_a, hcl_out)
print("Input : {}".format(hcl_a.asnumpy()))
print("Output : {}".format(hcl_out.asnumpy()))

The full traceback is reported below.

Traceback (most recent call last):
  File "popcount.py", line 25, in <module>
    f = hcl.build(s)
  File "/home/chz/heterocl/python/heterocl/api.py", line 318, in build
    return _build(schedule.sch, new_inputs, target=target, name=name, stmt=stmt)
  File "/home/chz/heterocl/python/heterocl/tvm/build_module.py", line 840, in build
    mhost = codegen.build_module(fhost, str(target_host))
  File "/home/chz/heterocl/python/heterocl/tvm/codegen.py", line 20, in build_module
    return _Build(lowered_func, target)
  File "/home/chz/heterocl/python/heterocl/tvm/_ffi/function.py", line 280, in my_api_func
    return flocal(*args)
  File "/home/chz/heterocl/python/heterocl/tvm/_ffi/_ctypes/function.py", line 183, in __call__
    ctypes.byref(ret_val), ctypes.byref(ret_tcode)))
  File "/home/chz/heterocl/python/heterocl/tvm/_ffi/base.py", line 66, in check_call
    raise TVMError(py_str(_LIB.TVMGetLastError()))
heterocl.tvm._ffi.base.TVMError: [19:06:13] src/codegen/llvm/codegen_llvm.cc:748: unknown intrinsic reinterpret

This bug is quite strange since it only happens for specific inputs. I write some test cases to demonstrate the behavior.

A = hcl.placeholder((3,), dtype=hcl.UInt(2), name="A")
for op1 in ["|","&"]:
    for op2 in ["|","&"]:
        for val1 in [1,2]:
            for val2 in [1,2]:
                test_case = "A[i] {} {} {} {}".format(op1,val1,op2,val2)
                try:
                    def kernel(A):
                        return hcl.compute((3,), lambda i: eval(test_case), dtype=hcl.UInt(2))
                    s = hcl.create_schedule([A], kernel)
                    f = hcl.build(s)
                    print("{} passed".format(test_case))
                except:
                    print("{} failed".format(test_case))

Only 3 of them failed the tests.

A[i] | 1 | 1 passed
A[i] | 1 | 2 passed
A[i] | 2 | 1 passed
A[i] | 2 | 2 passed
A[i] | 1 & 1 passed
A[i] | 1 & 2 passed
A[i] | 2 & 1 passed
A[i] | 2 & 2 passed
A[i] & 1 | 1 failed
A[i] & 1 | 2 failed
A[i] & 2 | 1 passed
A[i] & 2 | 2 passed
A[i] & 1 & 1 passed
A[i] & 1 & 2 failed
A[i] & 2 & 1 passed
A[i] & 2 & 2 passed