diff --git a/codes/correlation/correlation.c b/codes/correlation/correlation.c new file mode 100644 index 0000000000000000000000000000000000000000..6e814357eb23b66eaf38e65edb02ec47cf56ef10 --- /dev/null +++ b/codes/correlation/correlation.c @@ -0,0 +1,168 @@ +/** + * This version is stamped on May 10, 2016 + * + * Contact: + * Louis-Noel Pouchet <pouchet.ohio-state.edu> + * Tomofumi Yuki <tomofumi.yuki.fr> + * + * Web address: http://polybench.sourceforge.net + */ +/* correlation.c: this file is part of PolyBench/C */ + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <math.h> + +/* Include polybench common header. */ +#include <polybench.h> + +/* Include benchmark-specific header. */ +#include "correlation.h" + + +/* Array initialization. */ +static +void init_array (int m, + int n, + DATA_TYPE *float_n, + DATA_TYPE POLYBENCH_2D(data,N,M,n,m)) +{ + int i, j; + + *float_n = (DATA_TYPE)N; + + for (i = 0; i < N; i++) + for (j = 0; j < M; j++) + data[i][j] = (DATA_TYPE)(i*j)/M + i; + +} + + +/* DCE code. Must scan the entire live-out data. + Can be used also to check the correctness of the output. */ +static +void print_array(int m, + DATA_TYPE POLYBENCH_2D(corr,M,M,m,m)) + +{ + int i, j; + + POLYBENCH_DUMP_START; + POLYBENCH_DUMP_BEGIN("corr"); + for (i = 0; i < m; i++) + for (j = 0; j < m; j++) { + if ((i * m + j) % 20 == 0) fprintf (POLYBENCH_DUMP_TARGET, "\n"); + fprintf (POLYBENCH_DUMP_TARGET, DATA_PRINTF_MODIFIER, corr[i][j]); + } + POLYBENCH_DUMP_END("corr"); + POLYBENCH_DUMP_FINISH; +} + + +/* Main computational kernel. The whole function will be timed, + including the call and return. */ +static +void kernel_correlation(int m, int n, + DATA_TYPE float_n, + DATA_TYPE POLYBENCH_2D(data,N,M,n,m), + DATA_TYPE POLYBENCH_2D(corr,M,M,m,m), + DATA_TYPE POLYBENCH_1D(mean,M,m), + DATA_TYPE POLYBENCH_1D(stddev,M,m)) +{ + int i, j, k; + + DATA_TYPE eps = SCALAR_VAL(0.1); + + +#pragma scop + for (j = 0; j < _PB_M; j++) + { + mean[j] = SCALAR_VAL(0.0); + for (i = 0; i < _PB_N; i++) + mean[j] += data[i][j]; + mean[j] /= float_n; + } + + + for (j = 0; j < _PB_M; j++) + { + stddev[j] = SCALAR_VAL(0.0); + for (i = 0; i < _PB_N; i++) + stddev[j] += (data[i][j] - mean[j]) * (data[i][j] - mean[j]); + stddev[j] /= float_n; + stddev[j] = SQRT_FUN(stddev[j]); + /* The following in an inelegant but usual way to handle + near-zero std. dev. values, which below would cause a zero- + divide. */ + stddev[j] = stddev[j] <= eps ? SCALAR_VAL(1.0) : stddev[j]; + } + + /* Center and reduce the column vectors. */ + for (i = 0; i < _PB_N; i++) + for (j = 0; j < _PB_M; j++) + { + data[i][j] -= mean[j]; + data[i][j] /= SQRT_FUN(float_n) * stddev[j]; + } + + /* Calculate the m * m correlation matrix. */ + for (i = 0; i < _PB_M-1; i++) + { + corr[i][i] = SCALAR_VAL(1.0); + for (j = i+1; j < _PB_M; j++) + { + corr[i][j] = SCALAR_VAL(0.0); + for (k = 0; k < _PB_N; k++) + corr[i][j] += (data[k][i] * data[k][j]); + corr[j][i] = corr[i][j]; + } + } + corr[_PB_M-1][_PB_M-1] = SCALAR_VAL(1.0); +#pragma endscop + +} + + +int main(int argc, char** argv) +{ + /* Retrieve problem size. */ + int n = N; + int m = M; + + /* Variable declaration/allocation. */ + DATA_TYPE float_n; + POLYBENCH_2D_ARRAY_DECL(data,DATA_TYPE,N,M,n,m); + POLYBENCH_2D_ARRAY_DECL(corr,DATA_TYPE,M,M,m,m); + POLYBENCH_1D_ARRAY_DECL(mean,DATA_TYPE,M,m); + POLYBENCH_1D_ARRAY_DECL(stddev,DATA_TYPE,M,m); + + /* Initialize array(s). */ + init_array (m, n, &float_n, POLYBENCH_ARRAY(data)); + + /* Start timer. */ + polybench_start_instruments; + + /* Run kernel. */ + kernel_correlation (m, n, float_n, + POLYBENCH_ARRAY(data), + POLYBENCH_ARRAY(corr), + POLYBENCH_ARRAY(mean), + POLYBENCH_ARRAY(stddev)); + + /* Stop and print timer. */ + polybench_stop_instruments; + polybench_print_instruments; + + /* Prevent dead-code elimination. All live-out data must be printed + by the function call in argument. */ + polybench_prevent_dce(print_array(m, POLYBENCH_ARRAY(corr))); + + /* Be clean. */ + POLYBENCH_FREE_ARRAY(data); + POLYBENCH_FREE_ARRAY(corr); + POLYBENCH_FREE_ARRAY(mean); + POLYBENCH_FREE_ARRAY(stddev); + + return 0; +} diff --git a/codes/correlation/correlation.h b/codes/correlation/correlation.h new file mode 100644 index 0000000000000000000000000000000000000000..f2660e2907b0e692f6915d07b68a1aad2ebc60d9 --- /dev/null +++ b/codes/correlation/correlation.h @@ -0,0 +1,80 @@ +/** + * This version is stamped on May 10, 2016 + * + * Contact: + * Louis-Noel Pouchet <pouchet.ohio-state.edu> + * Tomofumi Yuki <tomofumi.yuki.fr> + * + * Web address: http://polybench.sourceforge.net + */ +#ifndef _CORRELATION_H +# define _CORRELATION_H + +/* Default to LARGE_DATASET. */ +# if !defined(MINI_DATASET) && !defined(SMALL_DATASET) && !defined(MEDIUM_DATASET) && !defined(LARGE_DATASET) && !defined(EXTRALARGE_DATASET) +# define LARGE_DATASET +# endif + +# if !defined(M) && !defined(N) +/* Define sample dataset sizes. */ +# ifdef MINI_DATASET +# define M 28 +# define N 32 +# endif + +# ifdef SMALL_DATASET +# define M 80 +# define N 100 +# endif + +# ifdef MEDIUM_DATASET +# define M 240 +# define N 260 +# endif + +# ifdef LARGE_DATASET +# define M 1200 +# define N 1400 +# endif + +# ifdef EXTRALARGE_DATASET +# define M 2600 +# define N 3000 +# endif + + +#endif /* !(M N) */ + +# define _PB_M POLYBENCH_LOOP_BOUND(M,m) +# define _PB_N POLYBENCH_LOOP_BOUND(N,n) + + +/* Default data type */ +# if !defined(DATA_TYPE_IS_INT) && !defined(DATA_TYPE_IS_FLOAT) && !defined(DATA_TYPE_IS_DOUBLE) +# define DATA_TYPE_IS_DOUBLE +# endif + +#ifdef DATA_TYPE_IS_INT +# define DATA_TYPE int +# define DATA_PRINTF_MODIFIER "%d " +#endif + +#ifdef DATA_TYPE_IS_FLOAT +# define DATA_TYPE float +# define DATA_PRINTF_MODIFIER "%0.2f " +# define SCALAR_VAL(x) x##f +# define SQRT_FUN(x) sqrtf(x) +# define EXP_FUN(x) expf(x) +# define POW_FUN(x,y) powf(x,y) +# endif + +#ifdef DATA_TYPE_IS_DOUBLE +# define DATA_TYPE double +# define DATA_PRINTF_MODIFIER "%0.2lf " +# define SCALAR_VAL(x) x +# define SQRT_FUN(x) sqrt(x) +# define EXP_FUN(x) exp(x) +# define POW_FUN(x,y) pow(x,y) +# endif + +#endif /* !_CORRELATION_H */