1 // RUN: %libomp-compile-and-run 2 #include <stdio.h> 3 #include <math.h> 4 #include "omp_testsuite.h" 5 6 int test_omp_parallel_sections_reduction() 7 { 8 int sum; 9 int known_sum; 10 double dpt; 11 double dsum; 12 double dknown_sum; 13 double dt=0.5; /* base of geometric row for + and - test*/ 14 double rounding_error= 1.E-5; 15 int diff; 16 double ddiff; 17 int product; 18 int known_product; 19 int logic_and; 20 int bit_and; 21 int logic_or; 22 int bit_or; 23 int exclusiv_bit_or; 24 int logics[1000]; 25 int i; 26 int result; 27 28 sum = 7; 29 dsum=0; 30 product =1; 31 dpt = 1; 32 logic_and=1; 33 bit_and=1; 34 logic_or=0; 35 bit_or=0; 36 exclusiv_bit_or=0; 37 result =0; 38 /* int my_islarger;*/ 39 /*int is_larger=1;*/ 40 41 // Test summation of integers 42 known_sum = (999*1000)/2+7; 43 #pragma omp parallel sections private(i) reduction(+:sum) 44 { 45 #pragma omp section 46 { 47 for (i=1;i<300;i++) { 48 sum=sum+i; 49 } 50 } 51 #pragma omp section 52 { 53 for (i=300;i<700;i++) { 54 sum=sum+i; 55 } 56 } 57 #pragma omp section 58 { 59 for (i=700;i<1000;i++) { 60 sum=sum+i; 61 } 62 } 63 } 64 if(known_sum!=sum) { 65 result++; 66 fprintf(stderr,"Error in sum with integers: Result was %d" 67 " instead of %d.\n",sum, known_sum); 68 } 69 70 // Test differences of integers 71 diff = (999*1000)/2; 72 #pragma omp parallel sections private(i) reduction(-:diff) 73 { 74 #pragma omp section 75 { 76 for (i=1;i<300;i++) { 77 diff=diff-i; 78 } 79 } 80 #pragma omp section 81 { 82 for (i=300;i<700;i++) { 83 diff=diff-i; 84 } 85 } 86 #pragma omp section 87 { 88 for (i=700;i<1000;i++) { 89 diff=diff-i; 90 } 91 } 92 } 93 if(diff != 0) { 94 result++; 95 fprintf(stderr,"Error in Difference with integers: Result was %d" 96 " instead of 0.\n",diff); 97 } 98 99 // Test summation of doubles 100 for (i=0;i<20;++i) { 101 dpt*=dt; 102 } 103 dknown_sum = (1-dpt)/(1-dt); 104 #pragma omp parallel sections private(i) reduction(+:dsum) 105 { 106 #pragma omp section 107 { 108 for (i=0;i<6;++i) { 109 dsum += pow(dt,i); 110 } 111 } 112 #pragma omp section 113 { 114 for (i=6;i<12;++i) { 115 dsum += pow(dt,i); 116 } 117 } 118 #pragma omp section 119 { 120 for (i=12;i<20;++i) { 121 dsum += pow(dt,i); 122 } 123 } 124 } 125 if( fabs(dsum-dknown_sum) > rounding_error ) { 126 result++; 127 fprintf(stderr,"Error in sum with doubles: Result was %f" 128 " instead of %f (Difference: %E)\n", 129 dsum, dknown_sum, dsum-dknown_sum); 130 } 131 132 // Test differences of doubles 133 dpt=1; 134 for (i=0;i<20;++i) { 135 dpt*=dt; 136 } 137 fprintf(stderr,"\n"); 138 ddiff = (1-dpt)/(1-dt); 139 #pragma omp parallel sections private(i) reduction(-:ddiff) 140 { 141 #pragma omp section 142 { 143 for (i=0;i<6;++i) { 144 ddiff -= pow(dt,i); 145 } 146 } 147 #pragma omp section 148 { 149 for (i=6;i<12;++i) { 150 ddiff -= pow(dt,i); 151 } 152 } 153 #pragma omp section 154 { 155 for (i=12;i<20;++i) { 156 ddiff -= pow(dt,i); 157 } 158 } 159 } 160 if( fabs(ddiff) > rounding_error) { 161 result++; 162 fprintf(stderr,"Error in Difference with doubles: Result was %E" 163 " instead of 0.0\n",ddiff); 164 } 165 166 // Test product of integers 167 known_product = 3628800; 168 #pragma omp parallel sections private(i) reduction(*:product) 169 { 170 #pragma omp section 171 { 172 for(i=1;i<3;i++) { 173 product *= i; 174 } 175 } 176 #pragma omp section 177 { 178 for(i=3;i<7;i++) { 179 product *= i; 180 } 181 } 182 #pragma omp section 183 { 184 for(i=7;i<11;i++) { 185 product *= i; 186 } 187 } 188 } 189 if(known_product != product) { 190 result++; 191 fprintf(stderr,"Error in Product with integers: Result was %d" 192 " instead of %d\n",product,known_product); 193 } 194 195 // Test logical AND 196 for(i=0;i<1000;i++) { 197 logics[i]=1; 198 } 199 200 #pragma omp parallel sections private(i) reduction(&&:logic_and) 201 { 202 #pragma omp section 203 { 204 for (i=1;i<300;i++) { 205 logic_and = (logic_and && logics[i]); 206 } 207 } 208 #pragma omp section 209 { 210 for (i=300;i<700;i++) { 211 logic_and = (logic_and && logics[i]); 212 } 213 } 214 #pragma omp section 215 { 216 for (i=700;i<1000;i++) { 217 logic_and = (logic_and && logics[i]); 218 } 219 } 220 } 221 if(!logic_and) { 222 result++; 223 fprintf(stderr,"Error in logic AND part 1\n"); 224 } 225 logic_and = 1; 226 logics[501] = 0; 227 228 #pragma omp parallel sections private(i) reduction(&&:logic_and) 229 { 230 #pragma omp section 231 { 232 for (i=1;i<300;i++) { 233 logic_and = (logic_and && logics[i]); 234 } 235 } 236 #pragma omp section 237 { 238 for (i=300;i<700;i++) { 239 logic_and = (logic_and && logics[i]); 240 } 241 } 242 #pragma omp section 243 { 244 for (i=700;i<1000;i++) { 245 logic_and = (logic_and && logics[i]); 246 } 247 } 248 } 249 if(logic_and) { 250 result++; 251 fprintf(stderr,"Error in logic AND part 2"); 252 } 253 254 // Test logical OR 255 for(i=0;i<1000;i++) { 256 logics[i]=0; 257 } 258 259 #pragma omp parallel sections private(i) reduction(||:logic_or) 260 { 261 #pragma omp section 262 { 263 for (i=1;i<300;i++) { 264 logic_or = (logic_or || logics[i]); 265 } 266 } 267 #pragma omp section 268 { 269 for (i=300;i<700;i++) { 270 logic_or = (logic_or || logics[i]); 271 } 272 } 273 #pragma omp section 274 { 275 for (i=700;i<1000;i++) { 276 logic_or = (logic_or || logics[i]); 277 } 278 } 279 } 280 if(logic_or) { 281 result++; 282 fprintf(stderr,"Error in logic OR part 1\n"); 283 } 284 285 logic_or = 0; 286 logics[501]=1; 287 288 #pragma omp parallel sections private(i) reduction(||:logic_or) 289 { 290 #pragma omp section 291 { 292 for (i=1;i<300;i++) { 293 logic_or = (logic_or || logics[i]); 294 } 295 } 296 #pragma omp section 297 { 298 for (i=300;i<700;i++) { 299 logic_or = (logic_or || logics[i]); 300 } 301 } 302 #pragma omp section 303 { 304 for (i=700;i<1000;i++) { 305 logic_or = (logic_or || logics[i]); 306 } 307 } 308 } 309 if(!logic_or) { 310 result++; 311 fprintf(stderr,"Error in logic OR part 2\n"); 312 } 313 314 // Test bitwise AND 315 for(i=0;i<1000;++i) { 316 logics[i]=1; 317 } 318 319 #pragma omp parallel sections private(i) reduction(&:bit_and) 320 { 321 #pragma omp section 322 { 323 for(i=0;i<300;++i) { 324 bit_and = (bit_and & logics[i]); 325 } 326 } 327 #pragma omp section 328 { 329 for(i=300;i<700;++i) { 330 bit_and = (bit_and & logics[i]); 331 } 332 } 333 #pragma omp section 334 { 335 for(i=700;i<1000;++i) { 336 bit_and = (bit_and & logics[i]); 337 } 338 } 339 } 340 if(!bit_and) { 341 result++; 342 fprintf(stderr,"Error in BIT AND part 1\n"); 343 } 344 345 bit_and = 1; 346 logics[501]=0; 347 348 #pragma omp parallel sections private(i) reduction(&:bit_and) 349 { 350 #pragma omp section 351 { 352 for(i=0;i<300;++i) { 353 bit_and = bit_and & logics[i]; 354 } 355 } 356 #pragma omp section 357 { 358 for(i=300;i<700;++i) { 359 bit_and = bit_and & logics[i]; 360 } 361 } 362 #pragma omp section 363 { 364 for(i=700;i<1000;++i) { 365 bit_and = bit_and & logics[i]; 366 } 367 } 368 } 369 if(bit_and) { 370 result++; 371 fprintf(stderr,"Error in BIT AND part 2"); 372 } 373 374 // Test bitwise OR 375 for(i=0;i<1000;i++) { 376 logics[i]=0; 377 } 378 379 #pragma omp parallel sections private(i) reduction(|:bit_or) 380 { 381 #pragma omp section 382 { 383 for(i=0;i<300;++i) { 384 bit_or = bit_or | logics[i]; 385 } 386 } 387 #pragma omp section 388 { 389 for(i=300;i<700;++i) { 390 bit_or = bit_or | logics[i]; 391 } 392 } 393 #pragma omp section 394 { 395 for(i=700;i<1000;++i) { 396 bit_or = bit_or | logics[i]; 397 } 398 } 399 } 400 if(bit_or) { 401 result++; 402 fprintf(stderr,"Error in BIT OR part 1\n"); 403 } 404 bit_or = 0; 405 logics[501]=1; 406 407 #pragma omp parallel sections private(i) reduction(|:bit_or) 408 { 409 #pragma omp section 410 { 411 for(i=0;i<300;++i) { 412 bit_or = bit_or | logics[i]; 413 } 414 } 415 #pragma omp section 416 { 417 for(i=300;i<700;++i) { 418 bit_or = bit_or | logics[i]; 419 } 420 } 421 #pragma omp section 422 { 423 for(i=700;i<1000;++i) { 424 bit_or = bit_or | logics[i]; 425 } 426 } 427 } 428 if(!bit_or) { 429 result++; 430 fprintf(stderr,"Error in BIT OR part 2\n"); 431 } 432 433 // Test bitwise XOR 434 for(i=0;i<1000;i++) { 435 logics[i]=0; 436 } 437 438 #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or) 439 { 440 #pragma omp section 441 { 442 for(i=0;i<300;++i) { 443 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 444 } 445 } 446 #pragma omp section 447 { 448 for(i=300;i<700;++i) { 449 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 450 } 451 } 452 #pragma omp section 453 { 454 for(i=700;i<1000;++i) { 455 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 456 } 457 } 458 } 459 if(exclusiv_bit_or) { 460 result++; 461 fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n"); 462 } 463 464 exclusiv_bit_or = 0; 465 logics[501]=1; 466 467 #pragma omp parallel sections private(i) reduction(^:exclusiv_bit_or) 468 { 469 #pragma omp section 470 { 471 for(i=0;i<300;++i) { 472 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 473 } 474 } 475 #pragma omp section 476 { 477 for(i=300;i<700;++i) { 478 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 479 } 480 } 481 #pragma omp section 482 { 483 for(i=700;i<1000;++i) { 484 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 485 } 486 } 487 } 488 if(!exclusiv_bit_or) { 489 result++; 490 fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n"); 491 } 492 493 /*printf("\nResult:%d\n",result);*/ 494 return (result==0); 495 } 496 497 int main() 498 { 499 int i; 500 int num_failed=0; 501 502 for(i = 0; i < REPETITIONS; i++) { 503 if(!test_omp_parallel_sections_reduction()) { 504 num_failed++; 505 } 506 } 507 return num_failed; 508 } 509