diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c8127376..a18b7801 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -67,6 +67,9 @@ jobs: cmake --build . cmake --build . --target check-mlir + + # Add LLVM tools to PATH + echo "${{github.workspace}}/llvm-project/build/bin" >> $GITHUB_PATH # setup mlir-cgra - name: setup dataflow tool-chain working-directory: ${{github.workspace}} diff --git a/.gitmodules b/.gitmodules index 73189b14..e3aae66b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "test/CGRA-Bench"] - path = test/CGRA-Bench - url = https://github.com/tancheng/CGRA-Bench +[submodule "test/benchmark/CGRA-Bench"] + path = test/benchmark/CGRA-Bench + url = https://github.com/tancheng/CGRA-Bench.git diff --git a/include/NeuraDialect/NeuraOps.td b/include/NeuraDialect/NeuraOps.td index edef5f3d..546aa3d2 100644 --- a/include/NeuraDialect/NeuraOps.td +++ b/include/NeuraDialect/NeuraOps.td @@ -92,16 +92,23 @@ def Neura_FMulOp : Op { def Neura_FDivOp : Op { let summary = "Floating division operation"; - let arguments = (ins AnyType:$lhs, Optional:$rhs); + let description = [{ + Performs a floating-point division operation, computing the result of + a / b, where / is the floating-point division operator. + + Example: + %result = neura.fdiv %a, %b : f32 + }]; + let arguments = (ins AnyType:$lhs, AnyType:$rhs); let results = (outs AnyType:$result); - // let assemblyFormat = "$lhs `,` $rhs `,` $predicate attr-dict `:` type($result)"; + let traits = [SameOperandsAndResultElementType]; } // Defines a bitwise OR operation. def Neura_OrOp : Op { let summary = "Bitwise OR operation"; - let arguments = (ins AnySignlessInteger:$lhs, AnySignlessInteger:$rhs); - let results = (outs AnySignlessInteger:$result); + let arguments = (ins AnyType:$lhs, AnyType:$rhs); + let results = (outs AnyType:$result); // let assemblyFormat = "$lhs `,` $rhs `,` attr-dict `:` type($result)"; let traits = [SameOperandsAndResultElementType]; } diff --git a/lib/Conversion/LlvmToNeura/LlvmToNeuraPass.cpp b/lib/Conversion/LlvmToNeura/LlvmToNeuraPass.cpp index 94f51676..f0f34821 100644 --- a/lib/Conversion/LlvmToNeura/LlvmToNeuraPass.cpp +++ b/lib/Conversion/LlvmToNeura/LlvmToNeuraPass.cpp @@ -134,6 +134,58 @@ struct LlvmSRemToNeuraRem : public OpRewritePattern { } }; +struct LlvmFDivToNeuraFDiv : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(mlir::LLVM::FDivOp op, + PatternRewriter &rewriter) const override { + Value lhs = op->getOperand(0); + Value rhs = op->getOperand(1); + Type result_type = op->getResult(0).getType(); + + // Only matches scalar float. + if (!mlir::isa(result_type)) + return failure(); + + rewriter.replaceOpWithNewOp(op, result_type, lhs, rhs); + return success(); + } +}; + +struct LlvmFPToSIToNeuraCast : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(mlir::LLVM::FPToSIOp op, + PatternRewriter &rewriter) const override { + Value input = op.getArg(); + Type result_type = op.getType(); + + // Creates a cast operation with "fptosi" as the cast type. + rewriter.replaceOpWithNewOp(op, result_type, input, + rewriter.getStringAttr("fptosi")); + return success(); + } +}; + +struct LlvmFMulAddToNeuraFMulFAdd : public OpRewritePattern { + using OpRewritePattern::OpRewritePattern; + + LogicalResult matchAndRewrite(mlir::LLVM::FMulAddOp op, + PatternRewriter &rewriter) const override { + Value a = op->getOperand(0); + Value b = op->getOperand(1); + Value c = op->getOperand(2); + Type result_type = op->getResult(0).getType(); + + // Only matches scalar float. + if (!mlir::isa(result_type)) + return failure(); + + rewriter.replaceOpWithNewOp(op, result_type, a, b, c); + return success(); + } +}; + struct LlvmVFMulToNeuraVFMul : public OpRewritePattern { using OpRewritePattern::OpRewritePattern; @@ -533,6 +585,9 @@ struct LowerLlvmToNeuraPass patterns.add(&getContext()); patterns.add(&getContext()); patterns.add(&getContext()); + patterns.add(&getContext()); + patterns.add(&getContext()); + patterns.add(&getContext()); FrozenRewritePatternSet frozen(std::move(patterns)); diff --git a/test/CGRA-Bench b/test/benchmark/CGRA-Bench similarity index 100% rename from test/CGRA-Bench rename to test/benchmark/CGRA-Bench diff --git a/test/e2e/fir/fir_kernel.mlir b/test/e2e/fir/fir_kernel.mlir new file mode 100644 index 00000000..e3a1d62f --- /dev/null +++ b/test/e2e/fir/fir_kernel.mlir @@ -0,0 +1,37 @@ +// Compiles the original C kernel to mlir, then lowers it via Neura. +// TODO: Got error when using -O3 -fno-vectorize -fno-slp-vectorize -mllvm -force-vector-width=1 +// Issue: https://github.com/coredac/dataflow/issues/164 +// RUN: clang++ -S -emit-llvm -O0 -o %t-kernel-full.ll %S/../../benchmark/CGRA-Bench/kernels/fir/fir.cpp +// RUN: llvm-extract --rfunc=".*kernel.*" %t-kernel-full.ll -o %t-kernel-only.ll +// RUN: mlir-translate --import-llvm %t-kernel-only.ll -o %t-kernel.mlir + +// RUN: mlir-neura-opt %t-kernel.mlir \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --promote-func-arg-to-const \ +// RUN: --insert-data-mov \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic" \ +// RUN: --architecture-spec=../../arch_spec/architecture.yaml \ +// RUN: --generate-code -o %t-mapping.mlir +// RUN: FileCheck %s --input-file=%t-mapping.mlir -check-prefix=MAPPING +// RUN: FileCheck %s --input-file=tmp-generated-instructions.yaml --check-prefix=YAML +// RUN: FileCheck %s --input-file=tmp-generated-instructions.asm --check-prefix=ASM + +// MAPPING: module +// MAPPING: func @_Z6kernelPfS_S_ +// MAPPING: neura.constant +// MAPPING: neura.fmul_fadd +// MAPPING: neura.load +// MAPPING: neura.store + +// YAML: instructions: +// YAML: - opcode: "CONSTANT" +// YAML: - opcode: "FMUL_FADD" +// YAML: - opcode: "LOAD" +// YAML: - opcode: "STORE" + +// ASM: PE(0,0): +// ASM: CONSTANT diff --git a/test/e2e/histogram/histogram_kernel.mlir b/test/e2e/histogram/histogram_kernel.mlir new file mode 100644 index 00000000..de7a1b3b --- /dev/null +++ b/test/e2e/histogram/histogram_kernel.mlir @@ -0,0 +1,36 @@ +// Compiles the original C kernel to mlir, then lowers it via Neura. +// TODO: Got error when using -O3 -fno-vectorize -fno-slp-vectorize -mllvm -force-vector-width=1 +// Issue: https://github.com/coredac/dataflow/issues/164 +// RUN: clang++ -S -emit-llvm -O2 -o %t-kernel-full.ll %S/../../benchmark/CGRA-Bench/kernels/histogram/histogram.cpp +// RUN: llvm-extract --rfunc=".*kernel.*" %t-kernel-full.ll -o %t-kernel-only.ll +// RUN: mlir-translate --import-llvm %t-kernel-only.ll -o %t-kernel.mlir + +// RUN: mlir-neura-opt %t-kernel.mlir \ +// RUN: --assign-accelerator \ +// RUN: --lower-llvm-to-neura \ +// RUN: --canonicalize-live-in \ +// RUN: --leverage-predicated-value \ +// RUN: --transform-ctrl-to-data-flow \ +// RUN: --promote-func-arg-to-const \ +// RUN: --insert-data-mov \ +// RUN: --map-to-accelerator="mapping-strategy=heuristic" \ +// RUN: --architecture-spec=%S/../../arch_spec/architecture.yaml \ +// RUN: --generate-code -o %t-mapping.mlir +// RUN: FileCheck %s --input-file=%t-mapping.mlir -check-prefix=MAPPING +// RUN: FileCheck %s --input-file=tmp-generated-instructions.yaml --check-prefix=YAML +// RUN: FileCheck %s --input-file=tmp-generated-instructions.asm --check-prefix=ASM + + +// MAPPING: module +// MAPPING: func @_Z6kernelPfPi +// MAPPING: neura.constant +// MAPPING: neura.fdiv +// MAPPING: neura.cast + +// YAML: instructions: +// YAML: - opcode: "CONSTANT" +// YAML: - opcode: "FDIV" +// YAML: - opcode: "CAST" + +// ASM: PE(0,0): +// ASM: CONSTANT diff --git a/test/testbench/Conv2D/.gitkeep b/test/testbench/Conv2D/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/FFT/.gitkeep b/test/testbench/FFT/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/SpMV/.gitkeep b/test/testbench/SpMV/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/dtw/.gitkeep b/test/testbench/dtw/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/fir/.gitkeep b/test/testbench/fir/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/gemm/.gitkeep b/test/testbench/gemm/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/histogram/.gitkeep b/test/testbench/histogram/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/test/testbench/relu/.gitkeep b/test/testbench/relu/.gitkeep deleted file mode 100644 index e69de29b..00000000