Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Reduction clause

Martin_Stein
Beginner
906 Views
I have been experimenting with the reduction clause and stumbled over two problems. I am using Ifort 10 and the documentation that comes along with it.

(1) Due to documentation a reduced max operator is supposed to intialise the private copies used by the thread to the largest representable value. This looks like a misprint and should be the smallest representable number (=neutral element in the max operator semigroup). However the code does not bother to do any initialisation. A little bit of testing shows that if I split the omp parallel do to a omp parallel and omp do and attach the reduction clause to the omp parallel clause, then the variable gets initialise. Looks like a bug?

(2) In a thread written a year ago which I found while searching for reduction related threads, I read that ifort does not support array variables in a reduction clause. Using an explicit-shape array works fine for me, and the documentation states likewise. So I assume the answer given in the mentioned thread is wrong (thread can easily be found by the search keywords "reduction clause"). So just to clarify things, does ifort10 correctly supports explicit shaped arrays in a reduction clause?

(edit: the formulation of (2) was a bit muddled)
0 Kudos
5 Replies
Martin_Stein
Beginner
906 Views
Regarding (1) I have to correct myself a little bit: It does not work with a split omp parallel/omp do clause as well. Even more:

!$omp parallel default(shared) private(i)
!$omp& reduction(max: value)
write(*,*) 'value: ', value
!$omp barrier
!$omp do schedule(static)
do i = 1,N
value = max(value, Arr(i))
end do
!$omp end do
!$omp end parallel
write(*,*) value

where value and array are real(8), gives the following: Each thread outputs something like -1e308, but then value = 0.0 is used or whatever I have initialised it with before diving into the omp parallel scope. This behavious looks pretty strange to me?
0 Kudos
jimdempseyatthecove
Honored Contributor III
906 Views
What is in Arr?

What does the following show?

!$omp parallel default(shared) private(i)
!$omp& reduction(max: value)
write(*,*) 'value: ', value
!$omp barrier
!$omp do schedule(static)
do i = 1,N
value = max(value, Arr(i))
end do
!$omp end do
!$omp critical
write(*,*) omp_get_thread_num(), value
!$omp end critical
!$omp end parallel
write(*,*) value

Jim Dempsey
0 Kudos
Martin_Stein
Beginner
906 Views
I ran the code with the additional output and the conclusion is as follows:

The thread-private instances of value are initialised as expected with about -1e308, the threads compute the local maxima correctly and print it correctly, the final update however depends on the number of the shared instance of value. If it is not initialised and hence has some random number in it and if the values in Arr are all chosen to be smaller than this random number, then the final result is this wrong random number. If value is initialised correctly, the result is correct.

I expected that the shared instance is also initialised with the smallest representable number automatically by the compiler. However after consulting the openmp-specs It is clear that the user has to initialise the shared variable himself, and the compiler behaves accordingly.

0 Kudos
Martin_Stein
Beginner
906 Views
Well, the openmp spec as well as iforts documentation clearly states the thread-private copies of a variable mentioned in a reduction close are initialised with a suitable (a neutral element with respect to the reduced operation, in this case max) value. What I missed was the fact that the shared instance is not initialised, that has to be done by the programmer before the omp block. Hence it is not only expected but as it should be? Or did I misread your question?
0 Kudos
TimP
Honored Contributor III
906 Views
OK, sorry, I misread your post, thanks for clarification.
0 Kudos
Reply