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