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

OpenMP : reduction clause

under7
Beginner
1,852 Views
Hi,

I stumbled upon a issue while trying to use the reduction clause of OpenMP with an array.

The standard specifies that : " Fortran pointers, Cray pointers, assumed-size arrays and allocatable arrays may not appear in a reduction clause ".

The provided code has the following output :
$ifort -openmp prog_bon.f90
prog_bon.f90(13) : (col. 8) remark: OpenMP DEFINED LOOP WAS PARALLELIZED.
prog_bon.f90(12) : (col. 8) remark: OpenMP DEFINED REGION WAS PARALLELIZED.
$ ./a.out
1 1 1 1 1 1
1 1 1 1
$ ifort -openmp prog_mauvais.f90
prog_mauvais.f90(25) : (col. 8) remark: OpenMP DEFINED LOOP WAS PARALLELIZED.
prog_mauvais.f90(24) : (col. 8) remark: OpenMP DEFINED REGION WAS PARALLELIZED.
$ ./a.out
Aborted
$


As you can see, during runtime, the application crashes when the compilor have no clue of the size of the array during compile-time.
That was using ifort 9.1.032 on an Itanium2 / RedHat and pentium-m / ubuntu system. Now, with 9.1.033, it works as I expected it to work, and both have the same ouput (at least, with the pentium-m / ubuntu system).


Does that mean that it is now supported by ifort, and that future releases will continue to support it? Or should I be wary of that?



Samples :
- code that works :
program reduc

implicit none
integer, parameter :: n = 10
integer, dimension(n) :: tab
integer :: i

tab = 0

call omp_set_num_threads(16)

!$omp parallel default( shared )
!$omp do &
!$omp private( i ) &
!$omp reduction( + : tab )
do i = 1, n
tab(i) = tab(i) + 1
end do
!$omp end do
!$omp end parallel

print *, tab
end program reduc



- code that does not work :
program reduc

implicit none
integer, parameter :: n = 10
integer, dimension(n) :: tab

call omp_set_num_threads(16)

call calc(n,tab)
print *, tab
end program reduc


subroutine calc(n,tab)

implicit none
integer, intent(in) :: n
integer, dimension(n), intent(inout) :: tab
integer :: i

tab = 0

!$omp parallel default( shared )
!$omp do &
!$omp private( i ) &
!$omp reduction( + : tab )
do i = 1, n
tab(i) = tab(i) + 1
end do
!$omp end do
!$omp end parallel

end subroutine calc


0 Kudos
10 Replies
Xiaogang_W_
Beginner
1,852 Views
I can confirm that a similar code got run-time error on
ifort 9.1.032 on itanium2. But it has no problems on ifort 8.1.

It is definitely a bug of ifort 9.1.032. (have not got chance
to test newer ifort 9.1). The bug happens when
the array used in "reduction" appears in calling parameters.

Xiaogang
0 Kudos
Steven_L_Intel1
Employee
1,852 Views
The example shown does not have any of the kinds of arrays the manual says are not supported. "array" is an adjustable array, not assumed-size.
0 Kudos
Xiaogang_W_
Beginner
1,852 Views
Exactly. So the example code should work. "reduction" on the
arrays in that code should work.
But it does not work on ifort 9.0.032 !!!


Xiaogang

0 Kudos
Steven_L_Intel1
Employee
1,852 Views
That it used to not work and now does sounds as if a bug was fixed. It has nothing to do with "support" of pointers, assumed-size or allocatable arrays, since this program doesn't use any of those. So it does not make sense to ask if these are now "supported".
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,852 Views

A couple of comments:

In the working example the value of the parameter n is known at time of loop compilation. n, by the way, is less than the number of processors. The loop may have been parallelized but with the restriction that the number of threads assigned may have been less than those available. In the non-working code the subroutine cannot assume anything about the value of n. So... what happens for both examples when you set n to 1000?

(I don't have your setup and cannot test here. I have a 4-way IA32 system)

The example code by the way does not require reduction as a given cell in tab is updated only by one of the available processors.

Jim

0 Kudos
under7
Beginner
1,852 Views
Well, I know that both examples that I submited should have compiled and executed normally (and also that they are totally moronic, that a reduction clause is not needed here), with identical results, since they are both within range of what is allowed by the OpenMP standard.

I just wanted to know if, since it was not supported in ifort 9.1.032, and it was by 9.1.033, it was now and would continue to be supported by future releases of ifort, or if it was still something that was in testing, thus not fully supported yet by ifort.


I tried with Compaq's f90 (don't know the version), and it simply refused to compile with an array in a reduction clause, whatever type the array may be. I stumbled upon a bug report of the GNU Fortran compiler, reporting it caused an Internal Compiler Error at compile-time. So, I do not find it ludicrous to ask if it could be used safely with ifort.


I submitted this to Intel Premier Support, and their answer was yes, that it was now fully suported by ifort.


0 Kudos
Steven_L_Intel1
Employee
1,852 Views
What I want to know is what is the "it" for which you want to know the support status? I haven't been able to determine that from your posts so far.
0 Kudos
under7
Beginner
1,852 Views
By "it", I meant the sample titled "code that does not work".

EDIT : enlarging the range of that sample, I would like to know if the OpenMP reduction clause is now fully supported by ifort, meaning any setup implying arrays (that are still within the scope of the standard, of course).
0 Kudos
Steven_L_Intel1
Employee
1,852 Views
The REDUCTION clause is fully supported and has been for a long time. Your sample program does not violate the OpenMP standard's restrictions on the list variables. It is likely that you encountered a bug that was fixed.
0 Kudos
under7
Beginner
1,852 Views
Thank you for the crystal clear answer.

Since the sample was that basic, and confronted by the lack of support from a few other compilers, I assumed that using an array within a reduction clause was still quite new to ifort (that is to say, before 9.1.033), thus not fully reliable.
0 Kudos
Reply