Index: MicroBenchmarks/CMakeLists.txt =================================================================== --- MicroBenchmarks/CMakeLists.txt +++ MicroBenchmarks/CMakeLists.txt @@ -4,4 +4,5 @@ add_subdirectory(libs) add_subdirectory(XRay) add_subdirectory(LCALS) + add_subdirectory(harris) endif() Index: MicroBenchmarks/harris/CMakeLists.txt =================================================================== --- MicroBenchmarks/harris/CMakeLists.txt +++ MicroBenchmarks/harris/CMakeLists.txt @@ -0,0 +1,5 @@ +list(APPEND CPPFLAGS -std=c++11 ) +llvm_test_run() + +llvm_test_executable(harris harrisKernel.cpp main.cpp) +target_link_libraries(harris benchmark) Index: MicroBenchmarks/harris/harris.h =================================================================== --- MicroBenchmarks/harris/harris.h +++ MicroBenchmarks/harris/harris.h @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include + +// ============================================================================ +// ============================================================================ + +// Image Size +// (Any box size will work) +// This parameter is used in input // used only in init_checkboard_image +#define BOX_SIZE 10 + +/*Comment this to not use google benchmark library*/ +#define BENCHMARK_LIB +#ifdef BENCHMARK_LIB +// Smaller input is fine here because benchmark lib takes care of small runtimes +#define HEIGHT 1000 +#define WIDTH 1000 +#else +// Without Benchmark sufficient time so that kernel runs aroung 0.8sec +#define HEIGHT 3000 +#define WIDTH 3000 +#endif +// ============================================================================ +// ============================================================================ + +// Parameters For harris kernel +#define THRESHOLD 0.1 + +// ============================================================================ +// ============================================================================ + +void initCheckboardImage(int height, int width); // Initialize a checkboard image +void printImage(int height, int width, float img[(2 + HEIGHT)][2 + WIDTH]); +void harrisKernel(float img[(2 + HEIGHT)][2 + WIDTH]); + +// ============================================================================ + +extern float (* __restrict__ image)[HEIGHT + 2][WIDTH + 2]; Index: MicroBenchmarks/harris/harrisKernel.cpp =================================================================== --- MicroBenchmarks/harris/harrisKernel.cpp +++ MicroBenchmarks/harris/harrisKernel.cpp @@ -0,0 +1,140 @@ +#include "harris.h" + +// harris kernel from polymage_naive.cpp +void harrisKernel(float img[(2 + HEIGHT)][2 + WIDTH]) { + + float (* __restrict__ Ix) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Iy) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Ixx) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Ixy) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Iyy) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Sxx) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Sxy) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ Syy) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ det) [2 + HEIGHT][2 + WIDTH]; + float (* __restrict__ trace)[2 + HEIGHT][2 + WIDTH]; + + Ix = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixx = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iyy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxx = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Syy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + det = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + trace = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + + for (int _i0 = 1; (_i0 - HEIGHT - 1 < 0); _i0++) { + for (int _i1 = 1; (_i1 - WIDTH - 1 <= 0); _i1++) { + (*Iy)[_i0][_i1] = (((((((img)[_i0 - 1][_i1 - 1] * -0.0833333333333f) + + ((img)[_i0 - 1][_i1 + 1] * 0.0833333333333f)) + + ((img)[_i0][_i1 - 1] * -0.166666666667f)) + + ((img)[_i0][_i1 + 1] * 0.166666666667f)) + + ((img)[_i0 + 1][_i1 - 1] * -0.0833333333333f)) + + ((img)[_i0 + 1][_i1 + 1] * 0.0833333333333f)); + } + } + + for (int _i0 = 1; (_i0 - HEIGHT - 1 < 0); _i0++) { + for (int _i1 = 1; (_i1 - WIDTH - 1 <= 0); _i1++) { + (*Ix)[_i0][_i1] = (((((((img)[-1 + _i0][-1 + _i1] * -0.0833333333333f) + + ((img)[1 + _i0][-1 + _i1] * 0.0833333333333f)) + + ((img)[-1 + _i0][_i1] * -0.166666666667f)) + + ((img)[1 + _i0][_i1] * 0.166666666667f)) + + ((img)[-1 + _i0][1 + _i1] * -0.0833333333333f)) + + ((img)[1 + _i0][1 + _i1] * 0.0833333333333f)); + } + } + + for (int _i0 = 1; (_i0 - HEIGHT - 1 < 0); _i0++) { + for (int _i1 = 1; (_i1 - WIDTH - 1 <= 0); _i1++) { + (*Iyy)[_i0][_i1] = (*Iy)[_i0][_i1] * (*Iy)[_i0][_i1]; + } + } + + for (int _i0 = 1; (_i0 - HEIGHT - 1 < 0); _i0++) { + for (int _i1 = 1; (_i1 - WIDTH - 1 <= 0); _i1++) { + (*Ixy)[_i0][_i1] = (*Ix)[_i0][_i1] * (*Iy)[_i0][_i1]; + } + } + + for (int _i0 = 1; (_i0 - HEIGHT - 1 < 0); _i0++) { + for (int _i1 = 1; (_i1 - WIDTH - 1 <= 0); _i1++) { + (*Ixx)[_i0][_i1] = (*Ix)[_i0][_i1] * (*Ix)[_i0][_i1]; + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + (*Syy)[_i0][_i1] = (((((((((*Iyy)[-1 + _i0][-1 + _i1] + (*Iyy)[-1 + _i0][_i1]) + + (*Iyy)[-1 + _i0][1 + _i1]) + + (*Iyy)[_i0][-1 + _i1]) + + (*Iyy)[_i0][_i1]) + + (*Iyy)[_i0][1 + _i1]) + + (*Iyy)[1 + _i0][-1 + _i1]) + + (*Iyy)[1 + _i0][_i1]) + + (*Iyy)[1 + _i0][1 + _i1]); + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + (*Sxy)[_i0][_i1] = (((((((((*Ixy)[-1 + _i0][-1 + _i1] + (*Ixy)[-1 + _i0][_i1]) + + (*Ixy)[-1 + _i0][1 + _i1]) + + (*Ixy)[_i0][-1 + _i1]) + + (*Ixy)[_i0][_i1]) + + (*Ixy)[_i0][1 + _i1]) + + (*Ixy)[1 + _i0][-1 + _i1]) + + (*Ixy)[1 + _i0][_i1]) + + (*Ixy)[1 + _i0][1 + _i1]); + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + (*Sxx)[_i0][_i1] = (((((((((*Ixx)[-1 + _i0][-1 + _i1] + (*Ixx)[-1 + _i0][_i1]) + + (*Ixx)[-1 + _i0][1 + _i1]) + + (*Ixx)[_i0][-1 + _i1]) + + (*Ixx)[_i0][_i1]) + + (*Ixx)[_i0][1 + _i1]) + + (*Ixx)[1 + _i0][-1 + _i1]) + + (*Ixx)[1 + _i0][_i1]) + + (*Ixx)[1 + _i0][1 + _i1]); + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + (*trace)[_i0][_i1] = ((*Sxx)[_i0][_i1] + (*Syy)[_i0][_i1]); + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + (*det)[_i0][_i1] = + (((*Sxx)[_i0][_i1] * (*Syy)[_i0][_i1]) - ((*Sxy)[_i0][_i1] * (*Sxy)[_i0][_i1])); + } + } + + for (int _i0 = 2; (_i0 < HEIGHT); _i0++) { + for (int _i1 = 2; (_i1 < WIDTH); _i1++) { + int value = + ((*det)[_i0][_i1] - ((0.04f * (*trace)[_i0][_i1]) * (*trace)[_i0][_i1])); + if (value > THRESHOLD) { + img[_i0][_i1] = 3; + } + } + } + + free((void*)Ix); + free((void*)Iy); + free((void*)Ixx); + free((void*)Ixy); + free((void*)Iyy); + free((void*)Sxx); + free((void*)Sxy); + free((void*)Syy); + free((void*)det); + free((void*)trace); +} Index: MicroBenchmarks/harris/main.cpp =================================================================== --- MicroBenchmarks/harris/main.cpp +++ MicroBenchmarks/harris/main.cpp @@ -0,0 +1,139 @@ +/* For polymage-benchmarks-harris kernel + Copyright (c) 2015 Indian Institute of Science + All rights reserved. + + Written and provided by: + Ravi Teja Mullapudi, Vinay Vasista, Uday Bondhugula + Dept of Computer Science and Automation + Indian Institute of Science + Bangalore 560012 + India + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Indian Institute of Science nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS MATERIAL IS PROVIDED BY Ravi Teja Mullapudi, Vinay Vasista, and Uday + Bondhugula, Indian Institute of Science ''AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL Ravi Teja Mullapudi, Vinay Vasista, CSA Indian Institute of + Science BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +// ============================================================================ +/* + * Pankaj Kukreja + * Indian Institute of Technology Hyderabad + * + * Acknowledgements + // ============================================================================ + * SHA1SUM computation source code from: + * https://github.com/vog/sha1 + * 100% Public Domain + // ============================================================================ + * HARRIS KERNEL (modified) + * https://github.com/bondhugula/polymage-benchmarks/ + * File: polymage-benchmarks/apps/harris/harris_polymage_naive.cpp +*/ +// ============================================================================ + +#include "harris.h" + +float (*__restrict__ image)[HEIGHT + 2][WIDTH + 2]; + + +#ifdef BENCHMARK_LIB +#include "benchmark/benchmark.h" +#endif + + +// This function initializes the input image to checkbox image +// Can be replaced with any other image initialization +void initCheckboardImage(int height, int width) { + image = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + int last_pixel_x = 0; + int last_pixel_y = 0; + + for (int i = 0; i < height; i++) { + if (i % BOX_SIZE == 0) { + last_pixel_y = (last_pixel_y + 1) % 2; + } + last_pixel_x = last_pixel_y; + for (int j = 0; j < width; j++) { + if (j % BOX_SIZE == 0) { + last_pixel_x = (last_pixel_x + 1) % 2; + } + if (last_pixel_x == 0) + (*image)[i][j] = 255; + else + (*image)[i][j] = 0; + } + } +} + +// Writes image matrix to a file (asuming values are only 0, 255 and 3. +// If different values are also there then remove % 8 +void printImage(int height, int width, float arr[(2 + HEIGHT)][2 + WIDTH]) { + std::ofstream myfile; + myfile.open("output.txt"); + for (int i = 0; i < height - 2; i++) { + for (int j = 0; j < width - 2; j++) { + myfile << (int)(arr[i][j]) % 8; + } + myfile << "\n"; + } +} + + + +#ifdef BENCHMARK_LIB +void BENCHMARK_HARRIS(benchmark::State &state) { + + float (* __restrict__ imageCopy)[2 + HEIGHT][2 + WIDTH]; + imageCopy = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + for (auto _ : state) { + state.PauseTiming(); + std::memcpy(imageCopy, image, (2 + HEIGHT) * (2 + WIDTH) * sizeof(float)); + state.ResumeTiming(); + harrisKernel(*imageCopy); + } + free((void*)imageCopy); + +} +BENCHMARK(BENCHMARK_HARRIS); +#endif + + + +int main(int argc, char *argv[]) { + initCheckboardImage((HEIGHT + 2), (WIDTH + 2)); +#ifdef BENCHMARK_LIB + ::benchmark::Initialize(&argc, argv); + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + ::benchmark::RunSpecifiedBenchmarks(); +#endif + harrisKernel(*image); + + printImage(HEIGHT + 2, WIDTH + 2, *image); + + free((void*)image); + return 0; +}