0

This post is clearly related to another one at MPI scatterv crashing for large N occasionally but I have removed all mention of MPI.

I am using the Intel compilers (ifort and ifx) from Intel OneAPI from the command line in Windows.

If I include the line B = transpose(B) in the following code then it will fail with

forrtl: severe (170): Program Exception - stack overflow
Image              PC                Routine            Line        Source             
temp.exe           00007FF653091D67  Unknown               Unknown  Unknown
temp.exe           00007FF653061216  Unknown               Unknown  Unknown
temp.exe           00007FF653091B8E  Unknown               Unknown  Unknown
temp.exe           00007FF653091F70  Unknown               Unknown  Unknown
KERNEL32.DLL       00007FFCA5547614  Unknown               Unknown  Unknown
ntdll.dll          00007FFCA5BE26B1  Unknown               Unknown  Unknown

If I replace with the line B1 = transpose(B) then it is fine.

If I reduce M (experiment suggests M <= 358 on my system) then it is fine.

If I use gfortran instead of intel compilers then it is fine.

So, is there anything fundamentally wrong with the following code?

program crash
  implicit none
  integer, parameter::dp = kind( 1.d0 )
  integer, parameter :: M = 1000, N = M, O = M        ! Matrix dimension (works OK up to M=358)
! real(dp) B(N,O), B1(N,O)
  real(dp), allocatable :: B(:,:), B1(:,:)
  allocate( B(N,O), B1(N,O) )

  B = 0
  B  = transpose(B)                 ! this fails with ifort and ifx under windows; it's fine with gfortran
! B1 = transpose(B)                 ! but this is fine

end program crash

To check compiler commands and version, here are the gruesome details: enter image description here

lastchance
  • 1,436
  • 1
  • 3
  • 12
  • Does naming a constant `O` count as fundamentally wrong? – francescalus Aug 16 '23 at 15:23
  • Where are you putting your array temporaries? – francescalus Aug 16 '23 at 15:23
  • @francescalus, I only named the constant ```O``` because it was thus in the related post. ```P``` would be fine (and the problem persists). I'm not sure what I should do about array temporaries. If I change the statement to ```B = B ** 2``` or ```B = sin(B)``` there is no problem. – lastchance Aug 16 '23 at 15:28
  • 1
    `B=B**2` can be done in place, unlike `B=transpose(B)`, so worth looking at whatever the Windows equivalent of `-heap-arrays` is. – francescalus Aug 16 '23 at 15:31
  • OK, I'll have a look at it. It doesn't like ```B = matmul( B, B )``` either. Probably for the same reason. Again, gfortran has no problems. – lastchance Aug 16 '23 at 15:33
  • @francescalus: Very good! ```ifort temp.f90 -heap-arrays``` seems to solve the problem. Would you like to explain why (and convert your solution to an answer)? – lastchance Aug 16 '23 at 15:38
  • 1
    The answer by IanH in the linked question covers about most of this (admittedly about a different form of array expression). The assignment `B1=transpose(B)` is a "restatement" (as that answer has it): as there's a brand new result array, individual elements can be populated without requiring the array temporary which `B=transpose(B)` would require. – francescalus Aug 16 '23 at 15:46
  • Thanks. This extra compiler option actually appears to solve the related problem with MPI from researcher_sp as well. – lastchance Aug 16 '23 at 15:49
  • I think (but this should be checked) that gfortran uses the heap instead of the stack when the size of the temporary object is above some threshold, which explains why it doesn't crash here. – PierU Aug 16 '23 at 16:23

0 Answers0