Silverfrost Forums

Welcome to our forums

Long array:Serious issue-stalk overflow

9 Sep 2011 11:52 #8933

Hi,

I have a serious problem and need to fix it fast,

I have a subroutine;

subroutine ProcessData(file_name,ival,
     +total_nodes,total_elements,node_start,elem_start,dom_start,
     +no_of_time_steps,total_domains)
     

     integer Array_A(total_elements),Array_B(total_nodes),
    -------------


---------------------

end
    
 

Now, total_nodes and total_elements are passed as arguments from the calling subroutine and total_nodes and total_elements happen to be 6,08,300 and 7,05,000 in a case.

I get a stack overflow and the program crashes.

Please help how to deal with this.Please help

Christy

9 Sep 2011 1:53 #8934

I have never worked with such huge arrays and tried the code given below. Keeping on increasing N resulted with stack overflow error. It seems like you should try and **increase the stack size **- never did this before (perhaps search the help for: Storage management routines).

program test
    implicit none
    integer,parameter :: N = 490000000
    integer ( kind = 3),dimension(N) :: arrayA
    integer :: i
    do i=1,N
        arrayA(i) = i
    enddo
    write( *,* ) arrayA(N)
end
9 Sep 2011 2:30 #8935

Please can anyonme suggest something, it is really getting me very tense as the whole work done is endangered

9 Sep 2011 2:48 #8936

I declare element topology and nodal data as fixed size arrays in COMMON blocks. I have larger arrays than you are trying to use. So you could try using this method instead of dynamic arrays.

9 Sep 2011 4:12 #8938

You can use local arrays with SAVE attribute that are 'BIG ENOUGH' to cope with the maximum values of total_elements and total_nodes.

If you really do want dynamic arrays, I would suggest you don't use automatic arrays but allocatable arrays and use ALLOCATE.

This will put the arrays on the heap, rather than the stack.

change

     integer Array_A(total_elements), Array_B(total_nodes)

to

     integer, allocatable :: Array_A(:), Array_B(:)
     allocate( Array_A(total_elements), Array_B(total_nodes) )

You don't need to DEALLOCATE them as this is done for you in Fortran 95.

I would expect the last statement to generate some debate!! David.

9 Sep 2011 4:24 #8939

Hi John,

Thanks for the reply.

Please can you advise how to declare element topology and nodal data as fixed size arrays in COMMON blocks??

Should the common block be in the subroutione as I mentioend above?(Subroutine ProcessData)??

Please help- I'm new to Fortran but have succeded with almost my whole project till now-sorry for a funda question-please advise

Christy

9 Sep 2011 4:29 #8940

You don't need common blocks. Just add SAVE and the arrays will be held in STATIC memory.

You would only use common if you want to 'see' the arrays in different subprograms.

9 Sep 2011 6:37 #8941

Hi David,

Please can you advise (an example) how to add SAVE?Please help- I'm new to this.

Christy

9 Sep 2011 8:08 #8942

Like this. You must set MAX_ELEMENTS and MAX_NODES to be big enough to handle the largest values of total_elements and total_nodes.

subroutine ProcessData(file_name,ival,
     +total_nodes,total_elements,node_start,elem_start,dom_start,
     +no_of_time_steps,total_domains)

    integer, parameter :: MAX_ELEMENTS    = 1000000
    integer, parameter :: MAX_NODES = 800000

     integer, save :: Array_A(MAX_ELEMENTS), Array_B(MAX_NODES),
    -------------


---------------------

end 

Or you can use the ALLOCATE method I posted earlier.

9 Sep 2011 8:26 #8943

where to set max_elements and max_nodes? IS the same sub routine?

Can you give an example, how to use ALLOCATE?

9 Sep 2011 8:28 #8944

Yes, same subroutine as my example code.

For the allocate method just replace your one line with the two lines I gave earlier.

You get this

subroutine ProcessData(file_name,ival,
     +total_nodes,total_elements,node_start,elem_start,dom_start,
     +no_of_time_steps,total_domains)
     

     integer, allocatable :: Array_A(:),Array_B(:)
     allocate (Array_A(total_elements),Array_B(total_nodes))
    -------------


---------------------

end 

I am online a little longer (here) browsing. So post back if you need some guidance.

10 Sep 2011 2:12 #8949

You should declare the arrays as common or in a module, especially if the total array size exceeds about 1.2 gb in size. ALLOCATE will not provide arrays bigger than this. This is due to the way SLINK allocates memory and only if you declare named common bigger than 1.2gb, will SLINK provide contiguous memory required for them. (MODULES probably also do this but I have not tested it.) These will be large named static arrays. If you do not place the large arrays in a named common or module, they would go onto the stack and you would then need to declare a sufficiently large stack. I have not been able to do this. You need to calculate the size of the arrays you are using. The limit is about (less than) 1.7gb for a typical win32 system.

The following can be used as a common definition, typically as an include file, to be used in each routine.

integer, parameter :: million = 1000000
integer, parameter :: MAX_ELEMENTS  = 10*million
integer, parameter :: MAX_NODES = 8*million 

! integer Array_A(max_elements),Array_B(max_nodes) ! common /big_arrays/ Array_A, Array_B

You should generate a .map file in SLINK and calculate the size of the named data areas to better understand this. I have provided past posts to show the mapping of free contiguous memory provided by SLINK, with and without large common declarations.

John

Please login to reply.