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 "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 "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 (dt, i); 93 } 94 } 95 if (dsum != dknown_sum && (fabs (dsum - dknown_sum) > rounding_error)) { 96 fprintf (stderr, "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 (dt, i); 115 } 116 } 117 if (fabs (ddiff) > rounding_error) { 118 fprintf (stderr, 119 "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 "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 "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(div-0.137787) >= 1.0E-4 ) { 173 result++; 174 fprintf (stderr, "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, "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, "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, "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, "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, "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, "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, "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, "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, "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, "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