1// RUN: %libomp-compile-and-run
2#include <stdio.h>
3#include <stdlib.h>
4#include <math.h>
5#include "omp_testsuite.h"
6
7#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
8#define MAX_FACTOR 10
9#define KNOWN_PRODUCT 3628800 /* 10! */
10
11int test_omp_for_reduction ()
12{
13 double dt;
14 int sum;
15 int diff;
16 int product = 1;
17 double dsum;
18 double dknown_sum;
19 double ddiff;
20 int logic_and;
21 int logic_or;
22 int bit_and;
23 int bit_or;
24 int exclusiv_bit_or;
25 int *logics;
26 int i;
27 int known_sum;
28 int known_product;
29 double rounding_error = 1.E-9; /* over all rounding error to be
30 ignored in the double tests */
31 double dpt;
32 int result = 0;
33 int logicsArray[LOOPCOUNT];
34
35 /* Variables for integer tests */
36 sum = 0;
37 product = 1;
38 known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
39 /* variabels for double tests */
40 dt = 1. / 3.; /* base of geometric row for + and - test*/
41 dsum = 0.;
42 /* Variabeles for logic tests */
43 logics = logicsArray;
44 logic_and = 1;
45 logic_or = 0;
46 /* Variabeles for bit operators tests */
47 bit_and = 1;
48 bit_or = 0;
49 /* Variables for exclusiv bit or */
50 exclusiv_bit_or = 0;
51
52 /************************************************************************/
53 /** Tests for integers **/
54 /************************************************************************/
55
56 /**** Testing integer addition ****/
57 #pragma omp parallel
58 {
59 int j;
60 #pragma omp for schedule(dynamic,1) reduction(+:sum)
61 for (j = 1; j <= LOOPCOUNT; j++) {
62 sum = sum + j;
63 }
64 }
65 if (known_sum != sum) {
66 result++;
67 fprintf (stderr, format: "Error in sum with integers: Result was %d"
68 " instead of %d.\n", sum, known_sum);
69 }
70
71 /**** Testing integer subtracton ****/
72 diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
73 #pragma omp parallel
74 {
75 int j;
76 #pragma omp for schedule(dynamic,1) reduction(-:diff)
77 for (j = 1; j <= LOOPCOUNT; j++) {
78 diff = diff - j;
79 }
80 }
81 if (diff != 0) {
82 result++;
83 fprintf (stderr, format: "Error in difference with integers: Result was %d"
84 " instead of 0.\n", diff);
85 }
86
87 /**** Testing integer multiplication ****/
88 #pragma omp parallel
89 {
90 int j;
91 #pragma omp for schedule(dynamic,1) reduction(*:product)
92 for (j = 1; j <= MAX_FACTOR; j++) {
93 product *= j;
94 }
95 }
96 known_product = KNOWN_PRODUCT;
97 if(known_product != product) {
98 result++;
99 fprintf (stderr,format: "Error in Product with integers: Result was %d"
100 " instead of %d\n",product,known_product);
101 }
102
103 /************************************************************************/
104 /** Tests for doubles **/
105 /************************************************************************/
106
107 /**** Testing double addition ****/
108 dsum = 0.;
109 dpt = 1.;
110 for (i = 0; i < DOUBLE_DIGITS; ++i) {
111 dpt *= dt;
112 }
113 dknown_sum = (1 - dpt) / (1 - dt);
114 #pragma omp parallel
115 {
116 int j;
117 #pragma omp for schedule(dynamic,1) reduction(+:dsum)
118 for (j = 0; j < DOUBLE_DIGITS; j++) {
119 dsum += pow (x: dt, y: j);
120 }
121 }
122 if (fabs (x: dsum - dknown_sum) > rounding_error) {
123 result++;
124 fprintf (stderr, format: "\nError in sum with doubles: Result was %f"
125 " instead of: %f (Difference: %E)\n",
126 dsum, dknown_sum, dsum-dknown_sum);
127 }
128
129 /**** Testing double subtraction ****/
130 ddiff = (1 - dpt) / (1 - dt);
131 #pragma omp parallel
132 {
133 int j;
134 #pragma omp for schedule(dynamic,1) reduction(-:ddiff)
135 for (j = 0; j < DOUBLE_DIGITS; ++j) {
136 ddiff -= pow (x: dt, y: j);
137 }
138 }
139 if (fabs (x: ddiff) > rounding_error) {
140 result++;
141 fprintf (stderr, format: "Error in Difference with doubles: Result was %E"
142 " instead of 0.0\n", ddiff);
143 }
144
145
146 /************************************************************************/
147 /** Tests for logical values **/
148 /************************************************************************/
149
150 /**** Testing logic and ****/
151 for (i = 0; i < LOOPCOUNT; i++) {
152 logics[i] = 1;
153 }
154
155 #pragma omp parallel
156 {
157 int j;
158 #pragma omp for schedule(dynamic,1) reduction(&&:logic_and)
159 for (j = 0; j < LOOPCOUNT; ++j) {
160 logic_and = (logic_and && logics[j]);
161 }
162 }
163 if(!logic_and) {
164 result++;
165 fprintf (stderr, format: "Error in logic AND part 1\n");
166 }
167
168 logic_and = 1;
169 logics[LOOPCOUNT / 2] = 0;
170
171 #pragma omp parallel
172 {
173 int j;
174 #pragma omp for schedule(dynamic,1) reduction(&&:logic_and)
175 for (j = 0; j < LOOPCOUNT; ++j) {
176 logic_and = logic_and && logics[j];
177 }
178 }
179 if(logic_and) {
180 result++;
181 fprintf (stderr, format: "Error in logic AND part 2\n");
182 }
183
184 /**** Testing logic or ****/
185 for (i = 0; i < LOOPCOUNT; i++) {
186 logics[i] = 0;
187 }
188
189 #pragma omp parallel
190 {
191 int j;
192 #pragma omp for schedule(dynamic,1) reduction(||:logic_or)
193 for (j = 0; j < LOOPCOUNT; ++j) {
194 logic_or = logic_or || logics[j];
195 }
196 }
197 if (logic_or) {
198 result++;
199 fprintf (stderr, format: "Error in logic OR part 1\n");
200 }
201
202 logic_or = 0;
203 logics[LOOPCOUNT / 2] = 1;
204
205 #pragma omp parallel
206 {
207 int j;
208 #pragma omp for schedule(dynamic,1) reduction(||:logic_or)
209 for (j = 0; j < LOOPCOUNT; ++j) {
210 logic_or = logic_or || logics[j];
211 }
212 }
213 if(!logic_or) {
214 result++;
215 fprintf (stderr, format: "Error in logic OR part 2\n");
216 }
217
218 /************************************************************************/
219 /** Tests for bit values **/
220 /************************************************************************/
221
222 /**** Testing bit and ****/
223 for (i = 0; i < LOOPCOUNT; ++i) {
224 logics[i] = 1;
225 }
226
227 #pragma omp parallel
228 {
229 int j;
230 #pragma omp for schedule(dynamic,1) reduction(&:bit_and)
231 for (j = 0; j < LOOPCOUNT; ++j) {
232 bit_and = (bit_and & logics[j]);
233 }
234 }
235 if (!bit_and) {
236 result++;
237 fprintf (stderr, format: "Error in BIT AND part 1\n");
238 }
239
240 bit_and = 1;
241 logics[LOOPCOUNT / 2] = 0;
242
243 #pragma omp parallel
244 {
245 int j;
246 #pragma omp for schedule(dynamic,1) reduction(&:bit_and)
247 for (j = 0; j < LOOPCOUNT; ++j) {
248 bit_and = bit_and & logics[j];
249 }
250 }
251 if (bit_and) {
252 result++;
253 fprintf (stderr, format: "Error in BIT AND part 2\n");
254 }
255
256 /**** Testing bit or ****/
257 for (i = 0; i < LOOPCOUNT; i++) {
258 logics[i] = 0;
259 }
260
261 #pragma omp parallel
262 {
263 int j;
264 #pragma omp for schedule(dynamic,1) reduction(|:bit_or)
265 for (j = 0; j < LOOPCOUNT; ++j) {
266 bit_or = bit_or | logics[j];
267 }
268 }
269 if (bit_or) {
270 result++;
271 fprintf (stderr, format: "Error in BIT OR part 1\n");
272 }
273
274 bit_or = 0;
275 logics[LOOPCOUNT / 2] = 1;
276
277 #pragma omp parallel
278 {
279 int j;
280 #pragma omp for schedule(dynamic,1) reduction(|:bit_or)
281 for (j = 0; j < LOOPCOUNT; ++j) {
282 bit_or = bit_or | logics[j];
283 }
284 }
285 if (!bit_or) {
286 result++;
287 fprintf (stderr, format: "Error in BIT OR part 2\n");
288 }
289
290 /**** Testing exclusive bit or ****/
291 for (i = 0; i < LOOPCOUNT; i++) {
292 logics[i] = 0;
293 }
294
295 #pragma omp parallel
296 {
297 int j;
298 #pragma omp for schedule(dynamic,1) reduction(^:exclusiv_bit_or)
299 for (j = 0; j < LOOPCOUNT; ++j) {
300 exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
301 }
302 }
303 if (exclusiv_bit_or) {
304 result++;
305 fprintf (stderr, format: "Error in EXCLUSIV BIT OR part 1\n");
306 }
307
308 exclusiv_bit_or = 0;
309 logics[LOOPCOUNT / 2] = 1;
310
311 #pragma omp parallel
312 {
313 int j;
314 #pragma omp for schedule(dynamic,1) reduction(^:exclusiv_bit_or)
315 for (j = 0; j < LOOPCOUNT; ++j) {
316 exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
317 }
318 }
319 if (!exclusiv_bit_or) {
320 result++;
321 fprintf (stderr, format: "Error in EXCLUSIV BIT OR part 2\n");
322 }
323
324 return (result == 0);
325 free (ptr: logics);
326}
327
328int main()
329{
330 int i;
331 int num_failed=0;
332
333 for(i = 0; i < REPETITIONS; i++) {
334 if(!test_omp_for_reduction()) {
335 num_failed++;
336 }
337 }
338 return num_failed;
339}
340

source code of openmp/runtime/test/worksharing/for/omp_for_reduction.c