cornell-zhang/heterocl

SODAC fails to generate HLS code

Closed this issue · 4 comments

[19:04:12] src/codegen/build_soda.cc:127: input SODA DSL

kernel: soda_gray_output
burst width: 512
unroll factor: 8
iterate: 1
input int32: gray(640, *)
local int32:
  output(0, 0) = int32(((int36((int35((int34((int33(gray(-1, 1)) + int33(gray(0, 0)))) + int34(gray(0, 1)))) + int35(gray(1, 1)))) + int36(gray(0, 2))) / 5L))

[19:04:13] src/codegen/build_soda.cc:85: ERROR:sodac.py:227: None:8:1: error: Expected '*' or '/' or '%' or '+' or '-' or '<=' or '>=' or '<' or '>' or '==' or '!=' or BinaryAndOp or XorOp or BinaryOrOp or LogicAndOp or LogicOrOp or 'local' or 'border' or 'cluster' or 'param' or 'output' at position (8, 1) => ')) / 5L)) *'.

@Blaok Is border and cluster required for the input SODA DSL now? I am using version sodac 0.0.20200829.dev2

The SODAC codegen works with the test cases, where SODA module is called inside the default_function. But if I put the Stencil node into a HCL module, then the error above occurs. This is kind of weird -- I checked the input SODA DSL, they are actually exactly the same.

Here is the IR of the problematic program.

def test(float32(input[480*640*3]), int32(output[480*640])) {
  // io attr: "input" mem(0) port(0) io_type(0) fifo_depth(1) direction(0) 
  // io attr: "output" mem(0) port(0) io_type(1) fifo_depth(1) direction(1) 
  // attr [gray] storage_scope = "global"
  allocate gray[int32 * 480 * 640]
  produce gray {
    // attr [0] extern_scope = 0
    // attr [gray.pipe.1] storage_scope = "global"
    allocate gray.pipe.1[int32 * 480 * 640]
    // attr gray.pipe.1 as FIFO (depth=10)
    for "stage_name"="gray" (y, 0, 480) {
      for "stage_name"="gray" (x, 0, 640) {
        // attr [gray.temp] storage_scope = "global"
        allocate gray.temp[int32 * 1]
        gray.temp[0] = int32((((input[((x + (y*640))*3)]*0.300000f) + (input[(((x + (y*640))*3) + 1)]*0.590000f)) + (input[(((x + (y*640))*3) + 2)]*0.110000f)))
        gray.pipe.1[0].write(gray.temp[0]);
      }
    }
  }
  produce output {
    // attr [0] extern_scope = 0
    stencil burst_width=512 unroll_factor=8 num_iteration=1 is_axis=1
    inputs=[gray]
    outputs=[output] {
      for "stage_name"="output" (y, 0, 480) {
        for "stage_name"="output" (x, 0, 640) {
          output[(x + (y*640))] = int32(((int36((int35((int34((int33(gray[((x + (y*640)) + 639)]) + int33(gray[(x + (y*640))]))) + int34(gray[((x + (y*640)) + 640)]))) + int35(gray[((x + (y*640)) + 641)]))) + int36(gray[((x + (y*640)) + 1280)]))/(int36)5))
        }
      }
    }
  }
}

Here is the test cases I used: https://github.com/Hecmay/heterocl/blob/autosa-integration/tests/test_schedule_systolic.py#L181-L214

I suddenly found that this should be

output int32:

but not

local int32:

Nvm. I found the issue. The VarExprs inside Stencil op are not updated in the mutation and thus they are mis-classified as local output. It is fixed now.

The test cases were fixed already. Issue closed.