[Fortran][PATCH][gomp4]: Transform OpenACC loop directive
Tobias Burnus
burnus@net-b.de
Tue Mar 25 23:28:00 GMT 2014
Hi Ilmir,
Ilmir Usmanov wrote:
>> For DO CONCURRENT, it is not.
> I always forget about this kind of loops.
And I tend to forget about the issues with mask as I don't use do
concurrent with mask.
>> * And do concurrent also supports masks:
>>
>> logical :: my_mask(3)
>> integer :: i, b(3)
>> b(i) = [5, 5, 2]
>> my_mask = [.true., .false., .true.]
>> do concurrent (i=1:3, b(i) == 5 .and. my_mask(i))
>> b(i) = -42
>> end do
>> end
> This is doable: generate mask conditions inside of the deepest for
> loop (see applied patch). So, GENERIC of your example will be like:
> #pragma acc loop collapse(1)
> for (i = 1; i < 3; i++)
> {
> if (b[i-1] == 5 && my_mask[i-1])
> {
> b[i-1] = -42;
> }
> }
That will work in the most common cases but not in general. At least it
is my understanding that Fortran requires that one first evaluates the
mask expression before one enters the loop. That's made explicit for
FORALL and DO CONCURRENT uses a forall header and does some refs to
FORALL (esp. 7.2.4.2.2 and 7.2.4.2.3), but it does not state so explicitly.
In particular, the following example shows a difference between creating
a temporary array for the mask and putting the condition in the loop
without a temporary. On my system, the example will give:
1 -1 -20 -2 -30
-10 -1 -20 -2 -30
I think you willl get the same result as on line 1 instead of the one of
line two. Thus, one will need a temporary (cf. PR60661 for a
missed-optimization tracking to avoid the temporary.)
Example:
implicit none
integer :: i, n
integer :: b(5)
n = 5
b = [1, -1, 2, -2, 3]
do i = 1, n
if (.not. (b(i) > 0)) cycle
b(n-i+1) = b(n-i+1)*(-10)
end do
print *, b
b = [1, -1, 2, -2, 3]
do concurrent (i = 1:n, b(i) > 0)
b(n-i+1) = b(n-i+1)*(-10)
end do
print *, b
end
Otherwise, the patch looks good to me.
Tobias
More information about the Gcc-patches
mailing list