Use random_number with OpenMP flag

This code can be compiled with the -fopenmp flag on GFortran, but executing it produces an error message: line 7: 30040 Segmentation fault (core dumped). I understand that random_number is not thread-safe, but in this case I didn’t use any OpenMP functions/subroutines. I am using GFortran 12.1.1 on Fedora Linux 36.

program main
  real(8) :: x(10000000)
  call random_number(x)
  print *, maxval(x) 
end program
2 Likes

I find the same issue. According to the Gfortran docs each openmp thread has its own random number state so the size of the array (and precision) maybe causing an issue? I can get it to run if you decrease the size of the array by a factor of ten.
Intel’s compiler has the same error though nvfortran runs with no seg fault.

Check this Stack Overflow question out:
with -fopenmp all arrays are placed on the stack by default, so you may try to increase the stack size or make it allocatable:

program main
   real(8), allocatable :: x(:)
   allocate(x(10000000))
   call random_number(x)
  print *, maxval(x)
end program
3 Likes

Creating longer arrays works totally fine with OpenMP. The issue seems to come from the interaction between OpenMP and random_number. Not sure if seed entropy plays a role here.

As already mentioned by @FedericoPerini this is due to stack size limitation by the OS and that -fopenmp activates -frecursive which causes all local arrays to be allocated on the stack. If you do not want to change your code to use allocatable arrays, you have some choices. On linux you can do

ulimit -s unlimited

to remove restriction on stack size, after which the program executes normally.

Not sure what the best solution on windows would be though. Intel fortran has a -heap-arrays flag. GCC has a equivalent configuration here. Not sure if that will work for gfortran. One alternative for gfortran is to use -fopenmp -fmax-stack-var-size=n with a small n (default n=65536) to cancel the -frecursive’s effect. I will end saying i dont know why -fopenmp sets -frecursive and what kind of side effects there will be if -frecursive is not enabled.

This is really strange. I couldn’t replicate this issue when I don’t use random_number. Also, this issue doesn’t seem to exist for C++'s std::vector.

program main
  real(8) :: x(1000000000)
  x = 0.0_8
  print *, maxval(x)  
end program

This code works with the -fopenmp flag on my machine. That’s why I suspect the issue comes from random_number.

Adding on @Abhilash’s answer. Here is the bug report for gfortran with a full discussion on the lack of thread safety with -frecursive (among other things): 91413 – [F2018]: Procedures are recursive by default; switching from stack to static allocation is not safe

As I said, when not using random_number, I don’t have this issue. So it is probably unrelated to restriction on stack size.

random_number uses/needs some stack memory as well, so the amount of stack memory used will be greater when random_number is called compared to when it isn’t.

You can put this to rest yourself by running the program with different limits on stack size and see that once the stack size is large enough the program runs fine.

ulimit -s unlimited

doesn’t solve the issue in my case. I guess I will stick to using allocatable.

found this bug report:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85364