|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
rayla_lsy
Joined: 23 Dec 2016 Posts: 6
|
Posted: Mon Jan 09, 2017 6:58 pm Post subject: Re: |
|
|
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1886
|
Posted: Mon Jan 09, 2017 11:42 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Tue Jan 10, 2017 12:10 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Tue Jan 10, 2017 9:37 am Post subject: |
|
|
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 |
|
|
rayla_lsy
Joined: 23 Dec 2016 Posts: 6
|
Posted: Tue Jan 10, 2017 5:24 pm Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Wed Jan 11, 2017 6:13 am Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Jan 11, 2017 8:08 am Post subject: |
|
|
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 |
|
|
rayla_lsy
Joined: 23 Dec 2016 Posts: 6
|
Posted: Wed Jan 11, 2017 5:48 pm Post subject: |
|
|
Thank you all for your help! |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Jan 11, 2017 11:25 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7924 Location: Salford, UK
|
Posted: Thu Jan 12, 2017 8:22 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2815 Location: South Pole, Antarctica
|
Posted: Fri Jan 13, 2017 9:56 am Post subject: |
|
|
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 |
|
|
|
|
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
|