1 // RUN: %libomp-compile-and-run
2 #include <stdio.h>
3 #include <math.h>
4 #include "omp_testsuite.h"
5 
test_omp_parallel_sections_reduction()6 int 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,"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,"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(dt,i);
110       }
111     }
112     #pragma omp section
113     {
114       for (i=6;i<12;++i) {
115         dsum += pow(dt,i);
116       }
117     }
118     #pragma omp section
119     {
120       for (i=12;i<20;++i) {
121         dsum += pow(dt,i);
122       }
123     }
124   }
125   if( fabs(dsum-dknown_sum) > rounding_error ) {
126     result++;
127     fprintf(stderr,"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,"\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(dt,i);
145       }
146     }
147     #pragma omp section
148     {
149       for (i=6;i<12;++i) {
150         ddiff -= pow(dt,i);
151       }
152     }
153     #pragma omp section
154     {
155       for (i=12;i<20;++i) {
156         ddiff -= pow(dt,i);
157       }
158     }
159   }
160   if( fabs(ddiff) > rounding_error) {
161     result++;
162     fprintf(stderr,"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,"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,"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,"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,"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,"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,"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,"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,"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,"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,"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,"Error in EXCLUSIV BIT OR part 2\n");
491   }
492 
493   /*printf("\nResult:%d\n",result);*/
494   return (result==0);
495 }
496 
main()497 int 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