255 lines · c
1// RUN: %libomp-compile-and-run2#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 108#define KNOWN_PRODUCT 3628800 /* 10! */9 10int 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 243int 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