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,13 @@ +list(APPEND CPPFLAGS -std=c++11 ) + +set(REFERENCE_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/harris.reference_output) +llvm_test_verify("${CMAKE_SOURCE_DIR}/HashProgramOutput.sh ${CMAKE_CURRENT_BINARY_DIR}/output.txt") +llvm_test_verify("${FPCMP} ${CMAKE_CURRENT_BINARY_DIR}/output.txt ${REFERENCE_OUTPUT}") + +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,55 @@ +#ifndef __HARRIS_H__ +#define __HARRIS_H__ + +#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 + + +// Smaller input is fine here because benchmark lib takes care of small runtimes +#define HEIGHT 1000 +#define WIDTH 1000 + +// ============================================================================ +// ============================================================================ + +// 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]); +// harris kernel from polymage_naive.cpp +void harrisKernel(int height + , int width + , float inputImg[2 + HEIGHT][2 + WIDTH] + , float outputImg[(2 + HEIGHT)][2 + WIDTH] + , float Ix [(2 + HEIGHT)][2 + WIDTH] + , float Iy [(2 + HEIGHT)][2 + WIDTH] + , float Ixx [(2 + HEIGHT)][2 + WIDTH] + , float Ixy [(2 + HEIGHT)][2 + WIDTH] + , float Iyy [(2 + HEIGHT)][2 + WIDTH] + , float Sxx [(2 + HEIGHT)][2 + WIDTH] + , float Sxy [(2 + HEIGHT)][2 + WIDTH] + , float Syy [(2 + HEIGHT)][2 + WIDTH] + , float det [(2 + HEIGHT)][2 + WIDTH] + , float trace [(2 + HEIGHT)][2 + WIDTH]); + +// ============================================================================ +#endif Index: MicroBenchmarks/harris/harris.reference_output =================================================================== --- MicroBenchmarks/harris/harris.reference_output +++ MicroBenchmarks/harris/harris.reference_output @@ -0,0 +1 @@ +33f734b11d0139b6c0e68f583fc9ce3a Index: MicroBenchmarks/harris/harrisKernel.cpp =================================================================== --- MicroBenchmarks/harris/harrisKernel.cpp +++ MicroBenchmarks/harris/harrisKernel.cpp @@ -0,0 +1,119 @@ +#include "harris.h" + + +// harris kernel from polymage_naive.cpp +void harrisKernel(int height, int width + , float inputImg[2 + HEIGHT][2 + WIDTH] + , float outputImg[(2 + HEIGHT)][2 + WIDTH] + , float Ix [(2 + HEIGHT)][2 + WIDTH] + , float Iy [(2 + HEIGHT)][2 + WIDTH] + , float Ixx [(2 + HEIGHT)][2 + WIDTH] + , float Ixy [(2 + HEIGHT)][2 + WIDTH] + , float Iyy [(2 + HEIGHT)][2 + WIDTH] + , float Sxx [(2 + HEIGHT)][2 + WIDTH] + , float Sxy [(2 + HEIGHT)][2 + WIDTH] + , float Syy [(2 + HEIGHT)][2 + WIDTH] + , float det [(2 + HEIGHT)][2 + WIDTH] + , float trace [(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] = + (((((((inputImg[_i0 - 1][_i1 - 1]) * -0.0833333333333f) + + ((inputImg[_i0 - 1][_i1 + 1]) * 0.0833333333333f)) + + ((inputImg[_i0][_i1 - 1]) * -0.166666666667f)) + + ((inputImg[_i0][_i1 + 1]) * 0.166666666667f)) + + ((inputImg[_i0 + 1][_i1 - 1]) * -0.0833333333333f)) + + ((inputImg[_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] = + ((((( + (inputImg[-1 + _i0][-1 + _i1] * -0.0833333333333f) + + (inputImg[ 1 + _i0][-1 + _i1] * 0.0833333333333f)) + + (inputImg[-1 + _i0][_i1 ] * -0.166666666667f)) + + (inputImg[ 1 + _i0][_i1 ] * 0.166666666667f)) + + (inputImg[-1 + _i0][ 1 + _i1] * -0.0833333333333f)) + + (inputImg[ 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++) { + outputImg[_i0][_i1] = (det[_i0][_i1] - ((0.04f * trace[_i0][_i1]) * trace[_i0][_i1])); + } + } +} Index: MicroBenchmarks/harris/main.cpp =================================================================== --- MicroBenchmarks/harris/main.cpp +++ MicroBenchmarks/harris/main.cpp @@ -0,0 +1,251 @@ +/* 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 + // ============================================================================ + * HARRIS KERNEL from Polymage benchmark (modified) + * File: polymage-benchmarks/apps/harris/harris_polymage_naive.cpp +*/ +// ============================================================================ + +#include "harris.h" +int sum=0; + + +#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, float image[(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. +void printImage(int height, int width, float arr[(2 + HEIGHT)][2 + WIDTH], int dummy) { + std::ofstream myfile; + myfile.open("output.txt"); + for (int i = 0; i < height - 2; i++) { + for (int j = 0; j < width - 2; j++) { + if(arr[i][j]<0) { + myfile << 0; + } + else if(arr[i][j]>255) { + myfile << 3; + } + else { + myfile << (int)(arr[i][j]); + } + } + myfile << "\n"; + } + //Dummy code to make sure the allocated ImageOutput Array is not optimized out + if(dummy > 0){ + myfile << sum; + } +} + + + +#ifdef BENCHMARK_LIB +void BENCHMARK_HARRIS(benchmark::State &state) { + float (*__restrict__ image)[HEIGHT + 2][WIDTH + 2]; + image = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + initCheckboardImage((HEIGHT + 2), (WIDTH + 2), *image); + + float (* __restrict__ imageOutput)[2 + HEIGHT][2 + WIDTH]; + imageOutput = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (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(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixx = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iyy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxx = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Syy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + det = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + trace = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + + harrisKernel(HEIGHT, WIDTH + , *image, *imageOutput + , *Ix, *Iy + , *Ixx, *Ixy, *Iyy + , *Sxx, *Sxy, *Syy + , *det, *trace); + + for (auto _ : state) { + harrisKernel(HEIGHT, WIDTH + , *image, *imageOutput + , *Ix, *Iy + , *Ixx, *Ixy, *Iyy + , *Sxx, *Sxy, *Syy + , *det, *trace); + } + + // state.SetBytesProcessed(static_cast(state.iterations())*WIDTH*HEIGHT*50); // ?? + + 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); + + for(int i =0;iUnit(benchmark::kMicrosecond); +#endif + + +int main(int argc, char *argv[]) { + sum =1; +#ifdef BENCHMARK_LIB + ::benchmark::Initialize(&argc, argv); + if (::benchmark::ReportUnrecognizedArguments(argc, argv)) + return 1; + ::benchmark::RunSpecifiedBenchmarks(); +#endif + + // Extra Call to verify output of kernel + float (*__restrict__ image)[HEIGHT + 2][WIDTH + 2]; + image = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + initCheckboardImage((HEIGHT + 2), (WIDTH + 2), *image); + + float (* __restrict__ imageOutput)[2 + HEIGHT][2 + WIDTH]; + imageOutput = (float(*)[2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (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(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixx = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Ixy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Iyy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxx = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Sxy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + Syy = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + det = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + trace = (float(* __restrict__) [2+HEIGHT][2+WIDTH]) malloc(sizeof(float)* (2+HEIGHT) * (2+WIDTH)); + + harrisKernel(HEIGHT, WIDTH + , *image, *imageOutput + , *Ix, *Iy + , *Ixx, *Ixy, *Iyy + , *Sxx, *Sxy, *Syy + , *det, *trace); + + 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); + + if(argc==2) { + printImage(HEIGHT + 2, WIDTH + 2, *imageOutput, sum); + } + else { + printImage(HEIGHT + 2, WIDTH + 2, *imageOutput, -1); + } + + free((void*)image); + free((void*)imageOutput); + return 0; +}