blob: 6c2d1aa9a0a3209f8a42ee4792c4f2a12e75cd87 [file] [log] [blame]
Jim Cownie18d84732014-05-10 17:02:09 +00001<ompts:test>
2<ompts:testdescription>Test which checks the omp atomic directive by counting up a variable in a parallelized loop with an atomic directive.</ompts:testdescription>
3<ompts:ompversion>2.0</ompts:ompversion>
4<ompts:directive>omp atomic</ompts:directive>
5<ompts:testcode>
6#include <stdio.h>
7#include <unistd.h>
8#include <math.h>
9
10#include "omp_testsuite.h"
11#include "omp_my_sleep.h"
12
13int <ompts:testcode:functionname>omp_atomic</ompts:testcode:functionname> (FILE * logFile)
14{
15 <ompts:orphan:vars>
16 int sum;
17 int diff;
18 double dsum = 0;
19 double dt = 0.5; /* base of geometric row for + and - test*/
20 double ddiff;
21 int product;
22 int x;
23 int *logics;
24 int bit_and = 1;
25 int bit_or = 0;
26 int exclusiv_bit_or = 0;
27 </ompts:orphan:vars>
28
29#define DOUBLE_DIGITS 20 /* dt^DOUBLE_DIGITS */
30#define MAX_FACTOR 10
31#define KNOWN_PRODUCT 3628800 /* 10! */
32 int j;
33 int known_sum;
34 int known_diff;
35 int known_product;
36 int result = 0;
37 int logic_and = 1;
38 int logic_or = 0;
39 double dknown_sum;
40 double rounding_error = 1.E-9;
41 double dpt, div;
42 int logicsArray[LOOPCOUNT];
43 logics = logicsArray;
44
45 sum = 0;
46 diff = 0;
47 product = 1;
48
49#pragma omp parallel
50 {
51 <ompts:orphan>
52 int i;
53#pragma omp for
54 for (i = 1; i <= LOOPCOUNT; i++)
55 {
56 <ompts:check>#pragma omp atomic</ompts:check>
57 sum += i;
58 }
59 </ompts:orphan>
60 }
61 known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2;
62 if (known_sum != sum)
63 {
64 fprintf (logFile,
65 "Error in sum with integers: Result was %d instead of %d.\n",
66 sum, known_sum);
67 result++;
68 }
69
70#pragma omp parallel
71 {
72 <ompts:orphan>
73 int i;
74#pragma omp for
75 for (i = 0; i < LOOPCOUNT; i++)
76 {
77 <ompts:check>#pragma omp atomic</ompts:check>
78 diff -= i;
79 }
80 </ompts:orphan>
81 }
82 known_diff = ((LOOPCOUNT - 1) * LOOPCOUNT) / 2 * -1;
83 if (diff != known_diff)
84 {
85 fprintf (logFile,
86 "Error in difference with integers: Result was %d instead of 0.\n",
87 diff);
88 result++;
89 }
90
91 /* Tests for doubles */
92 dsum = 0;
93 dpt = 1;
94
95 for (j = 0; j < DOUBLE_DIGITS; ++j)
96 {
97 dpt *= dt;
98 }
99 dknown_sum = (1 - dpt) / (1 -dt);
100#pragma omp parallel
101 {
102 <ompts:orphan>
103 int i;
104#pragma omp for
105 for (i = 0; i < DOUBLE_DIGITS; ++i)
106 {
107 <ompts:check>#pragma omp atomic</ompts:check>
108 dsum += pow (dt, i);
109 }
110 </ompts:orphan>
111 }
112
113 if (dsum != dknown_sum && (fabs (dsum - dknown_sum) > rounding_error))
114 {
115 fprintf (logFile,
116 "Error in sum with doubles: Result was %f instead of: %f (Difference: %E)\n",
117 dsum, dknown_sum, dsum - dknown_sum);
118 result++;
119 }
120
121 dpt = 1;
122
123 for (j = 0; j < DOUBLE_DIGITS; ++j)
124 {
125 dpt *= dt;
126 }
127 ddiff = (1 - dpt) / (1 - dt);
128#pragma omp parallel
129 {
130 <ompts:orphan>
131 int i;
132#pragma omp for
133 for (i = 0; i < DOUBLE_DIGITS; ++i)
134 {
135 <ompts:check>#pragma omp atomic</ompts:check>
136 ddiff -= pow (dt, i);
137 }
138 </ompts:orphan>
139 }
140 if (fabs (ddiff) > rounding_error)
141 {
142 fprintf (logFile,
143 "Error in difference with doubles: Result was %E instead of 0.0\n",
144 ddiff);
145 result++;
146 }
147
148#pragma omp parallel
149 {
150 <ompts:orphan>
151 int i;
152#pragma omp for
153 for (i = 1; i <= MAX_FACTOR; i++)
154 {
155 <ompts:check>#pragma omp atomic</ompts:check>
156 product *= i;
157 }
158 </ompts:orphan>
159 }
160
161 known_product = KNOWN_PRODUCT;
162 if (known_product != product)
163 {
164 fprintf (logFile,
165 "Error in product with integers: Result was %d instead of %d\n",
166 product, known_product);
167 result++;
168 }
169
170 product = KNOWN_PRODUCT;
171#pragma omp parallel
172 {
173 <ompts:orphan>
174 int i;
175#pragma omp for
176 for (i = 1; i <= MAX_FACTOR; ++i)
177 {
178 <ompts:check>#pragma omp atomic</ompts:check>
179 product /= i;
180 }
181 </ompts:orphan>
182 }
183
184 if (product != 1)
185 {
186 fprintf (logFile,
187 "Error in product division with integers: Result was %d instead of 1\n",
188 product);
189 result++;
190 }
191
192 div = 5.0E+5;
193#pragma omp parallel
194 {
195 int i;
196#pragma omp for
197 for (i = 1; i <= MAX_FACTOR; i++)
198 {
199 <ompts:check>#pragma omp atomic</ompts:check>
200 div /= i;
201 }
202 }
203
204 if (fabs(div-0.137787) >= 1.0E-4 )
205 {
206 result++;
207 fprintf (logFile,
208 "Error in division with double: Result was %f instead of 0.137787\n", div);
209 }
210
211 x = 0;
212
213#pragma omp parallel
214 {
215 <ompts:orphan>
216 int i;
217#pragma omp for
218 for (i = 0; i < LOOPCOUNT; ++i)
219 {
220 <ompts:check>#pragma omp atomic</ompts:check>
221 x++;
222 }
223 </ompts:orphan>
224 }
225
226 if (x != LOOPCOUNT)
227 {
228 result++;
229 fprintf (logFile, "Error in ++\n");
230 }
231
232#pragma omp parallel
233 {
234 <ompts:orphan>
235 int i;
236#pragma omp for
237 for (i = 0; i < LOOPCOUNT; ++i)
238 {
239 <ompts:check>#pragma omp atomic</ompts:check>
240 x--;
241 }
242 </ompts:orphan>
243 }
244
245 if (x != 0)
246 {
247 result++;
248 fprintf (logFile, "Error in --\n");
249 }
250
251 for (j = 0; j < LOOPCOUNT; ++j)
252 {
253 logics[j] = 1;
254 }
255 bit_and = 1;
256
257#pragma omp parallel
258 {
259 <ompts:orphan>
260 int i;
261#pragma omp for
262 for (i = 0; i < LOOPCOUNT; ++i)
263 {
264 <ompts:check>#pragma omp atomic</ompts:check>
265 bit_and &= logics[i];
266 }
267 </ompts:orphan>
268 }
269
270 if (!bit_and)
271 {
272 result++;
273 fprintf (logFile, "Error in BIT AND part 1\n");
274 }
275
276 bit_and = 1;
277 logics[LOOPCOUNT / 2] = 0;
278
279#pragma omp parallel
280 {
281 <ompts:orphan>
282 int i;
283#pragma omp for
284 for (i = 0; i < LOOPCOUNT; ++i)
285 {
286 <ompts:check>#pragma omp atomic</ompts:check>
287 bit_and &= logics[i];
288 }
289 </ompts:orphan>
290 }
291
292 if (bit_and)
293 {
294 result++;
295 fprintf (logFile, "Error in BIT AND part 2\n");
296 }
297
298 for (j = 0; j < LOOPCOUNT; j++)
299 {
300 logics[j] = 0;
301 }
302 bit_or = 0;
303
304#pragma omp parallel
305 {
306 <ompts:orphan>
307 int i;
308#pragma omp for
309 for (i = 0; i < LOOPCOUNT; ++i)
310 {
311 <ompts:check>#pragma omp atomic</ompts:check>
312 bit_or |= logics[i];
313 }
314 </ompts:orphan>
315 }
316
317 if (bit_or)
318 {
319 result++;
320 fprintf (logFile, "Error in BIT OR part 1\n");
321 }
322 bit_or = 0;
323 logics[LOOPCOUNT / 2] = 1;
324
325#pragma omp parallel
326 {
327 <ompts:orphan>
328 int i;
329#pragma omp for
330 for (i = 0; i < LOOPCOUNT; ++i)
331 {
332 <ompts:check>#pragma omp atomic</ompts:check>
333 bit_or |= logics[i];
334 }
335 </ompts:orphan>
336 }
337
338 if (!bit_or)
339 {
340 result++;
341 fprintf (logFile, "Error in BIT OR part 2\n");
342 }
343
344 for (j = 0; j < LOOPCOUNT; j++)
345 {
346 logics[j] = 0;
347 }
348 exclusiv_bit_or = 0;
349
350#pragma omp parallel
351 {
352 <ompts:orphan>
353 int i;
354#pragma omp for
355 for (i = 0; i < LOOPCOUNT; ++i)
356 {
357 <ompts:check>#pragma omp atomic</ompts:check>
358 exclusiv_bit_or ^= logics[i];
359 }
360 </ompts:orphan>
361 }
362
363 if (exclusiv_bit_or)
364 {
365 result++;
366 fprintf (logFile, "Error in EXCLUSIV BIT OR part 1\n");
367 }
368
369 exclusiv_bit_or = 0;
370 logics[LOOPCOUNT / 2] = 1;
371
372#pragma omp parallel
373 {
374 <ompts:orphan>
375 int i;
376#pragma omp for
377 for (i = 0; i < LOOPCOUNT; ++i)
378 {
379 <ompts:check>#pragma omp atomic</ompts:check>
380 exclusiv_bit_or ^= logics[i];
381 }
382 </ompts:orphan>
383 }
384
385 if (!exclusiv_bit_or)
386 {
387 result++;
388 fprintf (logFile, "Error in EXCLUSIV BIT OR part 2\n");
389 }
390
391 x = 1;
392#pragma omp parallel
393 {
394 <ompts:orphan>
395 int i;
396#pragma omp for
397 for (i = 0; i < 10; ++i)
398 {
399 <ompts:check>#pragma omp atomic</ompts:check>
400 x <<= 1;
401 }
402 </ompts:orphan>
403 }
404
405 if ( x != 1024)
406 {
407 result++;
408 fprintf (logFile, "Error in <<\n");
409 x = 1024;
410 }
411
412#pragma omp parallel
413 {
414 <ompts:orphan>
415 int i;
416#pragma omp for
417 for (i = 0; i < 10; ++i)
418 {
419 <ompts:check>#pragma omp atomic</ompts:check>
420 x >>= 1;
421 }
422 </ompts:orphan>
423 }
424
425 if (x != 1)
426 {
427 result++;
428 fprintf (logFile, "Error in >>\n");
429 }
430
431 return (result == 0);
432}
433</ompts:testcode>
434</ompts:test>