Skip to content

Commit

Permalink
[DIP] Add benchmark for Buddy & OpenCV resize2d operation.
Browse files Browse the repository at this point in the history
  • Loading branch information
taiqzheng committed May 21, 2023
1 parent 7db95bb commit 0b189ab
Show file tree
Hide file tree
Showing 4 changed files with 489 additions and 0 deletions.
219 changes: 219 additions & 0 deletions benchmarks/ImageProcessing/BuddyResize2DBenchmark.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
//===- BuddyResize2DBenchmark.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 Resize2D operation.
//
//===----------------------------------------------------------------------===//

#include <benchmark/benchmark.h>
#include <buddy/Core/Container.h>
#include <buddy/DIP/ImageContainer.h>
#include <buddy/DIP/DIP.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

// Declare input image.
Mat inputImageBuddyResize2D;

// Define the output size or factor.
int outputRowsBuddyResize2DLength, outputColsBuddyResize2DLength;
float outputRowsBuddyResize2DFactor, outputColsBuddyResize2DFactor;

// Define sizes of input and output.
intptr_t sizesInputBuddyResize2D[2];
intptr_t sizesOutputBuddyResize2D[2];
std::vector<float> factorsOutputBuddyResize2D = {1.0, 1.0};

// Declare Interpolation option supported.
enum InterpolationOption { bilinear_interpolation, nearest_neighbour_interpolation };

// Declare Scale option supported.
enum ScaleOption { scale_factor, scale_length };

// Define Interpolation option selected.
InterpolationOption InterpolationType;

// Define Scale option selected.
ScaleOption ScaleType;

void initializeBuddyResize2D(char **argv) {
inputImageBuddyResize2D = imread(argv[1], IMREAD_GRAYSCALE);

sizesInputBuddyResize2D[0] = inputImageBuddyResize2D.rows;
sizesInputBuddyResize2D[1] = inputImageBuddyResize2D.cols;

if (static_cast<string>(argv[2]) == "SCALE_FACTOR") {
ScaleType = scale_factor;
} else {
ScaleType = scale_length;
}

std::string argRow = argv[3];
std::string argCol = argv[4];
try {
if (ScaleType == scale_factor) {
float outputRowsBuddyResize2DFactor = std::stof(argRow);
float outputColsBuddyResize2DFactor = std::stof(argCol);
factorsOutputBuddyResize2D[0] = outputRowsBuddyResize2DFactor;
factorsOutputBuddyResize2D[1] = outputColsBuddyResize2DFactor;
sizesOutputBuddyResize2D[0] = sizesInputBuddyResize2D[0] * outputRowsBuddyResize2DFactor;
sizesOutputBuddyResize2D[1] = sizesInputBuddyResize2D[1] * outputColsBuddyResize2DFactor;
} else {
intptr_t outputRowsBuddyResize2DLength = std::stoi(argRow);
intptr_t outputColsBuddyResize2DLength = std::stoi(argCol);
sizesOutputBuddyResize2D[0] = outputRowsBuddyResize2DLength;
sizesOutputBuddyResize2D[1] = outputColsBuddyResize2DLength;
}
} catch (const std::exception& e) {
cout << "Exception converting row and col scale_factor/scale_length to number." << endl;
}

if (static_cast<string>(argv[5]) == "NEAREST_NEIGHBOUR_INTERPOLATION") {
InterpolationType = nearest_neighbour_interpolation;
} else {
InterpolationType = bilinear_interpolation;
}
}

static void Buddy_Resize2D_Bilinear_Interpolation_Length(benchmark::State &state) {
// Define the MemRef descriptor for input.
Img<float, 2> inputBuddyResize2D(inputImageBuddyResize2D);

for (auto _ : state) {
for (int i = 0; i < state.range(0); ++i) {
// Call the MLIR Resize2D function.
MemRef<float, 2> output = dip::Resize2D(&inputBuddyResize2D,
dip::INTERPOLATION_TYPE::BILINEAR_INTERPOLATION,
sizesOutputBuddyResize2D);
}
}
}

static void Buddy_Resize2D_Nearest_Neighbour_Interpolation_Length(benchmark::State &state) {
// Define the MemRef descriptor for input.
Img<float, 2> inputBuddyResize2D(inputImageBuddyResize2D);

for (auto _ : state) {
for (int i = 0; i < state.range(0); ++i) {
// Call the MLIR Resize2D function.
MemRef<float, 2> output = dip::Resize2D(&inputBuddyResize2D,
dip::INTERPOLATION_TYPE::NEAREST_NEIGHBOUR_INTERPOLATION,
sizesOutputBuddyResize2D);
}
}
}

static void Buddy_Resize2D_Bilinear_Interpolation_Factor(benchmark::State &state) {
// Define the MemRef descriptor for input.
Img<float, 2> inputBuddyResize2D(inputImageBuddyResize2D);

for (auto _ : state) {
for (int i = 0; i < state.range(0); ++i) {
// Call the MLIR Resize2D function.
MemRef<float, 2> output = dip::Resize2D(&inputBuddyResize2D,
dip::INTERPOLATION_TYPE::BILINEAR_INTERPOLATION,
factorsOutputBuddyResize2D);
}
}
}

static void Buddy_Resize2D_Nearest_Neighbour_Interpolation_Factor(benchmark::State &state) {
// Define the MemRef descriptor for input.
Img<float, 2> inputBuddyResize2D(inputImageBuddyResize2D);

for (auto _ : state) {
for (int i = 0; i < state.range(0); ++i) {
// Call the MLIR Resize2D function.
MemRef<float, 2> output = dip::Resize2D(&inputBuddyResize2D,
dip::INTERPOLATION_TYPE::NEAREST_NEIGHBOUR_INTERPOLATION,
factorsOutputBuddyResize2D);
}
}
}

// Register benchmarking function.
void registerBenchmarkBuddyResize2D() {
if (InterpolationType == nearest_neighbour_interpolation && ScaleType == scale_factor) {
BENCHMARK(Buddy_Resize2D_Nearest_Neighbour_Interpolation_Factor)
->Arg(1)
->Unit(benchmark::kMillisecond);
} else if (InterpolationType == bilinear_interpolation && ScaleType == scale_factor) {
BENCHMARK(Buddy_Resize2D_Bilinear_Interpolation_Factor)
->Arg(1)
->Unit(benchmark::kMillisecond);
} else if (InterpolationType == nearest_neighbour_interpolation && ScaleType == scale_length) {
BENCHMARK(Buddy_Resize2D_Nearest_Neighbour_Interpolation_Length)
->Arg(1)
->Unit(benchmark::kMillisecond);
} else if (InterpolationType == bilinear_interpolation && ScaleType == scale_length) {
BENCHMARK(Buddy_Resize2D_Bilinear_Interpolation_Length)
->Arg(1)
->Unit(benchmark::kMillisecond);
}
}

// Generate result image.
void generateResultBuddyResize2D() {
// Define the MemRef descriptor for input.
Img<float, 2> input(inputImageBuddyResize2D);
MemRef<float, 2> output(sizesOutputBuddyResize2D);
// Run the resize 2D operation.
if (InterpolationType == nearest_neighbour_interpolation && ScaleType == scale_factor) {
// Call the MLIR Resize2D function.
output = dip::Resize2D(&input,
dip::INTERPOLATION_TYPE::NEAREST_NEIGHBOUR_INTERPOLATION,
factorsOutputBuddyResize2D);
} else if (InterpolationType == bilinear_interpolation && ScaleType == scale_factor) {
// Call the MLIR Resize2D function.
output = dip::Resize2D(&input,
dip::INTERPOLATION_TYPE::BILINEAR_INTERPOLATION,
factorsOutputBuddyResize2D);
} else if (InterpolationType == nearest_neighbour_interpolation && ScaleType == scale_length) {
// Call the MLIR Resize2D function.
output = dip::Resize2D(&input,
dip::INTERPOLATION_TYPE::NEAREST_NEIGHBOUR_INTERPOLATION,
sizesOutputBuddyResize2D);
} else if (InterpolationType == bilinear_interpolation && ScaleType == scale_length) {
// Call the MLIR Resize2D function.
output = dip::Resize2D(&input,
dip::INTERPOLATION_TYPE::BILINEAR_INTERPOLATION,
sizesOutputBuddyResize2D);
}

// 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<int> compressionParams;
compressionParams.push_back(IMWRITE_PNG_COMPRESSION);
compressionParams.push_back(9);

// Write output to PNG.
bool result = true;
try {
result = imwrite("ResultBuddyResize2D.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;
}
28 changes: 28 additions & 0 deletions benchmarks/ImageProcessing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,31 @@ target_link_libraries(image-processing-benchmark
# Link Buddy MLIR DIP Library.
BuddyLibDIP
)

#-------------------------------------------------------------------------------
# Image Processing Resize Benchmark Target
#-------------------------------------------------------------------------------

add_executable(image-processing-resize-benchmark
MainResize.cpp
BuddyResize2DBenchmark.cpp
OpenCVResize2DBenchmark.cpp
)

target_include_directories(image-processing-resize-benchmark
PRIVATE
${BUDDY_SOURCE_DIR}/benchmarks/ImageProcessing/include/
)

target_link_directories(image-processing-resize-benchmark
PRIVATE
${BUDDY_MLIR_LIB_DIR}
)

target_link_libraries(image-processing-resize-benchmark
GoogleBenchmark
${OpenCV_LIBS}
# Link Buddy MLIR DIP Library.
BuddyLibDIP
)

62 changes: 62 additions & 0 deletions benchmarks/ImageProcessing/MainResize.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//===- MainResize.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 resize benchmark.
//
//===----------------------------------------------------------------------===//

#include <benchmark/benchmark.h>
#include <stdexcept>

void initializeBuddyResize2D(char **);
void initializeOpenCVResize2D(char **);

void generateResultBuddyResize2D();
void generateResultOpenCVResize2D();

void registerBenchmarkBuddyResize2D();
void registerBenchmarkOpenCVResize2D();

// Run benchmarks.
int main(int argc, char **argv) {
if (argc != 6) {
throw std::invalid_argument(
"Wrong format of command line arguments.\n"
"Correct format is ./image-processing-resize-benchmark <image path> <Scale "
"option> <RowNum> <ColNum> <InterpolationOption>\n where "
"image path provides path of the image to be processed, Scale option "
"available are SCALE_FACTOR, SCALE_LENGTH. "
"RowNum and ColNum are the "
"scale_factors/scale_length for row and col, "
"Interpolation option available "
"are NEAREST_NEIGHBOUR_INTERPOLATION, BILINEAR_INTERPOLATION.\n");
}

initializeBuddyResize2D(argv);
initializeOpenCVResize2D(argv);

registerBenchmarkBuddyResize2D();
registerBenchmarkOpenCVResize2D();

::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks();

// Generate result image.
generateResultBuddyResize2D();
generateResultOpenCVResize2D();

return 0;
}
Loading

0 comments on commit 0b189ab

Please sign in to comment.