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_parallel_reduction() 11 { 12 int sum; 13 int known_sum; 14 double dsum; 15 double dknown_sum; 16 double dt=0.5; /* base of geometric row for + and - test*/ 17 double rounding_error= 1.E-9; 18 int diff; 19 double ddiff; 20 int product; 21 int known_product; 22 int logic_and; 23 int logic_or; 24 int bit_and; 25 int bit_or; 26 int exclusiv_bit_or; 27 int logics[LOOPCOUNT]; 28 int i; 29 double dpt; 30 int result; 31 32 sum =0; 33 dsum=0; 34 product=1; 35 logic_and=1; 36 logic_or=0; 37 bit_and=1; 38 bit_or=0; 39 exclusiv_bit_or=0; 40 result=0; 41 dt = 1./3.; 42 known_sum = (LOOPCOUNT*(LOOPCOUNT+1))/2; 43 44 /* Tests for integers */ 45 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:sum) 46 for (i=1;i<=LOOPCOUNT;i++) { 47 sum=sum+i; 48 } 49 50 if(known_sum!=sum) { 51 result++; 52 fprintf(stderr,"Error in sum with integers: Result was %d instead of %d\n",sum,known_sum); 53 } 54 55 diff = (LOOPCOUNT*(LOOPCOUNT+1))/2; 56 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:diff) 57 for (i=1;i<=LOOPCOUNT;++i) { 58 diff=diff-i; 59 } 60 61 if(diff != 0) { 62 result++; 63 fprintf(stderr,"Error in difference with integers: Result was %d instead of 0.\n",diff); 64 } 65 66 /* Tests for doubles */ 67 dsum=0; 68 dpt=1; 69 for (i=0;i<DOUBLE_DIGITS;++i) { 70 dpt*=dt; 71 } 72 dknown_sum = (1-dpt)/(1-dt); 73 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(+:dsum) 74 for (i=0;i<DOUBLE_DIGITS;++i) { 75 dsum += pow(dt,i); 76 } 77 78 if( fabs(dsum-dknown_sum) > rounding_error ) { 79 result++; 80 fprintf(stderr,"Error in sum with doubles: Result was %f instead of %f (Difference: %E)\n",dsum,dknown_sum, dsum-dknown_sum); 81 } 82 83 dpt=1; 84 85 for (i=0;i<DOUBLE_DIGITS;++i) { 86 dpt*=dt; 87 } 88 fprintf(stderr,"\n"); 89 ddiff = (1-dpt)/(1-dt); 90 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(-:ddiff) 91 for (i=0;i<DOUBLE_DIGITS;++i) { 92 ddiff -= pow(dt,i); 93 } 94 if( fabs(ddiff) > rounding_error) { 95 result++; 96 fprintf(stderr,"Error in Difference with doubles: Result was %E instead of 0.0\n",ddiff); 97 } 98 99 /* Tests for product of integers */ 100 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(*:product) 101 for(i=1;i<=MAX_FACTOR;i++) { 102 product *= i; 103 } 104 105 known_product = KNOWN_PRODUCT; 106 if(known_product != product) { 107 result++; 108 fprintf(stderr,"Error in Product with integers: Result was %d instead of %d\n\n",product,known_product); 109 } 110 111 /* Tests for logical and */ 112 for(i=0;i<LOOPCOUNT;i++) { 113 logics[i]=1; 114 } 115 116 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and) 117 for(i=0;i<LOOPCOUNT;++i) { 118 logic_and = (logic_and && logics[i]); 119 } 120 if(!logic_and) { 121 result++; 122 fprintf(stderr,"Error in logic AND part 1.\n"); 123 } 124 125 logic_and = 1; 126 logics[LOOPCOUNT/2]=0; 127 128 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&&:logic_and) 129 for(i=0;i<LOOPCOUNT;++i) { 130 logic_and = logic_and && logics[i]; 131 } 132 if(logic_and) { 133 result++; 134 fprintf(stderr,"Error in logic AND part 2.\n"); 135 } 136 137 /* Tests for logical or */ 138 for(i=0;i<LOOPCOUNT;i++) { 139 logics[i]=0; 140 } 141 142 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or) 143 for(i=0;i<LOOPCOUNT;++i) { 144 logic_or = logic_or || logics[i]; 145 } 146 if(logic_or) { 147 result++; 148 fprintf(stderr,"Error in logic OR part 1.\n"); 149 } 150 logic_or = 0; 151 logics[LOOPCOUNT/2]=1; 152 153 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(||:logic_or) 154 for(i=0;i<LOOPCOUNT;++i) { 155 logic_or = logic_or || logics[i]; 156 } 157 if(!logic_or) { 158 result++; 159 fprintf(stderr,"Error in logic OR part 2.\n"); 160 } 161 162 /* Tests for bitwise and */ 163 for(i=0;i<LOOPCOUNT;++i) { 164 logics[i]=1; 165 } 166 167 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and) 168 for(i=0;i<LOOPCOUNT;++i) { 169 bit_and = (bit_and & logics[i]); 170 } 171 if(!bit_and) { 172 result++; 173 fprintf(stderr,"Error in BIT AND part 1.\n"); 174 } 175 176 bit_and = 1; 177 logics[LOOPCOUNT/2]=0; 178 179 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(&:bit_and) 180 for(i=0;i<LOOPCOUNT;++i) { 181 bit_and = bit_and & logics[i]; 182 } 183 if(bit_and) { 184 result++; 185 fprintf(stderr,"Error in BIT AND part 2.\n"); 186 } 187 188 for(i=0;i<LOOPCOUNT;i++) { 189 logics[i]=0; 190 } 191 192 /* Tests for bitwise or */ 193 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or) 194 for(i=0;i<LOOPCOUNT;++i) { 195 bit_or = bit_or | logics[i]; 196 } 197 if(bit_or) { 198 result++; 199 fprintf(stderr,"Error in BIT OR part 1\n"); 200 } 201 bit_or = 0; 202 logics[LOOPCOUNT/2]=1; 203 204 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(|:bit_or) 205 for(i=0;i<LOOPCOUNT;++i) { 206 bit_or = bit_or | logics[i]; 207 } 208 if(!bit_or) { 209 result++; 210 fprintf(stderr,"Error in BIT OR part 2\n"); 211 } 212 213 for(i=0;i<LOOPCOUNT;i++) { 214 logics[i]=0; 215 } 216 217 /* Tests for bitwise xor */ 218 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or) 219 for(i=0;i<LOOPCOUNT;++i) { 220 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 221 } 222 if(exclusiv_bit_or) { 223 result++; 224 fprintf(stderr,"Error in EXCLUSIV BIT OR part 1\n"); 225 } 226 227 exclusiv_bit_or = 0; 228 logics[LOOPCOUNT/2]=1; 229 230 #pragma omp parallel for schedule(dynamic,1) private(i) reduction(^:exclusiv_bit_or) 231 for(i=0;i<LOOPCOUNT;++i) { 232 exclusiv_bit_or = exclusiv_bit_or ^ logics[i]; 233 } 234 if(!exclusiv_bit_or) { 235 result++; 236 fprintf(stderr,"Error in EXCLUSIV BIT OR part 2\n"); 237 } 238 239 /*printf("\nResult:%d\n",result);*/ 240 return (result==0); 241 } 242 243 int main() 244 { 245 int i; 246 int num_failed=0; 247 248 for(i = 0; i < REPETITIONS; i++) { 249 if(!test_omp_parallel_reduction()) { 250 num_failed++; 251 } 252 } 253 return num_failed; 254 } 255