Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

OpenMP Array Reduction in Fortran

rmf166
Beginner
1,324 Views

Howdy,

I have two simple questions.

First, are Fortran arrays used in the OpenMP REDUCTION clause considered PRIVATE or FIRSTPRIVATE? In other words, are they assumed to be initialized or uninitialized?

Secondly, is it possible to perform a reduction on only part of an array? Sometimes it is advantageous to update only a portion of an array in iterative schemes instead of the entirety of the array, i.e. instead of updating all elements of a(1:i2), only update elements a(i1:i2).

Thanks in advance

0 Kudos
5 Replies
SergeyKostrov
Valued Contributor II
1,324 Views
Hi, You can get answers much faster if you ask on Intel Fortran forum. Sorry for my generic response. Best regards, Sergey
0 Kudos
TimP
Honored Contributor III
1,324 Views
According to my copy of Chapman, Jost, van der Pas, the visible array used in a Fortran OpenMP array reduction must be a shared array. The implementation will use implicit hidden private arrays which aren't accessible to the program. It certainly appears that a section of a shared array qualifies, and that this section must be defined prior to the parallel region (and is useless unless defined when the parallel completes). I haven't seen any test cases which would be sufficient to determine meaningful differences in how various OpenMP compilers implement this. As the question is specific to Intel Fortran, I agree with Sergey that you ought to pick one of the Intel Fortran forums, according to your OS of interest.
0 Kudos
rmf166
Beginner
1,324 Views
Sergey, TimP- Thank you for your responses. I will go ahead and post a message on the Intel Fortran board. Regarding the visible variable declaration, I think I misstated my question. I do understand that the array on which the REDUCTION is performed needs to be declared as shared. I was wondering if the hidden private arrays are initialized to zero or to the visible shared array in the REDUCTION declaration. I would've guessed they are initialized to the shared array values set before the do-loop/reduction. I performed the following test using Intel Fortran 11.1 on a Linux 64-bit machine using 1 thread ! Initialize a(1,1:10)=1.0d0 a(2,1:5)=1.0d0 a(2,6:10)=2.0d0 !$ nthreads=1 !$ call omp_set_num_threads(nthreads) !$ omp parallel do private(i) reduction(+:a) do i=1, 10 a(2,i)=a(2,i)+a(1,i) end do !$ omp end parallel do Compiling the code without the -openmp flag yields the correct result, i.e. a(2,1:5)=2 and a(2,6:10)=3. However, compiling with the -openmp results is a(2,1:5)=1 and a(2,6:10)=2. What seems to happen here is that the private copy of "a", a_priv, is initialized as a_priv(1,1:10)=0.0d0, and a_prive(2,1:10)=a(2,1:10), I think. Regarding the second question, I took the code shown above and reduced the dimension of a to a(1:10) and added 1.0d0 inside the loop. If I changed the extent of the loop to i=1, 5 then the reduction did in fact only affect elements a(1:5), and left a(6:10) as initialized, resulting in the correct values for a. I'll go over to Intel Fortran and post a similar message to see what they say. Feel free to comment, thanks!
0 Kudos
rmf166
Beginner
1,324 Views
Hello again, I just wanted to follow up with the solution to this post. If you go to http://openmp.org/wp/openmp-specifications/ and read the specs (I looked at OpenMP 3.0), it turns out that invisible or private copies of the shared array under a reduction operator are set to 0 by default when using the addition operator. Once the parallel loop is executed, these values are added to the shared array, however it has been initialized. Hence in the code shown above, if OpenMP is used, the values of the private array are a_priv=0.0d0, so the loop simply returns the original initialization. Conversely, if OpenMP is NOT used, then we get the expected results. The second question may be answered along similar lines. That is, since all private or invisible copies of a are initialized to zero, then performing a reduction on all (or part of the shared array a), yields the same result, since all indices left unchanged have a value of zero for each private copy. Thanks for the help!
0 Kudos
SergeyKostrov
Valued Contributor II
1,324 Views
Hi, >>If you go to http://openmp.org/wp/openmp-specifications/ and read the specs >>(I looked at OpenMP 3.0), it turns out that invisible or private copies of the >>shared array under a reduction operator are set to 0 by default when using >>the addition operator. Once the parallel loop is executed, these values >>are added to the shared array, however it has been initialized. I'll check it. Thnks for the update.
0 Kudos
Reply