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_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
355int 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

source code of openmp/runtime/test/atomic/omp_atomic.c