[Samples] add ablation test script; update Readme; bug fix in InsertPipelinePragma
This commit is contained in:
parent
939f01cd05
commit
7cb98f3a87
|
@ -1,7 +1,9 @@
|
|||
.vscode
|
||||
.ipynb_checkpoints
|
||||
|
||||
build
|
||||
samples/hls_proj
|
||||
samples/cpp_src
|
||||
samples/test_results
|
||||
|
||||
*.log
|
||||
|
|
|
@ -30,7 +30,7 @@ $ cmake -G Ninja .. \
|
|||
$ ninja check-scalehls
|
||||
```
|
||||
|
||||
### 3. Test ScaleHLS
|
||||
### 3. Try ScaleHLS
|
||||
After the installation and test successfully completed, you should be able to play with
|
||||
```sh
|
||||
$ export PATH=$SCALEHLS_DIR/build/bin:$PATH
|
||||
|
@ -45,10 +45,11 @@ $
|
|||
$ scalehls-opt -qor-estimation test/Analysis/QoREstimation/test_for.mlir
|
||||
```
|
||||
|
||||
If Vivado HLS (2019.1 tested) is installed on your machine, running the following script will report the HLS results for some benchmarks.
|
||||
### 4. Ablation test
|
||||
If Vivado HLS (2019.1 tested) is installed on your machine, running the following script will report the HLS results for some benchmarks (around 2 hours on AMD Ryzen7 3800X for all 16 tests). "-n" determines the number of tests to be processed, the maximum supported value of which is 16. "-c" determines whether to run Vivado HLS C synthesis. "-r" determines whether to run report generation. The generated C++ source code will be written to $SCALEHLS_DIR/sample/cpp_src; the Vivado HLS project will be established in $SCALEHLS_DIR/sample/hls_proj; the generated report will be written to $SCALEHLS_DIR/sample/test_results.
|
||||
```sh
|
||||
$ cd $SCALEHLS_DIR/sample
|
||||
$ source ./test_run.sh rerun
|
||||
$ ./ablation_test_run.sh -n 16 -c true -r true
|
||||
```
|
||||
|
||||
## References
|
||||
|
|
|
@ -66,10 +66,10 @@ def PartialAffineLoopTile : Pass<"partial-affine-loop-tile", "ModuleOp"> {
|
|||
];
|
||||
}
|
||||
|
||||
def RemoveVarLoopBound : Pass<"remove-val-loop-bound", "ModuleOp"> {
|
||||
def RemoveVarLoopBound : Pass<"remove-var-loop-bound", "ModuleOp"> {
|
||||
let summary = "Try to remove variable loop bounds";
|
||||
let description = [{
|
||||
This remove-val-loop-bound pass will try to remove the variable loop bounds.
|
||||
This remove-var-loop-bound pass will try to remove the variable loop bounds.
|
||||
Specifically, this is only possible when the variable loop bound is an
|
||||
affine expression of induction variables of other loops with constant lower
|
||||
or upper bound.
|
||||
|
|
|
@ -27,11 +27,11 @@ void InsertPipelinePragma::runOnOperation() {
|
|||
for (auto func : module.getOps<FuncOp>()) {
|
||||
for (auto forOp : func.getOps<mlir::AffineForOp>()) {
|
||||
SmallVector<mlir::AffineForOp, 4> nestedLoops;
|
||||
getPerfectlyNestedLoops(nestedLoops, forOp);
|
||||
forOp.walk([&](mlir::AffineForOp loop) { nestedLoops.push_back(loop); });
|
||||
|
||||
auto targetLoop = nestedLoops.front();
|
||||
auto targetLoop = nestedLoops.back();
|
||||
if (nestedLoops.size() > insertLevel)
|
||||
targetLoop = *std::prev(nestedLoops.end(), insertLevel);
|
||||
targetLoop = *std::next(nestedLoops.begin(), insertLevel);
|
||||
|
||||
targetLoop.setAttr("pipeline", builder.getBoolAttr(true));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Script options.
|
||||
while getopts 'n:c:r:' opt
|
||||
do
|
||||
case $opt in
|
||||
n) ablation_number=$OPTARG ;;
|
||||
c) rerun_csynth=$OPTARG ;;
|
||||
r) rerun_report=$OPTARG ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Create directories.
|
||||
if [ ! -d "cpp_src" ]
|
||||
then
|
||||
mkdir cpp_src
|
||||
fi
|
||||
|
||||
if [ ! -d "hls_proj" ]
|
||||
then
|
||||
mkdir hls_proj
|
||||
fi
|
||||
|
||||
if [ ! -d "test_results" ]
|
||||
then
|
||||
mkdir test_results
|
||||
fi
|
||||
|
||||
# Candidate passes.
|
||||
hta=-hlskernel-to-affine
|
||||
pft=-affine-loop-perfection
|
||||
rvb=-remove-var-loop-bound
|
||||
can=-canonicalize
|
||||
|
||||
p0=-insert-pipeline-pragma="insert-level=0"
|
||||
p1=-insert-pipeline-pragma="insert-level=1"
|
||||
p2=-insert-pipeline-pragma="insert-level=2"
|
||||
p3=-insert-pipeline-pragma="insert-level=3"
|
||||
|
||||
u1=-affine-loop-unroll="unroll-full unroll-num-reps=1"
|
||||
u2=-affine-loop-unroll="unroll-full unroll-num-reps=2"
|
||||
u3=-affine-loop-unroll="unroll-full unroll-num-reps=3"
|
||||
|
||||
t1s2=-partial-affine-loop-tile="tile-level=1 tile-size=2"
|
||||
t1s4=-partial-affine-loop-tile="tile-level=1 tile-size=4"
|
||||
t2s2=-partial-affine-loop-tile="tile-level=2 tile-size=2"
|
||||
t2s4=-partial-affine-loop-tile="tile-level=2 tile-size=4"
|
||||
t3s2=-partial-affine-loop-tile="tile-level=3 tile-size=2"
|
||||
t3s4=-partial-affine-loop-tile="tile-level=3 tile-size=4"
|
||||
|
||||
emit=-emit-hlscpp
|
||||
|
||||
# Ablation test.
|
||||
n=0
|
||||
while [ $n -lt $ablation_number ]
|
||||
do
|
||||
# Generate HLS C++ files.
|
||||
for file in ../test/Conversion/HLSKernelToAffine/*
|
||||
do
|
||||
output="cpp_src/${file##*Affine/}.cpp"
|
||||
case $n in
|
||||
0) scalehls-opt $hta $can $file | scalehls-translate $emit -o $output ;;
|
||||
|
||||
# Apply pipeline.
|
||||
1) scalehls-opt $hta "$p0" $can $file | scalehls-translate $emit -o $output ;;
|
||||
2) scalehls-opt $hta "$p1" $can $file | scalehls-translate $emit -o $output ;;
|
||||
3) scalehls-opt $hta "$p2" $can $file | scalehls-translate $emit -o $output ;;
|
||||
4) scalehls-opt $hta "$p3" $can $file | scalehls-translate $emit -o $output ;;
|
||||
|
||||
# Apply loop perfection + pipeline.
|
||||
5) scalehls-opt $hta $pft "$p0" $can $file | scalehls-translate $emit -o $output ;;
|
||||
6) scalehls-opt $hta $pft "$p1" $can $file | scalehls-translate $emit -o $output ;;
|
||||
7) scalehls-opt $hta $pft "$p2" $can $file | scalehls-translate $emit -o $output ;;
|
||||
8) scalehls-opt $hta $pft "$p3" $can $file | scalehls-translate $emit -o $output ;;
|
||||
|
||||
# Apply loop perfection + remove variable bound + pipeline.
|
||||
9) scalehls-opt $hta $pft $rvb "$p0" $can $file | scalehls-translate $emit -o $output ;;
|
||||
10) scalehls-opt $hta $pft $rvb "$p1" $can $file | scalehls-translate $emit -o $output ;;
|
||||
11) scalehls-opt $hta $pft $rvb "$p2" $can $file | scalehls-translate $emit -o $output ;;
|
||||
12) scalehls-opt $hta $pft $rvb "$p3" $can $file | scalehls-translate $emit -o $output ;;
|
||||
|
||||
# Apply loop perfection + remove variable bound + loop tiling + pipeline.
|
||||
13) scalehls-opt $hta $pft $rvb "$t1s4" "$p1" "$u1" $can $file | scalehls-translate $emit -o $output ;;
|
||||
14) scalehls-opt $hta $pft $rvb "$t2s4" "$p2" "$u2" $can $file | scalehls-translate $emit -o $output ;;
|
||||
15) scalehls-opt $hta $pft $rvb "$t3s4" "$p3" "$u3" $can $file | scalehls-translate $emit -o $output ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ $rerun_csynth == "true" ]
|
||||
then
|
||||
# Run HLS synthesis.
|
||||
cd hls_proj
|
||||
vivado_hls ../hls_script.tcl
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ $rerun_report == "true" ]
|
||||
then
|
||||
# Generate latency report.
|
||||
echo -e "benchmark\tdsp\tlut\tcycles" > test_results/test_result$n.log
|
||||
# echo "----------------------------------------" >> test_results/test_result$n.log
|
||||
for file in cpp_src/*
|
||||
do
|
||||
name=${file##*cpp_src/}
|
||||
name=${name%.mlir*}
|
||||
cycles=$(awk '/<\/*Worst-caseLatency>/{gsub(/<\/*Worst-caseLatency>/,"");print $0}' hls_proj/$name/$name/syn/report/csynth.xml)
|
||||
dsp=$(awk '/<\/*DSP48E>/{gsub(/<\/*DSP48E>/,"");print $0;exit;}' hls_proj/$name/$name/syn/report/csynth.xml)
|
||||
lut=$(awk '/<\/*LUT>/{gsub(/<\/*LUT>/,"");print $0;exit;}' hls_proj/$name/$name/syn/report/csynth.xml)
|
||||
|
||||
echo -e "$name\t$dsp\t$lut\t$cycles" >> test_results/test_result$n.log
|
||||
done
|
||||
fi
|
||||
|
||||
let n++
|
||||
done
|
|
@ -1,37 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Generate HLS C++ files.
|
||||
if [ ! -d "cpp_src" ]
|
||||
then
|
||||
mkdir cpp_src
|
||||
fi
|
||||
for file in ../test/Conversion/HLSKernelToAffine/*
|
||||
do
|
||||
scalehls-opt -hlskernel-to-affine -affine-loop-perfection $file | scalehls-translate -emit-hlscpp -o "cpp_src/${file##*Affine/}.cpp"
|
||||
done
|
||||
|
||||
if [ $1 == "rerun" ]
|
||||
then
|
||||
# Run HLS synthesis.
|
||||
if [ ! -d "hls_proj" ]
|
||||
then
|
||||
mkdir hls_proj
|
||||
fi
|
||||
cd hls_proj
|
||||
vivado_hls ../hls_script.tcl
|
||||
cd ..
|
||||
fi
|
||||
|
||||
# Generate latency report.
|
||||
echo -e "testcase\tlatency" > test_result.log
|
||||
echo "--------------------------------" >> test_result.log
|
||||
for file in cpp_src/*
|
||||
do
|
||||
name=${file##*cpp_src/}
|
||||
name=${name%.mlir*}
|
||||
latency=$(cat hls_proj/$name/$name/syn/report/csynth.xml | grep Worst-caseLatency)
|
||||
latency=${latency##<Worst-caseLatency>}
|
||||
latency=${latency%</Worst-caseLatency>}
|
||||
|
||||
echo -e $name"\t"$latency >> test_result.log
|
||||
done
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: scalehls-opt -remove-val-loop-bound %s | FileCheck %s
|
||||
// RUN: scalehls-opt -remove-var-loop-bound %s | FileCheck %s
|
||||
|
||||
// CHECK-LABEL: func @test_for
|
||||
func @test_for() {
|
Loading…
Reference in New Issue