Index: test-suite/trunk/LICENSE.TXT =================================================================== --- test-suite/trunk/LICENSE.TXT +++ test-suite/trunk/LICENSE.TXT @@ -64,6 +64,7 @@ Autoconf: llvm-test/autoconf Benchmark: llvm-test/libs/benchmark-1.1.0 LCALS: llvm-test/MicroBenchmarks/LCALS +harris: llvm-test/MicroBenchmarks/harris Burg: llvm-test/MultiSource/Applications/Burg Aha: llvm-test/MultiSource/Applications/aha SGEFA: llvm-test/MultiSource/Applications/sgefa Index: test-suite/trunk/MicroBenchmarks/CMakeLists.txt =================================================================== --- test-suite/trunk/MicroBenchmarks/CMakeLists.txt +++ test-suite/trunk/MicroBenchmarks/CMakeLists.txt @@ -4,4 +4,6 @@ add_subdirectory(libs) add_subdirectory(XRay) add_subdirectory(LCALS) + add_subdirectory(harris) + endif() Index: test-suite/trunk/MicroBenchmarks/harris/CMakeLists.txt =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/CMakeLists.txt +++ test-suite/trunk/MicroBenchmarks/harris/CMakeLists.txt @@ -0,0 +1,8 @@ +list(APPEND CPPFLAGS -std=c++11 -ffast-math) + +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(WORKDIR ${CMAKE_CURRENT_BINARY_DIR}) +llvm_test_executable(harris harrisKernel.cpp main.cpp) +target_link_libraries(harris benchmark) Index: test-suite/trunk/MicroBenchmarks/harris/LICENSE.txt =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/LICENSE.txt +++ test-suite/trunk/MicroBenchmarks/harris/LICENSE.txt @@ -0,0 +1,37 @@ + 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. + Index: test-suite/trunk/MicroBenchmarks/harris/harris.h =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/harris.h +++ test-suite/trunk/MicroBenchmarks/harris/harris.h @@ -0,0 +1,50 @@ +#ifndef __HARRIS_H__ +#define __HARRIS_H__ + +#include +#include +#include +#include +#include +#include + +// ============================================================================ + +// This parameter is used to initialize the input image +#define BOX_SIZE 10 + +/* Comment this to not use google benchmark library */ +#define BENCHMARK_LIB + +// Image Size +#define HEIGHT 2050 +#define WIDTH 2050 + +// Parameters For harris kernel +#define THRESHOLD 0.1 + +// ============================================================================ + +// Initialize a checkboard image +void initCheckboardImage(int height, int width); +// print image to output.txt +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: test-suite/trunk/MicroBenchmarks/harris/harris.reference_output =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/harris.reference_output +++ test-suite/trunk/MicroBenchmarks/harris/harris.reference_output @@ -0,0 +1 @@ +8e390d93bb5942d09e958f5c791c94ad Index: test-suite/trunk/MicroBenchmarks/harris/harrisKernel.cpp =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/harrisKernel.cpp +++ test-suite/trunk/MicroBenchmarks/harris/harrisKernel.cpp @@ -0,0 +1,112 @@ +#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 = 0; (_i0 - height < 0); _i0++) { + for (int _i1 = 0; (_i1 - width < 0); _i1++) { + Iy[_i0 + 1][_i1 + 1] = + (((((((inputImg[_i0][_i1]) * -0.0833333333333f) + + ((inputImg[_i0][_i1 + 2]) * 0.0833333333333f)) + + ((inputImg[_i0 + 1][_i1]) * -0.166666666667f)) + + ((inputImg[_i0 + 1][_i1 + 2]) * 0.166666666667f)) + + ((inputImg[_i0 + 2][_i1]) * -0.0833333333333f)) + + ((inputImg[_i0 + 2][_i1 + 2]) * 0.0833333333333f)); + } + } + + for (int _i0 = 0; (_i0 - height < 0); _i0++) { + for (int _i1 = 0; (_i1 - width < 0); _i1++) { + Ix[_i0 + 1][_i1 + 1] = + ((((((inputImg[_i0][_i1] * -0.0833333333333f) + + (inputImg[_i0 + 2][_i1] * 0.0833333333333f)) + + (inputImg[_i0][_i1 + 1] * -0.166666666667f)) + + (inputImg[_i0 + 2][_i1 + 1] * 0.166666666667f)) + + (inputImg[_i0][_i1 + 2] * -0.0833333333333f)) + + (inputImg[_i0 + 2][_i1 + 2] * 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: test-suite/trunk/MicroBenchmarks/harris/main.cpp =================================================================== --- test-suite/trunk/MicroBenchmarks/harris/main.cpp +++ test-suite/trunk/MicroBenchmarks/harris/main.cpp @@ -0,0 +1,216 @@ +#include "harris.h" +int sum = 0; + +#ifdef BENCHMARK_LIB +#include "benchmark/benchmark.h" +#endif + +// This function initializes the input image to checkbox image +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) { + int height = state.range(0); + int width = state.range(1); + + float(*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(*imageOutput)[2 + HEIGHT][2 + WIDTH]; + imageOutput = (float(*)[2 + HEIGHT][2 + WIDTH]) + malloc(sizeof(float) * (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]; + + 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)); + + 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); + } + + 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; i < height + 2; i++) { + for (int j = 0; j < width + 2; j++) { + sum = (sum + 1) & (int)(*imageOutput)[i][j]; + } + } + + state.SetBytesProcessed(sizeof(float) * (height + 2) * (width + 2) * + state.iterations()); + + free((void *)imageOutput); + free((void *)image); +} +BENCHMARK(BENCHMARK_HARRIS) + ->Args({256, 256}) + ->Args({512, 512}) + ->Args({1024, 1024}) + ->Args({2048, 2048}) + ->Unit(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(*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(*imageOutput)[2 + HEIGHT][2 + WIDTH]; + imageOutput = (float(*)[2 + HEIGHT][2 + WIDTH]) + malloc(sizeof(float) * (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]; + + 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)); + + 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; +}