aboutsummaryrefslogtreecommitdiff
path: root/MicroBenchmarks
diff options
context:
space:
mode:
authorPankaj Kukreja <cs15btech11029@iith.ac.in>2018-08-07 08:52:57 +0000
committerPankaj Kukreja <cs15btech11029@iith.ac.in>2018-08-07 08:52:57 +0000
commit9ad270d323a08de54ac21c7668f1d5813625e8c2 (patch)
treefa930331f8a229615132f2ff9356b7bc308c0d77 /MicroBenchmarks
parent4c6c9b86d177819151fe50334988308525e08041 (diff)
Add interpolation kernels using Benchmark Library
Contains Implementation of Bicubic and bilinear Algortihms Reviewers: Meinersbur Differential Revision: https://reviews.llvm.org/D50345 git-svn-id: https://llvm.org/svn/llvm-project/test-suite/trunk@339115 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'MicroBenchmarks')
-rw-r--r--MicroBenchmarks/ImageProcessing/CMakeLists.txt1
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/CMakeLists.txt13
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/bicubic.reference_output1
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/bicubicKernel.c59
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/bilinear.reference_output1
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/bilinearKernel.c41
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/interpolation.h15
-rw-r--r--MicroBenchmarks/ImageProcessing/Interpolation/main.cpp152
8 files changed, 283 insertions, 0 deletions
diff --git a/MicroBenchmarks/ImageProcessing/CMakeLists.txt b/MicroBenchmarks/ImageProcessing/CMakeLists.txt
index eb808f12..f148ebc4 100644
--- a/MicroBenchmarks/ImageProcessing/CMakeLists.txt
+++ b/MicroBenchmarks/ImageProcessing/CMakeLists.txt
@@ -1,3 +1,4 @@
add_subdirectory(Dither)
add_subdirectory(AnisotropicDiffusion)
+add_subdirectory(Interpolation)
add_subdirectory(Blur)
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/CMakeLists.txt b/MicroBenchmarks/ImageProcessing/Interpolation/CMakeLists.txt
new file mode 100644
index 00000000..f0cec8df
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(IMAGEPROC_UTILS MicroBenchmarks/ImageProcessing/utils)
+list(APPEND CPPFLAGS -I ${CMAKE_SOURCE_DIR}/${IMAGEPROC_UTILS} -std=c++11)
+
+llvm_test_verify("${CMAKE_SOURCE_DIR}/HashProgramOutput.sh ${CMAKE_CURRENT_BINARY_DIR}/bicubicOutput.txt")
+llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/bicubicOutput.txt ${CMAKE_CURRENT_SOURCE_DIR}/bicubic.reference_output")
+
+llvm_test_verify("${CMAKE_SOURCE_DIR}/HashProgramOutput.sh ${CMAKE_CURRENT_BINARY_DIR}/bilinearOutput.txt")
+llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/bilinearOutput.txt ${CMAKE_CURRENT_SOURCE_DIR}/bilinear.reference_output")
+
+llvm_test_run(WORKDIR ${CMAKE_CURRENT_BINARY_DIR})
+llvm_test_executable(Interpolation bicubicKernel.c bilinearKernel.c main.cpp ../utils/ImageHelper.cpp ../utils/glibc_compat_rand.c)
+
+target_link_libraries(Interpolation benchmark)
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/bicubic.reference_output b/MicroBenchmarks/ImageProcessing/Interpolation/bicubic.reference_output
new file mode 100644
index 00000000..b4cae2b6
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/bicubic.reference_output
@@ -0,0 +1 @@
+289aae9408984be189aa2c8dfec4cdc7
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/bicubicKernel.c b/MicroBenchmarks/ImageProcessing/Interpolation/bicubicKernel.c
new file mode 100644
index 00000000..a43d5966
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/bicubicKernel.c
@@ -0,0 +1,59 @@
+/** This is a modified version of serial/bicubicInterpolation.cpp of
+ * https://github.com/srijanmishra/parallel-bicubic-interpolation
+ *
+ * Modified by
+ * Pankaj Kukreja (github.com/proton0001)
+ * Indian Institute of Technology Hyderabad
+ */
+#include "interpolation.h"
+void bicubicKernel(int height, int width, int inputImage[HEIGHT][WIDTH],
+ int outputImage[ZOOM * height][ZOOM * width]) {
+ int f = ZOOM;
+ int newheight = f * height;
+ int newwidth = f * width;
+ double arr[4][4];
+ for (int i = 0; i < newheight - 3 * f; i++) {
+ for (int j = 0; j < newwidth - 3 * f; j++) {
+ // for row offset
+ for (int l = 0; l < 4; l++) {
+ // for column offset
+ for (int k = 0; k < 4; k++) {
+ arr[l][k] = inputImage[i / f + l][j / f + k];
+ }
+ }
+ double x = (double)(i % f) / f;
+ double y = (double)(j % f) / f;
+ double arr2[4];
+ arr2[0] = arr[0][1] + 0.5 * y *
+ (arr[0][2] - arr[0][0] +
+ y * (2.0 * arr[0][0] - 5.0 * arr[0][1] +
+ 4.0 * arr[0][2] - arr[0][3] +
+ y * (3.0 * (arr[0][1] - arr[0][2]) +
+ arr[0][3] - arr[0][0])));
+ arr2[1] = arr[1][1] + 0.5 * y *
+ (arr[1][2] - arr[1][0] +
+ y * (2.0 * arr[1][0] - 5.0 * arr[1][1] +
+ 4.0 * arr[1][2] - arr[1][3] +
+ y * (3.0 * (arr[1][1] - arr[1][2]) +
+ arr[1][3] - arr[1][0])));
+ arr2[2] = arr[2][1] + 0.5 * y *
+ (arr[2][2] - arr[2][0] +
+ y * (2.0 * arr[2][0] - 5.0 * arr[2][1] +
+ 4.0 * arr[2][2] - arr[2][3] +
+ y * (3.0 * (arr[2][1] - arr[2][2]) +
+ arr[2][3] - arr[2][0])));
+ arr2[3] = arr[3][1] + 0.5 * y *
+ (arr[3][2] - arr[3][0] +
+ y * (2.0 * arr[3][0] - 5.0 * arr[3][1] +
+ 4.0 * arr[3][2] - arr[3][3] +
+ y * (3.0 * (arr[3][1] - arr[3][2]) +
+ arr[3][3] - arr[3][0])));
+ outputImage[i][j] =
+ arr2[1] +
+ 0.5 * x *
+ (arr2[2] - arr2[0] +
+ x * (2.0 * arr2[0] - 5.0 * arr2[1] + 4.0 * arr2[2] - arr2[3] +
+ x * (3.0 * (arr2[1] - arr2[2]) + arr2[3] - arr2[0])));
+ }
+ }
+}
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/bilinear.reference_output b/MicroBenchmarks/ImageProcessing/Interpolation/bilinear.reference_output
new file mode 100644
index 00000000..85f258db
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/bilinear.reference_output
@@ -0,0 +1 @@
+9ab422ac2cb253fdd6687fa1cd009006
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/bilinearKernel.c b/MicroBenchmarks/ImageProcessing/Interpolation/bilinearKernel.c
new file mode 100644
index 00000000..988222b1
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/bilinearKernel.c
@@ -0,0 +1,41 @@
+/**
+ Source: github ->
+ https://github.com/yglukhov/bicubic-interpolation-image-processing/blob/master/libimage.c
+
+ Modifications by
+ Pankaj Kukreja (github.com/proton0001)
+ Indian Institute of Technology Hyderabad
+*/
+#include "interpolation.h"
+
+void bilinearKernel(int height, int width, int inputImage[HEIGHT][WIDTH],
+ int outputImage[ZOOM * height][ZOOM * width]) {
+ int x, y;
+
+ float x_diff, y_diff;
+ int i, j;
+
+ int newheight = ZOOM * height;
+ int newwidth = ZOOM * width;
+
+ for (i = 0; i < newheight; i++) {
+ for (j = 0; j < newwidth; j++) {
+ x = j / ZOOM;
+ y = i / ZOOM;
+
+ x_diff = ((j / (float)ZOOM) - x);
+ y_diff = ((i / (float)ZOOM) - y);
+ if ((x + 1) < width && (y + 1) < height) {
+ outputImage[i][j] = inputImage[y][x] * (1 - x_diff) * (1 - y_diff) +
+ inputImage[y][x + 1] * (1 - y_diff) * (x_diff) +
+ inputImage[y + 1][x] * (y_diff) * (1 - x_diff) +
+ inputImage[y + 1][x + 1] * (y_diff) * (x_diff);
+ } else if ((x + 1) < width) {
+ outputImage[i][j] = inputImage[y][x] * (1 - x_diff) * (1 - y_diff) +
+ inputImage[y][x + 1] * (1 - y_diff) * (x_diff);
+ } else {
+ outputImage[i][j] = inputImage[y][x] * (1 - x_diff) * (1 - y_diff);
+ }
+ }
+ }
+}
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/interpolation.h b/MicroBenchmarks/ImageProcessing/Interpolation/interpolation.h
new file mode 100644
index 00000000..8acab022
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/interpolation.h
@@ -0,0 +1,15 @@
+/**
+ Pankaj Kukreja
+ github.com/proton0001
+ Indian Institute of Technology Hyderabad
+*/
+#ifndef _INTERPOLATION_H_
+#define _INTERPOLATION_H_
+
+#define HEIGHT 256
+#define WIDTH 256
+
+// 4x zoom
+#define ZOOM 4
+
+#endif /* _INTERPOLATION_H_ */
diff --git a/MicroBenchmarks/ImageProcessing/Interpolation/main.cpp b/MicroBenchmarks/ImageProcessing/Interpolation/main.cpp
new file mode 100644
index 00000000..4561bb2d
--- /dev/null
+++ b/MicroBenchmarks/ImageProcessing/Interpolation/main.cpp
@@ -0,0 +1,152 @@
+/**
+ Pankaj Kukreja
+ github.com/proton0001
+ Indian Institute of Technology Hyderabad
+*/
+#include "ImageHelper.h"
+#include "interpolation.h"
+#include <iostream> // std::cerr
+
+#define BENCHMARK_LIB
+#ifdef BENCHMARK_LIB
+#include "benchmark/benchmark.h"
+#endif
+
+extern "C" void bicubicKernel(int height, int width, int *inpImage,
+ int *outImage);
+extern "C" void bilinearKernel(int height, int width, int *inpImage,
+ int *outImage);
+
+int *inputImage;
+int main(int argc, char **argv) {
+#ifdef BENCHMARK_LIB
+ ::benchmark::Initialize(&argc, argv);
+#endif
+
+ const char *bicubicOutputFilename = (const char *)"./bicubicOutput.txt";
+ const char *bilinearOutputFileName = (const char *)"./bilinearOutput.txt";
+
+ inputImage = (int *)malloc(sizeof(int) * (HEIGHT) * (WIDTH));
+
+ if (inputImage == NULL) {
+ std::cerr << "Insufficient memory\n";
+ exit(1);
+ }
+
+ initializeRandomImage(inputImage, HEIGHT, WIDTH);
+
+#ifdef BENCHMARK_LIB
+ ::benchmark::RunSpecifiedBenchmarks();
+#endif
+
+ int outputHeight = ZOOM * HEIGHT;
+ int outputWidth = ZOOM * HEIGHT;
+
+ int *outputImage =
+ (int *)malloc(sizeof(int) * (outputHeight) * (outputWidth));
+
+ if (outputImage == NULL) {
+ std::cerr << "Insufficient memory\n";
+ exit(1);
+ }
+
+ for (int i = 0; i < outputHeight; i++) {
+ for (int j = 0; j < outputWidth; j++) {
+ outputImage[i * outputWidth + j] = 0;
+ }
+ }
+
+ bicubicKernel(HEIGHT, WIDTH, inputImage, outputImage);
+ saveImage(outputImage, bicubicOutputFilename, outputHeight, outputWidth);
+
+ for (int i = 0; i < outputHeight; i++) {
+ for (int j = 0; j < outputWidth; j++) {
+ outputImage[i * outputWidth + j] = 0;
+ }
+ }
+
+ bilinearKernel(HEIGHT, WIDTH, inputImage, outputImage);
+ saveImage(outputImage, bilinearOutputFileName, outputHeight, outputWidth);
+
+ free(inputImage);
+ free(outputImage);
+ return 0;
+}
+
+#ifdef BENCHMARK_LIB
+void BENCHMARK_BICUBIC_INTERPOLATION(benchmark::State &state) {
+ int inputHeight = state.range(0);
+ int inputWidth = state.range(0);
+ int outputHeight = ZOOM * inputHeight;
+ int outputWidth = ZOOM * inputWidth;
+
+ int *outputImage = (int *)malloc(sizeof(int) * outputHeight * outputWidth);
+
+ if (outputImage == NULL) {
+ std::cerr << "Insufficient memory\n";
+ exit(1);
+ }
+ /* This call is to warm up the cache */
+ bicubicKernel(inputHeight, inputWidth, inputImage, outputImage);
+
+ for (auto _ : state) {
+ bicubicKernel(inputHeight, inputWidth, inputImage, outputImage);
+ }
+
+ /* Since we are not passing state.range as 20 this if case will always be
+ * false.
+ * This call is to prevent above function calls from getting optimized out
+ */
+ if (state.range(0) == 20) {
+ saveImage(outputImage, (const char *)"failedCase.txt", outputHeight,
+ outputWidth);
+ }
+
+ free(outputImage);
+}
+BENCHMARK(BENCHMARK_BICUBIC_INTERPOLATION)
+ ->Arg(16)
+ ->Arg(32)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Unit(benchmark::kMicrosecond);
+
+void BENCHMARK_BILINEAR_INTERPOLATION(benchmark::State &state) {
+ int inputHeight = state.range(0);
+ int inputWidth = state.range(0);
+ int outputHeight = ZOOM * inputHeight;
+ int outputWidth = ZOOM * inputWidth;
+ int *outputImage = (int *)malloc(sizeof(int) * outputHeight * outputWidth);
+
+ if (outputImage == NULL) {
+ std::cerr << "Insufficient memory\n";
+ exit(1);
+ }
+ /* This call is to warm up the cache */
+ bilinearKernel(inputHeight, inputWidth, inputImage, outputImage);
+
+ for (auto _ : state) {
+ bilinearKernel(inputHeight, inputWidth, inputImage, outputImage);
+ }
+
+ /* Since we are not passing state.range as 20 this if case will always be
+ * false.
+ * This call is to prevent above function calls from getting optimized out
+ */
+ if (state.range(0) == 20) {
+ saveImage(outputImage, (const char *)"failedCase.txt", outputHeight,
+ outputWidth);
+ }
+
+ free(outputImage);
+}
+BENCHMARK(BENCHMARK_BILINEAR_INTERPOLATION)
+ ->Arg(16)
+ ->Arg(32)
+ ->Arg(64)
+ ->Arg(128)
+ ->Arg(256)
+ ->Unit(benchmark::kMicrosecond);
+
+#endif \ No newline at end of file