Silverfrost Forums

Welcome to our forums

Salford run-time library

11 Jan 2017 5:13 (Edited: 11 Jan 2017 7:40) #18689

I do not use Plato and usually compile all my codes using BAT files.

So if call your program r.f95 and extend stack to 500MB, and then run this batch file below (pushing F6 to start the program under debugger). all ends with no problems.

ftn95 r.f95 /checkmate
slink r.obj /stack:500000000
sdbg r.EXE
11 Jan 2017 7:08 #18690

rayla_lsy,

I have modified (untested!!) the code you posted to replace local and automatic arrays with ALLOCATE arrays. This should reduce the stack requirement. Compile and test and hopefully it will work better.

John

 program test 
 integer, parameter :: ikind_real = selected_real_kind(p=8 ) 
 integer, parameter :: NP106 = 70695 
 real(kind = ikind_real), ALLOCATABLE :: rcoeff_dist(:,:)
 integer :: stat, n
 
 allocate ( rcoeff_dist (NP106,28 ), stat=stat )
  call check_allocate ( 'rcoeff_dist (NP106,28 )', stat )

 call init_random_seed() 
 n=28 
 call r8_normal_mn(rcoeff_dist,NP106,n) 
 end program test 

 !======================================================================================================================================== 
 !A subroutine to generate random variable from N(0,1) 
 !======================================================================================================================================== 


 subroutine r8_normal_mn(X,m,n) 
 implicit none 
 integer, parameter :: ikind_real= selected_real_kind(p=8 ) 
 integer :: m,n, i,j, stat
 real(kind = ikind_real), allocatable, dimension(:,:) :: r1,r2 
 real, parameter :: r4_pi = 3.141592653589793E+00 
 real(kind = ikind_real), dimension(m,n) :: X 

 allocate ( r1(m,n), stat = stat )  ; call check_allocate ( 'r1(m,n)', stat )
 allocate ( r2(m,n), stat = stat )  ; call check_allocate ( 'r2(m,n)', stat )

 call psurand(r1,m,n) 
 call psurand(r2,m,n) 

 do i = 1,m 
 do j = 1,n 
 X(i,j) = sqrt ( - 2.0E+00 * log ( r1(i,j) ) ) * cos ( 2.0E+00 * r4_pi * r2(i,j) ) 
 end do 
 end do 
 write (*,*) 'X initialised'
 return 
 end subroutine r8_normal_mn 

 ! ======================================================================================================================================== 
 ! A subroutine to generate random vector for uniform distribution 
 ! ======================================================================================================================================== 
 subroutine psurand(X,m,n) 
 implicit none 
 integer :: m,n 
 integer, parameter :: ikind_real = selected_real_kind(p=8 ) 
 real(kind = ikind_real), dimension(m,n) :: X 
 CALL RANDOM_NUMBER(HARVEST = X) 
 END subroutine psurand 

 !======================================================================================================================================== 
 ! A subroutine to generate seed 
 !======================================================================================================================================== 

 !We just need to regenerate the seed each time I am starting the program. 

 subroutine init_random_seed() 

 INTEGER :: i, n, clock 
 INTEGER, DIMENSION( : ), ALLOCATABLE :: seed 

 CALL RANDOM_SEED(size = n) 
 ALLOCATE(seed(n)) 

 CALL SYSTEM_CLOCK(COUNT=clock) 

 seed = clock + 37 * (/ (i - 1, i = 1, n) /) 
 CALL RANDOM_SEED(PUT = seed) 
 DEALLOCATE(seed) 

 end subroutine init_random_seed

 subroutine check_allocate ( array, stat )
   character array*(*)
   integer   stat
!
   if ( stat /= 0 ) then
     write (*,*) 'Unable to allocate array ',array,' stat=',stat
     stop
   else
     write (*,*) 'array :',array,' allocated sucessfully'
   end if
 end subroutine check_allocate
11 Jan 2017 4:48 #18691

Thank you all for your help!

11 Jan 2017 10:25 #18692

Paul,

Some compilers provide an option that local and automatic arrays (optionally above a specified size) do not go on the stack, but are allocated using ALLOCATE/malloc. My preference would be that this is the default, as placing large arrays onto the stack often creates problems, especially for FTN95 users who are not familiar with stack management.

Could an option /heap_arrays:size be provided ? (I can't see it documented) Size could be array size in bytes.

I note Help:'Efficient use of Fortran 95' states 'Temporary arrays (required only during the life time of a function call) are better implemented using automatic arrays in preference to ALLOCATABLE arrays because these can be allocated more efficiently.' Would the option /heap_arrays of all local and automatic arrays being allocated provide a significant performance problem ? If not, it should be the default. Perhaps /heap_arrays:1k should be a default.

This option would certainly make a significant proportion of stack overflow errors (most) disappear.

John

12 Jan 2017 7:22 #18693

John

As far as 64 bit compilation is concerned, we are working on that right now.

Automatic arrays are allocated on a virtual stack and we are looking to make all static arrays above a certain size behave like automatic arrays.

There is something similar for 32 bit compilation but it is currently only applied to arrays in the main program.

The plan is not to have an option but to make it happen anyway.

13 Jan 2017 8:56 #18697

On this planet it is only compiler developers who love stack hell knows why (even in 64bits case -- 'virtual stack')

For original poster here how to run his code in 64bits without stack. Errors of compilation are collected in ErrCompil and ErrLink

ftn95 r.f95 /64 /debug     >ErrCompil
slink64 r.obj /file:r.exe  >ErrLink
sdbg64 r.EXE 
Please login to reply.