Temporary variables inside Fortran `forall` or `do concurrent`
I have an array assignment that I formulated using forall. The indices to
one array have to be computed from the loop variables, so I tried to use
temporary variables in a way analogous to ii this simple example:
program test
integer :: i, ii, a(10), b(20)
a=(/(i, i=1,10)/)
forall (i=1:20)
ii = (i+1)/2
b(i) = a(ii)
end forall
print '(20I3)', b
end program test
But gfortran warns me that "The FORALL with index 'i' is not used on the
left side of the assignment at (1) and so might cause multiple assignment
to this object", and indeed the output is not what I wanted:
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
(ifort even throws an error.) I realize I could just repeat the definition
of ii every time it appears, but that can get tedious in real-life cases.
Q1: Is there a way to do this sort of thing correctly using forall?
Now, as you can read in some other questions, forall no longer seems to be
recommended, and a straight do may be faster.
However, my use of forall in this instance was as much about readability
as about speed. In my real program, I have something like forall (i=1:10,
j=1:10, i<=10), and I like the way the forall header lets me specify this
without nested loops.
I also learned about do concurrent in those questions, and that seems to
solve the problem, i.e. replacing forall above with do concurrent, the
output becomes:
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
and I still get to use a forall header.
Q2: Is that guaranteed to work, rather than specific to gfortran?
Unfortunately, for now I cannot use do concurrent anyway, because slightly
older ifort and gfortran versions do not support it.
No comments:
Post a Comment