blob: 2b25a457b2d6708c5aa64c5b06cc618170e1e650 [file] [log] [blame]
Jim Cownie18d84732014-05-10 17:02:09 +00001<ompts:test>
2<ompts:testdescription>Test which checks the omp do reduction directive wich all its options.</ompts:testdescription>
3<ompts:ompversion>2.0</ompts:ompversion>
4<ompts:directive>omp do reduction</ompts:directive>
5<ompts:testcode>
6 INTEGER FUNCTION <ompts:testcode:functionname>do_reduction</ompts:testcode:functionname>()
7 IMPLICIT NONE
8 INTEGER sum2, known_sum
9 INTEGER known_product
10 DOUBLE PRECISION rounding_error, dpt
11 INTEGER double_DIGITS
12 DOUBLE PRECISION dknown_sum
13 INTEGER result
14 INCLUDE "omp_testsuite.f"
15 PARAMETER (known_product=3628800)
16 PARAMETER (rounding_error=1.E-6)
17<ompts:orphan:vars>
18 INTEGER sum,diff,product,i
19 DOUBLE PRECISION dsum,ddiff,dt
20 LOGICAL logic_and, logic_or, logic_eqv,logic_neqv
21 LOGICAL logics(LOOPCOUNT)
22 INTEGER bit_and, bit_or
23 INTEGER exclusiv_bit_or
24 INTEGER min_value, max_value
25 INTEGER int_array(LOOPCOUNT)
26 DOUBLE PRECISION d_array(LOOPCOUNT)
27 DOUBLE PRECISION dmin, dmax
28 COMMON /orphvars/ sum,product,diff,i,dsum,ddiff,dt,logic_and,
29 & logic_or,logic_eqv,logic_neqv,logics,bit_and,bit_or,int_array,
30 & exclusiv_bit_or,min_value,dmin,dmax,d_array,max_value
31 INTEGER MAX_FACTOR
32 PARAMETER (double_DIGITS=20,MAX_FACTOR=10)
33</ompts:orphan:vars>
34
35 dt = 1./3.
36 known_sum = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
37 product = 1
38 sum2 = 0
39 sum = 0
40 dsum = 0.
41 result =0
42 logic_and = .true.
43 logic_or = .false.
44 bit_and = 1
45 bit_or = 0
46 exclusiv_bit_or = 0
47!$omp parallel
48<ompts:orphan>
49!$omp do schedule(dynamic, 1) <ompts:check>reduction(+:sum)</ompts:check>
50 DO i = 1, LOOPCOUNT
51 sum = sum + i
52 END DO
53!$omp end do
54</ompts:orphan>
55!$omp end parallel
56
57 IF (known_sum .NE. sum) THEN
58 result = result + 1
59 WRITE(1,*) "Error in sum with integers: Result was ",
60 & sum,"instead of ", known_sum
61 END IF
62
63
64 diff = (LOOPCOUNT * (LOOPCOUNT + 1)) / 2
65!$omp parallel
66<ompts:orphan>
67!$omp do schedule(dynamic, 1) <ompts:check>reduction (-: diff)</ompts:check>
68 DO i = 1, LOOPCOUNT
69 diff = diff - i
70 END DO
71!$omp end do
72</ompts:orphan>
73!$omp end parallel
74
75 IF ( diff .NE. 0 ) THEN
76 result = result + 1
77 WRITE(1,*) "Error in difference with integers: Result was ",
78 & sum,"instead of 0."
79 END IF
80
81!... Test for doubles
82 dsum =0.
83 dpt = 1
84
85 DO i=1, DOUBLE_DIGITS
86 dpt= dpt * dt
87 END DO
88 dknown_sum = (1-dpt)/(1-dt)
89
90!$omp parallel
91<ompts:orphan>
92!$omp do schedule(dynamic,1) <ompts:check>reduction(+:dsum)</ompts:check>
93 DO i=0,DOUBLE_DIGITS-1
94 dsum = dsum + dt**i
95 END DO
96!$omp end do
97</ompts:orphan>
98!$omp end parallel
99
100
101 IF(dsum .NE. dknown_sum .AND.
102 & ABS(dsum - dknown_sum) .GT. rounding_error ) THEN
103 result = result + 1
104 WRITE(1,*) "Error in sum with doubles: Result was ",
105 & dsum,"instead of ",dknown_sum,"(Difference: ",
106 & dsum - dknown_sum,")"
107 END IF
108 dpt = 1
109
110
111
112 DO i=1, DOUBLE_DIGITS
113 dpt = dpt*dt
114 END DO
115 ddiff = ( 1-dpt)/(1-dt)
116!$omp parallel
117<ompts:orphan>
118!$omp do schedule(dynamic,1) <ompts:check>reduction(-:ddiff)</ompts:check>
119 DO i=0, DOUBLE_DIGITS-1
120 ddiff = ddiff - dt**i
121 END DO
122!$omp end do
123</ompts:orphan>
124!$omp end parallel
125
126 IF ( ABS(ddiff) .GT. rounding_error ) THEN
127 result = result + 1
128 WRITE(1,*) "Error in Difference with doubles: Result was ",
129 & ddiff,"instead of 0.0"
130 END IF
131
132!$omp parallel
133<ompts:orphan>
134!$omp do schedule(dynamic,1) <ompts:check>reduction(*:product)</ompts:check>
135 DO i=1,MAX_FACTOR
136 product = product * i
137 END DO
138!$omp end do
139</ompts:orphan>
140!$omp end parallel
141
142 IF (known_product .NE. product) THEN
143 result = result + 1
144 write(1,*) "Error in Product with integers: Result was ",
145 & product," instead of",known_product
146 END IF
147
148 DO i=1,LOOPCOUNT
149 logics(i) = .TRUE.
150 END DO
151
152!$omp parallel
153<ompts:orphan>
154!$omp do schedule(dynamic,1) <ompts:check>reduction(.AND.:logic_and)</ompts:check>
155 DO i=1,LOOPCOUNT
156 logic_and = logic_and .AND. logics(i)
157 END DO
158!$omp end do
159</ompts:orphan>
160!$omp end parallel
161
162 IF (.NOT. logic_and) THEN
163 result = result + 1
164 WRITE(1,*) "Error in logic AND part 1"
165 END IF
166
167
168 logic_and = .TRUE.
169 logics(LOOPCOUNT/2) = .FALSE.
170
171!$omp parallel
172<ompts:orphan>
173!$omp do schedule(dynamic,1) <ompts:check>reduction(.AND.:logic_and)</ompts:check>
174 DO i=1,LOOPCOUNT
175 logic_and = logic_and .AND. logics(i)
176 END DO
177!$omp end do
178</ompts:orphan>
179!$omp end parallel
180
181 IF (logic_and) THEN
182 result = result + 1
183 WRITE(1,*) "Error in logic AND pass 2"
184 END IF
185
186 DO i=1, LOOPCOUNT
187 logics(i) = .FALSE.
188 END DO
189
190!$omp parallel
191<ompts:orphan>
192!$omp do schedule(dynamic,1) <ompts:check>reduction(.OR.:logic_or)</ompts:check>
193 DO i = 1, LOOPCOUNT
194 logic_or = logic_or .OR. logics(i)
195 END DO
196!$omp end do
197</ompts:orphan>
198!$omp end parallel
199
200 IF (logic_or) THEN
201 result = result + 1
202 WRITE(1,*) "Error in logic OR part 1"
203 END IF
204
205 logic_or = .FALSE.
206 logics(LOOPCOUNT/2) = .TRUE.
207
208!$omp parallel
209<ompts:orphan>
210!$omp do schedule(dynamic,1) <ompts:check>reduction(.OR.:logic_or)</ompts:check>
211 DO i=1,LOOPCOUNT
212 logic_or = logic_or .OR. logics(i)
213 END DO
214!$omp end do
215</ompts:orphan>
216!$omp end parallel
217
218 IF ( .NOT. logic_or ) THEN
219 result = result + 1
220 WRITE(1,*) "Error in logic OR part 2"
221 END IF
222
223!... Test logic EQV, unique in Fortran
224 DO i=1, LOOPCOUNT
225 logics(i) = .TRUE.
226 END DO
227
228 logic_eqv = .TRUE.
229
230!$omp parallel
231<ompts:orphan>
232!$omp do schedule(dynamic,1) <ompts:check>reduction(.EQV.:logic_eqv)</ompts:check>
233 DO i = 1, LOOPCOUNT
234 logic_eqv = logic_eqv .EQV. logics(i)
235 END DO
236!$omp end do
237</ompts:orphan>
238!$omp end parallel
239
240 IF (.NOT. logic_eqv) THEN
241 result = result + 1
242 WRITE(1,*) "Error in logic EQV part 1"
243 END IF
244
245 logic_eqv = .TRUE.
246 logics(LOOPCOUNT/2) = .FALSE.
247
248!$omp parallel
249<ompts:orphan>
250!$omp do schedule(dynamic,1) <ompts:check>reduction(.EQV.:logic_eqv)</ompts:check>
251 DO i=1,LOOPCOUNT
252 logic_eqv = logic_eqv .EQV. logics(i)
253 END DO
254!$omp end do
255</ompts:orphan>
256!$omp end parallel
257
258 IF ( logic_eqv ) THEN
259 result = result + 1
260 WRITE(1,*) "Error in logic EQV part 2"
261 END IF
262
263!... Test logic NEQV, which is unique in Fortran
264 DO i=1, LOOPCOUNT
265 logics(i) = .FALSE.
266 END DO
267
268 logic_neqv = .FALSE.
269
270!$omp parallel
271<ompts:orphan>
272!$omp do schedule(dynamic,1) <ompts:check>reduction(.NEQV.:logic_neqv)</ompts:check>
273 DO i = 1, LOOPCOUNT
274 logic_neqv = logic_neqv .NEQV. logics(i)
275 END DO
276!$omp end do
277</ompts:orphan>
278!$omp end parallel
279
280 IF (logic_neqv) THEN
281 result = result + 1
282 WRITE(1,*) "Error in logic NEQV part 1"
283 END IF
284
285 logic_neqv = .FALSE.
286 logics(LOOPCOUNT/2) = .TRUE.
287
288!$omp parallel
289<ompts:orphan>
290!$omp do schedule(dynamic,1) <ompts:check>reduction(.neqv.:logic_neqv)</ompts:check>
291 DO i=1,LOOPCOUNT
292 logic_neqv = logic_neqv .NEQV. logics(i)
293 END DO
294!$omp end do
295</ompts:orphan>
296!$omp end parallel
297
298 IF ( .NOT. logic_neqv ) THEN
299 result = result + 1
300 WRITE(1,*) "Error in logic NEQV part 2"
301 END IF
302
303 DO i=1, LOOPCOUNT
304 int_array(i) = 1
305 END DO
306!$omp parallel
307<ompts:orphan>
308!$omp do schedule(dynamic,1) <ompts:check>reduction(IAND:bit_and)</ompts:check>
309 DO i=1, LOOPCOUNT
310!... iand(I,J): Returns value resulting from boolean AND of
311!... pair of bits in each of I and J.
312 bit_and = IAND(bit_and,int_array(i))
313 END DO
314!$omp end do
315</ompts:orphan>
316!$omp end parallel
317
318 IF ( bit_and .LT. 1 ) THEN
319 result = result + 1
320 WRITE(1,*) "Error in IAND part 1"
321 END IF
322
323 bit_and = 1
324 int_array(LOOPCOUNT/2) = 0
325
326!$omp parallel
327<ompts:orphan>
328!$omp do schedule(dynamic,1) <ompts:check>reduction(IAND:bit_and)</ompts:check>
329 DO i=1, LOOPCOUNT
330 bit_and = IAND ( bit_and, int_array(i) )
331 END DO
332!$omp end do
333</ompts:orphan>
334!$omp end parallel
335
336 IF( bit_and .GE. 1) THEN
337 result = result + 1
338 WRITE(1,*) "Error in IAND part 2"
339 END IF
340
341 DO i=1, LOOPCOUNT
342 int_array(i) = 0
343 END DO
344
345
346!$omp parallel
347<ompts:orphan>
348!$omp do schedule(dynamic,1) <ompts:check>reduction(IOR:bit_or)</ompts:check>
349 DO i=1, LOOPCOUNT
350!... Ior(I,J): Returns value resulting from boolean OR of
351!... pair of bits in each of I and J.
352 bit_or = IOR(bit_or, int_array(i) )
353 END DO
354!$omp end do
355</ompts:orphan>
356!$omp end parallel
357
358 IF ( bit_or .GE. 1) THEN
359 result = result + 1
360 WRITE(1,*) "Error in Ior part 1"
361 END IF
362
363
364 bit_or = 0
365 int_array(LOOPCOUNT/2) = 1
366!$omp parallel
367<ompts:orphan>
368!$omp do schedule(dynamic,1) <ompts:check>reduction(IOR:bit_or)</ompts:check>
369 DO i=1, LOOPCOUNT
370 bit_or = IOR(bit_or, int_array(i) )
371 END DO
372!$omp end do
373</ompts:orphan>
374!$omp end parallel
375
376 IF ( bit_or .LE. 0) THEN
377 result = result + 1
378 WRITE(1,*) "Error in Ior part 2"
379 END IF
380
381 DO i=1, LOOPCOUNT
382 int_array(i) = 0
383 END DO
384
385!$omp parallel
386<ompts:orphan>
387!$omp do schedule(dynamic,1) <ompts:check>reduction(IEOR:exclusiv_bit_or)</ompts:check>
388 DO i = 1, LOOPCOUNT
389 exclusiv_bit_or = ieor(exclusiv_bit_or, int_array(i))
390 END DO
391!$omp end do
392</ompts:orphan>
393!$omp end parallel
394
395 IF ( exclusiv_bit_or .ge. 1) THEN
396 result = result + 1
397 WRITE(1,*) "Error in Ieor part 1"
398 END IF
399
400 exclusiv_bit_or = 0
401 int_array(LOOPCOUNT/2) = 1
402
403!$omp parallel
404<ompts:orphan>
405!$omp do schedule(dynamic,1) <ompts:check>reduction(IEOR:exclusiv_bit_or)</ompts:check>
406 DO i = 1, LOOPCOUNT
407 exclusiv_bit_or = IEOR(exclusiv_bit_or, int_array(i))
408 END DO
409!$omp end do
410</ompts:orphan>
411!$omp end parallel
412
413 IF ( exclusiv_bit_or .LE. 0) THEN
414 result = result + 1
415 WRITE(1,*) "Error in Ieor part 2"
416 END IF
417
418 DO i=1,LOOPCOUNT
419 int_array(i) = 10 - i
420 END DO
421
422 min_value = 65535
423
424!$omp parallel
425<ompts:orphan>
426!$omp do schedule(dynamic,1) <ompts:check>reduction(MIN:min_value)</ompts:check>
427 DO i = 1, LOOPCOUNT
428 min_value = MIN(min_value,int_array(i) )
429 END DO
430!$omp end do
431</ompts:orphan>
432!$omp end parallel
433
434 IF ( min_value .GT. (10-LOOPCOUNT) )THEN
435 result = result + 1
436 WRITE(1,*) "Error in integer MIN"
437 END IF
438
439
440 DO i=1,LOOPCOUNT
441 int_array(i) = i
442 END DO
443
444 max_value = -32768
445
446!$omp parallel
447<ompts:orphan>
448!$omp do schedule(dynamic,1) <ompts:check>reduction(MAX:max_value)</ompts:check>
449 DO i = 1, LOOPCOUNT
450 max_value = MAX(max_value,int_array(i) )
451 END DO
452!$omp end do
453</ompts:orphan>
454!$omp end parallel
455
456 IF ( max_value .LT. LOOPCOUNT )THEN
457 result = result + 1
458 WRITE(1,*) "Error in integer MAX"
459 END IF
460
461!... test double min, max
462 DO i=1,LOOPCOUNT
463 d_array(i) = 10 - i*dt
464 END DO
465
466 dmin = 2**10
467 dt = 0.5
468
469!$omp parallel
470<ompts:orphan>
471!$omp do schedule(dynamic,1) <ompts:check>reduction(MIN:dmin)</ompts:check>
472 DO i = 1, LOOPCOUNT
473 dmin= MIN(dmin,d_array(i) )
474 END DO
475!$omp end do
476</ompts:orphan>
477!$omp end parallel
478
479 IF ( dmin .GT. (10-dt) )THEN
480 result = result + 1
481 WRITE(1,*) "Error in double MIN"
482 END IF
483
484
485 DO i=1,LOOPCOUNT
486 d_array(i) = i * dt
487 END DO
488
489 dmax= - (2**10)
490
491!$omp parallel
492<ompts:orphan>
493!$omp do schedule(dynamic,1) <ompts:check>reduction(MAX:dmax)</ompts:check>
494 DO i = 1, LOOPCOUNT
495 dmax= MAX(dmax,d_array(i) )
496 END DO
497!$omp end do
498</ompts:orphan>
499!$omp end parallel
500
501 IF ( dmax .LT. LOOPCOUNT*dt )THEN
502 result = result + 1
503 WRITE(1,*) "Error in double MAX"
504 END IF
505
506 IF ( result .EQ. 0 ) THEN
507 <testfunctionname></testfunctionname> = 1
508 ELSE
509 <testfunctionname></testfunctionname> = 0
510 END IF
511
512 END FUNCTION
513</ompts:testcode>
514</ompts:test>