1// RUN: %libomp-compile-and-run
2#include <stdio.h>
3#include <math.h>
4#include "omp_testsuite.h"
5
6#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
7#define MAX_FACTOR 10
8#define KNOWN_PRODUCT 3628800 /* 10! */
9
10int test_omp_parallel_reduction()
11{
12 int sum;
13 int known_sum;
14 double dsum;
15 double dknown_sum;
16 double dt=0.5; /* base of geometric row for + and - test*/
17 double rounding_error= 1.E-9;
18 int diff;
19 double ddiff;
20 int product;
21 int known_product;
22 int logic_and;
23 int logic_or;
24 int bit_and;
25 int bit_or;
26 int exclusiv_bit_or;
27 int logics[LOOPCOUNT];
28 int i;
29 double dpt;
30 int result;
31
32 sum =0;
33 dsum=0;
34 product=1;
35 logic_and=1;
36 logic_or=0;
37 bit_and=1;
38 bit_or=0;
39 exclusiv_bit_or=0;
40 result=0;
41 dt = 1./3.;
42 known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
43
44 /* Tests for integers */
45 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:sum)
46 for (i=1;i<=LOOPCOUNT;i++) {
47 sum=sum+i;
48 }
49
50 if(known_sum!=sum) {
51 result++;
52 fprintf(stderr,format: "Error in sum with integers: Result was %d instead of %d\n",sum,known_sum);
53 }
54
55 diff = (LOOPCOUNT*(LOOPCOUNT+1))/2;
56 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:diff)
57 for (i=1;i<=LOOPCOUNT;++i) {
58 diff=diff-i;
59 }
60
61 if(diff != 0) {
62 result++;
63 fprintf(stderr,format: "Error in difference with integers: Result was %d instead of 0.\n",diff);
64 }
65
66 /* Tests for doubles */
67 dsum=0;
68 dpt=1;
69 for (i=0;i<DOUBLE_DIGITS;++i) {
70 dpt*=dt;
71 }
72 dknown_sum = (1-dpt)/(1-dt);
73 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:dsum)
74 for (i=0;i<DOUBLE_DIGITS;++i) {
75 dsum += pow(x: dt,y: i);
76 }
77
78 if( fabs(x: dsum-dknown_sum) > rounding_error ) {
79 result++;
80 fprintf(stderr,format: "Error in sum with doubles: Result was %f instead of %f (Difference: %E)\n",dsum,dknown_sum, dsum-dknown_sum);
81 }
82
83 dpt=1;
84
85 for (i=0;i<DOUBLE_DIGITS;++i) {
86 dpt*=dt;
87 }
88 fprintf(stderr,format: "\n");
89 ddiff = (1-dpt)/(1-dt);
90 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff)
91 for (i=0;i<DOUBLE_DIGITS;++i) {
92 ddiff -= pow(x: dt,y: i);
93 }
94 if( fabs(x: ddiff) > rounding_error) {
95 result++;
96 fprintf(stderr,format: "Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff);
97 }
98
99 /* Tests for product of integers */
100 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product)
101 for(i=1;i<=MAX_FACTOR;i++) {
102 product *= i;
103 }
104
105 known_product = KNOWN_PRODUCT;
106 if(known_product != product) {
107 result++;
108 fprintf(stderr,format: "Error in Product with integers: Result was %d instead of %d\n\n",product,known_product);
109 }
110
111 /* Tests for logical and */
112 for(i=0;i<LOOPCOUNT;i++) {
113 logics[i]=1;
114 }
115
116 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and)
117 for(i=0;i<LOOPCOUNT;++i) {
118 logic_and = (logic_and && logics[i]);
119 }
120 if(!logic_and) {
121 result++;
122 fprintf(stderr,format: "Error in logic AND part 1.\n");
123 }
124
125 logic_and = 1;
126 logics[LOOPCOUNT/2]=0;
127
128 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and)
129 for(i=0;i<LOOPCOUNT;++i) {
130 logic_and = logic_and && logics[i];
131 }
132 if(logic_and) {
133 result++;
134 fprintf(stderr,format: "Error in logic AND part 2.\n");
135 }
136
137 /* Tests for logical or */
138 for(i=0;i<LOOPCOUNT;i++) {
139 logics[i]=0;
140 }
141
142 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or)
143 for(i=0;i<LOOPCOUNT;++i) {
144 logic_or = logic_or || logics[i];
145 }
146 if(logic_or) {
147 result++;
148 fprintf(stderr,format: "Error in logic OR part 1.\n");
149 }
150 logic_or = 0;
151 logics[LOOPCOUNT/2]=1;
152
153 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or)
154 for(i=0;i<LOOPCOUNT;++i) {
155 logic_or = logic_or || logics[i];
156 }
157 if(!logic_or) {
158 result++;
159 fprintf(stderr,format: "Error in logic OR part 2.\n");
160 }
161
162 /* Tests for bitwise and */
163 for(i=0;i<LOOPCOUNT;++i) {
164 logics[i]=1;
165 }
166
167 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and)
168 for(i=0;i<LOOPCOUNT;++i) {
169 bit_and = (bit_and & logics[i]);
170 }
171 if(!bit_and) {
172 result++;
173 fprintf(stderr,format: "Error in BIT AND part 1.\n");
174 }
175
176 bit_and = 1;
177 logics[LOOPCOUNT/2]=0;
178
179 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and)
180 for(i=0;i<LOOPCOUNT;++i) {
181 bit_and = bit_and & logics[i];
182 }
183 if(bit_and) {
184 result++;
185 fprintf(stderr,format: "Error in BIT AND part 2.\n");
186 }
187
188 for(i=0;i<LOOPCOUNT;i++) {
189 logics[i]=0;
190 }
191
192 /* Tests for bitwise or */
193 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or)
194 for(i=0;i<LOOPCOUNT;++i) {
195 bit_or = bit_or | logics[i];
196 }
197 if(bit_or) {
198 result++;
199 fprintf(stderr,format: "Error in BIT OR part 1\n");
200 }
201 bit_or = 0;
202 logics[LOOPCOUNT/2]=1;
203
204 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or)
205 for(i=0;i<LOOPCOUNT;++i) {
206 bit_or = bit_or | logics[i];
207 }
208 if(!bit_or) {
209 result++;
210 fprintf(stderr,format: "Error in BIT OR part 2\n");
211 }
212
213 for(i=0;i<LOOPCOUNT;i++) {
214 logics[i]=0;
215 }
216
217 /* Tests for bitwise xor */
218 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or)
219 for(i=0;i<LOOPCOUNT;++i) {
220 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
221 }
222 if(exclusiv_bit_or) {
223 result++;
224 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 1\n");
225 }
226
227 exclusiv_bit_or = 0;
228 logics[LOOPCOUNT/2]=1;
229
230 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or)
231 for(i=0;i<LOOPCOUNT;++i) {
232 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
233 }
234 if(!exclusiv_bit_or) {
235 result++;
236 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 2\n");
237 }
238
239 /*printf("\nResult:%d\n",result);*/
240 return (result==0);
241}
242
243int main()
244{
245 int i;
246 int num_failed=0;
247
248 for(i = 0; i < REPETITIONS; i++) {
249 if(!test_omp_parallel_reduction()) {
250 num_failed++;
251 }
252 }
253 return num_failed;
254}
255

source code of openmp/runtime/test/parallel/omp_parallel_reduction.c