1// RUN: %libomp-compile-and-run
2#include <stdio.h>
3#include <math.h>
4#include "omp_testsuite.h"
5
6int test_omp_parallel_sections_reduction()
7{
8 int sum;
9 int known_sum;
10 double dpt;
11 double dsum;
12 double dknown_sum;
13 double dt=0.5; /* base of geometric row for + and - test*/
14 double rounding_error= 1.E-5;
15 int diff;
16 double ddiff;
17 int product;
18 int known_product;
19 int logic_and;
20 int bit_and;
21 int logic_or;
22 int bit_or;
23 int exclusiv_bit_or;
24 int logics[1000];
25 int i;
26 int result;
27
28 sum = 7;
29 dsum=0;
30 product =1;
31 dpt = 1;
32 logic_and=1;
33 bit_and=1;
34 logic_or=0;
35 bit_or=0;
36 exclusiv_bit_or=0;
37 result =0;
38 /* int my_islarger;*/
39 /*int is_larger=1;*/
40
41 // Test summation of integers
42 known_sum = (999*1000)/2+7;
43 #pragma omp parallel sections private(i) reduction(+:sum)
44 {
45 #pragma omp section
46 {
47 for (i=1;i<300;i++) {
48 sum=sum+i;
49 }
50 }
51 #pragma omp section
52 {
53 for (i=300;i<700;i++) {
54 sum=sum+i;
55 }
56 }
57 #pragma omp section
58 {
59 for (i=700;i<1000;i++) {
60 sum=sum+i;
61 }
62 }
63 }
64 if(known_sum!=sum) {
65 result++;
66 fprintf(stderr,format: "Error in sum with integers: Result was %d"
67 " instead of %d.\n",sum, known_sum);
68 }
69
70 // Test differences of integers
71 diff = (999*1000)/2;
72 #pragma omp parallel sections private(i) reduction(-:diff)
73 {
74 #pragma omp section
75 {
76 for (i=1;i<300;i++) {
77 diff=diff-i;
78 }
79 }
80 #pragma omp section
81 {
82 for (i=300;i<700;i++) {
83 diff=diff-i;
84 }
85 }
86 #pragma omp section
87 {
88 for (i=700;i<1000;i++) {
89 diff=diff-i;
90 }
91 }
92 }
93 if(diff != 0) {
94 result++;
95 fprintf(stderr,format: "Error in Difference with integers: Result was %d"
96 " instead of 0.\n",diff);
97 }
98
99 // Test summation of doubles
100 for (i=0;i<20;++i) {
101 dpt*=dt;
102 }
103 dknown_sum = (1-dpt)/(1-dt);
104 #pragma omp parallel sections private(i) reduction(+:dsum)
105 {
106 #pragma omp section
107 {
108 for (i=0;i<6;++i) {
109 dsum += pow(x: dt,y: i);
110 }
111 }
112 #pragma omp section
113 {
114 for (i=6;i<12;++i) {
115 dsum += pow(x: dt,y: i);
116 }
117 }
118 #pragma omp section
119 {
120 for (i=12;i<20;++i) {
121 dsum += pow(x: dt,y: i);
122 }
123 }
124 }
125 if( fabs(x: dsum-dknown_sum) > rounding_error ) {
126 result++;
127 fprintf(stderr,format: "Error in sum with doubles: Result was %f"
128 " instead of %f (Difference: %E)\n",
129 dsum, dknown_sum, dsum-dknown_sum);
130 }
131
132 // Test differences of doubles
133 dpt=1;
134 for (i=0;i<20;++i) {
135 dpt*=dt;
136 }
137 fprintf(stderr,format: "\n");
138 ddiff = (1-dpt)/(1-dt);
139 #pragma omp parallel sections private(i) reduction(-:ddiff)
140 {
141 #pragma omp section
142 {
143 for (i=0;i<6;++i) {
144 ddiff -= pow(x: dt,y: i);
145 }
146 }
147 #pragma omp section
148 {
149 for (i=6;i<12;++i) {
150 ddiff -= pow(x: dt,y: i);
151 }
152 }
153 #pragma omp section
154 {
155 for (i=12;i<20;++i) {
156 ddiff -= pow(x: dt,y: i);
157 }
158 }
159 }
160 if( fabs(x: ddiff) > rounding_error) {
161 result++;
162 fprintf(stderr,format: "Error in Difference with doubles: Result was %E"
163 " instead of 0.0\n",ddiff);
164 }
165
166 // Test product of integers
167 known_product = 3628800;
168 #pragma omp parallel sections private(i) reduction(*:product)
169 {
170 #pragma omp section
171 {
172 for(i=1;i<3;i++) {
173 product *= i;
174 }
175 }
176 #pragma omp section
177 {
178 for(i=3;i<7;i++) {
179 product *= i;
180 }
181 }
182 #pragma omp section
183 {
184 for(i=7;i<11;i++) {
185 product *= i;
186 }
187 }
188 }
189 if(known_product != product) {
190 result++;
191 fprintf(stderr,format: "Error in Product with integers: Result was %d"
192 " instead of %d\n",product,known_product);
193 }
194
195 // Test logical AND
196 for(i=0;i<1000;i++) {
197 logics[i]=1;
198 }
199
200 #pragma omp parallel sections private(i) reduction(&&:logic_and)
201 {
202 #pragma omp section
203 {
204 for (i=1;i<300;i++) {
205 logic_and = (logic_and && logics[i]);
206 }
207 }
208 #pragma omp section
209 {
210 for (i=300;i<700;i++) {
211 logic_and = (logic_and && logics[i]);
212 }
213 }
214 #pragma omp section
215 {
216 for (i=700;i<1000;i++) {
217 logic_and = (logic_and && logics[i]);
218 }
219 }
220 }
221 if(!logic_and) {
222 result++;
223 fprintf(stderr,format: "Error in logic AND part 1\n");
224 }
225 logic_and = 1;
226 logics[501] = 0;
227
228 #pragma omp parallel sections private(i) reduction(&&:logic_and)
229 {
230 #pragma omp section
231 {
232 for (i=1;i<300;i++) {
233 logic_and = (logic_and && logics[i]);
234 }
235 }
236 #pragma omp section
237 {
238 for (i=300;i<700;i++) {
239 logic_and = (logic_and && logics[i]);
240 }
241 }
242 #pragma omp section
243 {
244 for (i=700;i<1000;i++) {
245 logic_and = (logic_and && logics[i]);
246 }
247 }
248 }
249 if(logic_and) {
250 result++;
251 fprintf(stderr,format: "Error in logic AND part 2");
252 }
253
254 // Test logical OR
255 for(i=0;i<1000;i++) {
256 logics[i]=0;
257 }
258
259 #pragma omp parallel sections private(i) reduction(||:logic_or)
260 {
261 #pragma omp section
262 {
263 for (i=1;i<300;i++) {
264 logic_or = (logic_or || logics[i]);
265 }
266 }
267 #pragma omp section
268 {
269 for (i=300;i<700;i++) {
270 logic_or = (logic_or || logics[i]);
271 }
272 }
273 #pragma omp section
274 {
275 for (i=700;i<1000;i++) {
276 logic_or = (logic_or || logics[i]);
277 }
278 }
279 }
280 if(logic_or) {
281 result++;
282 fprintf(stderr,format: "Error in logic OR part 1\n");
283 }
284
285 logic_or = 0;
286 logics[501]=1;
287
288 #pragma omp parallel sections private(i) reduction(||:logic_or)
289 {
290 #pragma omp section
291 {
292 for (i=1;i<300;i++) {
293 logic_or = (logic_or || logics[i]);
294 }
295 }
296 #pragma omp section
297 {
298 for (i=300;i<700;i++) {
299 logic_or = (logic_or || logics[i]);
300 }
301 }
302 #pragma omp section
303 {
304 for (i=700;i<1000;i++) {
305 logic_or = (logic_or || logics[i]);
306 }
307 }
308 }
309 if(!logic_or) {
310 result++;
311 fprintf(stderr,format: "Error in logic OR part 2\n");
312 }
313
314 // Test bitwise AND
315 for(i=0;i<1000;++i) {
316 logics[i]=1;
317 }
318
319 #pragma omp parallel sections private(i) reduction(&:bit_and)
320 {
321 #pragma omp section
322 {
323 for(i=0;i<300;++i) {
324 bit_and = (bit_and & logics[i]);
325 }
326 }
327 #pragma omp section
328 {
329 for(i=300;i<700;++i) {
330 bit_and = (bit_and & logics[i]);
331 }
332 }
333 #pragma omp section
334 {
335 for(i=700;i<1000;++i) {
336 bit_and = (bit_and & logics[i]);
337 }
338 }
339 }
340 if(!bit_and) {
341 result++;
342 fprintf(stderr,format: "Error in BIT AND part 1\n");
343 }
344
345 bit_and = 1;
346 logics[501]=0;
347
348 #pragma omp parallel sections private(i) reduction(&:bit_and)
349 {
350 #pragma omp section
351 {
352 for(i=0;i<300;++i) {
353 bit_and = bit_and & logics[i];
354 }
355 }
356 #pragma omp section
357 {
358 for(i=300;i<700;++i) {
359 bit_and = bit_and & logics[i];
360 }
361 }
362 #pragma omp section
363 {
364 for(i=700;i<1000;++i) {
365 bit_and = bit_and & logics[i];
366 }
367 }
368 }
369 if(bit_and) {
370 result++;
371 fprintf(stderr,format: "Error in BIT AND part 2");
372 }
373
374 // Test bitwise OR
375 for(i=0;i<1000;i++) {
376 logics[i]=0;
377 }
378
379 #pragma omp parallel sections private(i) reduction(|:bit_or)
380 {
381 #pragma omp section
382 {
383 for(i=0;i<300;++i) {
384 bit_or = bit_or | logics[i];
385 }
386 }
387 #pragma omp section
388 {
389 for(i=300;i<700;++i) {
390 bit_or = bit_or | logics[i];
391 }
392 }
393 #pragma omp section
394 {
395 for(i=700;i<1000;++i) {
396 bit_or = bit_or | logics[i];
397 }
398 }
399 }
400 if(bit_or) {
401 result++;
402 fprintf(stderr,format: "Error in BIT OR part 1\n");
403 }
404 bit_or = 0;
405 logics[501]=1;
406
407 #pragma omp parallel sections private(i) reduction(|:bit_or)
408 {
409 #pragma omp section
410 {
411 for(i=0;i<300;++i) {
412 bit_or = bit_or | logics[i];
413 }
414 }
415 #pragma omp section
416 {
417 for(i=300;i<700;++i) {
418 bit_or = bit_or | logics[i];
419 }
420 }
421 #pragma omp section
422 {
423 for(i=700;i<1000;++i) {
424 bit_or = bit_or | logics[i];
425 }
426 }
427 }
428 if(!bit_or) {
429 result++;
430 fprintf(stderr,format: "Error in BIT OR part 2\n");
431 }
432
433 // Test bitwise XOR
434 for(i=0;i<1000;i++) {
435 logics[i]=0;
436 }
437
438 #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or)
439 {
440 #pragma omp section
441 {
442 for(i=0;i<300;++i) {
443 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
444 }
445 }
446 #pragma omp section
447 {
448 for(i=300;i<700;++i) {
449 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
450 }
451 }
452 #pragma omp section
453 {
454 for(i=700;i<1000;++i) {
455 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
456 }
457 }
458 }
459 if(exclusiv_bit_or) {
460 result++;
461 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 1\n");
462 }
463
464 exclusiv_bit_or = 0;
465 logics[501]=1;
466
467 #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or)
468 {
469 #pragma omp section
470 {
471 for(i=0;i<300;++i) {
472 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
473 }
474 }
475 #pragma omp section
476 {
477 for(i=300;i<700;++i) {
478 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
479 }
480 }
481 #pragma omp section
482 {
483 for(i=700;i<1000;++i) {
484 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
485 }
486 }
487 }
488 if(!exclusiv_bit_or) {
489 result++;
490 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 2\n");
491 }
492
493 /*printf("\nResult:%d\n",result);*/
494 return (result==0);
495}
496
497int main()
498{
499 int i;
500 int num_failed=0;
501
502 for(i = 0; i < REPETITIONS; i++) {
503 if(!test_omp_parallel_sections_reduction()) {
504 num_failed++;
505 }
506 }
507 return num_failed;
508}
509

source code of openmp/runtime/test/worksharing/sections/omp_parallel_sections_reduction.c