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