OpenMP Array Reduction in Fortran

OpenMP Array Reduction in Fortran

Imagen de rmf166

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

publicaciones de 6 / 0 nuevos
Último envío
Para obtener más información sobre las optimizaciones del compilador, consulte el aviso sobre la optimización.
Imagen de Sergey Kostrov

Hi,
You can get answers much faster if you ask on Intel Fortran forum. Sorry for my generic response.
Best regards,
Sergey

Imagen de Tim Prince

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.

Imagen de rmf166

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!

Imagen de rmf166

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!

Imagen de Sergey Kostrov

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.

Inicie sesión para dejar un comentario.