The following code and variations of it often but not always abort with a segfault if compiled with option -qopenmp in Linux. Using valgrind I always see invalid reads and sometimes invalid writes and conditional jumps depending on uninitialised data, depending on the code variation I run.
Without command line option -qopenmp, everything looks fine. However, note that there is no parallel region. Traceback by valgrind points to the memory allocator.
Anyway, in order to get invalid reads (writes...), I also need recursion and a local variable with allocatable component. Interestingly, if I put the local variable tmp in a block section (and the code of the subroutine as well, obviously) then it works without complains from valgrind.
As I mentioned I have tried some variants, all of which failed. In particular I have tried it with a character(len=:), allocatable variable and some character actions. I actually see this problem in recursive parser code, where it always crashs at some point. This looks like a big show-stopper for any modern code which uses openmp, where recursion and allocatable components are common.
module mod implicit none public type :: t integer, dimension(:), allocatable :: a end type t contains recursive subroutine rec(c, n, x) integer, dimension(:), intent(in) :: c integer, intent(in) :: n type(t), intent(out) :: x type(t) :: tmp if (n > 0) then call rec(c, n-1, tmp) x%a = tmp%a x%a(n) = x%a(n) + 1 else x%a = c end if end subroutine rec end module mod program alloc_rec use mod implicit none type(t) :: s call rec([1,2,4], 2, s) print *,s%a end program alloc_rec
While this is a compiler bug, see if the following changes resolve the issue:
type(t), automatic, :: tmp
Note, automatic is (supposed to be) implicit with -qopenmp and/or recursive procedures.
Older Fortran standards (older versions of Intel's Fortrans), for non -qopenmp and/or recursive procedures, implicitly had UDT's and arrays SAVE.
IIF this corrects the problem, then it is likely that there is an improper IF (...) THEN ... ELSE ... ENDIF in the compiler code. IOW it is erroneously making the UDT's static.
Please report back if this corrects the problem.
actually, @jimdempseyatthecove you can change tmp to save to work around the issue
type(t), save :: tmp
still, appears to be a bug that you have to do that with IFX. I'm checking with our OMP architect on this issue.
IFX has to allow OMP offload so, yes, -qopenmp takes different code paths in IFX than IFORT. IFX took a wrong turn at Albuquerque.
I went there once for four days. Starting raining as I landed, taxi driver said never rains here, four days later as I got on the plane it was still raining, taxi driver on way to airport said never seen this before.
Sir, we have never known a period of 3 weeks without rain to my father, wonderful weather.
Never trust a weatherman, statistically they are wrong about 30% of the time.
>>...you can change tmp to save to work around the issue
No, Ron, it is the opposite. The point is to force tmp (actually the array descriptor for tmp) to be stack allocated.
My suspicion is the error is induced in the user's program by the array descriptor for tmp being (implicitly) SAVE as would be for the older implementations of Fortran, and by explicitly tagging it with automatic (unnecessary with newer versions of Fortran) is a means to workaround this bug.