Index: MicroBenchmarks/ImageProcessing/BilateralFiltering/CMakeLists.txt =================================================================== --- MicroBenchmarks/ImageProcessing/BilateralFiltering/CMakeLists.txt +++ MicroBenchmarks/ImageProcessing/BilateralFiltering/CMakeLists.txt @@ -0,0 +1,11 @@ +set(IMAGEPROC_UTILS MicroBenchmarks/ImageProcessing/utils) +list(APPEND CPPFLAGS -I ${CMAKE_SOURCE_DIR}/${IMAGEPROC_UTILS}) +list(APPEND LDFLAGS -lm) + +llvm_test_verify("${CMAKE_SOURCE_DIR}/HashProgramOutput.sh ${CMAKE_CURRENT_BINARY_DIR}/bilateralFilterOutput.txt") +llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/bilateralFilterOutput.txt ${CMAKE_CURRENT_SOURCE_DIR}/bilateralFilter.reference_output") + +llvm_test_run(WORKDIR ${CMAKE_CURRENT_BINARY_DIR}) +llvm_test_executable(BilateralFilter ../utils/ImageHelper.cpp ../utils/glibc_compat_rand.c main.cpp bilateralFilterKernel.c) + +target_link_libraries(BilateralFilter benchmark) Index: MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilter.reference_output =================================================================== --- MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilter.reference_output +++ MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilter.reference_output @@ -0,0 +1 @@ +9922121db0fb69e92638574b6d8c474b Index: MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilterKernel.c =================================================================== --- MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilterKernel.c +++ MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFilterKernel.c @@ -0,0 +1,44 @@ +/** + Source: https://github.com/anlcnydn/bilateral + Modified by + Pankaj Kukreja + Indian Institute of technology, Hyderabad +*/ +#include "bilateralFiltering.h" +#include + +#define sigmaI 12.0 +#define sigmaS 16.0 + +#define GAUSSIAN(x, sigma) \ + (exp(-(x * x) / (2 * sigma * sigma)) / (2 * M_PI * (sigma * sigma))) + +void bilateralFilterKernel(int height, int width, int inputImage[HEIGHT][WIDTH], + int outputImage[height][width], int diameter) { + int half = diameter / 2; + for (int x = half; x < height - half; x++) { + for (int y = half; y < width - half; y++) { + double iFiltered = 0; + double wP = 0; + int neighbor_x = 0; + int neighbor_y = 0; + for (int i = 0; i < diameter; i++) { + for (int j = 0; j < diameter; j++) { + neighbor_x = x - (half - i); + neighbor_y = y - (half - j); + double gi = GAUSSIAN( + inputImage[neighbor_x][neighbor_y] - inputImage[x][y], sigmaI); + double gs = + GAUSSIAN((float)(sqrt(((x - neighbor_x) * (x - neighbor_x)) + + ((y - neighbor_y) * (y - neighbor_y)))), + sigmaS); + double w = gi * gs; + iFiltered = iFiltered + inputImage[neighbor_x][neighbor_y] * w; + wP = wP + w; + } + } + iFiltered = iFiltered / wP; + outputImage[x][y] = iFiltered; + } + } +} \ No newline at end of file Index: MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFiltering.h =================================================================== --- MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFiltering.h +++ MicroBenchmarks/ImageProcessing/BilateralFiltering/bilateralFiltering.h @@ -0,0 +1,14 @@ +/** + Pankaj Kukreja + github.com/proton0001 + Indian Institute of Technology Hyderabad +*/ + +#ifndef _BILATERAL_FILTERING_H_ +#define _BILATERAL_FILTERING_H_ + +#define HEIGHT 128 +#define WIDTH 128 +#define DIAMETER 5 + +#endif /* _BILATERAL_FILTERING_H_ */ Index: MicroBenchmarks/ImageProcessing/BilateralFiltering/main.cpp =================================================================== --- MicroBenchmarks/ImageProcessing/BilateralFiltering/main.cpp +++ MicroBenchmarks/ImageProcessing/BilateralFiltering/main.cpp @@ -0,0 +1,110 @@ +/** + Pankaj Kukreja + github.com/proton0001 + Indian Institute of Technology Hyderabad +*/ + +#include "ImageHelper.h" +#include "bilateralFiltering.h" +#include // std::cerr + +#define BENCHMARK_LIB +#ifdef BENCHMARK_LIB +#include "benchmark/benchmark.h" +#endif + +int *inputImage; +extern "C" void bilateralFilterKernel(int height, int width, int *inputImage, + int *outputImage, int diameter); + +int main(int argc, char *argv[]) { + +#ifdef BENCHMARK_LIB + ::benchmark::Initialize(&argc, argv); +#endif + + const char *bilateralFilterOutputFileName = + (const char *)"./bilateralFilterOutput.txt"; + + inputImage = (int *)malloc(sizeof(int) * (HEIGHT) * (WIDTH)); + + if (inputImage == NULL) { + std::cerr << "Insufficient memory\n"; + exit(EXIT_FAILURE); + } + + initializeRandomImage(inputImage, HEIGHT, WIDTH); + +#ifdef BENCHMARK_LIB + ::benchmark::RunSpecifiedBenchmarks(); +#endif + + int *outputImage = (int *)malloc(sizeof(int) * (HEIGHT) * (WIDTH)); + if (outputImage == NULL) { + std::cerr << "Insufficient memory\n"; + exit(EXIT_FAILURE); + } + for (int i = 0; i < HEIGHT; i++) { + for (int j = 0; j < WIDTH; j++) { + outputImage[i * WIDTH + j] = 0; + } + } + + bilateralFilterKernel(HEIGHT, WIDTH, inputImage, outputImage, DIAMETER); + + saveImage(outputImage, bilateralFilterOutputFileName, HEIGHT, WIDTH); + + free(outputImage); + free(inputImage); + return (EXIT_SUCCESS); +} + +#ifdef BENCHMARK_LIB +void BENCHMARK_BILATERAL_FILTER(benchmark::State &state) { + + int height = state.range(0); + int width = state.range(0); + int diameter = state.range(1); + + int *outputImage = (int *)malloc(sizeof(int) * (height) * (width)); + if (outputImage == NULL) { + std::cerr << "Insufficient memory\n"; + exit(EXIT_FAILURE); + } + /* first call made to warm up the cache*/ + bilateralFilterKernel(height, width, inputImage, outputImage, diameter); + while (state.KeepRunning()) { + bilateralFilterKernel(height, width, inputImage, outputImage, diameter); + } + + /* Since we are not passing state.range as 20 this if case will always be + * false. This check 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); +} + +#if (HEIGHT < WIDTH) +#define MINIMUM_DIM HEIGHT +#else +#define MINIMUM_DIM WIDTH +#endif +static void CustomArguments(benchmark::internal::Benchmark *b) { + int limit = MINIMUM_DIM; + int start = 16; + if (start > limit) { + start = 1; + } + for (int i = start; i < limit; i <<= 1) { + b->ArgPair(i, 2); + b->ArgPair(i, 4); + } +} +BENCHMARK(BENCHMARK_BILATERAL_FILTER) + ->Apply(CustomArguments) + ->Unit(benchmark::kMicrosecond); +#endif Index: MicroBenchmarks/ImageProcessing/CMakeLists.txt =================================================================== --- MicroBenchmarks/ImageProcessing/CMakeLists.txt +++ MicroBenchmarks/ImageProcessing/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(AnisotropicDiffusion) add_subdirectory(Interpolation) add_subdirectory(Blur) +add_subdirectory(BilateralFiltering)