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

[Backend] Fix Vivado HLS CodeGen for Data Type Casting #201

Closed hecmay closed 4 years ago

hecmay commented 4 years ago

This PR solves the data type casting error in VHLS code generator, which should address the following two problems:

  1. Casting fixed-point value to integer (causing precision problem). Brief example showing the minimal test case and which function caused the error.
        A = hcl.placeholder((8, 8), "A", dtype=hcl.Int(20))
        B = hcl.placeholder((8, 8), "B", dtype=hcl.Fixed(16,12))
        def kernel(A, B):
            return hcl.compute((8, 8), lambda y, x:
                hcl.select(x < 4, A[y][x], B[y][x]), "C", dtype=hcl.Int(8))

    With the example above, HeteroCL casts fixed point value B[y, x] into ap_int<20>, which makes B[y, x] lose all the fractional bits. The issue happens when ternary operation is generated with implicit data type casting. i.e., the two branches in select expression are compared, then HeteroCL selects a higher-precision data type and cast the two branches into this data type:

    // tvm/src/api/api_ir.cc: 135
    TVM_REGISTER_API("make.Select")
    .set_body([](TVMArgs args,  TVMRetValue *ret) {
    Expr cond = args[0], if_case = args[1], then_case = args[2];
    match_types(if_case, then_case);
    *ret = Select::make(cond, if_case, then_case);
    });
  2. VHLS code generator does not explicitly case the BinaryOpNode expressions, which causes the error mentioned in #193. We fix the issue by adding type checking logic in code generator. The code generator checks if the two branches are of the same data type, and explicitly cast those branches if the type casting logic is missing.