simplify scalehls-opt and scalehls-translate tool; add InitAllDialects and InitAllPasses methods; remove ablation_test_run.sh and update readme as well

This commit is contained in:
Hanchen Ye 2021-01-21 16:14:13 -06:00
parent 032cf88f21
commit 9b527faf0c
14 changed files with 89 additions and 462 deletions

View File

@ -85,15 +85,6 @@ $ scalehls-opt resnet18.mlir -legalize-onnx -affine-loop-normalize -canonicalize
| scalehls-translate -emit-hlscpp
```
## Ablation Study (Deprecated)
If Vivado HLS (2019.1 tested) is installed on your machine, running the following script will report the HLS results for some benchmarks (around 8 hours on AMD Ryzen7 3800X for all 33 tests).
For the `ablation_test_run.sh` script, `-n` determines the number of tests to be processed, the maximum supported value of which is 33; `-c` determines from which test to begin to rerun the C++ synthesis. The generated C++ source code will be written to `sample/cpp_src`; the Vivado HLS project will be established in `sample/hls_proj`; the collected report will be written to `sample/test_results`; the test summary will be generated to `sample`.
```sh
$ cd $SCALEHLS_DIR/sample
$ ./ablation_test_run.sh -n 33 -c 0
```
## References
1. [MLIR documents](https://mlir.llvm.org)
2. [mlir-npcomp github](https://github.com/llvm/mlir-npcomp)

View File

@ -0,0 +1,37 @@
//===----------------------------------------------------------------------===//
//
// Copyright 2020-2021 The ScaleHLS Authors.
//
//===----------------------------------------------------------------------===//
#ifndef SCALEHLS_INITALLDIALECTS_H
#define SCALEHLS_INITALLDIALECTS_H
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/SCF/SCF.h"
#include "mlir/IR/Dialect.h"
#include "scalehls/Dialect/HLSCpp/HLSCpp.h"
#include "scalehls/Dialect/HLSKernel/HLSKernel.h"
namespace mlir {
namespace scalehls {
// Add all the ScaleHLS dialects to the provided registry.
inline void registerAllDialects(mlir::DialectRegistry &registry) {
// clang-format off
registry.insert<
mlir::scalehls::hlscpp::HLSCppDialect,
mlir::scalehls::hlskernel::HLSKernelDialect,
mlir::StandardOpsDialect,
mlir::AffineDialect,
mlir::scf::SCFDialect,
mlir::linalg::LinalgDialect
>();
// clang-format on
}
} // namespace scalehls
} // namespace mlir
#endif // SCALEHLS_INITALLDIALECTS_H

View File

@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// Copyright 2020-2021 The ScaleHLS Authors.
//
//===----------------------------------------------------------------------===//
#ifndef SCALEHLS_INITALLPASSES_H
#define SCALEHLS_INITALLPASSES_H
#include "mlir/InitAllPasses.h"
#include "scalehls/Analysis/Passes.h"
#include "scalehls/Conversion/Passes.h"
#include "scalehls/Transforms/Passes.h"
namespace mlir {
namespace scalehls {
// Add all the ScaleHLS passes.
inline void registerAllPasses() {
scalehls::registerAnalysisPasses();
scalehls::registerConversionPasses();
scalehls::registerTransformsPasses();
// TODO: only register required passes.
mlir::registerAllPasses();
}
} // namespace scalehls
} // namespace mlir
#endif // SCALEHLS_INITALLPASSES_H

View File

@ -10,7 +10,7 @@
namespace mlir {
namespace scalehls {
void registerHLSCppEmitterTranslation();
void registerEmitHLSCppTranslation();
} // namespace scalehls
} // namespace mlir

View File

@ -8,4 +8,5 @@ add_mlir_library(MLIRScaleHLSAnalysis
LINK_LIBS PUBLIC
MLIRHLSCpp
MLIRHLSKernel
)

View File

@ -8,4 +8,5 @@ add_mlir_library(MLIRScaleHLSTransforms
LINK_LIBS PUBLIC
MLIRHLSCpp
MLIRHLSKernel
)

View File

@ -5,4 +5,5 @@ add_mlir_library(MLIRScaleHLSEmitHLSCpp
LINK_LIBS PUBLIC
MLIRHLSCpp
MLIRHLSKernel
)

View File

@ -12,6 +12,7 @@
#include "mlir/Translation.h"
#include "scalehls/Analysis/Utils.h"
#include "scalehls/Dialect/HLSCpp/Visitor.h"
#include "scalehls/InitAllDialects.h"
#include "llvm/Support/raw_ostream.h"
using namespace mlir;
@ -1576,6 +1577,9 @@ static LogicalResult emitHLSCpp(ModuleOp module, llvm::raw_ostream &os) {
return failure(state.encounteredError);
}
void scalehls::registerHLSCppEmitterTranslation() {
static TranslateFromMLIRRegistration toHLSCpp("emit-hlscpp", emitHLSCpp);
void scalehls::registerEmitHLSCppTranslation() {
static TranslateFromMLIRRegistration toHLSCpp(
"emit-hlscpp", emitHLSCpp, [&](DialectRegistry &registry) {
scalehls::registerAllDialects(registry);
});
}

View File

@ -1,232 +0,0 @@
#!/bin/bash
# Script options.
while getopts 'n:c:' opt
do
case $opt in
n) ablation_number=$OPTARG ;;
c) rerun_csynth_from=$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
cth=-legalize-to-hlscpp
can=-canonicalize
alp=-affine-loop-perfection
rvb=-remove-variable-bound
par=-array-partition
p0=-loop-pipelining="pipeline-level=0"
p1=-loop-pipelining="pipeline-level=1"
p2=-loop-pipelining="pipeline-level=2"
p3=-loop-pipelining="pipeline-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"
t1s8=-partial-affine-loop-tile="tile-level=1 tile-size=8"
t2s2=-partial-affine-loop-tile="tile-level=2 tile-size=2"
t2s4=-partial-affine-loop-tile="tile-level=2 tile-size=4"
t2s8=-partial-affine-loop-tile="tile-level=2 tile-size=8"
t3s2=-partial-affine-loop-tile="tile-level=3 tile-size=2"
t3s4=-partial-affine-loop-tile="tile-level=3 tile-size=4"
t3s8=-partial-affine-loop-tile="tile-level=3 tile-size=8"
emit=-emit-hlscpp
# Ablation test.
n=0
while [ $n -lt $ablation_number ]
do
# Generate HLS C++ files.
for file in ../test/Conversion/HLSKernelToAffine/*
do
name=${file##*Affine/}
name=top-function=${name%.mlir*}
output="cpp_src/${file##*Affine/}.cpp"
case $n in
0) scalehls-opt $hta $cth="$name" $can $file | scalehls-translate $emit -o $output ;;
# Apply pipeline.
1) scalehls-opt $hta $cth="$name" "$p0" $can $file | scalehls-translate $emit -o $output ;;
2) scalehls-opt $hta $cth="$name" "$p1" $can $file | scalehls-translate $emit -o $output ;;
3) scalehls-opt $hta $cth="$name" "$p2" $can $file | scalehls-translate $emit -o $output ;;
4) scalehls-opt $hta $cth="$name" "$p3" $can $file | scalehls-translate $emit -o $output ;;
# Apply pipeline + array partition.
5) scalehls-opt $hta $cth="$name" "$p0" $par $can $file | scalehls-translate $emit -o $output ;;
6) scalehls-opt $hta $cth="$name" "$p1" $par $can $file | scalehls-translate $emit -o $output ;;
7) scalehls-opt $hta $cth="$name" "$p2" $par $can $file | scalehls-translate $emit -o $output ;;
8) scalehls-opt $hta $cth="$name" "$p3" $par $can $file | scalehls-translate $emit -o $output ;;
# Apply loop perfection + remove variable bound + pipeline.
9) scalehls-opt $hta $alp $rvb $cth="$name" "$p0" $can $file | scalehls-translate $emit -o $output ;;
10) scalehls-opt $hta $alp $rvb $cth="$name" "$p1" $can $file | scalehls-translate $emit -o $output ;;
11) scalehls-opt $hta $alp $rvb $cth="$name" "$p2" $can $file | scalehls-translate $emit -o $output ;;
12) scalehls-opt $hta $alp $rvb $cth="$name" "$p3" $can $file | scalehls-translate $emit -o $output ;;
# Apply loop perfection + remove variable bound + pipeline + array partition.
13) scalehls-opt $hta $alp $rvb $cth="$name" "$p0" $par $can $file | scalehls-translate $emit -o $output ;;
14) scalehls-opt $hta $alp $rvb $cth="$name" "$p1" $par $can $file | scalehls-translate $emit -o $output ;;
15) scalehls-opt $hta $alp $rvb $cth="$name" "$p2" $par $can $file | scalehls-translate $emit -o $output ;;
16) scalehls-opt $hta $alp $rvb $cth="$name" "$p3" $par $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 1st-level loop tiling + pipeline.
17) scalehls-opt $hta $alp $rvb "$t1s2" $cth="$name" "$p1" $can $file | scalehls-translate $emit -o $output ;;
18) scalehls-opt $hta $alp $rvb "$t1s4" $cth="$name" "$p1" $can $file | scalehls-translate $emit -o $output ;;
19) scalehls-opt $hta $alp $rvb "$t1s8" $cth="$name" "$p1" $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 1st-level loop tiling + pipeline + array partition.
20) scalehls-opt $hta $alp $rvb "$t1s2" $cth="$name" "$p1" $par $can $file | scalehls-translate $emit -o $output ;;
21) scalehls-opt $hta $alp $rvb "$t1s4" $cth="$name" "$p1" $par $can $file | scalehls-translate $emit -o $output ;;
22) scalehls-opt $hta $alp $rvb "$t1s8" $cth="$name" "$p1" $par $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 2nd-level loop tiling + pipeline.
23) scalehls-opt $hta $alp $rvb "$t2s2" $cth="$name" "$p2" $can $file | scalehls-translate $emit -o $output ;;
24) scalehls-opt $hta $alp $rvb "$t2s4" $cth="$name" "$p2" $can $file | scalehls-translate $emit -o $output ;;
25) scalehls-opt $hta $alp $rvb "$t2s8" $cth="$name" "$p2" $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 2nd-level loop tiling + pipeline + array partition.
26) scalehls-opt $hta $alp $rvb "$t2s2" $cth="$name" "$p2" $par $can $file | scalehls-translate $emit -o $output ;;
27) scalehls-opt $hta $alp $rvb "$t2s4" $cth="$name" "$p2" $par $can $file | scalehls-translate $emit -o $output ;;
28) scalehls-opt $hta $alp $rvb "$t2s8" $cth="$name" "$p2" $par $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 3rd-level loop tiling + pipeline.
29) scalehls-opt $hta $alp $rvb "$t3s2" $cth="$name" "$p3" $can $file | scalehls-translate $emit -o $output ;;
30) scalehls-opt $hta $alp $rvb "$t3s4" $cth="$name" "$p3" $can $file | scalehls-translate $emit -o $output ;;
# Apply ... + 3rd-level loop tiling + pipeline + array partition.
31) scalehls-opt $hta $alp $rvb "$t3s2" $cth="$name" "$p3" $par $can $file | scalehls-translate $emit -o $output ;;
32) scalehls-opt $hta $alp $rvb "$t3s4" $cth="$name" "$p3" $par $can $file | scalehls-translate $emit -o $output ;;
esac
done
if [ $n -ge $rerun_csynth_from ]
then
# Run HLS synthesis.
cd hls_proj
vivado_hls ../hls_script.tcl
cd ..
fi
if [ $n -ge $rerun_csynth_from ]
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
# Generate report summary.
echo -e "test summary" > test_summary.log
echo -e "benchmark\tdsp\tlut\tcycles" >> test_summary.log
idx=2
for file in cpp_src/*
do
name=${file##*cpp_src/}
name=${name%.mlir*}
n=0
while [ $n -lt $ablation_number ]
do
result=test_results/test_result$n.log
case $n in
0) echo -e "$name\t\c" >> test_summary.log ;;
# Apply pipeline.
1) echo -e "p0\t\c" >> test_summary.log ;;
2) echo -e "p1\t\c" >> test_summary.log ;;
3) echo -e "p2\t\c" >> test_summary.log ;;
4) echo -e "p3\t\c" >> test_summary.log ;;
# Apply pipeline + array partition.
5) echo -e "p0+par\t\c" >> test_summary.log ;;
6) echo -e "p1+par\t\c" >> test_summary.log ;;
7) echo -e "p2+par\t\c" >> test_summary.log ;;
8) echo -e "p3+par\t\c" >> test_summary.log ;;
# Apply loop perfection + remove variable bound + pipeline.
9) echo -e "ar+p0\t\c" >> test_summary.log ;;
10) echo -e "ar+p1\t\c" >> test_summary.log ;;
11) echo -e "ar+p2\t\c" >> test_summary.log ;;
12) echo -e "ar+p3\t\c" >> test_summary.log ;;
# Apply loop perfection + remove variable bound + pipeline + array partition.
13) echo -e "ar+p0+par\t\c" >> test_summary.log ;;
14) echo -e "ar+p1+par\t\c" >> test_summary.log ;;
15) echo -e "ar+p2+par\t\c" >> test_summary.log ;;
16) echo -e "ar+p3+par\t\c" >> test_summary.log ;;
# Apply ... + 1st-level loop tiling + pipeline.
17) echo -e "ar+t1s2+p1\t\c" >> test_summary.log ;;
18) echo -e "ar+t1s4+p1\t\c" >> test_summary.log ;;
19) echo -e "ar+t1s8+p1\t\c" >> test_summary.log ;;
# Apply ... + 1st-level loop tiling + pipeline + array partition.
20) echo -e "ar+t1s2+p1+par\t\c" >> test_summary.log ;;
21) echo -e "ar+t1s4+p1+par\t\c" >> test_summary.log ;;
22) echo -e "ar+t1s8+p1+par\t\c" >> test_summary.log ;;
# Apply ... + 2nd-level loop tiling + pipeline.
23) echo -e "ar+t2s2+p2\t\c" >> test_summary.log ;;
24) echo -e "ar+t2s4+p2\t\c" >> test_summary.log ;;
25) echo -e "ar+t2s8+p2\t\c" >> test_summary.log ;;
# Apply ... + 2nd-level loop tiling + pipeline + array partition.
26) echo -e "ar+t2s2+p2+par\t\c" >> test_summary.log ;;
27) echo -e "ar+t2s4+p2+par\t\c" >> test_summary.log ;;
28) echo -e "ar+t2s8+p2+par\t\c" >> test_summary.log ;;
# Apply ... + 3rd-level loop tiling + pipeline.
29) echo -e "ar+t3s2+p3\t\c" >> test_summary.log ;;
30) echo -e "ar+t3s4+p3\t\c" >> test_summary.log ;;
# Apply ... + 3rd-level loop tiling + pipeline + array partition.
31) echo -e "ar+t3s2+p3+par\t\c" >> test_summary.log ;;
32) echo -e "ar+t3s4+p3+par\t\c" >> test_summary.log ;;
esac
cat $result | awk "NR==$idx{OFS=\"\t\";print \$2,\$3,\$4}" >> test_summary.log
let n++
done
let idx++
done

View File

@ -1,16 +0,0 @@
foreach file [glob -directory "../cpp_src" -- "*.cpp"] {
set begin [string first "test_" $file]
set end [expr [string first ".mlir" $file] - 1]
set name [string range $file $begin $end]
open_project $name
set_top $name
add_files $file
open_solution $name
set_part {xc7z020-clg400-1} -tool vivado
create_clock -period 10 -name default
#csim_design
csynth_design
#cosim_design
close_project
}

View File

@ -6,8 +6,8 @@ set(LIBS
${conversion_libs}
MLIROptLib
MLIRHLSKernel
MLIRHLSCpp
MLIRHLSKernel
MLIRScaleHLSConversion
MLIRScaleHLSTransforms
MLIRScaleHLSAnalysis

View File

@ -4,108 +4,16 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/InitAllDialects.h"
#include "mlir/InitAllPasses.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/MlirOptMain.h"
#include "scalehls/Analysis/Passes.h"
#include "scalehls/Conversion/Passes.h"
#include "scalehls/Dialect/HLSCpp/HLSCpp.h"
#include "scalehls/Dialect/HLSKernel/HLSKernel.h"
#include "scalehls/Transforms/Passes.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/ToolOutputFile.h"
static llvm::cl::opt<std::string> inputFilename(llvm::cl::Positional,
llvm::cl::desc("<input file>"),
llvm::cl::init("-"));
static llvm::cl::opt<std::string>
outputFilename("o", llvm::cl::desc("Output filename"),
llvm::cl::value_desc("filename"), llvm::cl::init("-"));
static llvm::cl::opt<bool> splitInputFile(
"split-input-file",
llvm::cl::desc("Split the input file into pieces and process each "
"chunk independently"),
llvm::cl::init(false));
static llvm::cl::opt<bool> verifyDiagnostics(
"verify-diagnostics",
llvm::cl::desc("Check that emitted diagnostics match "
"expected-* lines on the corresponding line"),
llvm::cl::init(false));
static llvm::cl::opt<bool> verifyPasses(
"verify-each",
llvm::cl::desc("Run the verifier after each transformation pass"),
llvm::cl::init(true));
static llvm::cl::opt<bool> allowUnregisteredDialects(
"allow-unregistered-dialect",
llvm::cl::desc("Allow operation with no registered dialects"),
llvm::cl::init(true));
static llvm::cl::opt<bool>
showDialects("show-dialects",
llvm::cl::desc("Print the list of registered dialects"),
llvm::cl::init(false));
#include "scalehls/InitAllDialects.h"
#include "scalehls/InitAllPasses.h"
int main(int argc, char **argv) {
mlir::DialectRegistry registry;
registry.insert<mlir::scalehls::hlscpp::HLSCppDialect>();
registry.insert<mlir::scalehls::hlskernel::HLSKernelDialect>();
registry.insert<mlir::StandardOpsDialect>();
registry.insert<mlir::AffineDialect>();
mlir::scalehls::registerAllDialects(registry);
mlir::scalehls::registerAllPasses();
mlir::registerAllDialects(registry);
mlir::registerAllPasses();
mlir::scalehls::registerTransformsPasses();
mlir::scalehls::registerAnalysisPasses();
mlir::scalehls::registerConversionPasses();
llvm::InitLLVM y(argc, argv);
// Register any pass manager command line options.
mlir::registerPassManagerCLOptions();
mlir::PassPipelineCLParser passPipeline("", "Compiler passes to run");
// Parse pass names in main to ensure static initialization completed.
llvm::cl::ParseCommandLineOptions(argc, argv,
"MLIR modular optimizer driver\n");
mlir::MLIRContext context;
if (showDialects) {
llvm::outs() << "Registered Dialects:\n";
for (const auto &nameAndRegistrationIt : registry) {
llvm::outs() << nameAndRegistrationIt.first << "\n";
}
return 0;
}
// Set up the input file.
std::string errorMessage;
auto file = mlir::openInputFile(inputFilename, &errorMessage);
if (!file) {
llvm::errs() << errorMessage << "\n";
return 1;
}
auto output = mlir::openOutputFile(outputFilename, &errorMessage);
if (!output) {
llvm::errs() << errorMessage << "\n";
exit(1);
}
if (failed(MlirOptMain(output->os(), std::move(file), passPipeline, registry,
splitInputFile, verifyDiagnostics, verifyPasses,
allowUnregisteredDialects))) {
return 1;
}
// Keep the output file if the invocation of MlirOptMain was successful.
output->keep();
return 0;
return mlir::failed(mlir::MlirOptMain(argc, argv,
"ScaleHLS Optimization Tool", registry,
/*prelaodDialectsInContext=*/true));
}

View File

@ -8,11 +8,6 @@ get_property(translation_libs GLOBAL PROPERTY MLIR_TRANSLATION_LIBS)
set(LIBS
${dialect_libs}
${translation_libs}
MLIRIR
MLIRParser
MLIRPass
MLIRTranslation
MLIRSupport
MLIRScaleHLSEmitHLSCpp
MLIRScaleHLSAnalysis

View File

@ -4,107 +4,13 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/IR/AsmState.h"
#include "mlir/IR/Diagnostics.h"
#include "mlir/InitAllDialects.h"
#include "mlir/InitAllTranslations.h"
#include "mlir/Support/FileUtilities.h"
#include "mlir/Support/ToolUtilities.h"
#include "mlir/Translation.h"
#include "scalehls/Dialect/HLSCpp/HLSCpp.h"
#include "scalehls/Translation/EmitHLSCpp.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/ToolOutputFile.h"
static llvm::cl::opt<std::string> inputFilename(llvm::cl::Positional,
llvm::cl::desc("<input file>"),
llvm::cl::init("-"));
static llvm::cl::opt<std::string>
outputFilename("o", llvm::cl::desc("Output filename"),
llvm::cl::value_desc("filename"), llvm::cl::init("-"));
static llvm::cl::opt<bool>
splitInputFile("split-input-file",
llvm::cl::desc("Split the input file into pieces and "
"process each chunk independently"),
llvm::cl::init(false));
static llvm::cl::opt<bool> verifyDiagnostics(
"verify-diagnostics",
llvm::cl::desc("Check that emitted diagnostics match "
"expected-* lines on the corresponding line"),
llvm::cl::init(false));
int main(int argc, char **argv) {
mlir::DialectRegistry registry;
mlir::registerAllDialects(registry);
mlir::registerAllTranslations();
mlir::scalehls::registerEmitHLSCppTranslation();
mlir::scalehls::registerHLSCppEmitterTranslation();
llvm::InitLLVM y(argc, argv);
// Add flags for all the registered translations.
llvm::cl::opt<const mlir::TranslateFunction *, false, mlir::TranslationParser>
translationRequested("", llvm::cl::desc("Translation to perform"),
llvm::cl::Required);
mlir::registerAsmPrinterCLOptions();
mlir::registerMLIRContextCLOptions();
llvm::cl::ParseCommandLineOptions(argc, argv, "MLIR translation driver\n");
std::string errorMessage;
auto input = mlir::openInputFile(inputFilename, &errorMessage);
if (!input) {
llvm::errs() << errorMessage << "\n";
return 1;
}
auto output = mlir::openOutputFile(outputFilename, &errorMessage);
if (!output) {
llvm::errs() << errorMessage << "\n";
return 1;
}
// Processes the memory buffer with a new MLIRContext.
auto processBuffer = [&](std::unique_ptr<llvm::MemoryBuffer> ownedBuffer,
llvm::raw_ostream &os) {
mlir::MLIRContext context;
context.loadDialect<mlir::scalehls::hlscpp::HLSCppDialect,
mlir::StandardOpsDialect, mlir::AffineDialect,
mlir::scf::SCFDialect>();
context.allowUnregisteredDialects();
context.printOpOnDiagnostic(!verifyDiagnostics);
llvm::SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(std::move(ownedBuffer), llvm::SMLoc());
if (!verifyDiagnostics) {
mlir::SourceMgrDiagnosticHandler sourceMgrHandler(sourceMgr, &context);
return (*translationRequested)(sourceMgr, os, &context);
}
// In the diagnostic verification flow, we ignore whether the translation
// failed (in most cases, it is expected to fail). Instead, we check if the
// diagnostics were produced as expected.
mlir::SourceMgrDiagnosticVerifierHandler sourceMgrHandler(sourceMgr,
&context);
(*translationRequested)(sourceMgr, os, &context);
return sourceMgrHandler.verify();
};
if (splitInputFile) {
if (failed(mlir::splitAndProcessBuffer(std::move(input), processBuffer,
output->os())))
return 1;
} else {
if (failed(processBuffer(std::move(input), output->os())))
return 1;
}
output->keep();
return 0;
return mlir::failed(
mlir::mlirTranslateMain(argc, argv, "ScaleHLS Translation Tool"));
}