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

Crashing of the program (matrix 500 x 500)

Lukas_W_
Beginner
1,438 Views

Good day,

In the main subroutine is declared a matrix size of 500 times 500. This matrix is transferred to the subroutine Set_null. In the subroutine Set_null I want another matrix (matrix_work) of the same size (a_matrix), but the program crashes. I have simplified the example to a minimum so that the problem still existed (see figures).

If you make
the same thing, but for matrix 300 by 300 everything is OK (
MAX_SIZE = 300).
If you use matrix_work allocatable everything is OK.

Intel Fortran Compiler 11.1.067.

Best regards
Lukas Weis

[fortran]

 

 !*******************************************************************************
  ! Experiment6 - Padani.
  !*******************************************************************************
  subroutine Experiment6    
    implicit none
    integer(4), parameter ::                  MAX_SIZE = 500
    real(8), dimension(MAX_SIZE, MAX_SIZE)::  a_matrix
 

      call Set_null(a_matrix(1:MAX_SIZE, 1:MAX_SIZE))

    
    return
  contains
    
    !*******************************************************************************
    ! Nulovani matice.
    !*******************************************************************************
    pure subroutine Set_null(matrix)
      implicit none
      real(8), intent(inout), dimension(:,:) ::                        matrix
      real(8), dimension(size(matrix, dim=1), size(matrix, dim=2)) ::  matrix_work
      
      matrix = 0.d0
      matrix_work = 0.d0
      
      return
    end subroutine
    
  end subroutine Experiment6

[/fortran]

0 Kudos
27 Replies
Steven_L_Intel1
Employee
1,149 Views

Stack overflow. Easy fix is to set the property Fortran > Optimization > Heap Arrays to 0. (I think that was in 11.1.) Or add /heap-arrays to the options list. Other choice is to set the Linker > System > Stack Reserve size to some larger value, say, 100000000. (Don't go above that unless you need to.

See Doctor Fortran - Don't Blow Your Stack!

0 Kudos
John_Campbell
New Contributor II
1,149 Views

Steve,

I am surprised that this is a stack overflow problem, as the matrices are 500 x 500 x 8 = 2mb. Given there are 2 matrices and a possible copy for the array sections, that's only 6mb, which is not a big demand on the stack.  I suspect there could be other heavy demands for exercises 1-5 ?

The more robust solution would be to make these arrays allocatable, or place them in a module or a common block.

Could I suggest that the Stack Reserve size selection is a bit unfriendly. Any consideration to supporting 100m or 100mb instead of 100000000.

John

0 Kudos
Bernard
Valued Contributor I
1,149 Views

@Lukas

Maybe your stack allocation crossed boundary of guard pages?When you inspect raw stack data specific pattern(I do not remeber which exactly) will be overwritten by your matrix allocation.

0 Kudos
mecej4
Honored Contributor III
1,149 Views

John Campbell wrote:

I am surprised that this is a stack overflow problem, as the matrices are 500 x 500 x 8 = 2mb.

The default stack size is set by the linker (a utility provided by MS with VC/WSDK) to 1 Mb. 

Could I suggest that the Stack Reserve size selection is a bit unfriendly. Any consideration to supporting 100m or 100mb instead of 100000000.

The linker accepts a stack size specification in decimal or hex. Thus, /stack:0x7000000 would provide over 100 Mb of stack.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,149 Views

>>Could I suggest that the Stack Reserve size selection is a bit unfriendly. Any consideration to supporting 100m or 100mb instead of 100000000.

I caution against that. Lukas is on a 32-bit system (at least the application is 32-bit). Assuming he gets the single threaded version to work with 100mb stack. If he then options to go multi-threaded, say on a 4 core with HT system (not unreasonable), then this would require 800MB of RAM (possibly 900MB if there is an additional monitor tread created). The best route is to use heap arrays or do the allocation.

Jim Dempsey

0 Kudos
mecej4
Honored Contributor III
1,149 Views

jimdempseyatthecove wrote:

I caution against that. 

Jim, my reading of John Campbell's post suggested a slightly different reason for his request. Rather than requesting a new (and large) default stack size, he asked for the suffix 'mb' or 'Mb' to be allowed, so that he could write /stack:100MB instead of the longer /stack:100000000.

0 Kudos
Steven_L_Intel1
Employee
1,149 Views

This is an MS linker option, we have no control over it.

The routine set_null declares an automatic array matrix_work - this is put on the stack by default. It could also make sense to declare this ALLOCATABLE and allocate it to the desired size. I prefer this to changing the stack size. It will get automatically deallocated on routine exit.

0 Kudos
John_Campbell
New Contributor II
1,149 Views

The stack size allocation is not just 1mb, as the following examples show.
I tested the following examples on XE 2011 IA-32 and did not get a stack overflow for the first example, but did for the second. There must be some recognition of the stack requirement for local arrays that are explicitly sized.

As much is practical, I always avoid the use of stack for temporary arrays, certainly those larger than 20 kbytes.  Stack overflow errors should be avoided, rather than changing the stack size. As Jim indicates, this becomes much more important for OpenMP when replicating private arrays.

[fortran]

      call Experiment6    !  this example works with no stack overflow
      end
 
!*******************************************************************************
! Experiment6 - Padani.
!*******************************************************************************

      subroutine Experiment6  

      implicit none
      integer(4), parameter ::                  MAX_SIZE = 500
      real(8), dimension(MAX_SIZE, MAX_SIZE) :: a_matrix

      write (*,*) 'size_of a_matrix =', sizeof (a_matrix),' bytes'

      call Set_null (a_matrix(1:MAX_SIZE, 1:MAX_SIZE))

      return

      contains

         !*******************************************************************************
         ! Nulovani matice.
         !*******************************************************************************

!        pure subroutine Set_null(matrix)
         subroutine Set_null(matrix)

         implicit none
         real(8), intent(inout), dimension(:,:) ::                       matrix
         real(8), dimension(size(matrix, dim=1), size(matrix, dim=2)) :: matrix_work

         matrix = 0.d0
         matrix_work = 0.d0

         write (*,*) 'size_of matrix_work =', sizeof (matrix_work),' bytes'

         return

         end subroutine

      end subroutine Experiment6[/fortran]

The following example fails at max_size = 400, indicating that a smaller default stack size has been allocated, probably about 2mb in size.

[fortran]

      do MAX_SIZE = 100,1000,100
         call Experiment6 (MAX_SIZE)
      end do

      end
 
!*******************************************************************************
! Experiment6 - Padani.
!*******************************************************************************

      subroutine Experiment6 (MAX_SIZE) 

      implicit none
      integer(4)                             :: MAX_SIZE
      real(8), dimension(MAX_SIZE, MAX_SIZE) :: a_matrix

      write (*,*) ' '
      write (*,*) 'Testing for MAX_SIZE =',max_size
      write (*,*) 'size_of a_matrix =', sizeof (a_matrix),' bytes'

      call Set_null (a_matrix(1:MAX_SIZE, 1:MAX_SIZE))

      return

      contains

         !*******************************************************************************
         ! Nulovani matice.
         !*******************************************************************************

!        pure subroutine Set_null(matrix)
         subroutine Set_null(matrix)

         implicit none
         real(8), intent(inout), dimension(:,:) ::                       matrix
         real(8), dimension(size(matrix, dim=1), size(matrix, dim=2)) :: matrix_work

         matrix = 0.d0
         matrix_work = 0.d0

         write (*,*) 'size_of matrix_work =', sizeof (matrix_work),' bytes'

         return

         end subroutine

      end subroutine Experiment6[/fortran]

John

ps: can we have a paste option that does not produce double lines for fortran code ?

0 Kudos
FortranFan
Honored Contributor III
1,149 Views

John Campbell wrote:

...

ps: can we have a paste option that does not produce double lines for fortran code ?

FWIW, I compose my responses in Word, paste code into Word first with a font setting of Courier New, and then add it to the forum comment section using "Paste from Word" option.  This works better for me, but YMMV.

0 Kudos
andrew_4619
Honored Contributor III
1,149 Views

[fortran]

subroutine GetintsDlg(imes,imax,ivals,nval)

        implicit none

        ! imax = max number of ints that can be returned

        ! itmp = array of integer returned

        ! nval = number of integers returned

        integer, intent(in)  :: imax, imes

        integer, intent(out) :: nval

        integer, intent(out) :: ivals(imax)

        integer(DWORD)       :: ret     

[/fortran]

Just trying that paste from word tip, which seems to work for me despite the fact it looks all wrong prior to hitting the submit button. Thanks for the tip the code format thing really bugs me.

 

 

0 Kudos
Steven_L_Intel1
Employee
1,149 Views

Use the Code button which is rightmost in the toolbar. Select Fortran as the language. No double spacing.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,149 Views

>>Use the Code button which is rightmost in the toolbar. Select Fortran as the language. No double spacing.

If you past from Linux gedit this works (no double space).
Paste from MS VS doesn't work
Paste from MS VS to MS NotePad, then Paste from NotePad (gets double space)

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,149 Views

I paste from VS all the time. In fact I just did it in another thread.

0 Kudos
FortranFan
Honored Contributor III
1,149 Views

Another reason I use Word is because then I've a locally saved copy of my topic/comments in case something wrong during posting on the forum site (which is a little too frequent for me in my work environment: IE8 (!) and poor extranet connectivity).

0 Kudos
TimP
Honored Contributor III
1,149 Views

In my last attempt, I went back and forth between linux and Windows, but ended up waiting a few hours until the file attach became successful.

I suppose the ability to paste may vary among browsers, with IE presumably having superior compatibility with Microsoft applications.

0 Kudos
andrew_4619
Honored Contributor III
1,149 Views

Steve Lionel (Intel) wrote:

I paste from VS all the time. In fact I just did it in another thread.

Pasting code from VS or Notepad always creates a mess for me. I am normally using chrome BTW. This suggests that success is dependant on a number of factors....

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,149 Views

VS copy and paste directly inline (not code button paste)

IF (IOPT .EQ. 1) THEN

!$OMP PARALLEL DO

!DIR$ VECTOR ALIGNED

DO 10 I=1,N

A(I)=DCONJG(A(I))

10 CONTINUE

END IF

C

VS copy and paste into code button

      IF (IOPT .EQ. 1) THEN
!$OMP PARALLEL DO
!DIR$ VECTOR ALIGNED
        DO 10 I=1,N
          A(I)=DCONJG(A(I))
   10   CONTINUE
      END IF
C

Jim

0 Kudos
Steven_L_Intel1
Employee
1,149 Views

I know copy and paste inline doesn't work. The code button does.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,149 Views

It worked that time.

VS C++ copy and paste into code window:

long SerialFib2( long n )
{
 if( n<2 )
  return n;
 long fib0 = 1; // most recent
 long fib1 = 1; // 1 prior to most recent
 long fib2 = 0; // 2 prior to most recent
 long i;
 for(i=2; i<n; ++i)
 {
  fib2 = fib1;
  fib1 = fib0;
  fib0 = fib1 + fib2;
 }
 return fib0;
}

Jim

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,050 Views

It is a mystery to me. Usually when I have something I really want in a post, it gets bunged up. Next a VC C++ copy followed by "paste from Word"

long SerialFib2( long n )

{

if( n<2 )

return n;

long fib0 = 1; // most recent

long fib1 = 1; // 1 prior to most recent

long fib2 = 0; // 2 prior to most recent

long i;

for(i=2; i<n; ++i)

{

fib2 = fib1;

fib1 = fib0;

fib0 = fib1 + fib2;

}

return fib0;

}

0 Kudos
Reply