UCLA-VAST / tapa

TAPA is a dataflow HLS framework that features fast compilation, expressive programming model and generates high-frequency FPGA accelerators.
https://tapa.rtfd.io
MIT License
144 stars 27 forks source link

About the invoke of the task #143

Closed lifeformg closed 8 months ago

lifeformg commented 8 months ago

Original VecAdd:

void VecAdd(tapa::mmap<const float> a, tapa::mmap<const float> b,
            tapa::mmap<float> c, uint64_t n) {
  tapa::stream<float> a_q("a");
  tapa::stream<float> b_q("b");
  tapa::stream<float> c_q("c");

  tapa::task().invoke(Mmap2Stream, a, n, a_q)
      .invoke(Mmap2Stream, b, n, b_q)
      .invoke(Add, a_q, b_q, c_q, n)
      .invoke(Stream2Mmap, c_q, c, n);
}

If I change it to:

void VecAdd(tapa::mmap<const float> a, tapa::mmap<const float> b,
            tapa::mmap<float> c, uint64_t n) {
  tapa::stream<float> a_q("a");
  tapa::stream<float> b_q("b");
  tapa::stream<float> c_q("c");

  tapa::task task;

  task.invoke(Mmap2Stream, a, n, a_q)
      .invoke(Mmap2Stream, b, n, b_q)
      .invoke(Add, a_q, b_q, c_q, n)
      .invoke(Stream2Mmap, c_q, c, n);
}

C Simulation is all fine, but hardware simulation failed.

make vadd-cosim
[ 16%] Generating VecAdd.xilinx_u280_xdma_201920_3.hw.xo
I1115 21:19:16.243 tapa.util:162] logging level set to INFO
I1115 21:19:16.243 tapa.tapa:54] tapa version: 0.0.20221113.1
I1115 21:19:16.243 tapa.tapa:58] Python recursion limit set to 3000
I1115 21:19:16.679 tapa.steps.analyze:139] added vendor include path `/space1/hs_data/Xilinx/Vitis_HLS/2021.2/include`
Traceback (most recent call last):
  File "/home/lg/.local/bin/tapa", line 8, in <module>
    sys.exit(entry_point())
  File "/home/lg/.local/lib/python3.8/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/home/lg/.local/lib/python3.8/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/home/lg/.local/lib/python3.8/site-packages/click/core.py", line 1719, in invoke
    rv.append(sub_ctx.command.invoke(sub_ctx))
  File "/home/lg/.local/lib/python3.8/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/lg/.local/lib/python3.8/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/home/lg/.local/lib/python3.8/site-packages/click/decorators.py", line 33, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/lg/.local/lib/python3.8/site-packages/tapa/steps/analyze.py", line 63, in analyze
    graph_dict = TapaGraph(None, graph_dict).get_flatten_graph().to_dict()
  File "/home/lg/.local/lib/python3.8/site-packages/tapa/common/graph.py", line 55, in get_flatten_graph
    new_subtask_instantiations = {
  File "/home/lg/.local/lib/python3.8/site-packages/tapa/common/graph.py", line 56, in <dictcomp>
    definition.name: list(
  File "/home/lg/.local/lib/python3.8/site-packages/tapa/common/graph.py", line 57, in <lambda>
    map(lambda inst: inst.to_dict(interconnect_global_name=True),
  File "/home/lg/.local/lib/python3.8/site-packages/tapa/common/task_instance.py", line 155, in to_dict
    for name, arg in obj['args'].items():
TypeError: 'NoneType' object is not subscriptable
make[3]: *** [CMakeFiles/myvadd-hw-xo.dir/build.make:73: VecAdd.xilinx_u280_xdma_201920_3.hw.xo] Error 1
make[2]: *** [CMakeFiles/Makefile2:114: CMakeFiles/myvadd-hw-xo.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:200: CMakeFiles/vadd-cosim.dir/rule] Error 2
make: *** [Makefile:176: vadd-cosim] Error 2

Why is it like this? The reason I'm doing this is because I need to dynamically link subtasks to the parent task, like through a loop (is there another way to do it?).

Blaok commented 8 months ago

Hi @lifeformg, the only supported way to instantiate tasks is tapa::task()::invoke(...).... I'm not sure what exactly you mean by "dynamically link subtasks to the parent task", but if you just want to instantiate a sequence of tasks, that is supported. See https://tapa.readthedocs.io/en/release/api.html#task for documentation and https://github.com/UCLA-VAST/tapa/blob/c2617e3e8fe9ab916f16410fd01cd90bebefcc8e/apps/network/network.cpp#L102 for a concrete example.

lifeformg commented 8 months ago

Thank you for your reply @Blaok . Simply put, this is my top-level function:

void SystolicArray(tapa::mmap<const data_t> A, tapa::mmap<const data_t> B,
                    tapa::mmap<data_t> C, const int K) {
  tapa::stream<data_t> row_fifo[M][N + 1];
  tapa::stream<data_t> col_fifo[M + 1][N];
  tapa::stream<data_t> c_out_fifo[M][N];

  tapa::task task;
  // Initialize and connect PE
  for (int i = 0; i < M; ++i) {
    for (int j = 0; j < N; ++j) {
      // Connect the stream to the adjacent PE or external input/back_hole
      auto& left = row_fifo[i][j];
      auto& top = col_fifo[i][j];
      auto& button = col_fifo[i + 1][j];
      auto& right = row_fifo[i][j + 1];
      auto& c_out = c_out_fifo[i][j];

      task.invoke(pe, left, top, button, right, c_out);

      if (i == M - 1) {
        task.invoke<tapa::detach>(black_hole, button);
      }
      if (j == N - 1) {
        task.invoke<tapa::detach>(black_hole, right);
      }
    }
  }

  task.invoke(read_A, A, row_fifo, K)
      .invoke(read_B, B, col_fifo, K)
      .invoke(write_C, C, c_out_fifo, K);

}

It can't compile into xo because I separated task and invoke. I did this because I wanted to connect some streams to PE in a more complex way. As you can see, this code is part of a simple systolic array.

Blaok commented 8 months ago

@lifeformg TAPA does not support your code in its current form; you'll have to refactor your code to make it compatible. :) See https://tapa.readthedocs.io/en/release/tutorial.html#less-repetitive-code-with-stream-mmap-array for what is supported.