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