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

OpenMP side-effect

bendel_boy1
Beginner
710 Views

I have code of the form

!$OMP PARALLEL DO

do i = 1, NumberOfUnits

select case (Unit(i)$ID)

case (1); CALL Unit1

...

end select

end do

!$OMP END PARALLEL DO

Unit1 is defined something along the lines of

integer, parameter:: NC = 13, NR = 12

double precision:: s(nc, nr)

and subsequently I have a loop

do i = 1, NC

do j = 1, NR

if (s(i,j) .ne. 0d0) then

dy(index) = dy(index) + reaction_rate(j) * s(i,j)

end if

end do

WIth OPM not enabled this runs.

With OMP enabled this fails witha message along the lines of

'At line 257 array s is accessed with first index of 14, exceeding upper bound of 13'

I'm using an elderly version of IVF: Intel Fortran Compiler Integration for Microsoft Visual Studio 2005, Version 9.1.3291.2005, Copyright (C) 2002-2006 Intel Corporation

Is this a known bug, to be resolved by either ignoring OMP or trying to get authorisation to upgrade? Or is there something I can do?

(The whole project is large, & I have no desire to try & break it down to something small ...)

0 Kudos
6 Replies
jimdempseyatthecove
Honored Contributor III
710 Views

Is variable i (at line of error) shared or private?

Also, in Fortran, performance is better when the left most array index is iterated on the inner most loop.

Jim Dempsey

0 Kudos
bendel_boy1
Beginner
710 Views

Thanks.

I is whatever the default is - so I'll try changing to provaye.

The loops I can swap over.

0 Kudos
bendel_boy1
Beginner
710 Views

Because I have the parallel DO in the calling routine, and the errant shared I in a DO block within a called routine, how do I go about flagging that the variable should be private? I tried

!$OMP PRIVATE (I, J)

and got an error message that this must be tied in with a parallel DO declaration - but the parallel DO is not in the immediate scope. Because I am using old Netlib code I have all variables DEFAULT SAVE - is this behind the problem? (When I try to recompile with AUTOMATIC allocation the compilation crashes.)

0 Kudos
TimP
Honored Contributor III
710 Views

As long as your DO loop index has local scope, in OpenMP Fortran it will always default to PRIVATE.

You can't mix default SAVE compile options with OpenMP. If you are trying to retain the DO index between subroutine invocations by SAVE (a chancy thing), you would likely require FIRSTPRIVATE and LASTPRIVATE.

If the compiler gives you an error message when you set /Qopenmp or /Qauto, or follow Steve Lionel's recommendation and designate the routines RECURSIVE, you must address the error. If it's an internal error report, that is a compiler bug, which you should report if it occurs in a current version, even if it stems from your choice of an incorrect combination of options.

0 Kudos
Martyn_C_Intel
Employee
710 Views
Quoting bendel boy

Because I have the parallel DO in the calling routine, and the errant shared I in a DO block within a called routine, how do I go about flagging that the variable should be private? I tried

!$OMP PRIVATE (I, J)

and got an error message that this must be tied in with a parallel DO declaration - but the parallel DO is not in the immediate scope. Because I am using old Netlib code I have all variables DEFAULT SAVE - is this behind the problem? (When I try to recompile with AUTOMATIC allocation the compilation crashes.)

Your subroutine UNIT1 needs to be threadsafe. Changing OpenMP directives in the calling routine has no effect on this, because the two compilations are independent. This is normally taken care of automatically, becaue when you compile UNIT1 with /Qopenmp (or /Qauto), both scalar and array local variables are allocated on the stack; since each thread gets itsown private stack, each thread gets its own copy of each local variable, and the threads don't overwrite each other. But if you override this by making all the local variables default to SAVE, a single copy gets allocated on the heap, and all the threads will write to the same copy, overwriting each other.

If you are not willing to make your whole program work without making SAVE the default, (with just an explicit SAVE for those variables whose value needs to be preserved from one subroutine call to another), then you will need to at least remove the SAVE default for those subroutines that may be called from inside an OpenMP parallel region. The loop indices I and J are obvious examples of where you would get an error if these were declared as SAVE.

There was a suggestion above that you could compile with /recursive or declare the routine as RECURSIVE. This would work (as would /Qauto or /Qopenmp) for overriding the default storage type, but I'm not sure that it will work if you have explicit SAVE statements or attributes - I do know that /Qauto or /Qopenmp will not override explicit SAVE statements. Others may know more.

0 Kudos
Steven_L_Intel1
Employee
710 Views
RECURSIVE does not override SAVE. Nothing does.
0 Kudos
Reply