blob: 6dd191711d3447efaaab3655ea8be75c3968797d [file] [log] [blame]
Jim Cownie18d84732014-05-10 17:02:09 +00001<ompts:test>
2<ompts:testdescription>Test which checks the omp for reduction directive wich all its options.</ompts:testdescription>
3<ompts:ompversion>2.0</ompts:ompversion>
4<ompts:directive>omp for reduction</ompts:directive>
5<ompts:testcode>
6#include <stdio.h>
7#include <stdlib.h>
8#include <math.h>
9
10#include "omp_testsuite.h"
11
12
13int <ompts:testcode:functionname>omp_for_reduction</ompts:testcode:functionname> (FILE * logFile)
14{
15 <ompts:orphan:vars>
16 double dt;
17 int sum;
18 int diff;
19 int product = 1;
20 double dsum;
21 double dknown_sum;
22 double ddiff;
23 int logic_and;
24 int logic_or;
25 int bit_and;
26 int bit_or;
27 int exclusiv_bit_or;
28 int *logics;
29 </ompts:orphan:vars>
30
31#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
32#define MAX_FACTOR 10
33#define KNOWN_PRODUCT 3628800 /* 10! */
34
35 int i;
36 int known_sum;
37 int known_product;
38 double rounding_error = 1.E-9; /* over all rounding error to be ignored in the double tests */
39 double dpt;
40 int result = 0;
41 int logicsArray[LOOPCOUNT];
42
43 /* Variables for integer tests */
44 sum = 0;
45 product = 1;
46 known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
47 /* variabels for double tests */
48 dt = 1. / 3.; /* base of geometric row for + and - test*/
49 dsum = 0.;
50 /* Variabeles for logic tests */
51 logics = logicsArray;
52 logic_and = 1;
53 logic_or = 0;
54 /* Variabeles for bit operators tests */
55 bit_and = 1;
56 bit_or = 0;
57 /* Variables for exclusiv bit or */
58 exclusiv_bit_or = 0;
59
60
61/****************************************************************************/
62/** Tests for integers **/
63/****************************************************************************/
64
65
66/**** Testing integer addition ****/
67
68#pragma omp parallel
69 {
70 <ompts:orphan>
71 int j;
72#pragma omp for schedule(dynamic,1) <ompts:check>reduction(+:sum)</ompts:check><ompts:crosscheck></ompts:crosscheck>
73 for (j = 1; j <= LOOPCOUNT; j++)
74 {
75 sum = sum + j;
76 }
77 </ompts:orphan>
78 }
79
80 if (known_sum != sum) {
81 result++;
82 fprintf (logFile, "Error in sum with integers: Result was %d instead of %d.\n", sum, known_sum);
83 }
84
85
86/**** Testing integer subtracton ****/
87
88 diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
89#pragma omp parallel
90 {
91 <ompts:orphan>
92 int j;
93#pragma omp for schedule(dynamic,1) <ompts:check>reduction(-:diff)</ompts:check><ompts:crosscheck></ompts:crosscheck>
94 for (j = 1; j <= LOOPCOUNT; j++)
95 {
96 diff = diff - j;
97 }
98 </ompts:orphan>
99 }
100
101 if (diff != 0) {
102 result++;
103 fprintf (logFile, "Error in difference with integers: Result was %d instead of 0.\n", diff);
104 }
105
106
107/**** Testing integer multiplication ****/
108
109#pragma omp parallel
110 {
111 <ompts:orphan>
112 int j;
113#pragma omp for schedule(dynamic,1) <ompts:check>reduction(*:product)</ompts:check><ompts:crosscheck></ompts:crosscheck>
114 for (j = 1; j <= MAX_FACTOR; j++)
115 {
116 product *= j;
117 }
118 </ompts:orphan>
119 }
120
121 known_product = KNOWN_PRODUCT;
122 if(known_product != product)
123 {
124 result++;
125 fprintf (logFile,"Error in Product with integers: Result was %d instead of %d\n",product,known_product);
126 }
127
128
129/****************************************************************************/
130/** Tests for doubles **/
131/****************************************************************************/
132
133
134/**** Testing double addition ****/
135
136 dsum = 0.;
137 dpt = 1.;
138
139 for (i = 0; i < DOUBLE_DIGITS; ++i)
140 {
141 dpt *= dt;
142 }
143 dknown_sum = (1 - dpt) / (1 - dt);
144
145#pragma omp parallel
146 {
147 <ompts:orphan>
148 int j;
149#pragma omp for schedule(dynamic,1) <ompts:check>reduction(+:dsum)</ompts:check>
150 for (j = 0; j < DOUBLE_DIGITS; j++)
151 {
152 dsum += pow (dt, j);
153 }
154 </ompts:orphan>
155 }
156
157 if (fabs (dsum - dknown_sum) > rounding_error) {
158 result++;
159 fprintf (logFile, "\nError in sum with doubles: Result was %f instead of: %f (Difference: %E)\n", dsum, dknown_sum, dsum-dknown_sum);
160 }
161
162#if 0
163 dpt = 1.;
164 for (i = 0; i < DOUBLE_DIGITS; ++i)
165 {
166 dpt *= dt;
167 }
168#endif
169
170
171/**** Testing double subtraction ****/
172
173 ddiff = (1 - dpt) / (1 - dt);
174
175#pragma omp parallel
176 {
177 <ompts:orphan>
178 int j;
179#pragma omp for schedule(dynamic,1) <ompts:check>reduction(-:ddiff)</ompts:check>
180 for (j = 0; j < DOUBLE_DIGITS; ++j)
181 {
182 ddiff -= pow (dt, j);
183 }
184 </ompts:orphan>
185 }
186
187 if (fabs (ddiff) > rounding_error) {
188 result++;
189 fprintf (logFile, "Error in Difference with doubles: Result was %E instead of 0.0\n", ddiff);
190 }
191
192
193/****************************************************************************/
194/** Tests for logical values **/
195/****************************************************************************/
196
197
198/**** Testing logic and ****/
199
200 for (i = 0; i < LOOPCOUNT; i++)
201 {
202 logics[i] = 1;
203 }
204
205#pragma omp parallel
206 {
207 <ompts:orphan>
208 int j;
209#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&&:logic_and)</ompts:check>
210 for (j = 0; j < LOOPCOUNT; ++j)
211 {
212 logic_and = (logic_and && logics[j]);
213 }
214 </ompts:orphan>
215 }
216
217 if(!logic_and) {
218 result++;
219 fprintf (logFile, "Error in logic AND part 1\n");
220 }
221
222 logic_and = 1;
223 logics[LOOPCOUNT / 2] = 0;
224
225#pragma omp parallel
226 {
227 <ompts:orphan>
228 int j;
229#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&&:logic_and)</ompts:check><ompts:crosscheck></ompts:crosscheck>
230 for (j = 0; j < LOOPCOUNT; ++j)
231 {
232 logic_and = logic_and && logics[j];
233 }
234 </ompts:orphan>
235 }
236
237 if(logic_and) {
238 result++;
239 fprintf (logFile, "Error in logic AND part 2\n");
240 }
241
242
243/**** Testing logic or ****/
244
245 for (i = 0; i < LOOPCOUNT; i++)
246 {
247 logics[i] = 0;
248 }
249
250#pragma omp parallel
251 {
252 <ompts:orphan>
253 int j;
254#pragma omp for schedule(dynamic,1) <ompts:check>reduction(||:logic_or) </ompts:check>
255 for (j = 0; j < LOOPCOUNT; ++j)
256 {
257 logic_or = logic_or || logics[j];
258 }
259 </ompts:orphan>
260 }
261
262 if (logic_or) {
263 result++;
264 fprintf (logFile, "Error in logic OR part 1\n");
265 }
266
267 logic_or = 0;
268 logics[LOOPCOUNT / 2] = 1;
269
270#pragma omp parallel
271 {
272 <ompts:orphan>
273 int j;
274#pragma omp for schedule(dynamic,1) <ompts:check>reduction(||:logic_or)</ompts:check>
275 for (j = 0; j < LOOPCOUNT; ++j)
276 {
277 logic_or = logic_or || logics[j];
278 }
279 </ompts:orphan>
280 }
281
282 if(!logic_or) {
283 result++;
284 fprintf (logFile, "Error in logic OR part 2\n");
285 }
286
287
288/****************************************************************************/
289/** Tests for bit values **/
290/****************************************************************************/
291
292
293/**** Testing bit and ****/
294
295 for (i = 0; i < LOOPCOUNT; ++i)
296 {
297 logics[i] = 1;
298 }
299
300#pragma omp parallel
301 {
302 <ompts:orphan>
303 int j;
304#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&:bit_and) </ompts:check>
305 for (j = 0; j < LOOPCOUNT; ++j)
306 {
307 bit_and = (bit_and & logics[j]);
308 }
309 </ompts:orphan>
310 }
311
312 if (!bit_and) {
313 result++;
314 fprintf (logFile, "Error in BIT AND part 1\n");
315 }
316
317 bit_and = 1;
318 logics[LOOPCOUNT / 2] = 0;
319
320#pragma omp parallel
321 {
322 <ompts:orphan>
323 int j;
324#pragma omp for schedule(dynamic,1) <ompts:check>reduction(&:bit_and)</ompts:check>
325 for (j = 0; j < LOOPCOUNT; ++j)
326 {
327 bit_and = bit_and & logics[j];
328 }
329 </ompts:orphan>
330 }
331 if (bit_and) {
332 result++;
333 fprintf (logFile, "Error in BIT AND part 2\n");
334 }
335
336
337/**** Testing bit or ****/
338
339 for (i = 0; i < LOOPCOUNT; i++)
340 {
341 logics[i] = 0;
342 }
343
344#pragma omp parallel
345 {
346 <ompts:orphan>
347 int j;
348#pragma omp for schedule(dynamic,1) <ompts:check>reduction(|:bit_or)</ompts:check>
349 for (j = 0; j < LOOPCOUNT; ++j)
350 {
351 bit_or = bit_or | logics[j];
352 }
353 </ompts:orphan>
354 }
355
356 if (bit_or) {
357 result++;
358 fprintf (logFile, "Error in BIT OR part 1\n");
359 }
360
361 bit_or = 0;
362 logics[LOOPCOUNT / 2] = 1;
363
364#pragma omp parallel
365 {
366 <ompts:orphan>
367 int j;
368#pragma omp for schedule(dynamic,1) <ompts:check>reduction(|:bit_or)</ompts:check>
369 for (j = 0; j < LOOPCOUNT; ++j)
370 {
371 bit_or = bit_or | logics[j];
372 }
373 </ompts:orphan>
374 }
375 if (!bit_or) {
376 result++;
377 fprintf (logFile, "Error in BIT OR part 2\n");
378 }
379
380
381/**** Testing exclusive bit or ****/
382
383 for (i = 0; i < LOOPCOUNT; i++)
384 {
385 logics[i] = 0;
386 }
387
388#pragma omp parallel
389 {
390 <ompts:orphan>
391 int j;
392#pragma omp for schedule(dynamic,1) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check>
393 for (j = 0; j < LOOPCOUNT; ++j)
394 {
395 exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
396 }
397 </ompts:orphan>
398 }
399 if (exclusiv_bit_or) {
400 result++;
401 fprintf (logFile, "Error in EXCLUSIV BIT OR part 1\n");
402 }
403
404 exclusiv_bit_or = 0;
405 logics[LOOPCOUNT / 2] = 1;
406
407#pragma omp parallel
408 {
409 <ompts:orphan>
410 int j;
411#pragma omp for schedule(dynamic,1) <ompts:check>reduction(^:exclusiv_bit_or)</ompts:check>
412 for (j = 0; j < LOOPCOUNT; ++j)
413 {
414 exclusiv_bit_or = exclusiv_bit_or ^ logics[j];
415 }
416 </ompts:orphan>
417 }
418 if (!exclusiv_bit_or) {
419 result++;
420 fprintf (logFile, "Error in EXCLUSIV BIT OR part 2\n");
421 }
422
423 /*fprintf ("\nResult:%d\n", result);*/
424 return (result == 0);
425
426 free (logics);
427}
428</ompts:testcode>
429</ompts:test>