forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Salford run-time library
Goto page Previous  1, 2
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Plato
View previous topic :: View next topic  
Author Message
rayla_lsy



Joined: 23 Dec 2016
Posts: 6

PostPosted: Mon Jan 09, 2017 6:58 pm    Post subject: Re: Reply with quote

Hi, I ran into a similar problem.

I can run my program under release mode, but cannot do it under checkmate mode.

My program involves generating a large random matrix. I can actually run my code under the checkmate mode if I reduce the size of the matrix. I prefer to use checkmate at this stage, is there any way I can solve this problem and run it under checkmate mode without changing the size of my matrix?

Thanks



PaulLaidler wrote:
How big is your program? Can you post it here?
If not then can you produce the failure in a small program?

You may need a larger stack size when linking but it may be a programming error.
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 739

PostPosted: Mon Jan 09, 2017 11:42 pm    Post subject: Reply with quote

How are you allocating the array for the matrix? If the array is a local automatic variable, you may be able to do better by making it an allocatable array.

In any case, some details regarding what your code looks like and what it is intended to do would be needed in order to offer suggestions on improving it.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1834
Location: Sydney

PostPosted: Tue Jan 10, 2017 12:10 am    Post subject: Reply with quote

You have not indicated the size of the array or the method of allocation.

Here is a cleaner example of using an allocatable array. This works up to varying sizes, depending on the compile option selected in Plato.
Checkmate32 : 923 mb works
Debug Win32 : 1953 mb works
Release Win32 : 1953 mb works
Release x64 : 6866 mb + works ( with adequate virtual/physical memory )

Code:
!  program to have large arrays not on the stack
 module aaa
    real*8, allocatable :: a_array(:,:)
 end module aaa

 program test_a
 use aaa
    integer*4 n,stat,mb
!
!  use a_array
    do n = 1000,30000,1000
      mb = ((n*n)/1024)*8/1024
!
      allocate (a_array(n,n),stat=stat)
      if ( stat /= 0 ) then
        write (*,*) 'a_array set to',n,' stat=',stat
        write (*,*) 'unable to allocate array',mb,' mb'
        stop
      end if
!
      a_array = n
      write (*,*) 'a_array size =',mb,' mb is ok'
!
      call use_a_array ( a_array, n )
!
      deallocate (a_array)
    end do
  end program test_a

  subroutine use_a_array ( a_array, n )
    integer*4 n
    real*8    a_array(n,n)
  end subroutine use_a_array


Allocating an array in a MODULE is the best approach to solve your problem, although with Cheakmate, you will have smaller contiguous memory available.
Compiling with Release x64 will give the largest array possible, although don't exceed your available memory.

John
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 1645
Location: South Pole, Antarctica

PostPosted: Tue Jan 10, 2017 9:37 am    Post subject: Reply with quote

rayla_lsy, Curious, have you tried my suggestion above about stack change?
Sorry, trying to make 1 GB allocation for stack I made a mistake there missing one more zero. With that number which was only 100 MB my suggestion actually decreased default stack which is larger ~200MB.

So you can increase this number using try and fail method up to probably 1.2-1.6 GB

But allocatable option as mecej4 and JohnCampbell suggested is the best.


Last edited by DanRRight on Wed Jan 11, 2017 8:38 am; edited 1 time in total
Back to top
View user's profile Send private message
rayla_lsy



Joined: 23 Dec 2016
Posts: 6

PostPosted: Tue Jan 10, 2017 5:24 pm    Post subject: Reply with quote

Here is the program that I ran into trouble. The problem occurs when I trying to call subroutine that generates a random matrix.

I just read the later post, and I will try that. Thank you.



program test
integer, parameter :: ikind_real = selected_real_kind(p=8 )
integer, parameter :: NP106 = 70695
real(kind = ikind_real) :: rcoeff_dist(NP106,28 )

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
real(kind = ikind_real), dimension(m,n) :: r1,r2
real, parameter :: r4_pi = 3.141592653589793E+00
real(kind = ikind_real), dimension(m,n) :: X

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
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
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 1645
Location: South Pole, Antarctica

PostPosted: Wed Jan 11, 2017 6:13 am    Post subject: Reply with quote

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.

Code:

ftn95 r.f95 /checkmate
slink r.obj /stack:500000000
sdbg r.EXE


Last edited by DanRRight on Wed Jan 11, 2017 8:40 am; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1834
Location: Sydney

PostPosted: Wed Jan 11, 2017 8:08 am    Post subject: Reply with quote

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
Code:
 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
Back to top
View user's profile Send private message
rayla_lsy



Joined: 23 Dec 2016
Posts: 6

PostPosted: Wed Jan 11, 2017 5:48 pm    Post subject: Reply with quote

Thank you all for your help!
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1834
Location: Sydney

PostPosted: Wed Jan 11, 2017 11:25 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 5043
Location: Salford, UK

PostPosted: Thu Jan 12, 2017 8:22 am    Post subject: Reply with quote

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.
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 1645
Location: South Pole, Antarctica

PostPosted: Fri Jan 13, 2017 9:56 am    Post subject: Reply with quote

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

Code:
ftn95 r.f95 /64 /debug     >ErrCompil
slink64 r.obj /file:r.exe  >ErrLink
sdbg64 r.EXE
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Plato All times are GMT + 1 Hour
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group