-
Notifications
You must be signed in to change notification settings - Fork 315
/
jacobi-1d-imper.c
171 lines (143 loc) · 4.2 KB
/
jacobi-1d-imper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* jacobi-1d-imper.c: This file is part of the PolyBench/C 3.2 test suite.
*
*
* Contact: Louis-Noel Pouchet <pouchet@cse.ohio-state.edu>
* Web address: http://polybench.sourceforge.net
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
/* Include polybench common header. */
#include <polybench.h>
/* Include benchmark-specific header. */
/* Default data type is double, default size is 100x10000. */
#include "jacobi-1d-imper.h"
/* Array initialization. */
static
void init_array (int n,
DATA_TYPE POLYBENCH_1D(A,N,n),
DATA_TYPE POLYBENCH_1D(B,N,n))
{
#pragma STDC FP_CONTRACT OFF
int i;
for (i = 0; i < n; i++)
{
A[i] = ((DATA_TYPE) i+ 2) / n;
B[i] = ((DATA_TYPE) i+ 3) / n;
}
}
/* 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 n,
DATA_TYPE POLYBENCH_1D(A,N,n))
{
int i;
char *printmat = malloc(n*16 + 1); printmat[n*16] = 0;
for (i = 0; i < n; i++)
print_element(A[i], i*16, printmat);
fputs(printmat, stderr);
free(printmat);
}
/* Main computational kernel. The whole function will be timed,
including the call and return. */
static
void kernel_jacobi_1d_imper(int tsteps,
int n,
DATA_TYPE POLYBENCH_1D(A,N,n),
DATA_TYPE POLYBENCH_1D(B,N,n))
{
int t, i, j;
#pragma scop
for (t = 0; t < _PB_TSTEPS; t++)
{
for (i = 1; i < _PB_N - 1; i++)
B[i] = 0.33333 * (A[i-1] + A[i] + A[i + 1]);
for (j = 1; j < _PB_N - 1; j++)
A[j] = B[j];
}
#pragma endscop
}
#if !FMA_DISABLED
// NOTE: FMA_DISABLED is true for targets where FMA contraction causes
// discrepancies which cause the accuracy checks to fail.
// In this case, the test runs with the option -ffp-contract=off
static void
kernel_jacobi_1d_imper_StrictFP(int tsteps,
int n,
DATA_TYPE POLYBENCH_1D(A,N,n),
DATA_TYPE POLYBENCH_1D(B,N,n))
{
#pragma STDC FP_CONTRACT OFF
int t, i, j;
for (t = 0; t < _PB_TSTEPS; t++)
{
for (i = 1; i < _PB_N - 1; i++)
B[i] = 0.33333 * (A[i-1] + A[i] + A[i + 1]);
for (j = 1; j < _PB_N - 1; j++)
A[j] = B[j];
}
}
/* Return 0 when one of the elements of arrays A and B do not match within the
allowed FP_ABSTOLERANCE. Return 1 when all elements match. */
static int
check_FP(int n,
DATA_TYPE POLYBENCH_1D(A,N,n),
DATA_TYPE POLYBENCH_1D(B,N,n)) {
int i;
double AbsTolerance = FP_ABSTOLERANCE;
for (i = 0; i < _PB_N; i++)
{
double V1 = A[i];
double V2 = B[i];
double Diff = fabs(V1 - V2);
if (Diff > AbsTolerance) {
fprintf(stderr, "A[%d] = %lf and B[%d] = %lf differ more than"
" FP_ABSTOLERANCE = %lf\n", i, V1, i, V2, AbsTolerance);
return 0;
}
}
return 1;
}
#endif
int main(int argc, char** argv)
{
/* Retrieve problem size. */
int n = N;
int tsteps = TSTEPS;
/* Variable declaration/allocation. */
POLYBENCH_1D_ARRAY_DECL(A, DATA_TYPE, N, n);
#if !FMA_DISABLED
POLYBENCH_1D_ARRAY_DECL(A_StrictFP, DATA_TYPE, N, n);
#endif
POLYBENCH_1D_ARRAY_DECL(B, DATA_TYPE, N, n);
/* Initialize array(s). */
init_array (n, POLYBENCH_ARRAY(A), POLYBENCH_ARRAY(B));
/* Start timer. */
polybench_start_instruments;
/* Run kernel. */
kernel_jacobi_1d_imper (tsteps, n, POLYBENCH_ARRAY(A), POLYBENCH_ARRAY(B));
/* Stop and print timer. */
polybench_stop_instruments;
polybench_print_instruments;
#if FMA_DISABLED
/* Prevent dead-code elimination. All live-out data must be printed
by the function call in argument. */
polybench_prevent_dce(print_array(n, POLYBENCH_ARRAY(A)));
#else
init_array (n, POLYBENCH_ARRAY(A_StrictFP), POLYBENCH_ARRAY(B));
kernel_jacobi_1d_imper (tsteps, n, POLYBENCH_ARRAY(A_StrictFP),
POLYBENCH_ARRAY(B));
if (!check_FP(n, POLYBENCH_ARRAY(A), POLYBENCH_ARRAY(A_StrictFP)))
return 1;
/* Prevent dead-code elimination. All live-out data must be printed
by the function call in argument. */
polybench_prevent_dce(print_array(n, POLYBENCH_ARRAY(A_StrictFP)));
#endif
/* Be clean. */
POLYBENCH_FREE_ARRAY(A);
POLYBENCH_FREE_ARRAY(B);
return 0;
}