From aedf1757dbb187ad3016f2957abac1beac77ac7c Mon Sep 17 00:00:00 2001 From: taiqzheng <2013898008@qq.com> Date: Sun, 21 May 2023 20:26:01 +0800 Subject: [PATCH] [DIP] Add benchmark for Buddy rotation operation. --- .../BuddyRotate2DBenchmark.cpp | 141 ++++++++++++++++++ benchmarks/ImageProcessing/CMakeLists.txt | 27 +++- benchmarks/ImageProcessing/MainRotate.cpp | 54 +++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 benchmarks/ImageProcessing/BuddyRotate2DBenchmark.cpp create mode 100644 benchmarks/ImageProcessing/MainRotate.cpp diff --git a/benchmarks/ImageProcessing/BuddyRotate2DBenchmark.cpp b/benchmarks/ImageProcessing/BuddyRotate2DBenchmark.cpp new file mode 100644 index 00000000..7e2c7fc2 --- /dev/null +++ b/benchmarks/ImageProcessing/BuddyRotate2DBenchmark.cpp @@ -0,0 +1,141 @@ +//===- BuddyRotate2DBenchmark.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 Rotate2D operation. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include + +using namespace cv; +using namespace std; + +// Declare input image. +Mat inputImageBuddyRotate2D; + +// Define the angle. +float BuddyRotate2DAngle; + +// Define sizes of input. +intptr_t sizesInputBuddyRotate2D[2]; + +// Declare Angle option supported. +enum AngleOption { ANGLE_DEGREE, ANGLE_RADIAN }; + +// Define Angle option selected. +AngleOption AngleType; + +void initializeBuddyRotate2D(char **argv) { + inputImageBuddyRotate2D = imread(argv[1], IMREAD_GRAYSCALE); + + sizesInputBuddyRotate2D[0] = inputImageBuddyRotate2D.rows; + sizesInputBuddyRotate2D[1] = inputImageBuddyRotate2D.cols; + + if (static_cast(argv[2]) == "DEGREE") { + AngleType = ANGLE_DEGREE; + } else { + AngleType = ANGLE_RADIAN; + } + + std::string argAngle = argv[3]; + try { + BuddyRotate2DAngle = std::stof(argAngle); + } catch (const std::exception& e) { + cout << "Exception converting rotation angle to float." << endl; + } +} + +static void Buddy_Rotate2D_ANGLE_DEGREE(benchmark::State &state) { + // Define the MemRef descriptor for input. + Img inputBuddyRotate2D(inputImageBuddyRotate2D); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + // Call the MLIR Rotate2D function. + MemRef output = dip::Rotate2D(&inputBuddyRotate2D, BuddyRotate2DAngle, + dip::ANGLE_TYPE::DEGREE); + } + } +} + +static void Buddy_Rotate2D_ANGLE_RADIAN(benchmark::State &state) { + // Define the MemRef descriptor for input. + Img inputBuddyRotate2D(inputImageBuddyRotate2D); + + for (auto _ : state) { + for (int i = 0; i < state.range(0); ++i) { + // Call the MLIR Rotate2D function. + MemRef output = dip::Rotate2D(&inputBuddyRotate2D, BuddyRotate2DAngle, + dip::ANGLE_TYPE::RADIAN); + } + } +} + +// Register benchmarking function. +void registerBenchmarkBuddyRotate2D() { + if (AngleType == ANGLE_DEGREE) { + BENCHMARK(Buddy_Rotate2D_ANGLE_DEGREE) + ->Arg(1) + ->Unit(benchmark::kMillisecond); + } else { + BENCHMARK(Buddy_Rotate2D_ANGLE_RADIAN) + ->Arg(1) + ->Unit(benchmark::kMillisecond); + } +} + +// Generate result image. +void generateResultBuddyRotate2D() { + // Define the MemRef descriptor for input. + Img input(inputImageBuddyRotate2D); + MemRef output(sizesInputBuddyRotate2D); + // Run the resize 2D operation. + if (AngleType == ANGLE_DEGREE) { + // Call the MLIR Rotate2D function. + output = dip::Rotate2D(&input, BuddyRotate2DAngle, + dip::ANGLE_TYPE::DEGREE); + } else { + // Call the MLIR Rotate2D function. + output = dip::Rotate2D(&input, BuddyRotate2DAngle, + dip::ANGLE_TYPE::RADIAN); + } + + // Define a cv::Mat with the output of the resize operation. + Mat outputImage(output.getSizes()[0], output.getSizes()[1], CV_32FC1, + output.getData()); + + // Choose a PNG compression level + vector compressionParams; + compressionParams.push_back(IMWRITE_PNG_COMPRESSION); + compressionParams.push_back(9); + + // Write output to PNG. + bool result = true; + try { + result = imwrite("ResultBuddyRotate2D.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/CMakeLists.txt b/benchmarks/ImageProcessing/CMakeLists.txt index 029beb4a..c36f448f 100644 --- a/benchmarks/ImageProcessing/CMakeLists.txt +++ b/benchmarks/ImageProcessing/CMakeLists.txt @@ -144,4 +144,29 @@ target_link_libraries(image-processing-resize-benchmark # Link Buddy MLIR DIP Library. BuddyLibDIP ) - \ No newline at end of file + +#------------------------------------------------------------------------------- +# Image Processing Rotate Benchmark Target +#------------------------------------------------------------------------------- + +add_executable(image-processing-rotate-benchmark + MainRotate.cpp + BuddyRotate2DBenchmark.cpp + ) + +target_include_directories(image-processing-rotate-benchmark + PRIVATE + ${BUDDY_SOURCE_DIR}/benchmarks/ImageProcessing/include/ + ) + +target_link_directories(image-processing-rotate-benchmark + PRIVATE + ${BUDDY_MLIR_LIB_DIR} + ) + +target_link_libraries(image-processing-rotate-benchmark + GoogleBenchmark + ${OpenCV_LIBS} + # Link Buddy MLIR DIP Library. + BuddyLibDIP + ) \ No newline at end of file diff --git a/benchmarks/ImageProcessing/MainRotate.cpp b/benchmarks/ImageProcessing/MainRotate.cpp new file mode 100644 index 00000000..ac7ceab9 --- /dev/null +++ b/benchmarks/ImageProcessing/MainRotate.cpp @@ -0,0 +1,54 @@ +//===- MainRotate.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 is the main file of the image processing rotate benchmark. +// +//===----------------------------------------------------------------------===// + +#include +#include + +void initializeBuddyRotate2D(char **); + +void generateResultBuddyRotate2D(); + +void registerBenchmarkBuddyRotate2D(); + +// Run benchmarks. +int main(int argc, char **argv) { + if (argc != 4) { + throw std::invalid_argument( + "Wrong format of command line arguments.\n" + "Correct format is ./image-processing-rotate-benchmark \n where " + "image path provides path of the image to be processed, Rotate option " + "available are DEGREE, RADIAN. " + "RotateAngle accepts a " + "float number for Rotate option.\n"); + } + + initializeBuddyRotate2D(argv); + + registerBenchmarkBuddyRotate2D(); + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + + // Generate result image. + generateResultBuddyRotate2D(); + + return 0; +}