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 | |
10 | int test_omp_atomic() |
11 | { |
12 | int sum; |
13 | int diff; |
14 | double dsum = 0; |
15 | double dt = 0.5; /* base of geometric row for + and - test*/ |
16 | double ddiff; |
17 | int product; |
18 | int x; |
19 | int *logics; |
20 | int bit_and = 1; |
21 | int bit_or = 0; |
22 | int exclusiv_bit_or = 0; |
23 | int j; |
24 | int known_sum; |
25 | int known_diff; |
26 | int known_product; |
27 | int result = 0; |
28 | int logic_and = 1; |
29 | int logic_or = 0; |
30 | double dknown_sum; |
31 | double rounding_error = 1.E-9; |
32 | double dpt, div; |
33 | int logicsArray[LOOPCOUNT]; |
34 | logics = logicsArray; |
35 | |
36 | sum = 0; |
37 | diff = 0; |
38 | product = 1; |
39 | |
40 | // sum of integers test |
41 | #pragma omp parallel |
42 | { |
43 | int i; |
44 | #pragma omp for |
45 | for (i = 1; i <= LOOPCOUNT; i++) { |
46 | #pragma omp atomic |
47 | sum += i; |
48 | } |
49 | |
50 | } |
51 | known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2; |
52 | if (known_sum != sum) |
53 | { |
54 | fprintf(stderr, |
55 | format: "Error in sum with integers: Result was %d instead of %d.\n" , |
56 | sum, known_sum); |
57 | result++; |
58 | } |
59 | |
60 | // difference of integers test |
61 | #pragma omp parallel |
62 | { |
63 | int i; |
64 | #pragma omp for |
65 | for (i = 0; i < LOOPCOUNT; i++) { |
66 | #pragma omp atomic |
67 | diff -= i; |
68 | } |
69 | } |
70 | known_diff = ((LOOPCOUNT - 1) * LOOPCOUNT) / 2 * -1; |
71 | if (diff != known_diff) |
72 | { |
73 | fprintf (stderr, |
74 | format: "Error in difference with integers: Result was %d instead of 0.\n" , |
75 | diff); |
76 | result++; |
77 | } |
78 | |
79 | // sum of doubles test |
80 | dsum = 0; |
81 | dpt = 1; |
82 | for (j = 0; j < DOUBLE_DIGITS; ++j) { |
83 | dpt *= dt; |
84 | } |
85 | dknown_sum = (1 - dpt) / (1 -dt); |
86 | #pragma omp parallel |
87 | { |
88 | int i; |
89 | #pragma omp for |
90 | for (i = 0; i < DOUBLE_DIGITS; ++i) { |
91 | #pragma omp atomic |
92 | dsum += pow (x: dt, y: i); |
93 | } |
94 | } |
95 | if (dsum != dknown_sum && (fabs (x: dsum - dknown_sum) > rounding_error)) { |
96 | fprintf (stderr, format: "Error in sum with doubles: Result was %f" |
97 | " instead of: %f (Difference: %E)\n" , |
98 | dsum, dknown_sum, dsum - dknown_sum); |
99 | result++; |
100 | } |
101 | |
102 | // difference of doubles test |
103 | dpt = 1; |
104 | for (j = 0; j < DOUBLE_DIGITS; ++j) { |
105 | dpt *= dt; |
106 | } |
107 | ddiff = (1 - dpt) / (1 - dt); |
108 | #pragma omp parallel |
109 | { |
110 | int i; |
111 | #pragma omp for |
112 | for (i = 0; i < DOUBLE_DIGITS; ++i) { |
113 | #pragma omp atomic |
114 | ddiff -= pow (x: dt, y: i); |
115 | } |
116 | } |
117 | if (fabs (x: ddiff) > rounding_error) { |
118 | fprintf (stderr, |
119 | format: "Error in difference with doubles: Result was %E instead of 0.0\n" , |
120 | ddiff); |
121 | result++; |
122 | } |
123 | |
124 | // product of integers test |
125 | #pragma omp parallel |
126 | { |
127 | int i; |
128 | #pragma omp for |
129 | for (i = 1; i <= MAX_FACTOR; i++) { |
130 | #pragma omp atomic |
131 | product *= i; |
132 | } |
133 | } |
134 | known_product = KNOWN_PRODUCT; |
135 | if (known_product != product) { |
136 | fprintf (stderr, |
137 | format: "Error in product with integers: Result was %d instead of %d\n" , |
138 | product, known_product); |
139 | result++; |
140 | } |
141 | |
142 | // division of integers test |
143 | product = KNOWN_PRODUCT; |
144 | #pragma omp parallel |
145 | { |
146 | int i; |
147 | #pragma omp for |
148 | for (i = 1; i <= MAX_FACTOR; ++i) { |
149 | #pragma omp atomic |
150 | product /= i; |
151 | } |
152 | } |
153 | if (product != 1) { |
154 | fprintf (stderr, |
155 | format: "Error in product division with integers: Result was %d" |
156 | " instead of 1\n" , |
157 | product); |
158 | result++; |
159 | } |
160 | |
161 | // division of doubles test |
162 | div = 5.0E+5; |
163 | #pragma omp parallel |
164 | { |
165 | int i; |
166 | #pragma omp for |
167 | for (i = 1; i <= MAX_FACTOR; i++) { |
168 | #pragma omp atomic |
169 | div /= i; |
170 | } |
171 | } |
172 | if (fabs(x: div-0.137787) >= 1.0E-4 ) { |
173 | result++; |
174 | fprintf (stderr, format: "Error in division with double: Result was %f" |
175 | " instead of 0.137787\n" , div); |
176 | } |
177 | |
178 | // ++ test |
179 | x = 0; |
180 | #pragma omp parallel |
181 | { |
182 | int i; |
183 | #pragma omp for |
184 | for (i = 0; i < LOOPCOUNT; ++i) { |
185 | #pragma omp atomic |
186 | x++; |
187 | } |
188 | } |
189 | if (x != LOOPCOUNT) { |
190 | result++; |
191 | fprintf (stderr, format: "Error in ++\n" ); |
192 | } |
193 | |
194 | // -- test |
195 | #pragma omp parallel |
196 | { |
197 | int i; |
198 | #pragma omp for |
199 | for (i = 0; i < LOOPCOUNT; ++i) { |
200 | #pragma omp atomic |
201 | x--; |
202 | } |
203 | } |
204 | if (x != 0) { |
205 | result++; |
206 | fprintf (stderr, format: "Error in --\n" ); |
207 | } |
208 | |
209 | // bit-and test part 1 |
210 | for (j = 0; j < LOOPCOUNT; ++j) { |
211 | logics[j] = 1; |
212 | } |
213 | bit_and = 1; |
214 | #pragma omp parallel |
215 | { |
216 | int i; |
217 | #pragma omp for |
218 | for (i = 0; i < LOOPCOUNT; ++i) { |
219 | #pragma omp atomic |
220 | bit_and &= logics[i]; |
221 | } |
222 | } |
223 | if (!bit_and) { |
224 | result++; |
225 | fprintf (stderr, format: "Error in BIT AND part 1\n" ); |
226 | } |
227 | |
228 | // bit-and test part 2 |
229 | bit_and = 1; |
230 | logics[LOOPCOUNT / 2] = 0; |
231 | #pragma omp parallel |
232 | { |
233 | int i; |
234 | #pragma omp for |
235 | for (i = 0; i < LOOPCOUNT; ++i) { |
236 | #pragma omp atomic |
237 | bit_and &= logics[i]; |
238 | } |
239 | } |
240 | if (bit_and) { |
241 | result++; |
242 | fprintf (stderr, format: "Error in BIT AND part 2\n" ); |
243 | } |
244 | |
245 | // bit-or test part 1 |
246 | for (j = 0; j < LOOPCOUNT; j++) { |
247 | logics[j] = 0; |
248 | } |
249 | bit_or = 0; |
250 | #pragma omp parallel |
251 | { |
252 | int i; |
253 | #pragma omp for |
254 | for (i = 0; i < LOOPCOUNT; ++i) { |
255 | #pragma omp atomic |
256 | bit_or |= logics[i]; |
257 | } |
258 | } |
259 | if (bit_or) { |
260 | result++; |
261 | fprintf (stderr, format: "Error in BIT OR part 1\n" ); |
262 | } |
263 | |
264 | // bit-or test part 2 |
265 | bit_or = 0; |
266 | logics[LOOPCOUNT / 2] = 1; |
267 | #pragma omp parallel |
268 | { |
269 | |
270 | int i; |
271 | #pragma omp for |
272 | for (i = 0; i < LOOPCOUNT; ++i) { |
273 | #pragma omp atomic |
274 | bit_or |= logics[i]; |
275 | } |
276 | } |
277 | if (!bit_or) { |
278 | result++; |
279 | fprintf (stderr, format: "Error in BIT OR part 2\n" ); |
280 | } |
281 | |
282 | // bit-xor test part 1 |
283 | for (j = 0; j < LOOPCOUNT; j++) { |
284 | logics[j] = 0; |
285 | } |
286 | exclusiv_bit_or = 0; |
287 | #pragma omp parallel |
288 | { |
289 | int i; |
290 | #pragma omp for |
291 | for (i = 0; i < LOOPCOUNT; ++i) { |
292 | #pragma omp atomic |
293 | exclusiv_bit_or ^= logics[i]; |
294 | } |
295 | } |
296 | if (exclusiv_bit_or) { |
297 | result++; |
298 | fprintf (stderr, format: "Error in EXCLUSIV BIT OR part 1\n" ); |
299 | } |
300 | |
301 | // bit-xor test part 2 |
302 | exclusiv_bit_or = 0; |
303 | logics[LOOPCOUNT / 2] = 1; |
304 | #pragma omp parallel |
305 | { |
306 | int i; |
307 | #pragma omp for |
308 | for (i = 0; i < LOOPCOUNT; ++i) { |
309 | #pragma omp atomic |
310 | exclusiv_bit_or ^= logics[i]; |
311 | } |
312 | |
313 | } |
314 | if (!exclusiv_bit_or) { |
315 | result++; |
316 | fprintf (stderr, format: "Error in EXCLUSIV BIT OR part 2\n" ); |
317 | } |
318 | |
319 | // left shift test |
320 | x = 1; |
321 | #pragma omp parallel |
322 | { |
323 | int i; |
324 | #pragma omp for |
325 | for (i = 0; i < 10; ++i) { |
326 | #pragma omp atomic |
327 | x <<= 1; |
328 | } |
329 | |
330 | } |
331 | if ( x != 1024) { |
332 | result++; |
333 | fprintf (stderr, format: "Error in <<\n" ); |
334 | x = 1024; |
335 | } |
336 | |
337 | // right shift test |
338 | #pragma omp parallel |
339 | { |
340 | int i; |
341 | #pragma omp for |
342 | for (i = 0; i < 10; ++i) { |
343 | #pragma omp atomic |
344 | x >>= 1; |
345 | } |
346 | } |
347 | if (x != 1) { |
348 | result++; |
349 | fprintf (stderr, format: "Error in >>\n" ); |
350 | } |
351 | |
352 | return (result == 0); |
353 | } // test_omp_atomic() |
354 | |
355 | int main() |
356 | { |
357 | int i; |
358 | int num_failed=0; |
359 | |
360 | for(i = 0; i < REPETITIONS; i++) { |
361 | if(!test_omp_atomic()) { |
362 | num_failed++; |
363 | } |
364 | } |
365 | return num_failed; |
366 | } |
367 | |