diff --git a/benchmarks/ImageProcessing/CMakeLists.txt b/benchmarks/ImageProcessing/CMakeLists.txt index f84ea539597d486f5b6aded5e52b2fbe733fcf5e..9896ca1bd7e0d0f498b6c8d1f1625f79532a5cb5 100644 --- a/benchmarks/ImageProcessing/CMakeLists.txt +++ b/benchmarks/ImageProcessing/CMakeLists.txt @@ -2,22 +2,52 @@ set(BUDDY_OPT_STRIP_MINING 256) set(BUDDY_OPT_ATTR avx512f) set(LLVM_MLIR_BINARY_DIR ${BUDDY_OPT_BUILD_DIR}/../llvm/build/bin) +#------------------------------------------------------------------------------- +# MLIR Linalg Dialect Conv2D Operation + CB Algorithm +#------------------------------------------------------------------------------- + add_custom_command(OUTPUT conv2d.o COMMAND ${BUDDY_OPT_BUILD_DIR}/bin/buddy-opt ${BUDDY_SOURCE_DIR}/benchmarks/ImageProcessing/Conv2D.mlir -conv-vectorization="strip-mining=${BUDDY_OPT_STRIP_MINING}" -lower-affine -convert-scf-to-std -convert-vector-to-llvm -convert-memref-to-llvm -convert-std-to-llvm='emit-c-wrappers=1' -reconcile-unrealized-casts | ${LLVM_MLIR_BINARY_DIR}/mlir-translate --mlir-to-llvmir | ${LLVM_MLIR_BINARY_DIR}/llc -mtriple=x86_64-unknown-linux-gnu -mattr=${BUDDY_OPT_ATTR} --filetype=obj -o ${BUDDY_BINARY_DIR}/../benchmarks/ImageProcessing/conv2d.o ) - add_library(Conv2D STATIC conv2d.o) - set_target_properties(Conv2D PROPERTIES LINKER_LANGUAGE CXX) -add_executable(image-processing-benchmark Main.cpp OpenCVBenchmark.cpp BuddyBenchmark.cpp) +#------------------------------------------------------------------------------- +# Buddy DIP Dialect Corr2D Operation + CB Algorithm +#------------------------------------------------------------------------------- + +add_custom_command(OUTPUT corr2d.o + COMMAND ${BUDDY_OPT_BUILD_DIR}/bin/buddy-opt + ${BUDDY_SOURCE_DIR}/benchmarks/ImageProcessing/Corr2D.mlir + -lower-dip -lower-affine -convert-scf-to-std -convert-vector-to-llvm + -convert-memref-to-llvm -convert-std-to-llvm='emit-c-wrappers=1' + -reconcile-unrealized-casts | + ${LLVM_MLIR_BINARY_DIR}/mlir-translate --mlir-to-llvmir | + ${LLVM_MLIR_BINARY_DIR}/llc -mtriple=x86_64-unknown-linux-gnu + -mattr=${BUDDY_OPT_ATTR} --filetype=obj + -o ${BUDDY_BINARY_DIR}/../benchmarks/ImageProcessing/corr2d.o +) +add_library(Corr2D STATIC corr2d.o) +set_target_properties(Corr2D PROPERTIES LINKER_LANGUAGE CXX) + +#------------------------------------------------------------------------------- +# Image Processing Benchmark Target +#------------------------------------------------------------------------------- + +add_executable(image-processing-benchmark + Main.cpp + OpenCVBenchmark.cpp + BuddyBenchmark.cpp + Corr2DBenchmark.cpp + ) target_link_libraries(image-processing-benchmark GoogleBenchmark ${OpenCV_LIBS} Conv2D + Corr2D Container PNGImage ) diff --git a/benchmarks/ImageProcessing/Corr2D.mlir b/benchmarks/ImageProcessing/Corr2D.mlir new file mode 100644 index 0000000000000000000000000000000000000000..b943583e3db376d916c7d03b2f0fe719d80d5796 --- /dev/null +++ b/benchmarks/ImageProcessing/Corr2D.mlir @@ -0,0 +1,8 @@ +func @corr_2d(%inputImage : memref<?x?xf32>, %kernel : memref<?x?xf32>, + %outputImage : memref<?x?xf32>, %centerX : index, + %centerY : index, %boundaryOption : index) { + dip.corr_2d %inputImage, %kernel, %outputImage, %centerX, %centerY, + %boundaryOption : memref<?x?xf32>, memref<?x?xf32>, + memref<?x?xf32>, index, index, index + return +} \ No newline at end of file diff --git a/benchmarks/ImageProcessing/Corr2DBenchmark.cpp b/benchmarks/ImageProcessing/Corr2DBenchmark.cpp new file mode 100644 index 0000000000000000000000000000000000000000..366cdfe088d3257b00932d3fd514cafd7888b709 --- /dev/null +++ b/benchmarks/ImageProcessing/Corr2DBenchmark.cpp @@ -0,0 +1,107 @@ +//===- Corr2DBenchmark.cpp ------------------------------------------------===// +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//===----------------------------------------------------------------------===// +// +// This file implements the benchmark for Corr2D operation. +// +//===----------------------------------------------------------------------===// + +#include "ImageProcessing/Kernels.h" +#include "Utils/Container.h" +#include <benchmark/benchmark.h> +#include <opencv2/opencv.hpp> + +using namespace cv; +using namespace std; + +// Declare the conv2d C interface. +extern "C" { +void _mlir_ciface_corr_2d(MemRef<float, 2> *inputCorr2D, + MemRef<float, 2> *kernelCorr2D, + MemRef<float, 2> *outputCorr2D, unsigned int centerX, + unsigned int centerY, int boundaryOption); +} + +// Read input image. +Mat inputImageCorr2D = imread( + "../../benchmarks/ImageProcessing/Images/YuTu.png", IMREAD_GRAYSCALE); + +// Define the kernel size. +int kernelRowsCorr2D = laplacianKernelRows; +int kernelColsCorr2D = laplacianKernelCols; + +// Define the output size. +int outputRowsCorr2D = inputImageCorr2D.rows; +int outputColsCorr2D = inputImageCorr2D.cols; + +// Define sizes of input, kernel, and output. +intptr_t sizesInputCorr2D[2] = {inputImageCorr2D.rows, inputImageCorr2D.cols}; +intptr_t sizesKernelCorr2D[2] = {kernelRowsCorr2D, kernelColsCorr2D}; +intptr_t sizesOutputCorr2D[2] = {outputRowsCorr2D, outputColsCorr2D}; + +// Define the MemRef descriptor for input, kernel, and output. +MemRef<float, 2> inputCorr2D(inputImageCorr2D, sizesInputCorr2D); +MemRef<float, 2> kernelCorr2D(laplacianKernelAlign, sizesKernelCorr2D); +MemRef<float, 2> outputCorr2D(sizesOutputCorr2D); + +static void BM_Corr2D(benchmark::State &state) { + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + _mlir_ciface_corr_2d(&inputCorr2D, &kernelCorr2D, &outputCorr2D, + 1 /* Center X */, 1 /* Center Y */, + 0 /* Boundary Option */); + } + } +} + +// Register benchmarking function with different arguments. +BENCHMARK(BM_Corr2D)->Arg(1); +BENCHMARK(BM_Corr2D)->Arg(2); +BENCHMARK(BM_Corr2D)->Arg(4); +BENCHMARK(BM_Corr2D)->Arg(8); +BENCHMARK(BM_Corr2D)->Arg(16); + +// Generate result image. +void generateResultCorr2D() { + // Define the MemRef descriptor for input, kernel, and output. + MemRef<float, 2> input(inputImageCorr2D, sizesInputCorr2D); + MemRef<float, 2> kernel(laplacianKernelAlign, sizesKernelCorr2D); + MemRef<float, 2> output(sizesOutputCorr2D); + // Run the 2D correlation. + _mlir_ciface_corr_2d(&input, &kernel, &output, 1 /* Center X */, + 1 /* Center Y */, 0 /* Boundary Option */); + + // Define a cv::Mat with the output of the correlation. + Mat outputImage(outputRowsCorr2D, outputColsCorr2D, CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector<int> compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = false; + try { + result = imwrite("ResultCorr2D.png", outputImage, compressionParams); + } catch (const cv::Exception &ex) { + fprintf(stderr, "Exception converting image to PNG format: %s\n", + ex.what()); + } + if (result) + cout << "Saved PNG file." << endl; + else + cout << "ERROR: Can't save PNG file." << endl; +} diff --git a/benchmarks/ImageProcessing/Main.cpp b/benchmarks/ImageProcessing/Main.cpp index e73a71839119c1b10c932b1b4a3efaee1ad12202..bd7b0d7109279d8071ea1feff98c2e091a16ae82 100644 --- a/benchmarks/ImageProcessing/Main.cpp +++ b/benchmarks/ImageProcessing/Main.cpp @@ -20,10 +20,14 @@ #include <benchmark/benchmark.h> +void generateResultCorr2D(); + // Run benchmarks. int main(int argc, char **argv) { ::benchmark::Initialize(&argc, argv); ::benchmark::RunSpecifiedBenchmarks(); + // Generate result image. + generateResultCorr2D(); return 0; }