[test-suite] r339006 - Add Image dithering kernels using Benchmark Library
Tim Northover via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 7 03:04:14 PDT 2018
Hi Prankaj,
On Mon, 6 Aug 2018 at 16:03, Pankaj Kukreja via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> + list(APPEND CPPFLAGS -I ${CMAKE_SOURCE_DIR}/${IMAGEPROC_UTILS} -std=c++11)
> [...]
> +llvm_test_executable(Dither main.cpp orderedDitherKernel.c floydDitherKernel.c ../utils/ImageHelper.cpp ../utils/glibc_compat_rand.c)
This combination is problematic because Clang complains that
-std=c++11 is an invalid option for .c files. It causes a build
failure for me on both Linux & macOS. I suspect it's also the cause of
this failure: http://green.lab.llvm.org/green/job/Testsuite-Tester/587/.
But the bot is struggling to give me a log at the moment.
Cheers.
Tim.> +
> +target_link_libraries(Dither benchmark)
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/dither.h
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/dither.h?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/dither.h (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/dither.h Mon Aug 6 04:19:13 2018
> @@ -0,0 +1,15 @@
> +/**
> + Pankaj Kukreja
> + github.com/proton0001
> + Indian Institute of Technology Hyderabad
> +*/
> +#ifndef _DITHER_H_
> +#define _DITHER_H_
> +
> +#define MaxGray 255
> +#define MXGRAY 256
> +
> +#define HEIGHT 512
> +#define WIDTH 512
> +
> +#endif /* _DITHER_H_ */
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDither.reference_output
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDither.reference_output?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDither.reference_output (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDither.reference_output Mon Aug 6 04:19:13 2018
> @@ -0,0 +1 @@
> +23473c2d34c91e33eaa3d5008ce3640e
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDitherKernel.c
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDitherKernel.c?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDitherKernel.c (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/floydDitherKernel.c Mon Aug 6 04:19:13 2018
> @@ -0,0 +1,69 @@
> +/**
> + Source: https://imagej.net/Dithering
> + Modified by Pankaj Kukreja (github.com/proton0001)
> + Indian Institute of Technology Hyderabad
> +*/
> +#include "dither.h"
> +void floydDitherKernel(int height, int width, int inputImage[HEIGHT][WIDTH],
> + int outputImage[height][width]) {
> + for (int i = 0; i < height; i++) {
> + for (int j = 0; j < width; j++) {
> + outputImage[i][j] = inputImage[i][j];
> + }
> + }
> +
> + int err;
> + int a, b, c, d;
> +
> + for (int i = 1; i < height - 1; i++) {
> + for (int j = 1; j < width - 1; j++) {
> + if (outputImage[i][j] > 127) {
> + err = outputImage[i][j] - 255;
> + outputImage[i][j] = 255;
> + } else {
> + err = outputImage[i][j] - 0;
> + outputImage[i][j] = 0;
> + }
> + a = (err * 7) / 16;
> + b = (err * 1) / 16;
> + c = (err * 5) / 16;
> + d = (err * 3) / 16;
> +
> + int temp1 = (outputImage[i][j + 1] + a);
> + if (temp1 > 255) {
> + outputImage[i][j + 1] = 255;
> + } else if (temp1 < 0) {
> + outputImage[i][j + 1] = 0;
> + } else {
> + outputImage[i][j + 1] = temp1;
> + }
> +
> + int temp2 = (outputImage[i + 1][j + 1] + b);
> + if (temp2 > 255) {
> + outputImage[i + 1][j + 1] = 255;
> + } else if (temp2 < 0) {
> + outputImage[i + 1][j + 1] = 0;
> + } else {
> + outputImage[i + 1][j + 1] = temp2;
> + }
> +
> + int temp3 = outputImage[i + 1][j + 0] + c;
> + if (temp3 > 255) {
> + outputImage[i + 1][j + 0] = 255;
> + } else if (temp3 < 0) {
> + outputImage[i + 1][j + 0] = 0;
> + } else {
> + outputImage[i + 1][j + 0] = temp3;
> + }
> +
> + int temp4 = outputImage[i + 1][j - 1] + d;
> + if (temp4 > 255) {
> + outputImage[i + 1][j - 1] = 255;
> + } else if (temp4 < 0) {
> + outputImage[i + 1][j - 1] = 0;
> + } else {
> + outputImage[i + 1][j - 1] = temp4;
> + }
> + }
> + }
> +}
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/main.cpp
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/main.cpp?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/main.cpp (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/main.cpp Mon Aug 6 04:19:13 2018
> @@ -0,0 +1,156 @@
> +/**
> + Pankaj Kukreja
> + github.com/proton0001
> + Indian Institute of Technology Hyderabad
> +*/
> +#include "ImageHelper.h"
> +#include "dither.h"
> +#include <cmath>
> +#include <iostream> // std::cerr
> +
> +#define BENCHMARK_LIB
> +#ifdef BENCHMARK_LIB
> +#include "benchmark/benchmark.h"
> +#endif
> +
> +int *inputImage;
> +extern "C" {
> +void orderedDitherKernel(int height, int width, int *inpImage, int *outImage,
> + int *temp, int n, int m);
> +void floydDitherKernel(int height, int width, int *inpImage, int *outImage);
> +}
> +int main(int argc, char **argv) {
> +#ifdef BENCHMARK_LIB
> + ::benchmark::Initialize(&argc, argv);
> +#endif
> +
> + const char *orderedOutputFilename = (char *)"./orderedOutput.txt";
> + const char *floydOutputFilename = (char *)"./floydOutput.txt";
> + inputImage = (int *)malloc(sizeof(int) * HEIGHT * WIDTH);
> + if (inputImage == NULL) {
> + std::cerr << "Insufficient memory\n";
> + exit(1);
> + }
> + initializeRandomImage(inputImage, HEIGHT, WIDTH);
> +
> +#ifdef BENCHMARK_LIB
> + ::benchmark::RunSpecifiedBenchmarks();
> +#endif
> + int *outputImage = (int *)malloc(sizeof(int) * HEIGHT * WIDTH);
> + int *temp = (int *)malloc(sizeof(int) * HEIGHT * WIDTH);
> + if (outputImage == NULL || temp == NULL) {
> + std::cerr << "Insufficient memory\n";
> + exit(1);
> + }
> + orderedDitherKernel(HEIGHT, WIDTH, inputImage, outputImage, temp, 16, 4);
> + saveImage(outputImage, orderedOutputFilename, HEIGHT, WIDTH);
> + floydDitherKernel(HEIGHT, WIDTH, inputImage, outputImage);
> +
> + for (int i = 0; i < HEIGHT; i++) {
> + outputImage[(i)*WIDTH + 0] = 0;
> + outputImage[(i)*WIDTH + WIDTH - 1] = 0;
> + }
> +
> + for (int j = 0; j < WIDTH; j++) {
> + outputImage[(0) * WIDTH + j] = 0;
> + outputImage[(HEIGHT - 1) * WIDTH + j] = 0;
> + }
> +
> + saveImage(outputImage, floydOutputFilename, HEIGHT, WIDTH);
> + free(temp);
> + free(outputImage);
> + free(inputImage);
> + return EXIT_SUCCESS;
> +}
> +
> +#ifdef BENCHMARK_LIB
> +void BENCHMARK_ORDERED_DITHER(benchmark::State &state) {
> + int height = state.range(0);
> + int width = state.range(0);
> + int m = state.range(1);
> + int n = pow(m, 2);
> + int *outputImage = (int *)malloc(sizeof(int) * height * width);
> + int *temp = (int *)malloc(sizeof(int) * height * width);
> +
> + if (outputImage == NULL) {
> + std::cerr << "Insufficient memory\n";
> + exit(1);
> + }
> + /* This call is to warm up the cache */
> + orderedDitherKernel(height, width, inputImage, outputImage, temp, n, m);
> +
> + for (auto _ : state) {
> + orderedDitherKernel(height, width, inputImage, outputImage, temp, n, m);
> + }
> + /* Since we are not passing state.range as 20 this if case will always be
> + * false. This call is to make compiler think that outputImage may be used
> + * later so that above kernel calls will not optimize out */
> + if (state.range(0) == 20) {
> + saveImage(outputImage, (const char *)"failedCase.txt", height, width);
> + }
> + free(temp);
> + 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 = 1;
> + if (limit > 128) {
> + start = 128;
> + }
> + for (int i = start; i <= limit; i <<= 1) {
> + b->Args({i, 2});
> + b->Args({i, 3});
> + b->Args({i, 4});
> + b->Args({i, 8});
> + }
> +}
> +BENCHMARK(BENCHMARK_ORDERED_DITHER)
> + ->Apply(CustomArguments)
> + ->Unit(benchmark::kMicrosecond);
> +
> +void BENCHMARK_FLOYD_DITHER(benchmark::State &state) {
> +
> + int height = state.range(0);
> + int width = state.range(0);
> +
> + 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 */
> + floydDitherKernel(height, width, inputImage, outputImage);
> + for (auto _ : state) {
> + floydDitherKernel(height, width, inputImage, outputImage);
> + }
> + /* Since we are not passing state.range as 20 this if case will always be
> + * false. This call is to make compiler think that outputImage may be used
> + * later so that above kernel calls will not optimize out */
> + if (state.range(0) == 20) {
> + saveImage(outputImage, (const char *)"failedCase.txt", height, width);
> + }
> +
> + free(outputImage);
> +}
> +
> +#if MINIMUM_DIM > 128
> +BENCHMARK(BENCHMARK_FLOYD_DITHER)
> + ->RangeMultiplier(2)
> + ->Range(128, MINIMUM_DIM)
> + ->Unit(benchmark::kMicrosecond);
> +#else
> +BENCHMARK(BENCHMARK_FLOYD_DITHER)
> + ->RangeMultiplier(2)
> + ->Range(1, MINIMUM_DIM)
> + ->Unit(benchmark::kMicrosecond);
> +#endif
> +
> +#endif
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDither.reference_output
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDither.reference_output?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDither.reference_output (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDither.reference_output Mon Aug 6 04:19:13 2018
> @@ -0,0 +1 @@
> +7b339ccc04bbaebf30f44f4f3129756f
>
> Added: test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDitherKernel.c
> URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDitherKernel.c?rev=339006&view=auto
> ==============================================================================
> --- test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDitherKernel.c (added)
> +++ test-suite/trunk/MicroBenchmarks/ImageProcessing/Dither/orderedDitherKernel.c Mon Aug 6 04:19:13 2018
> @@ -0,0 +1,72 @@
> +/**
> + Source: github -> https://github.com/brianwu02/ImageProcessing.git
> + Modified by Pankaj Kukreja (github.com/proton0001)
> + Indian Institute of Technology Hyderabad
> +*/
> +#include "dither.h"
> +#include <math.h> // pow
> +
> +#define GAMMA 0.5
> +
> +void orderedDitherKernel(int height, int width, int inputImage[HEIGHT][WIDTH],
> + int outputImage[height][width],
> + int temp[height][width], int n, int m) {
> + int scale;
> +
> + for (int i = 0; i < height; i++) {
> + for (int j = 0; j < width; j++) {
> + temp[i][j] =
> + (int)(pow((double)inputImage[i][j] / 255.0, (1.0 / GAMMA)) * 255.0);
> + }
> + }
> +
> + scale = 256 / n;
> + for (int i = 0; i < height; i++) {
> + for (int j = 0; j < width; j++) {
> + outputImage[i][j] = (int)(scale * (temp[i][j] / scale)) / scale;
> + }
> + }
> +
> + if (m == 2) {
> + int dither[2][2] = {{0, 2}, {3, 1}};
> + for (int y = 0; y < height; y++) {
> + for (int x = 0; x < width; x++) {
> + int i = x % m;
> + int j = y % m;
> + outputImage[y][x] = ((outputImage[y][x] > dither[i][j]) ? 255 : 0);
> + }
> + }
> + } else if (m == 3) {
> + int dither[3][3] = {{6, 8, 4}, {1, 0, 3}, {5, 2, 7}};
> + for (int y = 0; y < height; y++) {
> + for (int x = 0; x < width; x++) {
> + int i = x % m;
> + int j = y % m;
> + outputImage[y][x] = ((outputImage[y][x] > dither[i][j]) ? 255 : 0);
> + }
> + }
> + } else if (m == 4) {
> + int dither[4][4] = {
> + {0, 8, 2, 10}, {12, 4, 14, 6}, {3, 11, 1, 9}, {15, 7, 13, 5}};
> + for (int y = 0; y < height; y++) {
> + for (int x = 0; x < width; x++) {
> + int i = x % m;
> + int j = y % m;
> + outputImage[y][x] = ((outputImage[y][x] > dither[i][j]) ? 255 : 0);
> + }
> + }
> + } else if (m == 8) {
> + int dither[8][8] = {
> + {0, 48, 12, 60, 3, 51, 15, 63}, {32, 16, 44, 28, 35, 19, 47, 31},
> + {8, 56, 4, 52, 11, 59, 7, 55}, {40, 24, 36, 20, 43, 27, 39, 23},
> + {2, 50, 14, 62, 1, 49, 13, 61}, {34, 18, 46, 30, 33, 17, 45, 29},
> + {10, 58, 6, 54, 9, 57, 5, 53}, {42, 26, 38, 22, 41, 25, 37, 21}};
> + for (int y = 0; y < height; y++) {
> + for (int x = 0; x < width; x++) {
> + int i = x % m;
> + int j = y % m;
> + outputImage[y][x] = ((outputImage[y][x] > dither[i][j]) ? 255 : 0);
> + }
> + }
> + }
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list