Hi there, I’m trying to use the circt
project as an hls
tool. I’ve created a gauss
filter function in the c file:
#define COLS 20
#define ROWS 20
#define KERN_SIZE 3
#define KERN_RAD (KERN_SIZE >> 1)
#define PIXELS COLS* ROWS
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
void gauss(uint8_t input[PIXELS], uint8_t output[PIXELS])
{
// Gauss kernel
int16_t kernel[KERN_SIZE][KERN_SIZE] = {
{1, 2, 1},
{2, 4, 2},
{1, 2, 1}
};
for (int32_t y = 0; y < ROWS; y++) {
for (int32_t x = 0; x < COLS; x++) {
// temp var to store the result
int16_t sum = 0;
for (int32_t i = -KERN_RAD; i <= KERN_RAD; i++) {
for (int32_t j = -KERN_RAD; j <= KERN_RAD; j++) {
int32_t yi = y + i;
int32_t xj = x + j;
if (xj >= 0 && xj < COLS && yi >= 0 && yi < ROWS)
sum +=
(int16_t)(input[yi * COLS + xj] * kernel[i + KERN_RAD][j + KERN_RAD]);
}
}
// Normalize and store
output[y * COLS + x] = (uint8_t)(MAX(MIN(255, sum >> 4), 0));
}
}
}
Then I used the Polygeist
to translate it into mlir
like the code following:
#set = affine_set<(d0, d1, d2, d3) : (-d0 - d1 + 19 >= 0, d0 + d1 >= 0, d2 + d3 >= 0, -d2 - d3 + 19 >= 0)>
module {
func.func @gauss(%arg0: memref<400xi8>, %arg1: memref<400xi8>) attributes {llvm.linkage = #llvm.linkage<external>} {
%true = arith.constant true
%c4_i32 = arith.constant 4 : i32
%c255_i32 = arith.constant 255 : i32
%c0_i16 = arith.constant 0 : i16
%c0_i32 = arith.constant 0 : i32
%c4_i16 = arith.constant 4 : i16
%c2_i16 = arith.constant 2 : i16
%c1_i16 = arith.constant 1 : i16
%alloca = memref.alloca() : memref<3x3xi16>
affine.store %c1_i16, %alloca[0, 0] : memref<3x3xi16>
affine.store %c2_i16, %alloca[0, 1] : memref<3x3xi16>
affine.store %c1_i16, %alloca[0, 2] : memref<3x3xi16>
affine.store %c2_i16, %alloca[1, 0] : memref<3x3xi16>
affine.store %c4_i16, %alloca[1, 1] : memref<3x3xi16>
affine.store %c2_i16, %alloca[1, 2] : memref<3x3xi16>
affine.store %c1_i16, %alloca[2, 0] : memref<3x3xi16>
affine.store %c2_i16, %alloca[2, 1] : memref<3x3xi16>
affine.store %c1_i16, %alloca[2, 2] : memref<3x3xi16>
affine.for %arg2 = 0 to 20 {
affine.for %arg3 = 0 to 20 {
%0 = affine.for %arg4 = -1 to 2 iter_args(%arg5 = %c0_i16) -> (i16) {
%7 = affine.for %arg6 = -1 to 2 iter_args(%arg7 = %arg5) -> (i16) {
%8 = affine.if #set(%arg2, %arg4, %arg3, %arg6) -> i16 {
%9 = affine.load %arg0[%arg4 * 20 + %arg3 + %arg6 + %arg2 * 20] : memref<400xi8>
%10 = arith.extsi %9 : i8 to i32
%11 = affine.load %alloca[%arg4 + 1, %arg6 + 1] : memref<3x3xi16>
%12 = arith.extsi %11 : i16 to i32
%13 = arith.muli %10, %12 : i32
%14 = arith.trunci %13 : i32 to i16
%15 = arith.addi %arg7, %14 : i16
affine.yield %15 : i16
} else {
affine.yield %arg7 : i16
}
affine.yield %8 : i16
}
affine.yield %7 : i16
}
%1 = arith.extsi %0 : i16 to i32
%2 = arith.shrsi %1, %c4_i32 : i32
%3 = arith.cmpi sgt, %2, %c255_i32 : i32
%4 = scf.if %3 -> (i1) {
scf.yield %true : i1
} else {
%7 = arith.cmpi sgt, %2, %c0_i32 : i32
scf.yield %7 : i1
}
%5 = scf.if %4 -> (i32) {
%7 = arith.select %3, %c255_i32, %2 : i32
scf.yield %7 : i32
} else {
scf.yield %c0_i32 : i32
}
%6 = arith.trunci %5 : i32 to i8
affine.store %6, %arg1[%arg3 + %arg2 * 20] : memref<400xi8>
}
}
return
}
}
For the first step I’m thinking use the pass --convert-affine-to-pipeline
as I’ve successfully tested with other simple loop functions. But with this programm I 've got this error backtrace:
circt-opt: /home/bi/Desktop/circt/llvm/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp:643: mlir::DependenceResult mlir::checkMemrefAccessDependence(const mlir::MemRefAccess &, const mlir::MemRefAccess &, unsigned int, mlir::FlatAffineValueConstraints *, SmallVector<mlir::DependenceComponent, 2> *, bool): Assertion `loopDepth <= numCommonLoops + 1' failed.
PLEASE submit a bug report to https://github.com/llvm/circt and include the crash backtrace.
Stack dump:
0. Program arguments: /home/bi/Desktop/circt/build/bin/circt-opt gauss.mlir -convert-affine-to-pipeline
#0 0x0000560a65fea36d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/bi/Desktop/circt/llvm/llvm/lib/Support/Unix/Signals.inc:567:11
#1 0x0000560a65fea7fb PrintStackTraceSignalHandler(void*) /home/bi/Desktop/circt/llvm/llvm/lib/Support/Unix/Signals.inc:641:1
#2 0x0000560a65fe8b76 llvm::sys::RunSignalHandlers() /home/bi/Desktop/circt/llvm/llvm/lib/Support/Signals.cpp:104:5
#3 0x0000560a65feaf25 SignalHandler(int) /home/bi/Desktop/circt/llvm/llvm/lib/Support/Unix/Signals.inc:412:1
#4 0x00007fbecfe3e420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
#5 0x00007fbecf8d100b raise /build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
#6 0x00007fbecf8b0859 abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:81:7
#7 0x00007fbecf8b0729 get_sysdep_segment_value /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:509:8
#8 0x00007fbecf8b0729 _nl_load_domain /build/glibc-SzIz7B/glibc-2.31/intl/loadmsgcat.c:970:34
#9 0x00007fbecf8c1fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
#10 0x0000560a67d850b8 mlir::checkMemrefAccessDependence(mlir::MemRefAccess const&, mlir::MemRefAccess const&, unsigned int, mlir::FlatAffineValueConstraints*, llvm::SmallVector<mlir::DependenceComponent, 2u>*, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Dialect/Affine/Analysis/AffineAnalysis.cpp:644:17
#11 0x0000560a67b528de checkMemrefDependence(llvm::SmallVectorImpl<mlir::Operation*>&, unsigned int, llvm::DenseMap<mlir::Operation*, llvm::SmallVector<circt::analysis::MemoryDependence, 1u>, llvm::DenseMapInfo<mlir::Operation*, void>, llvm::detail::DenseMapPair<mlir::Operation*, llvm::SmallVector<circt::analysis::MemoryDependence, 1u>>>&) /home/bi/Desktop/circt/lib/Analysis/DependenceAnalysis.cpp:46:33
#12 0x0000560a67b526ef circt::analysis::MemoryDependenceAnalysis::MemoryDependenceAnalysis(mlir::Operation*) /home/bi/Desktop/circt/lib/Analysis/DependenceAnalysis.cpp:142:65
#13 0x0000560a65ffa004 mlir::detail::AnalysisModel<circt::analysis::MemoryDependenceAnalysis>::AnalysisModel<mlir::func::FuncOp&>(mlir::func::FuncOp&) /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/AnalysisManager.h:120:48
#14 0x0000560a65ff9f7e std::_MakeUniq<mlir::detail::AnalysisModel<circt::analysis::MemoryDependenceAnalysis>>::__single_object std::make_unique<mlir::detail::AnalysisModel<circt::analysis::MemoryDependenceAnalysis>, mlir::func::FuncOp&>(mlir::func::FuncOp&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/unique_ptr.h:962:34
#15 0x0000560a65ff7147 auto mlir::detail::AnalysisMap::constructAnalysis<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp, (void*)0>(mlir::AnalysisManager&, mlir::func::FuncOp) /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/AnalysisManager.h:233:12
#16 0x0000560a65ff6c36 circt::analysis::MemoryDependenceAnalysis& mlir::detail::AnalysisMap::getAnalysisImpl<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp>(mlir::PassInstrumentor*, mlir::func::FuncOp, mlir::AnalysisManager&) /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/AnalysisManager.h:211:27
#17 0x0000560a65ff6b15 std::enable_if<std::is_constructible<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp>::value || std::is_constructible<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp, mlir::AnalysisManager&>::value, circt::analysis::MemoryDependenceAnalysis&>::type mlir::detail::AnalysisMap::getAnalysis<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp>(mlir::PassInstrumentor*, mlir::AnalysisManager&) /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/AnalysisManager.h:167:5
#18 0x0000560a65ff69a4 circt::analysis::MemoryDependenceAnalysis& mlir::AnalysisManager::getAnalysis<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp>() /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/AnalysisManager.h:326:5
#19 0x0000560a65ff6932 circt::analysis::MemoryDependenceAnalysis& mlir::Pass::getAnalysis<circt::analysis::MemoryDependenceAnalysis, mlir::func::FuncOp>() /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/Pass.h:225:5
#20 0x0000560a65ff64b5 circt::analysis::MemoryDependenceAnalysis& mlir::OperationPass<mlir::func::FuncOp>::getAnalysis<circt::analysis::MemoryDependenceAnalysis>() /home/bi/Desktop/circt/llvm/mlir/include/mlir/Pass/Pass.h:373:5
#21 0x0000560a65ff0d4f (anonymous namespace)::AffineToPipeline::runOnOperation() /home/bi/Desktop/circt/lib/Conversion/AffineToPipeline/AffineToPipeline.cpp:68:29
#22 0x0000560a6888545a mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:471:21
#23 0x0000560a68885a74 mlir::detail::OpToOpPassAdaptor::runPipeline(mlir::OpPassManager&, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:534:16
#24 0x0000560a6888b058 mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_14::operator()(mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo&) const /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:754:36
#25 0x0000560a6888acc9 mlir::LogicalResult mlir::failableParallelForEach<__gnu_cxx::__normal_iterator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*, std::vector<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo, std::allocator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo>>>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_14&>(mlir::MLIRContext*, __gnu_cxx::__normal_iterator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*, std::vector<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo, std::allocator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo>>>, __gnu_cxx::__normal_iterator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo*, std::vector<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo, std::allocator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo>>>, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_14&) /home/bi/Desktop/circt/llvm/mlir/include/mlir/IR/Threading.h:46:18
#26 0x0000560a68886d53 mlir::LogicalResult mlir::failableParallelForEach<std::vector<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo, std::allocator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo>>&, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_14&>(mlir::MLIRContext*, std::vector<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo, std::allocator<mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::OpPMInfo>>&, mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool)::$_14&) /home/bi/Desktop/circt/llvm/mlir/include/mlir/IR/Threading.h:92:10
#27 0x0000560a688865f7 mlir::detail::OpToOpPassAdaptor::runOnOperationAsyncImpl(bool) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:764:14
#28 0x0000560a68885727 mlir::detail::OpToOpPassAdaptor::runOnOperation(bool) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:655:5
#29 0x0000560a6888544b mlir::detail::OpToOpPassAdaptor::run(mlir::Pass*, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:468:5
#30 0x0000560a68885a74 mlir::detail::OpToOpPassAdaptor::runPipeline(mlir::OpPassManager&, mlir::Operation*, mlir::AnalysisManager, bool, unsigned int, mlir::PassInstrumentor*, mlir::PassInstrumentation::PipelineParentInfo const*) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:534:16
#31 0x0000560a6888749c mlir::PassManager::runPasses(mlir::Operation*, mlir::AnalysisManager) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:843:10
#32 0x0000560a688873b2 mlir::PassManager::run(mlir::Operation*) /home/bi/Desktop/circt/llvm/mlir/lib/Pass/Pass.cpp:823:60
#33 0x0000560a67a36c6f performActions(llvm::raw_ostream&, bool, bool, std::shared_ptr<llvm::SourceMgr> const&, mlir::MLIRContext*, llvm::function_ref<mlir::LogicalResult (mlir::PassManager&)>, bool, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:90:17
#34 0x0000560a67a368ff processBuffer(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, bool, bool, bool, bool, bool, bool, llvm::function_ref<mlir::LogicalResult (mlir::PassManager&)>, mlir::DialectRegistry&, llvm::ThreadPool*) /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:138:12
#35 0x0000560a67a366b8 mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (mlir::PassManager&)>, mlir::DialectRegistry&, bool, bool, bool, bool, bool, bool, bool)::$_0::operator()(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) const /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:180:12
#36 0x0000560a67a365ad mlir::LogicalResult llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>::callback_fn<mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (mlir::PassManager&)>, mlir::DialectRegistry&, bool, bool, bool, bool, bool, bool, bool)::$_0>(long, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) /home/bi/Desktop/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:45:12
#37 0x0000560a67a798d9 llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>::operator()(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&) const /home/bi/Desktop/circt/llvm/llvm/include/llvm/ADT/STLFunctionalExtras.h:68:12
#38 0x0000560a67a78eb5 mlir::splitAndProcessBuffer(std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::raw_ostream&)>, llvm::raw_ostream&, bool, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Support/ToolUtilities.cpp:28:12
#39 0x0000560a67a355d3 mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, llvm::function_ref<mlir::LogicalResult (mlir::PassManager&)>, mlir::DialectRegistry&, bool, bool, bool, bool, bool, bool, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:185:10
#40 0x0000560a67a3576f mlir::MlirOptMain(llvm::raw_ostream&, std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>, mlir::PassPipelineCLParser const&, mlir::DialectRegistry&, bool, bool, bool, bool, bool, bool, bool, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:208:10
#41 0x0000560a67a363b1 mlir::MlirOptMain(int, char**, llvm::StringRef, mlir::DialectRegistry&, bool) /home/bi/Desktop/circt/llvm/mlir/lib/Tools/mlir-opt/MlirOptMain.cpp:305:14
#42 0x0000560a65ea774b main /home/bi/Desktop/circt/tools/circt-opt/circt-opt.cpp:68:23
#43 0x00007fbecf8b2083 __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:342:3
#44 0x0000560a65ea75ae _start (/home/bi/Desktop/circt/build/bin/circt-opt+0x18915ae)
[1] 69702 abort (core dumped) /home/bi/Desktop/circt/build/bin/circt-opt gauss.mlir
I don’t really understand how this is happening. Could anyone tell me what causes this problem?