1! Test optional arguments in reduction clauses.  The effect of
2! non-present arguments in reduction clauses is undefined, and is not tested
3! for.  The tests are based on those in reduction-1.f90.
4
5! { dg-do run }
6
7program optional_reduction
8  implicit none
9
10  integer :: rg, rw, rv, rc
11
12  rg = 0
13  rw = 0
14  rv = 0
15  rc = 0
16
17  call do_test(rg, rw, rv, rc)
18contains
19  subroutine do_test(rg, rw, rv, rc)
20    integer, parameter     :: n = 10, ng = 8, nw = 4, vl = 32
21    integer, optional      :: rg, rw, rv, rc
22    integer                :: i, vresult
23    integer, dimension (n) :: array
24
25    vresult = 0
26    do i = 1, n
27       array(i) = i
28    end do
29
30    !$acc parallel num_gangs(ng) copy(rg)
31    !$acc loop reduction(+:rg) gang
32    do i = 1, n
33       rg = rg + array(i)
34    end do
35    !$acc end parallel
36
37    !$acc parallel num_workers(nw) copy(rw)
38    !$acc loop reduction(+:rw) worker
39    do i = 1, n
40       rw = rw + array(i)
41    end do
42    !$acc end parallel
43
44    !$acc parallel vector_length(vl) copy(rv)
45    !$acc loop reduction(+:rv) vector
46    do i = 1, n
47       rv = rv + array(i)
48    end do
49    !$acc end parallel
50
51    !$acc parallel num_gangs(ng) num_workers(nw) vector_length(vl) copy(rc)
52    !$acc loop reduction(+:rc) gang worker vector
53    do i = 1, n
54       rc = rc + array(i)
55    end do
56    !$acc end parallel
57
58    ! Verify the results
59    do i = 1, n
60       vresult = vresult + array(i)
61    end do
62
63    if (rg .ne. vresult) STOP 1
64    if (rw .ne. vresult) STOP 2
65    if (rv .ne. vresult) STOP 3
66    if (rc .ne. vresult) STOP 4
67  end subroutine do_test
68end program optional_reduction
69