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_for_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 dt = 1./3.;
35 result = 0;
36 product = 1;
37 logic_and=1;
38 logic_or=0;
39 bit_and=1;
40 bit_or=0;
41 exclusiv_bit_or=0;
42
43 /* Tests for integers */
44 known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2;
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 if(known_sum!=sum) {
50 result++;
51 fprintf(stderr,format: "Error in sum with integers: Result was %d"
52 " 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 if(diff != 0) {
61 result++;
62 fprintf(stderr,format: "Error in difference with integers: Result was %d"
63 " 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 if( fabs(x: dsum-dknown_sum) > rounding_error ) {
78 result++;
79 fprintf(stderr,format: "Error in sum with doubles: Result was %f"
80 " instead of %f (Difference: %E)\n",
81 dsum, dknown_sum, dsum-dknown_sum);
82 }
83
84 dpt=1;
85
86 for (i=0;i<DOUBLE_DIGITS;++i) {
87 dpt*=dt;
88 }
89 fprintf(stderr,format: "\n");
90 ddiff = (1-dpt)/(1-dt);
91 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff)
92 for (i=0;i<DOUBLE_DIGITS;++i) {
93 ddiff -= pow(x: dt,y: i);
94 }
95 if( fabs(x: ddiff) > rounding_error) {
96 result++;
97 fprintf(stderr,format: "Error in Difference with doubles: Result was %E"
98 " instead of 0.0\n",ddiff);
99 }
100
101 /* Tests for integers */
102 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product)
103 for(i=1;i<=MAX_FACTOR;i++) {
104 product *= i;
105 }
106 known_product = KNOWN_PRODUCT;
107 if(known_product != product) {
108 result++;
109 fprintf(stderr,format: "Error in Product with integers: Result was %d"
110 " instead of %d\n\n",product,known_product);
111 }
112
113 /* Tests for logic AND */
114 for(i=0;i<LOOPCOUNT;i++) {
115 logics[i]=1;
116 }
117
118 #pragma omp parallel for schedule(dynamic,1) private(i) \
119 reduction(&&:logic_and)
120 for(i=0;i<LOOPCOUNT;++i) {
121 logic_and = (logic_and && logics[i]);
122 }
123 if(!logic_and) {
124 result++;
125 fprintf(stderr,format: "Error in logic AND part 1.\n");
126 }
127
128 logic_and = 1;
129 logics[LOOPCOUNT/2]=0;
130
131 #pragma omp parallel for schedule(dynamic,1) private(i) \
132 reduction(&&:logic_and)
133 for(i=0;i<LOOPCOUNT;++i) {
134 logic_and = logic_and && logics[i];
135 }
136 if(logic_and) {
137 result++;
138 fprintf(stderr,format: "Error in logic AND part 2.\n");
139 }
140
141 /* Tests for logic OR */
142 for(i=0;i<LOOPCOUNT;i++) {
143 logics[i]=0;
144 }
145
146 #pragma omp parallel for schedule(dynamic,1) private(i) \
147 reduction(||:logic_or)
148 for(i=0;i<LOOPCOUNT;++i) {
149 logic_or = logic_or || logics[i];
150 }
151 if(logic_or) {
152 result++;
153 fprintf(stderr,format: "Error in logic OR part 1.\n");
154 }
155 logic_or = 0;
156 logics[LOOPCOUNT/2]=1;
157
158 #pragma omp parallel for schedule(dynamic,1) private(i) \
159 reduction(||:logic_or)
160 for(i=0;i<LOOPCOUNT;++i) {
161 logic_or = logic_or || logics[i];
162 }
163 if(!logic_or) {
164 result++;
165 fprintf(stderr,format: "Error in logic OR part 2.\n");
166 }
167
168 /* Tests for bitwise AND */
169 for(i=0;i<LOOPCOUNT;++i) {
170 logics[i]=1;
171 }
172
173 #pragma omp parallel for schedule(dynamic,1) private(i) \
174 reduction(&:bit_and)
175 for(i=0;i<LOOPCOUNT;++i) {
176 bit_and = (bit_and & logics[i]);
177 }
178 if(!bit_and) {
179 result++;
180 fprintf(stderr,format: "Error in BIT AND part 1.\n");
181 }
182
183 bit_and = 1;
184 logics[LOOPCOUNT/2]=0;
185
186 #pragma omp parallel for schedule(dynamic,1) private(i) \
187 reduction(&:bit_and)
188 for(i=0;i<LOOPCOUNT;++i) {
189 bit_and = bit_and & logics[i];
190 }
191 if(bit_and) {
192 result++;
193 fprintf(stderr,format: "Error in BIT AND part 2.\n");
194 }
195
196 /* Tests for bitwise OR */
197 for(i=0;i<LOOPCOUNT;i++) {
198 logics[i]=0;
199 }
200
201 #pragma omp parallel for schedule(dynamic,1) private(i) \
202 reduction(|:bit_or)
203 for(i=0;i<LOOPCOUNT;++i) {
204 bit_or = bit_or | logics[i];
205 }
206 if(bit_or) {
207 result++;
208 fprintf(stderr,format: "Error in BIT OR part 1\n");
209 }
210 bit_or = 0;
211 logics[LOOPCOUNT/2]=1;
212
213 #pragma omp parallel for schedule(dynamic,1) private(i) \
214 reduction(|:bit_or)
215 for(i=0;i<LOOPCOUNT;++i) {
216 bit_or = bit_or | logics[i];
217 }
218 if(!bit_or) {
219 result++;
220 fprintf(stderr,format: "Error in BIT OR part 2\n");
221 }
222
223 /* Tests for bitwise XOR */
224 for(i=0;i<LOOPCOUNT;i++) {
225 logics[i]=0;
226 }
227
228 #pragma omp parallel for schedule(dynamic,1) private(i) \
229 reduction(^:exclusiv_bit_or)
230 for(i=0;i<LOOPCOUNT;++i) {
231 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
232 }
233 if(exclusiv_bit_or) {
234 result++;
235 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 1\n");
236 }
237
238 exclusiv_bit_or = 0;
239 logics[LOOPCOUNT/2]=1;
240
241 #pragma omp parallel for schedule(dynamic,1) private(i) \
242 reduction(^:exclusiv_bit_or)
243 for(i=0;i<LOOPCOUNT;++i) {
244 exclusiv_bit_or = exclusiv_bit_or ^ logics[i];
245 }
246 if(!exclusiv_bit_or) {
247 result++;
248 fprintf(stderr,format: "Error in EXCLUSIV BIT OR part 2\n");
249 }
250
251 /*printf("\nResult:%d\n",result);*/
252 return (result==0);
253}
254
255int main()
256{
257 int i;
258 int num_failed=0;
259
260 for(i = 0; i < REPETITIONS; i++) {
261 if(!test_omp_parallel_for_reduction()) {
262 num_failed++;
263 }
264 }
265 return num_failed;
266}
267

source code of openmp/runtime/test/worksharing/for/omp_parallel_for_reduction.c