Index: SingleSource/Benchmarks/Polybench/linear-algebra/kernels/2mm/2mm.c =================================================================== --- SingleSource/Benchmarks/Polybench/linear-algebra/kernels/2mm/2mm.c +++ SingleSource/Benchmarks/Polybench/linear-algebra/kernels/2mm/2mm.c @@ -26,7 +26,8 @@ DATA_TYPE POLYBENCH_2D(A,NI,NK,ni,nl), DATA_TYPE POLYBENCH_2D(B,NK,NJ,nk,nj), DATA_TYPE POLYBENCH_2D(C,NL,NJ,nl,nj), - DATA_TYPE POLYBENCH_2D(D,NI,NL,ni,nl)) + DATA_TYPE POLYBENCH_2D(D,NI,NL,ni,nl), + DATA_TYPE POLYBENCH_2D(D_Strict_FP,NI,NL,ni,nl)) { int i, j; @@ -44,6 +45,9 @@ for (i = 0; i < ni; i++) for (j = 0; j < nl; j++) D[i][j] = ((DATA_TYPE) i*(j+2)) / nk; + for (i = 0; i < ni; i++) + for (j = 0; j < nl; j++) + D_Strict_FP[i][j] = ((DATA_TYPE) i*(j+2)) / nk; } @@ -99,6 +103,56 @@ } +static void +kernel_2mm_StrictFP(int ni, int nj, int nk, int nl, + DATA_TYPE alpha, + DATA_TYPE beta, + DATA_TYPE POLYBENCH_2D(tmp,NI,NJ,ni,nj), + DATA_TYPE POLYBENCH_2D(A,NI,NK,ni,nk), + DATA_TYPE POLYBENCH_2D(B,NK,NJ,nk,nj), + DATA_TYPE POLYBENCH_2D(C,NL,NJ,nl,nj), + DATA_TYPE POLYBENCH_2D(D,NI,NL,ni,nl)) +{ +#pragma STDC FP_CONTRACT OFF + int i, j, k; + + /* D := alpha*A*B*C + beta*D */ + for (i = 0; i < _PB_NI; i++) + for (j = 0; j < _PB_NJ; j++) + { + tmp[i][j] = 0; + for (k = 0; k < _PB_NK; ++k) + tmp[i][j] += alpha * A[i][k] * B[k][j]; + } + for (i = 0; i < _PB_NI; i++) + for (j = 0; j < _PB_NL; j++) + { + D[i][j] *= beta; + for (k = 0; k < _PB_NJ; ++k) + D[i][j] += tmp[i][k] * C[k][j]; + } +} + +static int +check_FP(int ni, int nl, + DATA_TYPE POLYBENCH_2D(D,NI,NL,ni,nl), + DATA_TYPE POLYBENCH_2D(D_Strict_FP,NI,NL,ni,nl)) { +#pragma STDC FP_CONTRACT OFF + int i, j; + for (i = 0; i < NI; i++) + for (j = 0; j < NL; j++) + { + /* FP_ABSTOLERANCE will be added to the defines when compiling this benchmark. */ +#define FP_ABSTOLERANCE 0.0001 + double V1 = D[i][j]; + double V2 = D_Strict_FP[i][j]; + if (FP_ABSTOLERANCE < fabs(V1 - V2)) { + fprintf(stderr, "D[%d][%d] = %lf D_Strict_FP[%d][%d] = %lf\n", i, j, V1, i, j, V2); + return 1; + } + } + return 0; +} int main(int argc, char** argv) { @@ -116,13 +170,15 @@ POLYBENCH_2D_ARRAY_DECL(B,DATA_TYPE,NK,NJ,nk,nj); POLYBENCH_2D_ARRAY_DECL(C,DATA_TYPE,NL,NJ,nl,nj); POLYBENCH_2D_ARRAY_DECL(D,DATA_TYPE,NI,NL,ni,nl); + POLYBENCH_2D_ARRAY_DECL(D_Strict_FP,DATA_TYPE,NI,NL,ni,nl); /* Initialize array(s). */ init_array (ni, nj, nk, nl, &alpha, &beta, POLYBENCH_ARRAY(A), POLYBENCH_ARRAY(B), POLYBENCH_ARRAY(C), - POLYBENCH_ARRAY(D)); + POLYBENCH_ARRAY(D), + POLYBENCH_ARRAY(D_Strict_FP)); /* Start timer. */ polybench_start_instruments; @@ -140,9 +196,20 @@ polybench_stop_instruments; polybench_print_instruments; + kernel_2mm_StrictFP (ni, nj, nk, nl, + alpha, beta, + POLYBENCH_ARRAY(tmp), + POLYBENCH_ARRAY(A), + POLYBENCH_ARRAY(B), + POLYBENCH_ARRAY(C), + POLYBENCH_ARRAY(D_Strict_FP)); + + + if (check_FP(ni, nl, POLYBENCH_ARRAY(D), POLYBENCH_ARRAY(D_Strict_FP))) + return 1; /* Prevent dead-code elimination. All live-out data must be printed by the function call in argument. */ - polybench_prevent_dce(print_array(ni, nl, POLYBENCH_ARRAY(D))); + polybench_prevent_dce(print_array(ni, nl, POLYBENCH_ARRAY(D_Strict_FP))); /* Be clean. */ POLYBENCH_FREE_ARRAY(tmp); @@ -150,6 +217,7 @@ POLYBENCH_FREE_ARRAY(B); POLYBENCH_FREE_ARRAY(C); POLYBENCH_FREE_ARRAY(D); + POLYBENCH_FREE_ARRAY(D_Strict_FP); return 0; }