[test-suite] r339055 - Add image blur algorithms using Benchmark Library

Pankaj Kukreja via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 6 14:16:08 PDT 2018


Author: proton
Date: Mon Aug  6 14:16:07 2018
New Revision: 339055

URL: http://llvm.org/viewvc/llvm-project?rev=339055&view=rev
Log:
Add image blur algorithms using Benchmark Library
Contains Implementation of mean box blur and gaussian blur

Reviewers: Meinersbur

Differential Revision: https://reviews.llvm.org/D49341

Added:
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/CMakeLists.txt
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/blur.h
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlur.reference_output
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlurKernel.c
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlur.reference_output
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlurKernel.c
    test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/main.cpp
Modified:
    test-suite/trunk/MicroBenchmarks/ImageProcessing/CMakeLists.txt

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/CMakeLists.txt?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/CMakeLists.txt (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/CMakeLists.txt Mon Aug  6 14:16:07 2018
@@ -0,0 +1,15 @@
+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}/boxBlurOutput.txt")
+llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/boxBlurOutput.txt ${CMAKE_CURRENT_SOURCE_DIR}/boxBlur.reference_output")
+
+llvm_test_verify("${CMAKE_SOURCE_DIR}/HashProgramOutput.sh ${CMAKE_CURRENT_BINARY_DIR}/gaussianBlurOutput.txt")
+llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/gaussianBlurOutput.txt ${CMAKE_CURRENT_SOURCE_DIR}/gaussianBlur.reference_output")
+
+llvm_test_run(WORKDIR ${CMAKE_CURRENT_BINARY_DIR})
+
+llvm_test_executable(blur ../utils/ImageHelper.cpp ../utils/glibc_compat_rand.c main.cpp boxBlurKernel.c gaussianBlurKernel.c)
+
+target_link_libraries(blur benchmark)

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/blur.h
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/blur.h?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/blur.h (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/blur.h Mon Aug  6 14:16:07 2018
@@ -0,0 +1,15 @@
+/**
+Pankaj Kukreja
+github.com/proton0001
+Indian Institute of Technology Hyderabad
+*/
+
+#ifndef _BOX_BLUR_H
+#define _BOX_BLUR_H
+
+#define HEIGHT 1024
+#define WIDTH 1024
+
+#define BOX_SIZE 9
+
+#endif /* _BOX_BLUR_H */

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlur.reference_output
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlur.reference_output?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlur.reference_output (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlur.reference_output Mon Aug  6 14:16:07 2018
@@ -0,0 +1 @@
+d976614a6d0487da6873eb9de4044480

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlurKernel.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlurKernel.c?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlurKernel.c (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/boxBlurKernel.c Mon Aug  6 14:16:07 2018
@@ -0,0 +1,26 @@
+/**
+Blur an Image using box blur
+
+Pankaj Kukreja
+Indian Institute of Technology Hyderabad
+*/
+
+#include "blur.h"
+void boxBlurKernel(int height, int width, int inputImage[HEIGHT][WIDTH],
+                   int outputImage[height][width]) {
+  int sum = 0;
+  int offset = (BOX_SIZE - 1) / 2;
+  int n = BOX_SIZE * BOX_SIZE;
+
+  for (int i = offset; i < height - offset; i++) {
+    for (int j = offset; j < width - offset; j++) {
+      sum = 0;
+      for (int k = -1 * offset; k < offset; k++) {
+        for (int l = -1 * offset; l < offset; l++) {
+          sum += inputImage[i + k][j + l];
+        }
+      }
+      outputImage[i][j] = (sum) / (n);
+    }
+  }
+}
\ No newline at end of file

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlur.reference_output
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlur.reference_output?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlur.reference_output (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlur.reference_output Mon Aug  6 14:16:07 2018
@@ -0,0 +1 @@
+7f4246596bcfbb5e6e44cd21ddfeaf07

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlurKernel.c
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlurKernel.c?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlurKernel.c (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/gaussianBlurKernel.c Mon Aug  6 14:16:07 2018
@@ -0,0 +1,45 @@
+/**
+Gaussian Blur Kernel
+
+Pankaj Kukreja
+github.com/proton0001
+Indian Institute of Technology Hyderabad
+*/
+
+#include "blur.h"
+#include <math.h> // For M_PI and exp
+
+void gaussianBlurKernel(int height, int width, int inputImage[height][width],
+                        int outputImage[height][width]) {
+
+  float sigma = 9;
+  float s = 2.0 * sigma * sigma;
+  int offset = (BOX_SIZE - 1) / 2;
+
+  float sum = 0;
+  float gaussianFilter[BOX_SIZE][BOX_SIZE] = {0};
+
+  for (int x = -1 * offset; x <= offset; x++) {
+    for (int y = -1 * offset; y <= offset; y++) {
+      gaussianFilter[x + offset][y + offset] =
+          (exp(-(x * x + y * y) / s)) / (M_PI * s);
+      sum += gaussianFilter[x + offset][y + offset];
+    }
+  }
+
+  float sum_in_current_frame = 0;
+  for (int i = offset; i < height - offset; i++) {
+    for (int j = offset; j < width - offset; j++) {
+      /* Computing sum of (elements * corresponding gaussianFilter) in window
+       * centered at i,j */
+      sum_in_current_frame = 0;
+      for (int k = -1 * offset; k <= offset; k++) {
+        for (int l = -1 * offset; l <= offset; l++) {
+          sum_in_current_frame += (inputImage[i + k][j + l] *
+                                   gaussianFilter[k + offset][l + offset]);
+        }
+      }
+      outputImage[i][j] = (sum_in_current_frame) / sum;
+    }
+  }
+}

Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/main.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/main.cpp?rev=339055&view=auto
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/main.cpp (added)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Blur/main.cpp Mon Aug  6 14:16:07 2018
@@ -0,0 +1,192 @@
+/**
+Pankaj Kukreja
+github.com/proton0001
+Indian Institute of Technology Hyderabad
+*/
+
+#include "ImageHelper.h"
+#include "blur.h"
+#include <iostream>
+
+#define BENCHMARK_LIB
+#ifdef BENCHMARK_LIB
+#include "benchmark/benchmark.h"
+#endif
+extern "C" void boxBlurKernel(int height, int width, int *inpImage,
+                              int *outpImage);
+extern "C" void gaussianBlurKernel(int height, int width, int *inpImage,
+                                   int *outpImage);
+int *inputImage;
+int main(int argc, char *argv[]) {
+
+#ifdef BENCHMARK_LIB
+  ::benchmark::Initialize(&argc, argv);
+#endif
+
+  const char *boxBlurOutputFileName = (const char *)"./boxBlurOutput.txt";
+  const char *gaussianBlurOutputFileName =
+      (const char *)"./gaussianBlurOutput.txt";
+
+  inputImage = (int *)malloc(sizeof(int) * (HEIGHT) * (WIDTH));
+
+  if (inputImage == NULL) {
+    std::cerr << "Insufficient memory\n";
+    exit(1);
+  }
+
+  initializeRandomImage(inputImage, HEIGHT, WIDTH);
+
+// Run Kernels Using Benchmark Library
+#ifdef BENCHMARK_LIB
+  ::benchmark::RunSpecifiedBenchmarks();
+#endif
+
+  // Run Kernels once more and save output in a file for Verification
+  int *outputImage;
+  outputImage = (int *)malloc(sizeof(int) * (HEIGHT) * (WIDTH));
+
+  if (outputImage == NULL) {
+    std::cerr << "Insufficient memory\n";
+    exit(1);
+  }
+
+  boxBlurKernel(HEIGHT, WIDTH, inputImage, outputImage);
+
+  // Blur not applied on edges so we add a black border
+  // Otherwise we may get garbage value which may create problem in output
+  // verification
+
+  int offset = (BOX_SIZE - 1) / 2;
+  // Top Edge
+  for (int i = 0; i < offset; i++) {
+    for (int j = 0; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  // Bottom Edge
+  for (int i = HEIGHT - offset; i < HEIGHT; i++) {
+    for (int j = 0; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  // Left Edge
+  for (int i = 0; i < HEIGHT; i++) {
+    for (int j = 0; j < offset; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+  // Right Edge
+  for (int i = 0; i < HEIGHT; i++) {
+    for (int j = WIDTH - offset; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  saveImage(outputImage, boxBlurOutputFileName, HEIGHT, WIDTH);
+
+  gaussianBlurKernel(HEIGHT, WIDTH, inputImage, outputImage);
+
+  // Top Edge
+  for (int i = 0; i < offset; i++) {
+    for (int j = 0; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  // Bottom Edge
+  for (int i = HEIGHT - offset; i < HEIGHT; i++) {
+    for (int j = 0; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  // Left Edge
+  for (int i = 0; i < HEIGHT; i++) {
+    for (int j = 0; j < offset; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+  // Right Edge
+  for (int i = 0; i < HEIGHT; i++) {
+    for (int j = WIDTH - offset; j < WIDTH; j++) {
+      outputImage[i * WIDTH + j] = 0;
+    }
+  }
+
+  saveImage(outputImage, gaussianBlurOutputFileName, HEIGHT, WIDTH);
+
+  free(outputImage);
+  free(inputImage);
+  return EXIT_SUCCESS;
+}
+
+#ifdef BENCHMARK_LIB
+void BENCHMARK_boxBlurKernel(benchmark::State &state) {
+
+  int height = state.range(0);
+  int width = state.range(1);
+
+  int *outputImage = (int *)malloc(sizeof(int) * (height) * (width));
+
+  if (outputImage == NULL) {
+    std::cerr << "Insufficient memory\n";
+    exit(1);
+  }
+  /* This call is to warm up the cache */
+  boxBlurKernel(height, width, inputImage, outputImage);
+
+  for (auto _ : state) {
+    boxBlurKernel(height, width, inputImage, outputImage);
+  }
+  /* Since we are not passing state.range as 20 this if case will always be
+   * false. This if case is to prevent above kernel calls from getting optimized
+   * out */
+  if (state.range(0) == 20) {
+    saveImage(outputImage, (const char *)"testFailed.txt", height, width);
+  }
+
+  free(outputImage);
+}
+BENCHMARK(BENCHMARK_boxBlurKernel)
+    ->Args({128, 128})
+    ->Args({256, 256})
+    ->Args({512, 512})
+    ->Args({1024, 1024})
+    ->Unit(benchmark::kMicrosecond);
+
+void BENCHMARK_GAUSSIAN_BLUR(benchmark::State &state) {
+
+  int height = state.range(0);
+  int width = state.range(1);
+
+  int *outputImage = (int *)malloc(sizeof(int) * (height) * (width));
+
+  if (outputImage == NULL) {
+    std::cerr << "Insufficient memory\n";
+    exit(1);
+  }
+  /* This call is to warm up the cache */
+  gaussianBlurKernel(height, width, inputImage, outputImage);
+
+  for (auto _ : state) {
+    gaussianBlurKernel(height, width, inputImage, outputImage);
+  }
+  /* Since we are not passing state.range as 20 this if case will always be
+   * false. This if case is to prevent above kernel calls from getting optimized
+   * out */
+  if (state.range(0) == 20) {
+    saveImage(outputImage, (const char *)"testFailed.txt", height, width);
+  }
+
+  free(outputImage);
+}
+
+BENCHMARK(BENCHMARK_GAUSSIAN_BLUR)
+    ->Args({128, 128})
+    ->Args({256, 256})
+    ->Args({512, 512})
+    ->Args({1024, 1024})
+    ->Unit(benchmark::kMicrosecond);
+#endif

Modified: test-suite/trunk/MicroBenchmarks/ImageProcessing/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/CMakeLists.txt?rev=339055&r1=339054&r2=339055&view=diff
==============================================================================
--- test-suite/trunk/MicroBenchmarks/ImageProcessing/CMakeLists.txt (original)
+++ test-suite/trunk/MicroBenchmarks/ImageProcessing/CMakeLists.txt Mon Aug  6 14:16:07 2018
@@ -1,2 +1,3 @@
 add_subdirectory(Dither)
 add_subdirectory(AnisotropicDiffusion)
+add_subdirectory(Blur)




More information about the llvm-commits mailing list