Welcome to my notes on HeteroCL.

How do we install HeteroCL?

To install HeteroCL, simple clone it from GitHub.

1
$ git clone --recursive https://github.com/cornell-zhang/heterocl.git

After that, go to the downloaded directory and make it.

1
$ make -j8

Options

  1. You can set your own CMake or LLVM version by setting the PATH in Makefile.config.
  2. You can turn off the VHLS C simulation feature by setting USE_VIVADO_HLS to 0 in Makefile.config.

Components of HeteroCL

HeteroCL framework overviewHeteroCL framework overview

HeteroCL is High-Level-Synthesis with style. How is that so? Previous HLS tools, for example, Vivado HLS, need us users to specify hardware customizations while describing the function, so that it could generate correct circuits from that description. HeteroCL does exactly the same job, but it decouples the hardware customization from algorithm specification, allowing a cleaner programming process.

Relation with TVM

HeteroCL is like an extension from TVM in the sense of compiler. TVM focuses on Tensor computations for CPU and GPU backends. Though TVM supports FPGA backend by using VTA, its tensor operations are pre-defined. On the other hand, HeteroCL offers additional features for FPGA programming that are more flexible and general. Such features include:

  • Decoupled Algorithm/Hardware specification
  • Imperative programming for general applications
  • Various hardware customization primitives
  • Bit-accurate data types

Workflow of HeteroCL

Basic steps to use HeteroCL include:

  1. Import HeteroCL import heterocl as hcl
  2. Initialize Environment hcl.init()
  3. Define Algorithm
  4. Define Inputs/Outputs hcl.placeholder()
  5. Apply Hardware Customization s= hcl.create_schedule
  6. View lower IR hcl.lower(s)
  7. Create Executable f = hcl.build()
  8. Run Executable f()

For FPGA backend HeteroCL generates HLS code. For CPU backend it generates a executable.

Tutorials

Quick Link

Using Vivado HLS Backend for csynth/csim

A simple HLS backend example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import heterocl as hcl
import numpy as np

def gemm(m=16, n=16, k=16, dtype=hcl.Int(), target=None):
matrix_1 = hcl.placeholder((m, k), dtype=dtype)
matrix_2 = hcl.placeholder((k, n), dtype=dtype)

def kernel(matrix_1, matrix_2):
r = hcl.reduce_axis(0, k, 'k')
return hcl.compute((m, n),
lambda x, y: hcl.sum(matrix_1[x, r] * matrix_2[r, y],
axis=r, dtype=dtype),
dtype=dtype,
name="out_matrix")

s = hcl.create_schedule([matrix_1, matrix_2], kernel)
s.to([matrix_1, matrix_2], target.xcel)
s.to(kernel.out_matrix, target.host)
f = hcl.build(s, target=target)
return f


target = hcl.platform.zc706
target.config(compile="vivado_hls", mode="csim|csyn")

m = k = n = 16
dtype = hcl.Int()
hcl_m1 = hcl.asarray(np.random.randint(10, size=(m, k)), dtype=hcl.Int())
hcl_m2 = hcl.asarray(np.random.randint(10, size=(m, k)), dtype=hcl.Int())
hcl_m3 = hcl.asarray(np.zeros((m, n)), dtype=dtype)

fg = gemm(m, n, k, dtype=hcl.Int(), target=target)
fg(hcl_m1, hcl_m2, hcl_m3)

report = fg.report(target)

With above installation steps and Vivado Design Suite 2018.3 installed, I could not get HLS backend working.
See the below error message:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[15:27:16] Generating harness files ...
[15:27:16] Compiling the program ...
Traceback (most recent call last):
File "hls_backend_example.py", line 36, in <module>
fg(hcl_m1, hcl_m2, hcl_m3)
File "/home/zhangniansong/.local/lib/python3.7/site-packages/heterocl-0.1-py3.7.egg/heterocl/tvm/_ffi/function.py", line 128, in __call__
return f(*args)
File "/home/zhangniansong/.local/lib/python3.7/site-packages/heterocl-0.1-py3.7.egg/heterocl/tvm/_ffi/_ctypes/function.py", line 183, in __call__
ctypes.byref(ret_val), ctypes.byref(ret_tcode)))
File "/home/zhangniansong/.local/lib/python3.7/site-packages/heterocl-0.1-py3.7.egg/heterocl/tvm/_ffi/base.py", line 66, in check_call
raise TVMError(py_str(_LIB.TVMGetLastError()))
heterocl.tvm._ffi.base.TVMError: TVMCall CFunc Error:
Traceback (most recent call last):
File "/home/zhangniansong/.local/lib/python3.7/site-packages/heterocl-0.1-py3.7.egg/heterocl/tvm/_ffi/_ctypes/function.py", line 54, in cfun
rv = local_pyfunc(*pyargs)
File "/home/zhangniansong/.local/lib/python3.7/site-packages/heterocl-0.1-py3.7.egg/heterocl/tvm/runtime.py", line 153, in copy_and_compile
with open("project/run.tcl","r") as tcl_file:
FileNotFoundError: [Errno 2] No such file or directory: 'project/run.tcl'

HeteroCL can’t find my Vivado HLS include files. So what we gotta do is to specify where the library files are located.

I added following two lines in the ~/.bashrc file

1
2
export VIVADO_HLS_HOME=/home/zhangniansong/Vivado/2018.3
export CPATH=$CPATH:$VIVADO_HLS_HOME/include

CPATH is for g++ include directory. It is the same as -I.

Then I reinstall HeteroCL, and Voila!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
INFO: [Common 17-206] Exiting vivado_hls at Sat Jul  4 16:07:47 2020...
+-------------------+-----------------------------------+
| HLS Version | Vivado HLS 2018.3 |
| Product family | zynq |
| Target device | xc7z020clg484-1 |
| Top Model Name | test |
+-------------------+-----------------------------------+
| Target CP | 10.00 ns |
| Estimated CP | 8.510 ns |
| Latency (cycles) | Min 18308 ; Max 18308 |
| Interval (cycles) | Min 18309 ; Max 18309 |
| Resources | Type Used Total Util |
| | -------- ------ ------- ------ |
| | BRAM_18K 3 280 1% |
| | DSP48E 3 220 1% |
| | FF 496 106400 0% |
| | LUT 756 53200 1% |
+-------------------+-----------------------------------+
[16:07:47] Execution complete

Vivado HLS backend now works.


Understanding How HeteroCL works

To understand how HeteroCL works, we try to answer following questions:

  1. How is the IR defined?
  2. How is the dataflow graph built?

The extended Halide IR system