From 7910d3ecf20385da054a83786841b3706ddb82ee Mon Sep 17 00:00:00 2001 From: matth2k Date: Sat, 9 Dec 2023 22:49:13 -0500 Subject: [PATCH 01/29] new blog post for project --- content/2023-12-09-allo-amc/index.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 content/2023-12-09-allo-amc/index.md diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md new file mode 100644 index 000000000..0c793cb15 --- /dev/null +++ b/content/2023-12-09-allo-amc/index.md @@ -0,0 +1,16 @@ ++++ +title = "Frontend Integration for AMC (Accelerator Memory Compiler)" +[extra] +bio = """ + Matthew Hofmann is a 2nd year Ph.D. student researching design automation for reconfigurable hardware. + Yixiao Du is a 3rd year Ph.D. student researching hardware acceleration for graph processing and sparse linear algebra. +""" +[[extra.authors]] +name = "Matthew Hofmann" +[[extra.authors]] +name = "Yixiao Du" ++++ + +## Summary + +TODO \ No newline at end of file From e6e2a86ae5b50fef9097026e577372997489abda Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 05:50:56 -0500 Subject: [PATCH 02/29] add Design Example section --- content/2023-12-09-allo-amc/index.md | 160 ++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 3 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 0c793cb15..ffc7d251c 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -2,7 +2,7 @@ title = "Frontend Integration for AMC (Accelerator Memory Compiler)" [extra] bio = """ - Matthew Hofmann is a 2nd year Ph.D. student researching design automation for reconfigurable hardware. + Matthew Hofmann is a 2nd year Ph.D. student researching design automation for reconfigurable hardware.
Yixiao Du is a 3rd year Ph.D. student researching hardware acceleration for graph processing and sparse linear algebra. """ [[extra.authors]] @@ -11,6 +11,160 @@ name = "Matthew Hofmann" name = "Yixiao Du" +++ -## Summary +## Introduction -TODO \ No newline at end of file +### Custom Hardware Accelerators + +TODO + +### High Level Synthesis + +TODO + +### MLIR and Incubator Projects + +TODO(introduce MLIR, CIRCT, hcl, amc dialects) + +## Design Example + +To use Allo with AMC, the designer writes their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. + +Our illustrative example will be verifying matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: + +```python +def test_amc(): + N = 16 + # Initialize 2 input matricies to random integers + A = np.random.randint(0, 20, size=(N, N), dtype="int32") + B = np.random.randint(0, 20, size=(N, N), dtype="int32") + + # Our kernel is just matrix multiplication + def kernel(A: int32[N, N], B: int32[N, N]) -> int32[N, N]: + return matmul(A, B) + + # Build the accelerator with AMC backend + s = allo.customize(kernel) + f = s.build(target="amc") + # Run the software simulation by invoking directly + np_out = kernel(A, B) + # Now run the hardware simulation with AMC + allo_out = f(A, B) + np.testing.assert_array_equal(allo_out, np_out) +``` + +Additionally, we can also get an approximation of how much FPGA resources this design uses. Simply call `.get_resource_estimates()` after building: + +```python + print(f.get_resource_estimates()) + # { + # "BRAM36": 1, + # "DSP": 3, + # "FF": 255, + # "LUT": 467, + # "LUTL": 467, + # "LUTM": 0, + # "cycles": 15016, + # "name": "kernel" + # } +``` + +This uses [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) RTL synthesis for Xilinx FPGAs, but it would only be a one-time effort to support other synthesis tools like [Yosys](https://yosyshq.net/yosys/). If errors arise, the AMC backend offers some options to help with debugging. To better understand what is going on under the hood, the first step would be to dump the underlying intermediate representation in MLIR with `print(f.module)`. + +```mlir +// print(f.module) +func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>) -> memref<16x16xi32> attributes {itypes = "ss", otypes = "s", top} { + %c0_i32 = arith.constant 0 : i32 + %alloc = memref.alloc() : memref<16x16xi32> + affine.for %arg2 = 0 to 16 { + affine.for %arg3 = 0 to 16 { + affine.store %c0_i32, %alloc[%arg2, %arg3] : memref<16x16xi32> + } + } + affine.for %arg2 = 0 to 16 { + affine.for %arg3 = 0 to 16 { + affine.for %arg4 = 0 to 16 { + %0 = affine.load %arg0[%arg2, %arg4] : memref<16x16xi32> + %1 = affine.load %arg1[%arg4, %arg3] : memref<16x16xi32> + %2 = affine.load %alloc[%arg2, %arg3] : memref<16x16xi32> + %3 = arith.muli %0, %1 : i32 + %4 = arith.addi %2, %3 : i32 + affine.store %4, %alloc[%arg2, %arg3] : memref<16x16xi32> + } + } + } + return %alloc : memref<16x16xi32> +} +``` + +To debug , we can inspect individual steps of the lowering pipline. For example, here is what this application would look like after AMC buffers are inserted: + +```mlir +module { + amc.memory @amcMemory0(!amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1>) { + %0 = amc.alloc : !amc.memref<16x16xi32> + %1 = amc.create_port(%0 : !amc.memref<16x16xi32>) : !amc.static_port<16x16xi32, w, 1> + %2 = amc.create_port(%0 : !amc.memref<16x16xi32>) : !amc.static_port<16x16xi32, rw, 1> + amc.extern %1, %2 : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> + } + func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>, %arg2: memref<16x16xi32>) attributes {itypes = "ss", otypes = "s", top} { + %c0_i32 = arith.constant 0 : i32 + %0:2 = amc.inst @amcMemory0_inst of @amcMemory0 : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> + affine.for %arg3 = 0 to 16 { + affine.for %arg4 = 0 to 16 { + amc.affine_store %c0_i32, %0#0[%arg3, %arg4] : !amc.static_port<16x16xi32, w, 1> + } {hls.pipeline, hls.unroll = 1 : i64} + } {hls.unroll = 1 : i64} + affine.for %arg3 = 0 to 16 { + affine.for %arg4 = 0 to 16 { + affine.for %arg5 = 0 to 16 { + %1 = affine.load %arg0[%arg3, %arg5] : memref<16x16xi32> + %2 = affine.load %arg1[%arg5, %arg4] : memref<16x16xi32> + %3 = amc.affine_load %0#1[%arg3, %arg4] : !amc.static_port<16x16xi32, rw, 1> + %4 = arith.muli %1, %2 : i32 + %5 = arith.addi %3, %4 : i32 + amc.affine_store %5, %0#1[%arg3, %arg4] : !amc.static_port<16x16xi32, rw, 1> + } {hls.pipeline, hls.unroll = 1 : i64} + } {hls.unroll = 1 : i64} + } {hls.unroll = 1 : i64} + affine.for %arg3 = 0 to 16 { + affine.for %arg4 = 0 to 16 { + %1 = amc.affine_load %0#1[%arg3, %arg4] : !amc.static_port<16x16xi32, rw, 1> + affine.store %1, %arg2[%arg3, %arg4] : memref<16x16xi32> + } {hls.bufferize, hls.pipeline, hls.unroll = 1 : i64} + } {hls.unroll = 1 : i64} + return + } +} +``` + +For more information on the motivation behin AMC and the dialect itself, you can visit the [Andrew Butt's blog post](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/banked-memory-compiler-backend-in-mlir/) from last year. As a last resort when debugging, the AMC backend has a `.dump_vcd()` method: + +```python + f.dump_vcd("waveform.vcd") + # You can now take the debugging to your favorite waveform viewer +``` + +## Tool flow + +To use Allo with AMC, The Allo frontend automates all the stages of the tool flow. Nonetheless, understanding each component + +### Overview + +### Allo + +### AMC + +TODO. Show pass pipeline + +## Results + +TODO + +## Future Work + +TODO +- Fix how allow constructs affine for. Needs to Store to load forward + +## Conclusion + +The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding a new test case. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. \ No newline at end of file From 81f933c196002efda0af9701418934a72707ff6b Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 06:49:48 -0500 Subject: [PATCH 03/29] start intro --- content/2023-12-09-allo-amc/index.md | 32 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index ffc7d251c..a0f573d99 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -13,6 +13,8 @@ name = "Yixiao Du" ## Introduction +For our final course project, we have integrated our HLS (high-level sythesis) compiler, AMC, with a Python frontend, called Allo. In the end, we are able to compile and simulate custom hardware designs with extremely concise design descriptions and short compile times. As a consequence, we greatly reduce the design effort required for new accelerators as well as offer a convenient tool for functional verification. In this report, we walk through an example design with our tool flow, offer insight into how the underlying compiler works, and finally evaluate some benchmarks with latency and resource utilization measurements. + ### Custom Hardware Accelerators TODO @@ -27,9 +29,9 @@ TODO(introduce MLIR, CIRCT, hcl, amc dialects) ## Design Example -To use Allo with AMC, the designer writes their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. +To use Allo with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. -Our illustrative example will be verifying matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: +Our illustrative example will be matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: ```python def test_amc(): @@ -68,7 +70,7 @@ Additionally, we can also get an approximation of how much FPGA resources this d # } ``` -This uses [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) RTL synthesis for Xilinx FPGAs, but it would only be a one-time effort to support other synthesis tools like [Yosys](https://yosyshq.net/yosys/). If errors arise, the AMC backend offers some options to help with debugging. To better understand what is going on under the hood, the first step would be to dump the underlying intermediate representation in MLIR with `print(f.module)`. +This uses [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) RTL synthesis for Xilinx FPGAs, but it would only be a one-time effort to support other synthesis tools like [Yosys](https://yosyshq.net/yosys/). If functional errors arise, the AMC backend also offers some options to help with debugging. To better understand what is going on under the hood, the first step would be to dump the underlying intermediate representation in MLIR with `print(f.module)`. ```mlir // print(f.module) @@ -96,7 +98,7 @@ func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>) -> memref< } ``` -To debug , we can inspect individual steps of the lowering pipline. For example, here is what this application would look like after AMC buffers are inserted: +The above IR helps give insight into what program the AMC is actually attempting to compile. To debug at a lower level, we can inspect the IR at individual steps of the pass pipeline. For example, here is what this application would look like after AMC buffers are inserted: ```mlir module { @@ -137,16 +139,34 @@ module { } ``` -For more information on the motivation behin AMC and the dialect itself, you can visit the [Andrew Butt's blog post](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/banked-memory-compiler-backend-in-mlir/) from last year. As a last resort when debugging, the AMC backend has a `.dump_vcd()` method: +For more information on the motivation behind AMC and the dialect itself, you can visit the [Andrew Butt's blog post](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/banked-memory-compiler-backend-in-mlir/) from last year. As a last resort when debugging, the AMC backend has a `.dump_vcd()` method which outputs the waveforms from the hardware simulation: ```python f.dump_vcd("waveform.vcd") # You can now take the debugging to your favorite waveform viewer ``` +Writing other types of kernels is as easy as writing normal Python. For example, here are a handful of other kernels which are just a simple to get up and running: + +```python +def fibonnaci(A: uint32[N]): + A[1] = 1 + for i in range(2, N): + A[i] = A[i - 1] + A[i - 2] + +def vadd(A: uint32[N], B: uint32[N]) -> uint32[N]: + return A + B +``` + +Outside of what is shown here, the Allo DSL allows much more elaborate kernels and control over compute customizations, like loop tiling and reuse buffers. One again, you can get more information on Allo and its MLIR dialect by reading last years blog post by [Hongzheng Chen](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/hcl-mlir/). + +To conclude, we hope this example demonstrates the usefulness of the Allo frontend for high-level hardware design and further development of the AMC HLS compiler. As far as we are aware, the only other frameworks using Python to drive FPGA high-level synthesis are [LeFlow](https://arxiv.org/abs/1807.05317) and [PyLog](https://ieeexplore.ieee.org/document/9591456). However, neither of these efforts are using a homebrewed HLS compiler like us. + ## Tool flow -To use Allo with AMC, The Allo frontend automates all the stages of the tool flow. Nonetheless, understanding each component +Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding each component is important to understanding the novelty in our approach. + +TODO(explain all the steps) ### Overview From e50c11f0288efb5e8748ad3c2395cfecc9266865 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 07:04:39 -0500 Subject: [PATCH 04/29] add a few results --- content/2023-12-09-allo-amc/index.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index a0f573d99..cc64d6091 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -178,7 +178,12 @@ TODO. Show pass pipeline ## Results -TODO +| Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | +| ------------- | ---------------- | ---- | --- | ------- | ---- | +| matmul16x16 | 15016 | 467 | 255 | 1 | 3 | +| spmv20x20 | 48 | 183 | 309 | 0 | 3 | +| vadd20 | 112 | 612 | 305 | 2 | 0 | +| fibonacci20 | 77 | 120 | 151 | 0 | 0 | ## Future Work From 3917edefec1b8fdc90ed7f355ea917fced850cb0 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 07:10:12 -0500 Subject: [PATCH 05/29] add image of amc passes --- content/2023-12-09-allo-amc/amc_passes.png | Bin 0 -> 177900 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 content/2023-12-09-allo-amc/amc_passes.png diff --git a/content/2023-12-09-allo-amc/amc_passes.png b/content/2023-12-09-allo-amc/amc_passes.png new file mode 100644 index 0000000000000000000000000000000000000000..90dbfecccd087498676b71a9fef48c198a85753c GIT binary patch literal 177900 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

&s$^nnB*Ae0`X<1-!)St>pgLpQJGeHq2 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

N5-4VlB9}9 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 z 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 NlTwx}eQWgTe*vl?*q8tS literal 0 HcmV?d00001 From 120a59ba6dd81a1366c6106825185b4fda1e54ef Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 07:13:17 -0500 Subject: [PATCH 06/29] reformat mlir --- content/2023-12-09-allo-amc/index.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index cc64d6091..bef10e9cd 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -108,9 +108,10 @@ module { %2 = amc.create_port(%0 : !amc.memref<16x16xi32>) : !amc.static_port<16x16xi32, rw, 1> amc.extern %1, %2 : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> } - func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>, %arg2: memref<16x16xi32>) attributes {itypes = "ss", otypes = "s", top} { + func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>, %arg2: memref<16x16xi32>) { %c0_i32 = arith.constant 0 : i32 - %0:2 = amc.inst @amcMemory0_inst of @amcMemory0 : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> + %0:2 = amc.inst @amcMemory0_inst of @amcMemory0 + : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> affine.for %arg3 = 0 to 16 { affine.for %arg4 = 0 to 16 { amc.affine_store %c0_i32, %0#0[%arg3, %arg4] : !amc.static_port<16x16xi32, w, 1> From f49578412b12267190705b6efc54a12341bdb65a Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 10:07:03 -0500 Subject: [PATCH 07/29] fill in AMC section --- content/2023-12-09-allo-amc/index.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index bef10e9cd..6e7d32a87 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -175,7 +175,19 @@ TODO(explain all the steps) ### AMC -TODO. Show pass pipeline +AMC (Accelerator Memory Compiler) is an entirely new plane of intermediate representation dedicated to representing memory architecture. To explain the need for such a dialect, the current state of conventional high-level synthesis compilers must be understood. As a brief summary, current HLS tools lacks an expressive model of memory, and it takes great manual effort to unlock the power of spatial architectures. This is by and large a consequence of the chosen source language. Most HLS compilers have a C/C++ frontend and LLVM middle end. As a consequence, every HLS compiler also has a set of compiler directives (`#pragma`'s) to fill in the semantic gaps of compiling to spatial hardware. For example, there are pragmas for partitioning memories, instantiating FIFOs, loop pipelining, and much more. By not having first class constructs for these design elements, optimization becomes tightly-coupled with source rewrites and HLS falls flat on its promises of high productivity. For the interested reader, we think this [blog post](https://specbranch.com/posts/fpgas-what-happened/) helps explain the current state of the FPGA accelerators for outsiders. + +Back to AMC, the custom dialect elaborates the *real* limiting resources of memory on spatial architectures: the ports. Each embedded block RAM on the FPGA has only two ports, and it takes an intelligent design methodology to utilize these memories in such a way that maximizes performance. AMC eliminates the guessing game by elaborating the description of the memory subsystem and optimizing it for the program at hand. To accompany the AMC dialect, we use [Calyx IR](https://calyxir.org/) to represent the control logic of the scheduled program. + + + +The following diagram shows the full pass pipeline of compiling the core MLIR dialects to Verilog: + +

+Diagram for AMC pass pipeline +
## Results From 1d106fe133ecf3b8813b5cdf0b08dc1b63bfe45f Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 10:11:03 -0500 Subject: [PATCH 08/29] code fmt --- content/2023-12-09-allo-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 6e7d32a87..ad3bf3839 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -74,7 +74,7 @@ This uses [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) RTL ```mlir // print(f.module) -func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>) -> memref<16x16xi32> attributes {itypes = "ss", otypes = "s", top} { +func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>) -> memref<16x16xi32> { %c0_i32 = arith.constant 0 : i32 %alloc = memref.alloc() : memref<16x16xi32> affine.for %arg2 = 0 to 16 { From 7bcfe13ab686a615e011943a8525d7bbe1fbe1a6 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 10:13:53 -0500 Subject: [PATCH 09/29] assume C is initialized for brevity --- content/2023-12-09-allo-amc/index.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index ad3bf3839..2a392c3dd 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -77,11 +77,6 @@ This uses [Vivado](https://www.xilinx.com/products/design-tools/vivado.html) RTL func.func @kernel(%arg0: memref<16x16xi32>, %arg1: memref<16x16xi32>) -> memref<16x16xi32> { %c0_i32 = arith.constant 0 : i32 %alloc = memref.alloc() : memref<16x16xi32> - affine.for %arg2 = 0 to 16 { - affine.for %arg3 = 0 to 16 { - affine.store %c0_i32, %alloc[%arg2, %arg3] : memref<16x16xi32> - } - } affine.for %arg2 = 0 to 16 { affine.for %arg3 = 0 to 16 { affine.for %arg4 = 0 to 16 { @@ -112,11 +107,6 @@ module { %c0_i32 = arith.constant 0 : i32 %0:2 = amc.inst @amcMemory0_inst of @amcMemory0 : !amc.static_port<16x16xi32, w, 1>, !amc.static_port<16x16xi32, rw, 1> - affine.for %arg3 = 0 to 16 { - affine.for %arg4 = 0 to 16 { - amc.affine_store %c0_i32, %0#0[%arg3, %arg4] : !amc.static_port<16x16xi32, w, 1> - } {hls.pipeline, hls.unroll = 1 : i64} - } {hls.unroll = 1 : i64} affine.for %arg3 = 0 to 16 { affine.for %arg4 = 0 to 16 { affine.for %arg5 = 0 to 16 { From 05d1d5e1b6d37fa7700661dd3c5521112a9b418a Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 11:42:04 -0500 Subject: [PATCH 10/29] add results section --- content/2023-12-09-allo-amc/index.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 2a392c3dd..a5910b9fa 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -141,6 +141,7 @@ Writing other types of kernels is as easy as writing normal Python. For example, ```python def fibonnaci(A: uint32[N]): + A[0] = 1 A[1] = 1 for i in range(2, N): A[i] = A[i - 1] + A[i - 2] @@ -181,6 +182,9 @@ The following diagram shows the full pass pipeline of compiling the core MLIR di ## Results +In this section, we report the latency and resource measures of a select set of micro-benchmarks. By using small testcases, we have the best chance of understanding how the high-level constructs are being mapped to hardware and where the compiler inefficiencies lie. With that said, here are a table of benchmarks compiled with our toolflow versus Vitis C HLS. + +**AMC** | Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | | ------------- | ---------------- | ---- | --- | ------- | ---- | | matmul16x16 | 15016 | 467 | 255 | 1 | 3 | @@ -188,6 +192,24 @@ The following diagram shows the full pass pipeline of compiling the core MLIR di | vadd20 | 112 | 612 | 305 | 2 | 0 | | fibonacci20 | 77 | 120 | 151 | 0 | 0 | +**Vitis 2022** +| Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | +| ------------- | ---------------- | ---- | --- | ------- | ---- | +| matmul16x16 | 5409 | 221 | 74 | 0 | 3 | +| spmv20x20 | 42 | 249 | 145 | 0 | 3 | +| vadd20 | 22 | 81 | 13 | 0 | 3 | +| fibonacci20 | 41 | 226 | 50 | 0 | 0 | + +**Difference: AMC - Vitis** +| Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | +| ------------- | ---------------- | ----- | ------ | ------- | ----- | +| matmul16x16 | +170% | +110% | +240% | - | +0% | +| spmv20x20 | +14% | -26% | +110% | - | +0% | +| vadd20 | +410% | +760% | +2200% | - | -300% | +| fibonacci20 | +88% | -47% | +200% | - | - | + +The main story here is revealed when looking at the core MLIR dialects Allo is emitting after parsing the AST. Inefficiencies in how Allo infers data types and creates `affine.for` loop nests is creating way too many redundant memory operations. For example, Allo is not using store-to-load forwarding between loop iterations. Even worse, Allo tries to explicity infer data type conversions when using operations that change the data width (e.g. 32b + 32b = 33b). This for some reason is causing extra memory copy loops to convert an entire memory before it is used. We anticipate that fixing the Allo frontend to produce higher-quality loops will take some time, as it depends on some level of memory dependence analysis. Nonetheless, it will be a very important improvement to make in order to reach similar latencies as what Vitis can produce with C code. + ## Future Work TODO From 22ecd538f8e18869197da4a984faf7fbaf800e48 Mon Sep 17 00:00:00 2001 From: Yixiao Du Date: Sun, 10 Dec 2023 15:44:49 -0500 Subject: [PATCH 11/29] finish intro; add Allo example: --- content/2023-12-09-allo-amc/index.md | 50 ++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index a5910b9fa..5fa5fd651 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -15,21 +15,23 @@ name = "Yixiao Du" For our final course project, we have integrated our HLS (high-level sythesis) compiler, AMC, with a Python frontend, called Allo. In the end, we are able to compile and simulate custom hardware designs with extremely concise design descriptions and short compile times. As a consequence, we greatly reduce the design effort required for new accelerators as well as offer a convenient tool for functional verification. In this report, we walk through an example design with our tool flow, offer insight into how the underlying compiler works, and finally evaluate some benchmarks with latency and resource utilization measurements. -### Custom Hardware Accelerators +### Hardware Accelerators -TODO +Hardware accelerators have been a promising way of improving the performance and energy efficiency of compute intensive applications. However, the design effort required to create a new accelerator is often too high for the average programmer. This is because the design process requires a deep understanding of the underlying hardware architecture and the tools used to compile the design. For example, the designer must understand how to map their algorithm to the hardware, how to optimize for the target (e.g., FPGAs), and how to debug the design. Moreover, the designer must also understand the tool flow, which includes the hardware description language (HDL), the synthesis tools, and the simulation tools. In the end, the designer must be an expert in both hardware and software to create a new accelerator. As a result, bringing up a new accelerator is a slow and sometimes tedious process. -### High Level Synthesis +### High-Level Synthesis -TODO +High-Level Synthesis (HLS) is a rising solution to the problem of hardware design productivity. The idea is to raise the level of abstraction of HDLs from the commonly-used register transfer level (RTL) to a higher-level language like C/C++. This allows the designer to focus more on the algorithm and less on the hardware details such as interfacing and timing. The core part of HLS it a compiler which infers a mapping from the high-level language to the hardware, which is often done by scheduling, resource allocation, and binding. In the end, the HLS compiler outputs RTL code to be synthesized by downstream tools. However, current HLS tools are not able to fully free designers from understanding hardware architectures. They often rely on special directives (e.g., C++ pragmas) from the designer to guide the optimization process. Sometimes, the designer must even rewrite their code to fit the HLS compiler's model of computation. ### MLIR and Incubator Projects -TODO(introduce MLIR, CIRCT, hcl, amc dialects) +Improving HLS with advanced compiler techniques is a very active area of research. There are many outstanding HLS tools/frameworks such as [TAPA](https://tapa.readthedocs.io/en/release/overview/overview.html), [Dynamatic](https://dynamatic.epfl.ch/), and [HeteroCL](https://heterocl.csl.cornell.edu/). However, these tools are developed independently with different compilation flows, which brings difficulties of integrating them together. [MLIR](https://mlir.llvm.org/) is a new compiler design paradigm where the source language is compiled through multiple levels of modularized intermediate representations (IRs), also known as dialects. Dialects act like domain-specific languages (DSLs) and can capture the approprate details at each level of abstraction. + +The [CIRCT](https://circt.llvm.org/) project proposes an MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called Allo. Allo decouples algorithm, optimization, and backend targets to enable productive hardware design and testing. Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. It captures common memory constructs such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is a part of the CIRCT system, and finally to synthesizable Verilog. In this project, we integrate Allo and AMC to enable a Python frontend for AMC. This allows us to use Allo to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single command. We hope that this integration will enable a more productive design flow for hardware accelerators. ## Design Example -To use Allo with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. +To use Allo with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts as a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. Our illustrative example will be matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: @@ -40,9 +42,9 @@ def test_amc(): A = np.random.randint(0, 20, size=(N, N), dtype="int32") B = np.random.randint(0, 20, size=(N, N), dtype="int32") - # Our kernel is just matrix multiplication + # Our kernel is just matrix multiplication, Allo provides a primitive for this def kernel(A: int32[N, N], B: int32[N, N]) -> int32[N, N]: - return matmul(A, B) + return allo.matmul(A, B) # Build the accelerator with AMC backend s = allo.customize(kernel) @@ -57,7 +59,7 @@ def test_amc(): Additionally, we can also get an approximation of how much FPGA resources this design uses. Simply call `.get_resource_estimates()` after building: ```python - print(f.get_resource_estimates()) + print(f.get_resource_estimates()) # { # "BRAM36": 1, # "DSP": 3, @@ -150,7 +152,7 @@ def vadd(A: uint32[N], B: uint32[N]) -> uint32[N]: return A + B ``` -Outside of what is shown here, the Allo DSL allows much more elaborate kernels and control over compute customizations, like loop tiling and reuse buffers. One again, you can get more information on Allo and its MLIR dialect by reading last years blog post by [Hongzheng Chen](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/hcl-mlir/). +Outside of what is shown here, the Allo DSL allows much more elaborate kernels and control over compute customizations, like loop tiling and reuse buffers. One again, you can get more information on Allo and its MLIR dialect by reading last years blog post by [Hongzheng Chen](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/hcl-mlir/). To conclude, we hope this example demonstrates the usefulness of the Allo frontend for high-level hardware design and further development of the AMC HLS compiler. As far as we are aware, the only other frameworks using Python to drive FPGA high-level synthesis are [LeFlow](https://arxiv.org/abs/1807.05317) and [PyLog](https://ieeexplore.ieee.org/document/9591456). However, neither of these efforts are using a homebrewed HLS compiler like us. @@ -163,6 +165,34 @@ TODO(explain all the steps) ### Overview ### Allo +Allo leverages an algorithm-optimization decoupled paradigm, which means users can first define the algorithm in a high-level language and then optimize the program with various hardware customization techniques (i.e., schedule primitives). Back to the matmul example, without using the provided primitive, the code would look like this: + +```python +def matmul(A: int32[16, 16], B: int32[16, 16]) -> int32[16, 16]: + C: int32[16, 16] = 0 + for i, j, k in allo.grid(16, 16, 16): + C[i, j] += A[i, k] * B[k, j] + return C +``` + +[This blog post](https://siboehm.com/articles/22/Fast-MMM-on-CPU) describes an effective way of optimizing matrix multiplication. The key idea is to reorder and tile the loops for a better data locality. The optimized loop order would be `i, k, j`. With Allo, we can easily achieve this with just two lines of code: + +```python +schedule = allo.customize(matmul) +schedule.reorder("i", "k", "j") +``` + +Loop tiling is supported by the `split()` directive: +```python +schedule.split("i", factor=4) +``` + +Finally, we can build the design for various backends: +```python +module = schedule.build(target="llvm") # can also be 'vlhs', 'amc' +``` + +TODO: what is the most important feature of Allo for this project? ### AMC From cfdd6b41bca6ffdb7b3413c73521573e821c885d Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 18:51:15 -0500 Subject: [PATCH 12/29] add dependency graph --- content/2023-12-09-allo-amc/index.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 5fa5fd651..e96c380f7 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -160,7 +160,13 @@ To conclude, we hope this example demonstrates the usefulness of the Allo fronte Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding each component is important to understanding the novelty in our approach. -TODO(explain all the steps) +
+Diagram of build dependencies +
+ +The top row of dependencies are C++ codebases linked together as static libraries. We enter interact with this library with input MLIR generated from Allo. On the backend, we emit Calyx which is lowered to Verilog by a separate [Calyx compiler](https://github.com/cucapra/calyx) that is written in Rust. + +The HCL dialect and passes are primarily responsible for processing the customization directives of the Allo frontend. Then, AMC and CIRCT carry out the "traditional" steps of high-level synthesis: allocation, scheduling, and binding. Finally, the Calyx compiler generates the data paths and control logic for the scheduled program. ### Overview From f9c3068af31f6df9a5c4c2d0ed994c6e509ae954 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 19:20:45 -0500 Subject: [PATCH 13/29] proofread intro --- content/2023-12-09-allo-amc/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index e96c380f7..f9e1a1aff 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -17,17 +17,17 @@ For our final course project, we have integrated our HLS (high-level sythesis) c ### Hardware Accelerators -Hardware accelerators have been a promising way of improving the performance and energy efficiency of compute intensive applications. However, the design effort required to create a new accelerator is often too high for the average programmer. This is because the design process requires a deep understanding of the underlying hardware architecture and the tools used to compile the design. For example, the designer must understand how to map their algorithm to the hardware, how to optimize for the target (e.g., FPGAs), and how to debug the design. Moreover, the designer must also understand the tool flow, which includes the hardware description language (HDL), the synthesis tools, and the simulation tools. In the end, the designer must be an expert in both hardware and software to create a new accelerator. As a result, bringing up a new accelerator is a slow and sometimes tedious process. +When CPU and GPU optimizations have been exhausted, custom hardware accelerators are the main option for improving the performance and energy efficiency of compute intensive applications. However, the design effort required to create a new accelerator is often too high for the average programmer. This is because the design process requires a deep understanding of the underlying hardware architecture, how it can be used, and how the CAD tools behave. For example, the designer must understand how to map their algorithm to the floorplan of the hardware and how to optimize for the functional units present in architecture (e.g., LUTs, DSPs on FPGAs). Of course, debugging is its own challenge when designing hardware. Finally, the designer also needs to battle with inadequate vendor tools, which are used to synthesize the hardware description language (HDL) and run behavioral and cycle-accurate simulations. In the end, the accelerator designer must be an expert in a very tall stack of technologies, spanning both hardware and software. As a result, bringing up a new accelerator is a slow, tedious, and typically expensive process. ### High-Level Synthesis -High-Level Synthesis (HLS) is a rising solution to the problem of hardware design productivity. The idea is to raise the level of abstraction of HDLs from the commonly-used register transfer level (RTL) to a higher-level language like C/C++. This allows the designer to focus more on the algorithm and less on the hardware details such as interfacing and timing. The core part of HLS it a compiler which infers a mapping from the high-level language to the hardware, which is often done by scheduling, resource allocation, and binding. In the end, the HLS compiler outputs RTL code to be synthesized by downstream tools. However, current HLS tools are not able to fully free designers from understanding hardware architectures. They often rely on special directives (e.g., C++ pragmas) from the designer to guide the optimization process. Sometimes, the designer must even rewrite their code to fit the HLS compiler's model of computation. +High-Level Synthesis (HLS) is one such solution to solve the problem of hardware design productivity. The general idea is to raise the level of abstraction from the commonly-used register transfer level (RTL) (e.g. Verilog) to a higher-level language like C/C++. This allows the designer to focus more at the algorithm level and less on the hardware details, such as interfaces and timing. The "magic" of HLS compilers is that it can infer a gate-level mapping from the high-level language to the underlying hardware. The main steps of generating this mapping are scheduling, resource allocation, and binding. In the end, the outputted RTL code from HLS can be synthesized by downstream tools. However, current HLS tools greatly fall short in their promise to free designers from thinking at the architecture level. They rely on special directives (e.g., C++ pragmas) from the designer to guide the optimization process. Oftentimes, the designer must even rewrite their code to fit the HLS compiler's model of computation. ### MLIR and Incubator Projects -Improving HLS with advanced compiler techniques is a very active area of research. There are many outstanding HLS tools/frameworks such as [TAPA](https://tapa.readthedocs.io/en/release/overview/overview.html), [Dynamatic](https://dynamatic.epfl.ch/), and [HeteroCL](https://heterocl.csl.cornell.edu/). However, these tools are developed independently with different compilation flows, which brings difficulties of integrating them together. [MLIR](https://mlir.llvm.org/) is a new compiler design paradigm where the source language is compiled through multiple levels of modularized intermediate representations (IRs), also known as dialects. Dialects act like domain-specific languages (DSLs) and can capture the approprate details at each level of abstraction. +Reinventing HLS with advanced compiler techniques is an active area of research. There are many outstanding HLS tools/frameworks such as [TAPA](https://tapa.readthedocs.io/en/release/overview/overview.html), [Dynamatic](https://dynamatic.epfl.ch/), and [HeteroCL](https://heterocl.csl.cornell.edu/). However, these tools are developed independently with different compilation flows, which brings difficulties of integrating them together. [MLIR](https://mlir.llvm.org/) is a new compiler design paradigm where the source language is compiled through multiple levels of modularized intermediate representations (IRs), also known as dialects. Dialects act like domain-specific languages (DSLs) and can capture the approprate details at each level of abstraction. -The [CIRCT](https://circt.llvm.org/) project proposes an MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called Allo. Allo decouples algorithm, optimization, and backend targets to enable productive hardware design and testing. Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. It captures common memory constructs such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is a part of the CIRCT system, and finally to synthesizable Verilog. In this project, we integrate Allo and AMC to enable a Python frontend for AMC. This allows us to use Allo to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single command. We hope that this integration will enable a more productive design flow for hardware accelerators. +The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called Allo. Allo decouples the interactions between the algorithm, hardware optimizations, and backend targets to enable productive design and testing. Lastly, Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. Its expressiveness is able to capture common memory organization strategies such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is also part of the CIRCT ecosystem. Calyx IR gives us a pathway to finally to synthesizable Verilog. The contribution of this project is that we integrated Allo with AMC to enable a Python frontend for AMC. This allows us to use Allo to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single function call. In the end, we hope that this integration will enable a more productive design flow for hardware accelerators as well as help us find more bugs in AMC. ## Design Example From a0e6fab445c434e50bcc3e09d2a0061c5ad90fce Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 19:43:44 -0500 Subject: [PATCH 14/29] add future work --- content/2023-12-09-allo-amc/index.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index f9e1a1aff..5a93cc3e9 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -139,7 +139,7 @@ For more information on the motivation behind AMC and the dialect itself, you ca # You can now take the debugging to your favorite waveform viewer ``` -Writing other types of kernels is as easy as writing normal Python. For example, here are a handful of other kernels which are just a simple to get up and running: +Writing other types of kernels is as easy as writing normal Python. For example, here are a couple of other kernels which are just a simple to get up and running: ```python def fibonnaci(A: uint32[N]): @@ -158,7 +158,7 @@ To conclude, we hope this example demonstrates the usefulness of the Allo fronte ## Tool flow -Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding each component is important to understanding the novelty in our approach. +Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding the interactions of each component is important to understanding the novelty in our approach.
Diagram of build dependencies @@ -248,8 +248,12 @@ The main story here is revealed when looking at the core MLIR dialects Allo is e ## Future Work -TODO -- Fix how allow constructs affine for. Needs to Store to load forward +Given that the focus of this project was primarily the software plumbing required to get things working end-to-end, there is still a lot of work needed to increase the quality of results. Right now, there are too many ways to accidentally create a slow design that has many redundant memory operations. Moreover, some designs just don't work, exposing bugs in our scheduling pass. Here is a list of features and fixes we intend to eventually implement: + +- Fix how Allo constructs `affine.for` loops. Right now Allo is not using inter-iteration arguments, meaning the data flow between loop iterations is through memory reads and writes. This is much slower, because it artificially increases the II of the pipeline. +- Handle scalar values. Allo creates a memref cell to hold scalar values, and this once again limits performance. Every interaction with the variable is with loads and stores, instead of doing the proper SSA conversion. +- Fix scheduler bugs. +- Use Allo customization directives to assist AMC in inferring more efficient scratchpad memories. For example, array partitioning and memory access patterns are hints that Allo could provide to our allocation pass. ## Conclusion From cf80385816ae81356c75c5f9a8b9f305cdf09593 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 19:47:54 -0500 Subject: [PATCH 15/29] add tool flow image --- .../2023-12-09-allo-amc/allo_dependencies.png | Bin 0 -> 30567 bytes content/2023-12-09-allo-amc/index.md | 30 +++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 content/2023-12-09-allo-amc/allo_dependencies.png diff --git a/content/2023-12-09-allo-amc/allo_dependencies.png b/content/2023-12-09-allo-amc/allo_dependencies.png new file mode 100644 index 0000000000000000000000000000000000000000..643dc6e2909f20fa1b503ee925c6d723ee3028c4 GIT binary patch literal 30567 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�qW8-uX8 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 +```mlir + amc.memory @amcMemory0(!amc.dynamic_port<256xi32, w>, !amc.dynamic_port<128xi32, r>, !amc.dynamic_port<128xi32, r>) { + %0 = amc.alloc : !amc.memref<256xi32> + %1 = amc.create_port(%0 : !amc.memref<256xi32>) : !amc.dynamic_port<256xi32, w> + %2 = amc.create_port(%0 : !amc.memref<256xi32>) : !amc.dynamic_port<256xi32, r> + amc.extern %1, %2, %2 : !amc.dynamic_port<256xi32, w>, !amc.dynamic_port<256xi32, r>, !amc.dynamic_port<256xi32, r> + } + func.func @main(%arg0: memref<256xi32>, %arg1: memref<256xi32>, %arg2: memref<256xi32>) { + %0:3 = amc.inst @amcMemory0_inst of @amcMemory0 : !amc.dynamic_port<256xi32, w>, !amc.dynamic_port<256xi32, r>, + !amc.dynamic_port<256xi32, r> + // Buffer data into a scratchpad + affine.for %arg3 = 0 to 256 { + %1 = affine.load %arg0[%arg3] : memref<256xi32> + amc.affine_store %1, %0#0[%arg3] : !amc.dynamic_port<256xi32, w> + } + // Split data into two separate outputs + affine.for %arg3 = 0 to 128 { + %1 = amc.affine_load %0#1[%arg3] : !amc.dynamic_port<256xi32, r> + %2 = amc.affine_load %0#2[%arg3 + 128] : !amc.dynamic_port<256xi32, r> + affine.store %1, %arg1[%arg3] : memref<128xi32> + affine.store %2, %arg2[%arg3 + 128] : memref<128xi32> + } + return + } +``` The following diagram shows the full pass pipeline of compiling the core MLIR dialects to Verilog: From 8a5a9a171529f98c652f635bd1e6fddbbd550677 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 20:00:47 -0500 Subject: [PATCH 16/29] fix some formatting issues --- content/2023-12-09-allo-amc/index.md | 31 +++++++++------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 61802c186..2c67c3671 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -42,7 +42,8 @@ def test_amc(): A = np.random.randint(0, 20, size=(N, N), dtype="int32") B = np.random.randint(0, 20, size=(N, N), dtype="int32") - # Our kernel is just matrix multiplication, Allo provides a primitive for this + # Our kernel is just matrix multiplication + # Allo provides a primitive for this def kernel(A: int32[N, N], B: int32[N, N]) -> int32[N, N]: return allo.matmul(A, B) @@ -161,7 +162,7 @@ To conclude, we hope this example demonstrates the usefulness of the Allo fronte Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding the interactions of each component is important to understanding the novelty in our approach.

-Diagram of build dependencies +Diagram of build dependencies
The top row of dependencies are C++ codebases linked together as static libraries. We enter interact with this library with input MLIR generated from Allo. On the backend, we emit Calyx which is lowered to Verilog by a separate [Calyx compiler](https://github.com/cucapra/calyx) that is written in Rust. @@ -204,7 +205,7 @@ TODO: what is the most important feature of Allo for this project? AMC (Accelerator Memory Compiler) is an entirely new plane of intermediate representation dedicated to representing memory architecture. To explain the need for such a dialect, the current state of conventional high-level synthesis compilers must be understood. As a brief summary, current HLS tools lacks an expressive model of memory, and it takes great manual effort to unlock the power of spatial architectures. This is by and large a consequence of the chosen source language. Most HLS compilers have a C/C++ frontend and LLVM middle end. As a consequence, every HLS compiler also has a set of compiler directives (`#pragma`'s) to fill in the semantic gaps of compiling to spatial hardware. For example, there are pragmas for partitioning memories, instantiating FIFOs, loop pipelining, and much more. By not having first class constructs for these design elements, optimization becomes tightly-coupled with source rewrites and HLS falls flat on its promises of high productivity. For the interested reader, we think this [blog post](https://specbranch.com/posts/fpgas-what-happened/) helps explain the current state of the FPGA accelerators for outsiders. -Back to AMC, the custom dialect elaborates the *real* limiting resources of memory on spatial architectures: the ports. Each embedded block RAM on the FPGA has only two ports, and it takes an intelligent design methodology to utilize these memories in such a way that maximizes performance. AMC eliminates the guessing game by elaborating the description of the memory subsystem and optimizing it for the program at hand. To accompany the AMC dialect, we use [Calyx IR](https://calyxir.org/) to represent the control logic of the scheduled program. Here is a very simple program allocated with an AMC memory: +Back to AMC, the custom dialect elaborates the *real* limiting resources of memory on spatial architectures: the ports. Each embedded block RAM on the FPGA has only two ports, and it takes an intelligent design methodology to utilize these memories in such a way that maximizes performance. AMC eliminates the guessing game by elaborating the description of the memory subsystem and optimizing it for the program at hand. To accompany the AMC dialect, we use [Calyx IR](https://calyxir.org/) to represent the control logic of the scheduled program. Here is a very simple program allocated with a high-level AMC memory: ```mlir amc.memory @amcMemory0(!amc.dynamic_port<256xi32, w>, !amc.dynamic_port<128xi32, r>, !amc.dynamic_port<128xi32, r>) { @@ -213,29 +214,14 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo %2 = amc.create_port(%0 : !amc.memref<256xi32>) : !amc.dynamic_port<256xi32, r> amc.extern %1, %2, %2 : !amc.dynamic_port<256xi32, w>, !amc.dynamic_port<256xi32, r>, !amc.dynamic_port<256xi32, r> } - func.func @main(%arg0: memref<256xi32>, %arg1: memref<256xi32>, %arg2: memref<256xi32>) { - %0:3 = amc.inst @amcMemory0_inst of @amcMemory0 : !amc.dynamic_port<256xi32, w>, !amc.dynamic_port<256xi32, r>, - !amc.dynamic_port<256xi32, r> - // Buffer data into a scratchpad - affine.for %arg3 = 0 to 256 { - %1 = affine.load %arg0[%arg3] : memref<256xi32> - amc.affine_store %1, %0#0[%arg3] : !amc.dynamic_port<256xi32, w> - } - // Split data into two separate outputs - affine.for %arg3 = 0 to 128 { - %1 = amc.affine_load %0#1[%arg3] : !amc.dynamic_port<256xi32, r> - %2 = amc.affine_load %0#2[%arg3 + 128] : !amc.dynamic_port<256xi32, r> - affine.store %1, %arg1[%arg3] : memref<128xi32> - affine.store %2, %arg2[%arg3 + 128] : memref<128xi32> - } - return - } ``` +The role of the AMC compiler is to take in a high-level description of memory organization and figure out how to best compile it to the target architecture. It accounts for some of the properties of ... TODO finish. + The following diagram shows the full pass pipeline of compiling the core MLIR dialects to Verilog:
-Diagram for AMC pass pipeline +Diagram for AMC pass pipeline
## Results @@ -243,6 +229,7 @@ The following diagram shows the full pass pipeline of compiling the core MLIR di In this section, we report the latency and resource measures of a select set of micro-benchmarks. By using small testcases, we have the best chance of understanding how the high-level constructs are being mapped to hardware and where the compiler inefficiencies lie. With that said, here are a table of benchmarks compiled with our toolflow versus Vitis C HLS. **AMC** + | Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | | ------------- | ---------------- | ---- | --- | ------- | ---- | | matmul16x16 | 15016 | 467 | 255 | 1 | 3 | @@ -251,6 +238,7 @@ In this section, we report the latency and resource measures of a select set of | fibonacci20 | 77 | 120 | 151 | 0 | 0 | **Vitis 2022** + | Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | | ------------- | ---------------- | ---- | --- | ------- | ---- | | matmul16x16 | 5409 | 221 | 74 | 0 | 3 | @@ -259,6 +247,7 @@ In this section, we report the latency and resource measures of a select set of | fibonacci20 | 41 | 226 | 50 | 0 | 0 | **Difference: AMC - Vitis** + | Benchmark | Latency (Cycles) | LUTs | FFs | BRAM36s | DSPs | | ------------- | ---------------- | ----- | ------ | ------- | ----- | | matmul16x16 | +170% | +110% | +240% | - | +0% | From 751942f82f3a84a94bfdc6e95762ad6e550423c6 Mon Sep 17 00:00:00 2001 From: Yixiao Du Date: Sun, 10 Dec 2023 20:56:20 -0500 Subject: [PATCH 17/29] add overview figure --- content/2023-12-09-allo-amc/index.md | 3 +++ content/2023-12-09-allo-amc/overview.svg | 1 + 2 files changed, 4 insertions(+) create mode 100644 content/2023-12-09-allo-amc/overview.svg diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 2c67c3671..274fb8d5f 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -14,6 +14,9 @@ name = "Yixiao Du" ## Introduction For our final course project, we have integrated our HLS (high-level sythesis) compiler, AMC, with a Python frontend, called Allo. In the end, we are able to compile and simulate custom hardware designs with extremely concise design descriptions and short compile times. As a consequence, we greatly reduce the design effort required for new accelerators as well as offer a convenient tool for functional verification. In this report, we walk through an example design with our tool flow, offer insight into how the underlying compiler works, and finally evaluate some benchmarks with latency and resource utilization measurements. +
+Project Overview +
### Hardware Accelerators diff --git a/content/2023-12-09-allo-amc/overview.svg b/content/2023-12-09-allo-amc/overview.svg new file mode 100644 index 000000000..52c392fdd --- /dev/null +++ b/content/2023-12-09-allo-amc/overview.svg @@ -0,0 +1 @@ +
design.py
design.py
Hardware
Hardware
Testbench
Testbench
Allo
Allo
AMC
AMC
Calyx
Calyx
Text is not SVG - cannot display
\ No newline at end of file From fb23a22e57b353b7ea602f6c8ac9dd2339a23827 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 22:34:36 -0500 Subject: [PATCH 18/29] address TODO comments --- content/2023-12-09-allo-amc/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 274fb8d5f..8674817e5 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -185,7 +185,7 @@ def matmul(A: int32[16, 16], B: int32[16, 16]) -> int32[16, 16]: return C ``` -[This blog post](https://siboehm.com/articles/22/Fast-MMM-on-CPU) describes an effective way of optimizing matrix multiplication. The key idea is to reorder and tile the loops for a better data locality. The optimized loop order would be `i, k, j`. With Allo, we can easily achieve this with just two lines of code: +[This blog post](https://siboehm.com/articles/22/Fast-MMM-on-CPU) elaborates effective ways of optimizing matrix multiplication, which can be replicated in Allo. The key idea is to reorder and tile the loops for better data locality. The optimized loop ordering would be `i, k, j`. With Allo, we can easily achieve this with just two lines of code: ```python schedule = allo.customize(matmul) @@ -202,7 +202,7 @@ Finally, we can build the design for various backends: module = schedule.build(target="llvm") # can also be 'vlhs', 'amc' ``` -TODO: what is the most important feature of Allo for this project? +This is just one example of compute customizations with Allo, and there are several other hardware customization primitives that will play to AMC's strengths. We believe that with some additional work the Allo frotnend can provides hints for AMC to better infer FIFO streams, partitioned arrays, and banked memories. Such memory customizations will allow for more elaborate parallelization schemes, and ultimately we expect speedups that will beat the commercial tools. ### AMC @@ -219,9 +219,7 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo } ``` -The role of the AMC compiler is to take in a high-level description of memory organization and figure out how to best compile it to the target architecture. It accounts for some of the properties of ... TODO finish. - -The following diagram shows the full pass pipeline of compiling the core MLIR dialects to Verilog: +The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count, as well as the context in which the memory is being used. It is a very gradual lowering process, and the explanation of the whole pass pipeline won't even start to fit in this post. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog:
Diagram for AMC pass pipeline @@ -271,4 +269,6 @@ Given that the focus of this project was primarily the software plumbing require ## Conclusion -The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding a new test case. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. \ No newline at end of file +The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding test cases. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. We are optimistic that having Allo as a frontend will accelerate the development of AMC. + +Both Allo and AMC are ongoing developments that are not ready to be open sourced. However, [the HCL dialect](https://github.com/cornell-zhang/hcl-dialect), [CIRCT](https://github.com/llvm/circt), and [Calyx](https://github.com/cucapra/calyx) all have public GitHub repositories. \ No newline at end of file From 6efeeb0557a6eafa57994823f33dcc051c90a1cf Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 22:39:48 -0500 Subject: [PATCH 19/29] giv eHongzheng shoutout --- content/2023-12-09-allo-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/2023-12-09-allo-amc/index.md b/content/2023-12-09-allo-amc/index.md index 8674817e5..9fbb9481c 100644 --- a/content/2023-12-09-allo-amc/index.md +++ b/content/2023-12-09-allo-amc/index.md @@ -271,4 +271,4 @@ Given that the focus of this project was primarily the software plumbing require The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding test cases. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. We are optimistic that having Allo as a frontend will accelerate the development of AMC. -Both Allo and AMC are ongoing developments that are not ready to be open sourced. However, [the HCL dialect](https://github.com/cornell-zhang/hcl-dialect), [CIRCT](https://github.com/llvm/circt), and [Calyx](https://github.com/cucapra/calyx) all have public GitHub repositories. \ No newline at end of file +Both Allo and AMC are ongoing developments that are not ready to be open sourced. However, [the HCL dialect](https://github.com/cornell-zhang/hcl-dialect), [CIRCT](https://github.com/llvm/circt), and [Calyx](https://github.com/cucapra/calyx) all have public GitHub repositories. Finally, we want to thank [Hongzheng](https://www.linkedin.com/in/hongzheng-chen/en) for helping familiarize us with his Allo work. \ No newline at end of file From 75be3350cf837121e6659da8bffce0344ebeb2c5 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 22:43:50 -0500 Subject: [PATCH 20/29] move post to right dir --- .../2023-12-09-allo-amc/allo_dependencies.png | Bin .../{ => blog}/2023-12-09-allo-amc/amc_passes.png | Bin content/{ => blog}/2023-12-09-allo-amc/index.md | 0 content/{ => blog}/2023-12-09-allo-amc/overview.svg | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename content/{ => blog}/2023-12-09-allo-amc/allo_dependencies.png (100%) rename content/{ => blog}/2023-12-09-allo-amc/amc_passes.png (100%) rename content/{ => blog}/2023-12-09-allo-amc/index.md (100%) rename content/{ => blog}/2023-12-09-allo-amc/overview.svg (100%) diff --git a/content/2023-12-09-allo-amc/allo_dependencies.png b/content/blog/2023-12-09-allo-amc/allo_dependencies.png similarity index 100% rename from content/2023-12-09-allo-amc/allo_dependencies.png rename to content/blog/2023-12-09-allo-amc/allo_dependencies.png diff --git a/content/2023-12-09-allo-amc/amc_passes.png b/content/blog/2023-12-09-allo-amc/amc_passes.png similarity index 100% rename from content/2023-12-09-allo-amc/amc_passes.png rename to content/blog/2023-12-09-allo-amc/amc_passes.png diff --git a/content/2023-12-09-allo-amc/index.md b/content/blog/2023-12-09-allo-amc/index.md similarity index 100% rename from content/2023-12-09-allo-amc/index.md rename to content/blog/2023-12-09-allo-amc/index.md diff --git a/content/2023-12-09-allo-amc/overview.svg b/content/blog/2023-12-09-allo-amc/overview.svg similarity index 100% rename from content/2023-12-09-allo-amc/overview.svg rename to content/blog/2023-12-09-allo-amc/overview.svg From 7d37730a0b62736df62c45f0be8ed6fb68eb3347 Mon Sep 17 00:00:00 2001 From: matth2k Date: Sun, 10 Dec 2023 22:49:01 -0500 Subject: [PATCH 21/29] make title not wrap --- content/blog/2023-12-09-allo-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/2023-12-09-allo-amc/index.md b/content/blog/2023-12-09-allo-amc/index.md index 9fbb9481c..b682d8809 100644 --- a/content/blog/2023-12-09-allo-amc/index.md +++ b/content/blog/2023-12-09-allo-amc/index.md @@ -1,5 +1,5 @@ +++ -title = "Frontend Integration for AMC (Accelerator Memory Compiler)" +title = "Frontend Integration for Accelerator Memory Compiler" [extra] bio = """ Matthew Hofmann is a 2nd year Ph.D. student researching design automation for reconfigurable hardware.
From 3fd08a09c12e991ecb9efcf4a97dcf059c6ab293 Mon Sep 17 00:00:00 2001 From: matth2k Date: Tue, 12 Dec 2023 18:23:46 -0500 Subject: [PATCH 22/29] rename frontend --- ..._dependencies.png => hcl_dependencies.png} | Bin content/blog/2023-12-09-allo-amc/index.md | 65 +++++++----------- 2 files changed, 25 insertions(+), 40 deletions(-) rename content/blog/2023-12-09-allo-amc/{allo_dependencies.png => hcl_dependencies.png} (100%) diff --git a/content/blog/2023-12-09-allo-amc/allo_dependencies.png b/content/blog/2023-12-09-allo-amc/hcl_dependencies.png similarity index 100% rename from content/blog/2023-12-09-allo-amc/allo_dependencies.png rename to content/blog/2023-12-09-allo-amc/hcl_dependencies.png diff --git a/content/blog/2023-12-09-allo-amc/index.md b/content/blog/2023-12-09-allo-amc/index.md index b682d8809..75021d90b 100644 --- a/content/blog/2023-12-09-allo-amc/index.md +++ b/content/blog/2023-12-09-allo-amc/index.md @@ -13,7 +13,7 @@ name = "Yixiao Du" ## Introduction -For our final course project, we have integrated our HLS (high-level sythesis) compiler, AMC, with a Python frontend, called Allo. In the end, we are able to compile and simulate custom hardware designs with extremely concise design descriptions and short compile times. As a consequence, we greatly reduce the design effort required for new accelerators as well as offer a convenient tool for functional verification. In this report, we walk through an example design with our tool flow, offer insight into how the underlying compiler works, and finally evaluate some benchmarks with latency and resource utilization measurements. +For our final course project, we have integrated our HLS (high-level sythesis) compiler, AMC, with a Python frontend, called HCL. In the end, we are able to compile and simulate custom hardware designs with extremely concise design descriptions and short compile times. As a consequence, we greatly reduce the design effort required for new accelerators as well as offer a convenient tool for functional verification. In this report, we walk through an example design with our tool flow, offer insight into how the underlying compiler works, and finally evaluate some benchmarks with latency and resource utilization measurements.
Project Overview
@@ -30,11 +30,11 @@ High-Level Synthesis (HLS) is one such solution to solve the problem of hardware Reinventing HLS with advanced compiler techniques is an active area of research. There are many outstanding HLS tools/frameworks such as [TAPA](https://tapa.readthedocs.io/en/release/overview/overview.html), [Dynamatic](https://dynamatic.epfl.ch/), and [HeteroCL](https://heterocl.csl.cornell.edu/). However, these tools are developed independently with different compilation flows, which brings difficulties of integrating them together. [MLIR](https://mlir.llvm.org/) is a new compiler design paradigm where the source language is compiled through multiple levels of modularized intermediate representations (IRs), also known as dialects. Dialects act like domain-specific languages (DSLs) and can capture the approprate details at each level of abstraction. -The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called Allo. Allo decouples the interactions between the algorithm, hardware optimizations, and backend targets to enable productive design and testing. Lastly, Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. Its expressiveness is able to capture common memory organization strategies such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is also part of the CIRCT ecosystem. Calyx IR gives us a pathway to finally to synthesizable Verilog. The contribution of this project is that we integrated Allo with AMC to enable a Python frontend for AMC. This allows us to use Allo to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single function call. In the end, we hope that this integration will enable a more productive design flow for hardware accelerators as well as help us find more bugs in AMC. +The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called HCL. HCL decouples the interactions between the algorithm, hardware optimizations, and backend targets to enable productive design and testing. Lastly, Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. Its expressiveness is able to capture common memory organization strategies such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is also part of the CIRCT ecosystem. Calyx IR gives us a pathway to finally to synthesizable Verilog. The contribution of this project is that we integrated HCL with AMC to enable a Python frontend for AMC. This allows us to use HCL to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single function call. In the end, we hope that this integration will enable a more productive design flow for hardware accelerators as well as help us find more bugs in AMC. ## Design Example -To use Allo with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts as a drop-in replacement to the other backends in the Allo ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. +To use HCL with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts as a drop-in replacement to the other backends in the HCL ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. Our illustrative example will be matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: @@ -46,18 +46,18 @@ def test_amc(): B = np.random.randint(0, 20, size=(N, N), dtype="int32") # Our kernel is just matrix multiplication - # Allo provides a primitive for this + # HCL provides a primitive for this def kernel(A: int32[N, N], B: int32[N, N]) -> int32[N, N]: - return allo.matmul(A, B) + return matmul(A, B) # Build the accelerator with AMC backend - s = allo.customize(kernel) + s = customize(kernel) f = s.build(target="amc") # Run the software simulation by invoking directly np_out = kernel(A, B) # Now run the hardware simulation with AMC - allo_out = f(A, B) - np.testing.assert_array_equal(allo_out, np_out) + hcl_out = f(A, B) + np.testing.assert_array_equal(hcl_out, np_out) ``` Additionally, we can also get an approximation of how much FPGA resources this design uses. Simply call `.get_resource_estimates()` after building: @@ -156,53 +156,38 @@ def vadd(A: uint32[N], B: uint32[N]) -> uint32[N]: return A + B ``` -Outside of what is shown here, the Allo DSL allows much more elaborate kernels and control over compute customizations, like loop tiling and reuse buffers. One again, you can get more information on Allo and its MLIR dialect by reading last years blog post by [Hongzheng Chen](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/hcl-mlir/). +Outside of what is shown here, the HCL DSL allows much more elaborate kernels and control over compute customizations, like loop tiling and reuse buffers. One again, you can get more information on HCL and its MLIR dialect by reading last years blog post by [Hongzheng Chen](https://www.cs.cornell.edu/courses/cs6120/2022sp/blog/hcl-mlir/). -To conclude, we hope this example demonstrates the usefulness of the Allo frontend for high-level hardware design and further development of the AMC HLS compiler. As far as we are aware, the only other frameworks using Python to drive FPGA high-level synthesis are [LeFlow](https://arxiv.org/abs/1807.05317) and [PyLog](https://ieeexplore.ieee.org/document/9591456). However, neither of these efforts are using a homebrewed HLS compiler like us. +To conclude, we hope this example demonstrates the usefulness of the HCL frontend for high-level hardware design and further development of the AMC HLS compiler. As far as we are aware, the only other frameworks using Python to drive FPGA high-level synthesis are [LeFlow](https://arxiv.org/abs/1807.05317) and [PyLog](https://ieeexplore.ieee.org/document/9591456). However, neither of these efforts are using a homebrewed HLS compiler like us. ## Tool flow -Under the hood, the Allo frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding the interactions of each component is important to understanding the novelty in our approach. +Under the hood, the HCL frontend is automating all the interactions with other tools, IRs, and frameworks. Nonetheless, understanding the interactions of each component is important to understanding the novelty in our approach.
-Diagram of build dependencies +Diagram of build dependencies
-The top row of dependencies are C++ codebases linked together as static libraries. We enter interact with this library with input MLIR generated from Allo. On the backend, we emit Calyx which is lowered to Verilog by a separate [Calyx compiler](https://github.com/cucapra/calyx) that is written in Rust. +The top row of dependencies are C++ codebases linked together as static libraries. We enter this library with input MLIR generated from HCL. On the backend, we emit Calyx which is lowered to Verilog by a separate [Calyx compiler](https://github.com/cucapra/calyx) that is written in Rust. -The HCL dialect and passes are primarily responsible for processing the customization directives of the Allo frontend. Then, AMC and CIRCT carry out the "traditional" steps of high-level synthesis: allocation, scheduling, and binding. Finally, the Calyx compiler generates the data paths and control logic for the scheduled program. +The HCL dialect and passes are primarily responsible for processing the customization directives of the HCL frontend. Then, AMC and CIRCT carry out the "traditional" steps of high-level synthesis: allocation, scheduling, and binding. Finally, the Calyx compiler generates the data paths and control logic for the scheduled program. ### Overview -### Allo -Allo leverages an algorithm-optimization decoupled paradigm, which means users can first define the algorithm in a high-level language and then optimize the program with various hardware customization techniques (i.e., schedule primitives). Back to the matmul example, without using the provided primitive, the code would look like this: +### HCL +HCL leverages an algorithm-optimization decoupled paradigm, which means users can first define the algorithm in a high-level language and then optimize the program with various hardware customization techniques (i.e., schedule primitives). Back to the matmul example, without using the provided primitive, the code would look like this: ```python def matmul(A: int32[16, 16], B: int32[16, 16]) -> int32[16, 16]: C: int32[16, 16] = 0 - for i, j, k in allo.grid(16, 16, 16): + for i, j, k in grid(16, 16, 16): C[i, j] += A[i, k] * B[k, j] return C ``` -[This blog post](https://siboehm.com/articles/22/Fast-MMM-on-CPU) elaborates effective ways of optimizing matrix multiplication, which can be replicated in Allo. The key idea is to reorder and tile the loops for better data locality. The optimized loop ordering would be `i, k, j`. With Allo, we can easily achieve this with just two lines of code: +[This blog post](https://siboehm.com/articles/22/Fast-MMM-on-CPU) elaborates effective ways of optimizing matrix multiplication, which can be replicated in HCL. The key idea is to reorder and tile the loops for better data locality. The optimized loop ordering would be `i, k, j`. -```python -schedule = allo.customize(matmul) -schedule.reorder("i", "k", "j") -``` - -Loop tiling is supported by the `split()` directive: -```python -schedule.split("i", factor=4) -``` - -Finally, we can build the design for various backends: -```python -module = schedule.build(target="llvm") # can also be 'vlhs', 'amc' -``` - -This is just one example of compute customizations with Allo, and there are several other hardware customization primitives that will play to AMC's strengths. We believe that with some additional work the Allo frotnend can provides hints for AMC to better infer FIFO streams, partitioned arrays, and banked memories. Such memory customizations will allow for more elaborate parallelization schemes, and ultimately we expect speedups that will beat the commercial tools. +This is just one example of compute customizations with HCL, and there are several other hardware customization primitives that will play to AMC's strengths. We believe that with some additional work the HCL frotnend can provides hints for AMC to better infer FIFO streams, partitioned arrays, and banked memories. Such memory customizations will allow for more elaborate parallelization schemes, and ultimately we expect speedups that will beat the commercial tools. ### AMC @@ -256,19 +241,19 @@ In this section, we report the latency and resource measures of a select set of | vadd20 | +410% | +760% | +2200% | - | -300% | | fibonacci20 | +88% | -47% | +200% | - | - | -The main story here is revealed when looking at the core MLIR dialects Allo is emitting after parsing the AST. Inefficiencies in how Allo infers data types and creates `affine.for` loop nests is creating way too many redundant memory operations. For example, Allo is not using store-to-load forwarding between loop iterations. Even worse, Allo tries to explicity infer data type conversions when using operations that change the data width (e.g. 32b + 32b = 33b). This for some reason is causing extra memory copy loops to convert an entire memory before it is used. We anticipate that fixing the Allo frontend to produce higher-quality loops will take some time, as it depends on some level of memory dependence analysis. Nonetheless, it will be a very important improvement to make in order to reach similar latencies as what Vitis can produce with C code. +The main story here is revealed when looking at the core MLIR dialects HCL is emitting after parsing the AST. Inefficiencies in how HCL infers data types and creates `affine.for` loop nests is creating way too many redundant memory operations. For example, HCL is not using store-to-load forwarding between loop iterations. Even worse, HCL tries to explicity infer data type conversions when using operations that change the data width (e.g. 32b + 32b = 33b). This for some reason is causing extra memory copy loops to convert an entire memory before it is used. We anticipate that fixing the HCL frontend to produce higher-quality loops will take some time, as it depends on some level of memory dependence analysis. Nonetheless, it will be a very important improvement to make in order to reach similar latencies as what Vitis can produce with C code. ## Future Work Given that the focus of this project was primarily the software plumbing required to get things working end-to-end, there is still a lot of work needed to increase the quality of results. Right now, there are too many ways to accidentally create a slow design that has many redundant memory operations. Moreover, some designs just don't work, exposing bugs in our scheduling pass. Here is a list of features and fixes we intend to eventually implement: -- Fix how Allo constructs `affine.for` loops. Right now Allo is not using inter-iteration arguments, meaning the data flow between loop iterations is through memory reads and writes. This is much slower, because it artificially increases the II of the pipeline. -- Handle scalar values. Allo creates a memref cell to hold scalar values, and this once again limits performance. Every interaction with the variable is with loads and stores, instead of doing the proper SSA conversion. +- Fix how HCL constructs `affine.for` loops. Right now HCL is not using inter-iteration arguments, meaning the data flow between loop iterations is through memory reads and writes. This is much slower, because it artificially increases the II of the pipeline. +- Handle scalar values. HCL creates a memref cell to hold scalar values, and this once again limits performance. Every interaction with the variable is with loads and stores, instead of doing the proper SSA conversion. - Fix scheduler bugs. -- Use Allo customization directives to assist AMC in inferring more efficient scratchpad memories. For example, array partitioning and memory access patterns are hints that Allo could provide to our allocation pass. +- Use HCL customization directives to assist AMC in inferring more efficient scratchpad memories. For example, array partitioning and memory access patterns are hints that HCL could provide to our allocation pass. ## Conclusion -The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding test cases. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. We are optimistic that having Allo as a frontend will accelerate the development of AMC. +The project was by and large a success, because we have achieved a much higher level of automation in evaluating the AMC+Calyx toolflow. Being able to write HLS kernels with `numpy` and run the RTL simulation as a normal function call greatly reduces the amount of effort in adding test cases. Moreover, the `.dump_vcd()` and `.get_resource_estimates()` provide more tools for debugging without having to manually interact with the synthesis tools. We are optimistic that having HCL as a frontend will accelerate the development of AMC. -Both Allo and AMC are ongoing developments that are not ready to be open sourced. However, [the HCL dialect](https://github.com/cornell-zhang/hcl-dialect), [CIRCT](https://github.com/llvm/circt), and [Calyx](https://github.com/cucapra/calyx) all have public GitHub repositories. Finally, we want to thank [Hongzheng](https://www.linkedin.com/in/hongzheng-chen/en) for helping familiarize us with his Allo work. \ No newline at end of file +Both HCL and AMC are ongoing developments that are not ready to be open sourced. However, [the HCL dialect](https://github.com/cornell-zhang/hcl-dialect), [CIRCT](https://github.com/llvm/circt), and [Calyx](https://github.com/cucapra/calyx) all have public GitHub repositories. Finally, we want to thank [Hongzheng](https://www.linkedin.com/in/hongzheng-chen/en) for helping familiarize us with his HCL work. \ No newline at end of file From 846d583d44637d200a2c0e255b23bf07c8d8e631 Mon Sep 17 00:00:00 2001 From: matth2k Date: Tue, 12 Dec 2023 18:25:43 -0500 Subject: [PATCH 23/29] update figure --- .../2023-12-09-allo-amc/hcl_dependencies.png | Bin 30567 -> 71026 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/content/blog/2023-12-09-allo-amc/hcl_dependencies.png b/content/blog/2023-12-09-allo-amc/hcl_dependencies.png index 643dc6e2909f20fa1b503ee925c6d723ee3028c4..eefe45430fbfe397bc97ae55acce8678eab2998b 100644 GIT binary patch literal 71026 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�Y7a-I%A{k+(VG#RxNwu$U|{Iqw)Q?!w; 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 literal 30567 zcmeFZXH-*L)F>MDC`S=E9t#QrDosH^snYeJVn9Ht(ovdp34|U%QLq6@l^S|4(xpbF z*Fb;(p(zjogb)cNAqh$Dj^}>w&%3Yuc;6fEzWePl_So5buRYhAbFJCu%9{sgwSiSovSRVSLl=EgvDkG>JC+gn8vyo#^t` z@!GAcOPjBLl=XeSG;;NUYuB062ao?1@ah8TuYwP}r@rfepZ{~H`v?yuWnxPNJihBa zUWAk+;GwqdLrl%ZB-1ZONTwDpbmW7Q2fE@YFg(zMM?U4}IX^&e?{pmkE|D)z0!V;B zIX`Y|aITkcoZ#bJk5!cs-yP;Yvm&WY1210WJaUj!XYcPQI1eN(OyTdeHE78*Uk?2D zH+yc&%;2A|_?1PrwL&lqsTj@&ky$^AW2qLr&62{L+f!Muxj5Iul1m4G%gt|Zf;hJi zo?ZI)b>@G){=Y*OGc(@f;aN0nY!fc~ba|^iuTa{0oz{otvMG22nD7oVj68#z6uT1J zFFB$n+o03rpw6MPr*5l#mxq1Qtgux=V|H}vRRhztJiit64vz1@-^(zn*Zb7=fSY%? ztPiD40NVBGysB?l+-C5PF6&C}ox$vPyPS?3uFb$MEeKXNyZSaW@VTN2zF|;#h^IvS zR%uZAtlt!qfL|r*nNtn|Z9g9l$S5A~p!elzj7{$3xp*1|StOX^+KH++xKpkUTZ8Rj zPLG8%!mZ+DDj6MFKZp6x6mNf%B(04T+^lEPn#?87sVR!y75*fO-++)pC9%`#+0%b= zMsYeI@paQB>b|=ru^jVe8S)G{B`R?~al7g2up?H?r+#(ojwEh+Il#EvdNR95&}SGS zYxA*5s;Sa0E157zdd8^L2#fHG)7VZ5V?{aoMW%3=;O47&M^ysq4h@S*t~JYtpb9?X z8+k+$6ML&;1F#yDA18yM^JpPlta$U*fXHe~#{r+czW3TLHiqdT_ZQTwBt+4yN9F1} zL-Q(FgnjE}IZJo$f5HCHYnu#S%IywrkPIg%Q9j*YKoBX$aWEs>yH{{lC$dCp)1+6rh;v3wut-MulMlq5G^XJQz4I-98iw&LmD)#Vpg|Cn@De3A>D}B zp>Bn{&edAu9I8y$@vx+~%{5a)&p;_{Yexg{2KOjs_>&a#>OM_s;G(FHZZQ50SFHm< zN7;CwMuf#jn>CR-XqRxjydUhR^^u$9?_^YOos}By8z`W8haUhLsdWU_73%j;KYdEM z?WZHDW1+APc3dbqQKG{7No%e1V`1w_S4M!D;m#o=Cud}Nd)(f5ChQ+Lwq5YD^FEjM zhs3G7Jyp)#!Ea?bBYbtOPt?wJD>P`{3@RF@TC^yMM6>$8OjNc1UA5D!C~ITQYOJd& z4Bl*RP-zrQ-%jksMUo{vZ@cY=P`5)H$jxmNt_mDLp^e{!wlVzJY~0jBV3itCGu)p| zO$eR((iTV%^{7)bnnOJ8eOYT^QQ+lec3w?>nU7d3WnQA`X-ctU033&S zl@bxpF-m#2n|0{e?1!?piTw!3yeQtl(g>GsoRF>781^td#c;S+w_3${mRTf<*kY!Y znV7UMpjojMBL{TGnK;YwwB#)C5j2}Kvgu)-h1X3XmRpw7xTAmBN|UCU*1vAQo)n^C z4h>u57D_T=AU-4=v&w8ux$+9x~{(0Nr@^Yjy2L$D5RDdeM+DJxk2cMj8 z?SjqIB@L=b={AjxR=o4IwSKUK-hC5MI$&4zog))+dM~v9U7fkQie8ZX>N4T08ewjG zcQ*?Kcjn$99Ddh|Xlhdo)JA8AdyNKs^SRD0@m39lMs(b0s=Svl8N8Z%$4!0P zXiBp=z&iGP+M#H%YKi`h)4}w@m4cQ5u%HzUMcN{Q6PS04T%NHqI2y)*>ul1Xn?20` zVYXeXal^)sOpV8p2jsxfXeZ1{I<$J0zi@k|A@!>lSEsIX7|~}jP4bKkq3(X8c9xr6 zeH(RhA?AD=Gw%|IPEiXN-UmsO24hmm(KYQoaf2&NbjD{(E`%!}x7tya3d7W<)!~kl zjs1OXR89P)pXKrUmtqMpWuLB$cM%^WLc_i8U3Fe67@MU&25bTl=(u~7+>(rKQfP>r zl{9vmI^j(0nB{uH_EinuY|)=zuxYzYh3?LD#PWU$d9u(-S^7$n zn|G%f|IyiUhJibm6(14i&fA!D2IvalSBoxb?cWlhal5q*oXh-|au!SMQPURW_~oCexIP}rj^bH=OsqvOtYovTv_ ze3ty%IFRp48SiK=5g%^n@d=U;Y2u;ANeg8sN>YL^^x%zlgO>=D>r0>bRy^$KkF>() zO5U$Y@@_TQ8!Uv<)0+3Hkwd!=WxsJ&tb>jYy27%~h48;wGgXMq7ae}n!Yyh$C~ksV zsF$-^YeEy>tR&a@8&ZzCJd57CCVPpbLE2MD?)Gth5A^gW)cn$ISvE{h)S-!gGtyG5s z{JWtl7QEktkuj^b%Z;rfBTKHS=DeN4!>p&czqSJo;ouSB8yg!^F^}W@wwiI~yfuex zgR#lUI-h&pyu5~+5KIEl_Xj@MnvUx7dxhWa@Rd!gjkDh6=UpVr%F737IJiA9rt`p< z1~vc3M*M#&asLZAM*#f4yP*G5X#S;a;D7@@Y1VpY!lc?M*j2Ugrzm9f#7Se7GE-Ha zoKFKnZXR9+v!vuJ#YrbbJxo+OlqUlm9~_TjX<8Zf`WY2M*GUyN$w_z5f5P~lG`6-? zEVSt%sU>UY&IMz78MYXVJOSpzn<^pQSx_LhH*_`P+S5 zs%(r6*H?%uH6rljbghgGgqo5<^~Q|rZoXoD(xypP6h-@T!*V?Gjl#%)s;l8WGDr)Y zl&XxSN3_ZBgrk#EC~qV5%&s)_PU0$%_8;ViO03yuOUji};Q_|7mi47@&y#v}5JEz^ ziFPFX#PpGOa>)LO0I-#LAmZv|W->mUoOOS3Zrd=S0Qe-tST?wx0kc!vpPLI?>`rT= zz*;Ne$pPCezJNal-DU{Mi3R1j2refxRPvU6#%TDIIPDi$61!PFqQ8uZv@p|i3%XL6 zofXnMZqU5?oe#Id2UF$IXM|I&uv_-F;Fcq-lLw=2=?Zv1y=SdD&&VmQBbN2FeCxz!t$wSkK+?YJZ?e$^NhB(Z`TI{_A2W2DG{HS*Lpvn#`vho zDX`huQNzYwMOiTKkt_wxUJ;X7n0e9MM|6yUJiBagXMT1TRr4!-h#3T#A5L|l_YExa z1hnDog2WwpHA^6$gi6~l?)VVzm2JoeFOd|r=RQVz;EI_;erR=WjlU|J=F(OXS#4WG z{@Me4^9en%+1E-&XA%areO+Xmn;4=I5VNfl< zMurdpx6)@5DXnq?GyEcnT&&*uSetX>AB(E9(^M_${oyMWX_<8+%zw0?J@xm`n#^k= z@@0ktW%{TH+Wgf=0Pcb#gPB#2o0l1NE!2-@4QZ?egY|n?PHMq? zJDz=iJ#Yo=F7K?sxKFt{Xi+irTvUa!cx=|pB6O>*@Cw$X$j52%b4QA`0Lu8~T8Aw) z;IoTqVOe9CFdp8Q8!x?A(Jg$5eR_q6^ay~$Gb?FyTqCosddUqeI9W#ZWGsg*(Y zHBCO7MjB$&A(R2__3`_;kC%rojio_6ZQajzZ9Vf+k-cZ)nlLsF`PMAG(~Z1(kHOr5 zFqiyDg}%vkDpmAPN6*!K5%j(IEk0#$Oflsy*+*|>6&v>qR(8at?l3ffNf!(P#zT_M@5;aAx^ zH|-c?!8En)wfk8?{**ESE7ey#n`P8Bbz}9%5Q+G*^Y$K)qAV?GTo`F$C`(m^J4M1v z8;}afjFdX5j$&rdjy$z&E7Afs*W4Vk(4A%%Ov!6ePSmCp-q(VK#BCf+@lt__NB9lY z+o%^yfT0qZTGA(_I%L2QstyffW&pN;{8*VuQ!0iRc8&IG^2rYP$+e+cwFS&E<&a~u z1xYQA?&FOmN`xkrf>OVbqUv_{AjcLf)H8j3W3$9`=Ir>w;^RTX8YaLM`Id&<)&-*6 z9pT_~wFJ{iY$m(mV`NkI#(f5Zxbgx#KT}1BmiA-btV(z;MvZh z{}3u{l|&*gmSy%(Mkmt`bEg{{8v8Bn-dA@HFr3#0H;eDAD)EH{v-jvjXEO@Qm121^ zERC(b2VTt1CX^jbQ(azT8J)Sh?=4GvY@JX*UwNk@z(tpe)s(bgGb<)c#n(Ltl-Scu z+>7V#!4Pm2YYc&{v!@yU{!!D7G&9Vt&O_+xA_rc&Z)r?v8H^U1{-%^6S?K&3yjLJ90 z5g)h>7fiq6A1YnM4QVP(PBx@H`@ZJ%Doe9XV|41}n}rfD;-85pZ>tS`E*9y_52Ocd5|Jl}(G8s|I18Wfo^Y zsLv*%y68hCc%s9X%pQ+wBYjn{ne7O@)lc~x7rIPqhnqGrZS3A-F!*vKjzw%eobk(i zYGaP^Yq@!oOS|75MhK;i$xv5l{HYd(vz2ru@zAT(J`>Opu(ZYGbfUSa* zg*8J2te;Motf%>gm4<=|1{qqpqx*Hy^#S4y#lw9y^Xf^r9-A<1;73Pc{=RjGWjTFa_*%zC08)wgqo87;vMH z$+!{pVd28Yw+Pt%aIo`1xsJr|<9A(|&1NqiPGTt7wP#YU{fX zy0xs2)CVTZH+N|1T4aEa~z+CCp(V zq51RSl(t`b;r@e~s_Z2qw${UY2!;r`WLvHhbo*!a<7;iYsj_|I+H1`+U;Ert8;J5> zs?ZvZCAfj4>xq8*DRa{9uFU<0< z_s?Z-i8nAc3n@P{{00-m9PtXFPa?{>jy>h98}L4~UpRl6@(zNDku5*J@H(#EYxm>N zYNz$uY~4hnf?9($#9_d2XK!48$9zhd{?q5AT`*xPS?8R*(>?5i>c&*eIK?TnY<5yU6ulBgU0O{N>CoB{(Nf{}-Ysi6 zW_Hq8+wmV+%L!C_0VR(IZanL2p(9{#q$fEv^8PwFyoN=w^YQ|$RI$PdVWm-Nr|C>! zl2&kh8YwA~sixkTWv_KoeQ&l+0_Tjddge-;yw-aj`UqP;KP3x`XUPu2y$tX@<}uJp zye}KHQG8uDrT)W5!wDo zwH_R=J)go6Y}ztk>ZmuKqV`0kiXXa73=Mq(f{k0=$gC#i!mtpm4in&`85uXc-iFJB z>px~F*oL14hW9s(CkL|g+m(iANfY^15cA4S)r|TGsK#vFCo6cwl}aSSRCP%C(eA{K zC2-Pkhhx*!*4HW)OsYSe`#>2&{2bXTbm|=%*#zT#DjCz8_nYfg4X|h%?dt3N=PiOA zT797k8wx)&m@=h=d*d>(>uXZZm^1~Gi~@wMZL^=5TF6$p$`kF-8p1m3m618`M+5lP z>7+%(WOArTxCT{gKWKrb%W&T4%9k$QObJ*It)I&rL}sQBO82T1nI^iy5o#9f;-h$C zrK2=i1ieZ1v z_jwhU^$+nG4c-Y<@eTuf(Z0>0b}m%SXi}N;*v4Lf7ymvHuX)$a2BrmFdY;@VIF?f6 zAvkUoOb#?lC^JrgMeekm6{r=?kE zxHtr(M4R(|t!fB>*8xH}T-$-zid>ipgttq_1RC85k54HxQCZ(RAMt&6f=w%yhi%@~ z>M-ZArsf8m}LmO_vPiES|-8u!wr|Sv==<9e2KbGMG zUal4EohW8~f-agoJv0L-yh}?py=Rqa6*hG3A`4!hlJbjwKGXNQ249<2YZlIpeM~N2 z7Bam_6t>O?B!cy;kF0fD*bT}Fhqpn3q7I=4qNbYKz50&m-wTKI!tle7vr-OE6*p%V z_?yOQw~5MdTT2x??G_xpGC!F~dJ71xp2nec^$+5H&{FvIi>Wf63l3nfUILHX#y!2_ z3Eaf+)g3vr_`X|aU~7w75;^$|-l_53MV;ssq~Q%^CDA}qvPsm}&Ue`(3SNU!F`2{G8!KCsl_vf17L7Em76@-EX1en(_I)D5rto&ciUpfBbmT;}{0}mDs|B-g z2>rOQ$->*kaljxg!V$SFH6YVWIw^@8AiJ7gE?$q>L6K7VdDm9SPz4v4?}fu|c0OP) zz{m5_)7480UoFjucoN`c>mDQFWs9xXoK1(g%N(9DEHczkTaLR?4+)B&>Ue?$`a_g& z0ah+16y@-JEXKlnL17ccF?Kb}0+^w!xGIBrUvir7_qnjWcigCuLGiSmO_B|DTwej^ zsGe!;<*qAfnVB?;L7|fm5EiFH;)0JKs1U~R%pJg6sQ9r(+S2gP*YBZpW&-q2PTVG``%t<6jg=NFMphX=InKhQMcJbIn_ z8LS4132o_cS|A%l{nOFaX|(`FH!Ah=xz~wQPuMU~2=&uC(g1 z%6G}y2cbG_yRO=rWeT@}uODh|vYT8P(kOJLZH@D!vDfGsjHz_%a7+?9Mo@tW-!f>m zK2Q_OtG@DepY}eHR9PLS%)j3ozuL9Tx)Ewd<17C{95a?+4^PqtCbmRB#f2hLnirog z^nv@0i?Wnul+3^bd@d}5L$FmR)nOhUH@mr{XnYk?M_S`rWESp2)Iyr2$o{wur3tr! z2nz^U(1!lAaD50oxlVVSeG%7zXO)P`25J;%ha%A+xj5EA7N{sR-6!{L0(v za9MaJjdlJy-8OlA`fmbHT0|(7m9v^;S-NP$rMYF2Ht(l^qs-z8A4gi0Ph?+LIH?Ct zQCwZsorT~G46YQbjcaSbzEZQ&!_b!V2we-0Rof5)%#mlx&C4l+km3CKm~y3Jq`;$V zFOP}pZe}PLW@oa)S(ZT7Lo1nc^HG#inc3JYy%}0xCX2IUCEpj$7Q@!>FE6gNa;xm0 zwN4K=cZoMlfTSY=!2(AhJ$~!^HWWF{Cea&V0WMi<{*vnE|H!;$34fnqM(;@Z#R=m64NW=}9#n!!dv^mL< zHQ0m0vsHwi!)_b*0q4|2J78nAy0Nlsu)=b@1qTJy5q z!T!GWQtjZJqjLRU{2)Iwx1w-yt+E3%_HLV6{iE@u@6vvh!`v-8-+%SfhJwk5c%wgv zMbIT9GPy@+k2=W7$W^3kW)fi4mq3oePSZ5iw&uc?t0k$MtyYkkSBvw{EG^xvI`-fj z07}-47jUrE1jWjdPvcW>i){Qy?zq`}EGSbON2*JXE4Q9}RjB~PCTQh|y=NVaNhGd9 zfqm7HPyGwvi9aM?A*Y#Vt&r6f*m!Q#ZiunkV{;ep)mt{N6h8p8`@>s_+uD7zxp_CC zXs9jcI$==2Z!D&$$ah4Q77x$-=(g-(VylOm$xaEy;nIEVJ_hpz!e7V&{&6a+$-qWt z2c-iD{@UilVw2Eu1?H#l2>$63j)TG4nVU)O^yIUxwEUb?8fw{Hl6I)$MFGXJPM&}_ zaNE3EOw*kzroH2*YWX%sG^F|VB!v+cit1UpFmK=WMljbk!d+r;4=yf2y+!N>2zi$&UWg$=79ggrLtSiW4%MIM5 ziWvh41+HgU`@#*k<~{pr{gJc`X_2*iy?N0#tnO%=Y_ZOAldL#@e@dD?;1aS!ys9$r zHpDzp9w zoq3o&3Y;GbO!c5QGYMl{gwKODuSpj*5AK^J806e7@Mgdp29`^ zqDYR~uJv_L`0bF-4_+zTFxK{fU|$-Pi~wP$luT$t@lX3zzRky~`K~TKM>R!myBiuX z8BHXe{*v|Py;Uy1-lh=)W1?pYyMz?xzON{5Wx@5Hmza3pF!(`Ei*h8!Z-6V&LXB*&k-f#-U4=&A(c>AV@RU zLT^{*fyk^PdJ>dxu}sT1V56z(=jonEU@;ux0rJDc=?!vcu0Hwz-(QhzX4P`jM{;vG zX}*r|Ngh?8?#;xa>EuWo3Q+~Yz`gqu}jvyjrGQ>_A?*N&ZTSwqF2`(H&Atu`0)D1 z#?{$HRsd_u&rg2qwT`q(oe*r}#ULq{4|dr#)Aug6Nb`G6M0`MFaRa%(t+q{6$hOni z7UtmIYjlqwVSZ&4VeQkd)HENEf%Izao2sV!n)3;z>>#xfkdvFfoACjeMz+r^wdiB< zEF2LSSa|Pl9Kw5D#ZT+{y%GuvApcO!!vg;ugdcWr*k(0BW=HRa9uve5Or`p38cRl zS(GN}7*N0shOmQcE1_`~s2B}+gGQU5;G15*-FC}!?nKNgQA?#5^2zo`kNVc2t`W>9 z`uI8H=A!}X|EAgFs?JAiV!nv-Rsy+uzo9z(JhfaBg4B7JAVy>)ZmX{EIZC;F&HgD` zoc$qw1<2$_3K@0@u7o|ECNJy}GJ-dn`Ny|2Ml!Ft*kAmNYN}`=Vc%nriH%#%}|GOcx6WBRU#=z?gxb|MhYGxy}M$aDZ; z{6z8FhszjgBPyumsQ6|9PBHB?3ut{LdCZ$&7R;H>*~HgevpMn@&GE*oK>TYX#PRo2 zy{@Rr-7W?FodFL-)%k@Bo1C6Jr2#wCIHG3jmQg9Ek46RH{(HKT2R#RddPI4`2&HIr2=lBHup$$`n7vf8iczqTEuJ!Mgvd($R>m@~j$<2*IzI0n%D)#3e( zMR@6XJ0#JZsYR8W^Izk@I(r#_HM&~$-5UR`S2-NXsSJ*k5nuXt24k9uZ+%Gt0^|Jy zDr$^>(N+V{e$Hg-F7! zt|*z$g%7u83gvLGQtd0xb4p96FI^HoJ_?}ZOnaN0+?ml(_>%)5$Jh)D`s}NVjvG+2 z2L#%Uh`<@PApTWJ-G(5MNJ;(FQsEE(~`#WDQYT06r^rUmG2G402HC%wr_a zuC1`TQ{M+IYvp?JZ+xI>U?~7&exBcRJ|T+le3}?%#dV{hyweD^-(k&bpwC&HvhS~V z4bFW%9U%Pl07yNCQ}^v@8Zqd^uuGd-JP&eU{01HyGIby#>32QNTxfjT^%&tKOq7RI z<3W)63(hCI9s^x0k!RPT3FQE4t|vGH3MbpjTGJxAshx)+fl3`M2c!@Z{ zL}odav(N(m;@~@75Ubht#L*G-HBOXMke=Z`cipjWQ7e?%A=?g<`wihf2ZC}rF#%J0 zGJa&ViFO$nZz3Z204Q>Jqcsd|Yz3O8l}T|bdZi|X!k_VKt!2@e#Ki%?uaQ=M9QZa#PiwLqgx&kcQywRJS(Krpr0TLUwnRGtvN8f+}Kvhp` zuSi>`{&#~WTT;#j*l61yKOV-A!cx+ENhu@76~PS%OSMDeL$X^pO=4a%kk;cf+P?qK!pqaen5+{ znW}SF2rWpmv+Br$2!KX`xj$^YGZIyc{KX{Aj;OrU068=%7X^5xAX=_U-Va9r{T#Zm zbnDxB-@S*yUfrbq?Xkq)ji5n<={7Q&sE`*Dagh&nSe^x#25Ox(;`a*)T-V9?hs2LMIa;dCXz_T+n)Rt|i%0y>&l)8RE@c*qs6rv|Q+ zx}L#KNvmi$oF;)HzioYpYV{E%eeKjnipo%Ng{iZsNiv%52lR9g5JC@*FUMzpIvJ;} zDktkPh>!~xi`eVz1ScHgJDYsS<8I+?0wp8p&VFD4a zW0fI@6RPV*MuWAf_I>Zl>;Vhvz{;P2AH%;RNMLfPM@@-kHmF5a}4P_Zoy&9k}24oY=8>KwTRl= zQQ!pa{m0Ohj?ZFp?Q<#osSVif)NG^zQuAX0Bl{bd@H1c@z6$GiMcr~B1|CN~bX?5J z@9Ag_^jv?3bYAC1Vqc}EtfYy*+gZ)X0;5{%&HE04j${C#>Zbsk$j3|y�qW8-uX8 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 Date: Tue, 12 Dec 2023 18:26:19 -0500 Subject: [PATCH 24/29] rename project dir --- .../amc_passes.png | Bin .../hcl_dependencies.png | Bin .../index.md | 0 .../overview.svg | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename content/blog/{2023-12-09-allo-amc => 2023-12-09-hcl-amc}/amc_passes.png (100%) rename content/blog/{2023-12-09-allo-amc => 2023-12-09-hcl-amc}/hcl_dependencies.png (100%) rename content/blog/{2023-12-09-allo-amc => 2023-12-09-hcl-amc}/index.md (100%) rename content/blog/{2023-12-09-allo-amc => 2023-12-09-hcl-amc}/overview.svg (100%) diff --git a/content/blog/2023-12-09-allo-amc/amc_passes.png b/content/blog/2023-12-09-hcl-amc/amc_passes.png similarity index 100% rename from content/blog/2023-12-09-allo-amc/amc_passes.png rename to content/blog/2023-12-09-hcl-amc/amc_passes.png diff --git a/content/blog/2023-12-09-allo-amc/hcl_dependencies.png b/content/blog/2023-12-09-hcl-amc/hcl_dependencies.png similarity index 100% rename from content/blog/2023-12-09-allo-amc/hcl_dependencies.png rename to content/blog/2023-12-09-hcl-amc/hcl_dependencies.png diff --git a/content/blog/2023-12-09-allo-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md similarity index 100% rename from content/blog/2023-12-09-allo-amc/index.md rename to content/blog/2023-12-09-hcl-amc/index.md diff --git a/content/blog/2023-12-09-allo-amc/overview.svg b/content/blog/2023-12-09-hcl-amc/overview.svg similarity index 100% rename from content/blog/2023-12-09-allo-amc/overview.svg rename to content/blog/2023-12-09-hcl-amc/overview.svg From 6d89feadc22913fc6dfa8be48e4909998f99ec55 Mon Sep 17 00:00:00 2001 From: matth2k Date: Wed, 20 Dec 2023 13:35:22 -0500 Subject: [PATCH 25/29] address first half of comments --- content/blog/2023-12-09-hcl-amc/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/blog/2023-12-09-hcl-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md index 75021d90b..9e551bb26 100644 --- a/content/blog/2023-12-09-hcl-amc/index.md +++ b/content/blog/2023-12-09-hcl-amc/index.md @@ -24,13 +24,13 @@ When CPU and GPU optimizations have been exhausted, custom hardware accelerators ### High-Level Synthesis -High-Level Synthesis (HLS) is one such solution to solve the problem of hardware design productivity. The general idea is to raise the level of abstraction from the commonly-used register transfer level (RTL) (e.g. Verilog) to a higher-level language like C/C++. This allows the designer to focus more at the algorithm level and less on the hardware details, such as interfaces and timing. The "magic" of HLS compilers is that it can infer a gate-level mapping from the high-level language to the underlying hardware. The main steps of generating this mapping are scheduling, resource allocation, and binding. In the end, the outputted RTL code from HLS can be synthesized by downstream tools. However, current HLS tools greatly fall short in their promise to free designers from thinking at the architecture level. They rely on special directives (e.g., C++ pragmas) from the designer to guide the optimization process. Oftentimes, the designer must even rewrite their code to fit the HLS compiler's model of computation. +High-Level Synthesis (HLS) is one such solution to solve the problem of hardware design productivity. The general idea is to raise the level of abstraction from the commonly-used register transfer level (RTL) (e.g., Verilog) to a higher-level language like C/C++. This allows the designer to focus more at the algorithm level and less on the hardware details, such as interfaces and timing. The "magic" of HLS compilers is that it can infer a gate-level mapping from the high-level language to the underlying hardware. The main steps of generating this mapping are scheduling, resource allocation, and binding. In the end, the outputted RTL code from HLS can be synthesized by downstream tools. However, current HLS tools greatly fall short in their promise to free designers from thinking at the architecture level. They rely on special directives (e.g., C++ pragmas) from the designer to guide the optimization process. Oftentimes, the designer must even rewrite their code to fit the HLS compiler's model of computation. ### MLIR and Incubator Projects Reinventing HLS with advanced compiler techniques is an active area of research. There are many outstanding HLS tools/frameworks such as [TAPA](https://tapa.readthedocs.io/en/release/overview/overview.html), [Dynamatic](https://dynamatic.epfl.ch/), and [HeteroCL](https://heterocl.csl.cornell.edu/). However, these tools are developed independently with different compilation flows, which brings difficulties of integrating them together. [MLIR](https://mlir.llvm.org/) is a new compiler design paradigm where the source language is compiled through multiple levels of modularized intermediate representations (IRs), also known as dialects. Dialects act like domain-specific languages (DSLs) and can capture the approprate details at each level of abstraction. -The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called HCL. HCL decouples the interactions between the algorithm, hardware optimizations, and backend targets to enable productive design and testing. Lastly, Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. Its expressiveness is able to capture common memory organization strategies such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is also part of the CIRCT ecosystem. Calyx IR gives us a pathway to finally to synthesizable Verilog. The contribution of this project is that we integrated HCL with AMC to enable a Python frontend for AMC. This allows us to use HCL to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single function call. In the end, we hope that this integration will enable a more productive design flow for hardware accelerators as well as help us find more bugs in AMC. +The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development methodology for hardware design. It represents key components of hardware as MLIR dialects such as finite state machines (FSM), pipelines, and interface handshaking. HeteroCL has been migrated to the MLIR ecosystem as a dialect, with a new Python frontend called HCL. HCL decouples the interactions between the algorithm, hardware optimizations, and backend targets to enable productive design and testing. Lastly, Accelerator Memory Compiler (AMC) is an MLIR dialect for representing memory architecture. Its expressiveness is able to capture common memory organization strategies such as partitioning, banking, and arbitration. AMC can be further lowered to Calyx, which is also integrated with the CIRCT ecosystem. Finally, the Calyx compiler gives us a pathway to synthesizable Verilog. The contribution of this project is that we integrated HCL with AMC to enable a Python frontend for AMC. This allows us to use HCL to describe the algorithm and AMC to describe the memory architecture. The resulting design can be compiled to Verilog and simulated with a single function call. In the end, we hope that this integration will enable a more productive design flow for hardware accelerators as well as help us find more bugs in AMC. ## Design Example @@ -55,7 +55,7 @@ def test_amc(): f = s.build(target="amc") # Run the software simulation by invoking directly np_out = kernel(A, B) - # Now run the hardware simulation with AMC + # Now run the hardware simulation with AMC+Calyx hcl_out = f(A, B) np.testing.assert_array_equal(hcl_out, np_out) ``` @@ -204,7 +204,7 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo } ``` -The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count, as well as the context in which the memory is being used. It is a very gradual lowering process, and the explanation of the whole pass pipeline won't even start to fit in this post. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog: +The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count, as well as the general context in which the memory is being used. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. The memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't even start to fit in this post. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog:

Diagram for AMC pass pipeline From 9461d99a02d5f7b05f913576a906d25065bc9e62 Mon Sep 17 00:00:00 2001 From: matth2k Date: Wed, 20 Dec 2023 14:08:10 -0500 Subject: [PATCH 26/29] address second half of comments --- content/blog/2023-12-09-hcl-amc/index.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/content/blog/2023-12-09-hcl-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md index 9e551bb26..0d6c294e1 100644 --- a/content/blog/2023-12-09-hcl-amc/index.md +++ b/content/blog/2023-12-09-hcl-amc/index.md @@ -34,7 +34,7 @@ The [CIRCT](https://circt.llvm.org/) project expands the MLIR-based development ## Design Example -To use HCL with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. Moreover, AMC acts as a drop-in replacement to the other backends in the HCL ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. +To use HCL with AMC, the designer only needs to write their kernel in Python. Then, then user can simply specify which Python function to build with the AMC backend. HCL will do the initial translation of the kernel AST into MLIR, along with some other high-level optimzations. Then, the AMC backend takes it the the rest of the way. Moreover, AMC acts as a drop-in replacement to the other backends in the HCL ecosystem, making functional testing and debugging seamless. In the far majority of cases, the [NumPy](https://numpy.org/) or the LLVM backend is suitable for use as a golden reference model. In this section, we walk through an example where we functionally verify a kernel built with AMC. Then, we will record some resource estimates and execution times. Our illustrative example will be matrix multiplication. What would ordinarily be a cumbersome task when using the vendor tools, like [Vitis HLS](https://www.xilinx.com/products/design-tools/vitis/vitis-hls.html), becomes a simple, 5 minute exercise. First, we specify some inputs initialized to random values. Then, `build()` the accelerator. Finally, we call both the software and hardware simulations and check their outputs. Compared to a C/C++ based tool flow, the amount of boilerplate code and scripting is reduced to near zero. In the end, we can represent this application with only 18 lines of code: @@ -50,8 +50,10 @@ def test_amc(): def kernel(A: int32[N, N], B: int32[N, N]) -> int32[N, N]: return matmul(A, B) - # Build the accelerator with AMC backend + # Traverse the kernel AST + # and create handle to Allo customizations s = customize(kernel) + # Build the accelerator with AMC backend f = s.build(target="amc") # Run the software simulation by invoking directly np_out = kernel(A, B) @@ -204,7 +206,9 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo } ``` -The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count, as well as the general context in which the memory is being used. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. The memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't even start to fit in this post. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog: +In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaing that they have non-static latency for every read/write request. This memory module is a very simple example. Given a more elaborate application, you can find very interesting interactions from the compositions of AMC operations not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). + +The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count. Moreover, AMC attempts to exploit the context in which the memory is being used for optimization. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. Overall, the memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't fit in this post about the frontend. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog:
Diagram for AMC pass pipeline From 095d8c186180c8f3140d3561d9d0d97bc54dc0b2 Mon Sep 17 00:00:00 2001 From: matth2k Date: Wed, 20 Dec 2023 14:10:05 -0500 Subject: [PATCH 27/29] typo --- content/blog/2023-12-09-hcl-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/2023-12-09-hcl-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md index 0d6c294e1..8a8e9ba3c 100644 --- a/content/blog/2023-12-09-hcl-amc/index.md +++ b/content/blog/2023-12-09-hcl-amc/index.md @@ -208,7 +208,7 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaing that they have non-static latency for every read/write request. This memory module is a very simple example. Given a more elaborate application, you can find very interesting interactions from the compositions of AMC operations not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). -The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count. Moreover, AMC attempts to exploit the context in which the memory is being used for optimization. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. Overall, the memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't fit in this post about the frontend. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects to Verilog: +The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count. Moreover, AMC attempts to exploit the context in which the memory is being used for optimization. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. Overall, the memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't fit in this post about the frontend. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects lower to Verilog:
Diagram for AMC pass pipeline From 0feb478e5c6dd84306cf19bad2a2d048cf68c679 Mon Sep 17 00:00:00 2001 From: matth2k Date: Wed, 20 Dec 2023 14:10:46 -0500 Subject: [PATCH 28/29] typo --- content/blog/2023-12-09-hcl-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/2023-12-09-hcl-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md index 8a8e9ba3c..a602d3e61 100644 --- a/content/blog/2023-12-09-hcl-amc/index.md +++ b/content/blog/2023-12-09-hcl-amc/index.md @@ -206,7 +206,7 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo } ``` -In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaing that they have non-static latency for every read/write request. This memory module is a very simple example. Given a more elaborate application, you can find very interesting interactions from the compositions of AMC operations not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). +In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaning that they have non-static latency for every read/write request. This memory module is a very simple example. Given a more elaborate application, you can find very interesting interactions from the compositions of AMC operations not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count. Moreover, AMC attempts to exploit the context in which the memory is being used for optimization. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. Overall, the memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't fit in this post about the frontend. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects lower to Verilog: From 7bc1ebe0480700f6c25f983330176d7fa6e8da63 Mon Sep 17 00:00:00 2001 From: matth2k Date: Wed, 20 Dec 2023 14:11:59 -0500 Subject: [PATCH 29/29] rephrase last sentence on AMC IR --- content/blog/2023-12-09-hcl-amc/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/blog/2023-12-09-hcl-amc/index.md b/content/blog/2023-12-09-hcl-amc/index.md index a602d3e61..b088cc5b5 100644 --- a/content/blog/2023-12-09-hcl-amc/index.md +++ b/content/blog/2023-12-09-hcl-amc/index.md @@ -206,7 +206,7 @@ Back to AMC, the custom dialect elaborates the *real* limiting resources of memo } ``` -In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaning that they have non-static latency for every read/write request. This memory module is a very simple example. Given a more elaborate application, you can find very interesting interactions from the compositions of AMC operations not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). +In the above snippet, AMC IR is being used to declare a simple memory interface. The body is the implementation of said memory. First, the definition starts with an `amc.alloc` operation which represents the memory banks themselves. Then, `amc.create_port` is used to create handles to ports on those banks. Finally, `amc.extern` exposes those ports in the memory interface. In this case, the port types are dynamic, meaning that they have non-static latency for every read/write request. While this memory module is a very simple example, you can encounter very interesting interactions from the compositions of AMC operations, especially the ones not shown here (`amc.merge`, `amc.reshape`, `amc.arbiter`, ...). The role of the AMC compiler is to take in a high-level description of memory organization (as seen above) and figure out how to best compile it to the target architecture. It accounts for some of the properties of underlying architecture, like BRAM size and port count. Moreover, AMC attempts to exploit the context in which the memory is being used for optimization. For example, suppose a 2D matrix is being accesssed along its columns. The compiler may bank the memory by the matrix's rows for higher throughput. Overall, the memory compilation is a very gradual lowering process, and the explanation of the whole pass pipeline won't fit in this post about the frontend. However, the following diagram may offer a rough idea of how the core MLIR and AMC dialects lower to Verilog: