Segmentation fault when allocating large vectors

Discussion in 'Mac Programming' started by laura74, Jul 9, 2010.

  1. laura74 macrumors newbie

    Joined:
    Mar 20, 2010
    #1
    Hallo all,
    I am writing Fortran90 code and compiling it using Intel Fortran on a MacBookPro (MacOSX version 10.5.8).
    My problem is, when I allocate large vectors, the program is compiled but does not run, due to "segmentation fault". There is no bug in the code, as it runs perfectly on a Unix machine.
    I'm talking about allocating 4 or more real vectors with length of about 700000. My computer has 4GB RAM. I have tried the option "unlim -s unlimited", and also the compiling option "-mcmodel=medium" or even "-mcmodel=large" but with no use.
    I would greatly appreciate any help!!!
    Regards
     
  2. wrldwzrd89 macrumors G5

    wrldwzrd89

    Joined:
    Jun 6, 2003
    Location:
    Solon, OH
    #2
    Do you get any other information along with the segmentation fault, such as a backtrace or log entries in the Console? If you do, have a look at those - you'd be surprised at how informative they can be at tracking down the root causes of such errors.
     
  3. laura74 thread starter macrumors newbie

    Joined:
    Mar 20, 2010
    #3
    Unfortunately I do not get any information. The program just gets stuck with either "Illegal instruction" or "Segmentation fault", and that's it. I also tried the CB option in the compilation but did not get any message in that way either.
     
  4. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #4
    does the Intel compiler add GDB-compatible debugging symbols? If so, you should be able to run your program in GDB and see where things go awry.

    Otherwise, can you post your code? Have you been able to reproduce with a short example? Are you doing your allocations in a subroutine that can be accessed multiple times? When you say "vector" do you just mean an allocatable array that you're allocating with the "allocate" keyword?

    If you can post more information we might be able to help a bit more.

    -Lee
     
  5. laura74 thread starter macrumors newbie

    Joined:
    Mar 20, 2010
    #5
    I'm attaching a zip containing the code (it is a very short stand-alone piece extracted from the general code), the makefile and the input data file. The current version does not work on my system (but it does on the Unix machine of my colleague). BUT if I comment out the declaration of real arrays A0_P and ORD0 it does work!
    Thanks in advance for your help
     
  6. laura74 thread starter macrumors newbie

    Joined:
    Mar 20, 2010
    #6
    I'm not sure I attached the file...I retry.
     

    Attached Files:

  7. laura74 thread starter macrumors newbie

    Joined:
    Mar 20, 2010
    #7

    Sorry, maybe it's faster for you to see the code pasted here. here is the main program:

    ****************************************************************
    program trial

    implicit none

    integer :: dim, nnz, i
    integer, allocatable :: iao:)), jao:))
    real*8, allocatable :: ao:))


    c
    c... Read in vectors
    c
    open (unit=50,file='input.dat')
    dim= 1288
    nnz= 733504

    c
    c... Allocate arrays
    c
    allocate(ao(nnz))
    allocate(jao(nnz))
    allocate(iao(dim+1))

    c
    c... Read vectors
    c
    do i = 1,nnz
    read (50,'(F14.5)') ao(i)
    enddo
    write(*,*) 'read ao'

    do i = 1,nnz
    read (50,'(I12)') jao(i)
    enddo
    write(*,*) 'read jao'

    do i = 1,dim+1
    read (50,'(I12)', ADVANCE = "YES") iao(i)
    enddo
    write(*,*) 'read iao'

    c.....Call coocsr_ord

    call coocsr_redord(dim,nnz,ao,jao,iao)

    end
    ****************************************************************


    and here is the subroutine coocsr_redord:



    ****************************************************************
    subroutine coocsr_redord(dim,nnz,A0,AC,AR)
    implicit none

    c ! PARAMETERS
    integer dim
    integer nnz

    ! COUNTERS
    integer i

    ! VARIABLES
    integer AC(nnz)
    integer AC_P(nnz)
    integer AR(dim+1)
    integer AR_P(dim+1)
    integer ORDC(dim)

    real*8 A0(nnz)
    real*8 A0_P(nnz)
    real*8 ORD0(dim)


    write(*,*) 'i, A0, AC'
    do i=1,nnz
    write(*,*) i,A0(i),AC(i)
    end do
    write(*,*) 'i, AR'
    do i=1,dim+1
    write(*,*) i,AR(i)
    end do

    return
    end
    subroutine coocsr_redord(dim,nnz,A0,AC,AR)
    implicit none

    c ! PARAMETERS
    integer dim
    integer nnz

    ! COUNTERS
    integer i

    ! VARIABLES
    integer AC(nnz)
    integer AC_P(nnz)
    integer AR(dim+1)
    integer AR_P(dim+1)
    integer ORDC(dim)

    real*8 A0(nnz)
    real*8 A0_P(nnz)
    real*8 ORD0(dim)


    write(*,*) 'i, A0, AC'
    do i=1,nnz
    write(*,*) i,A0(i),AC(i)
    end do
    write(*,*) 'i, AR'
    do i=1,dim+1
    write(*,*) i,AR(i)
    end do

    return
    end
     
  8. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    I'm sorry I can't spend too much time picking this apart, but I'll just pitch one thing out there. In your program block you declare your "big" arrays as allocatable, and allocate the memory for them. This is going to be on the heap. In cooscr_redord you declare A0_P on the stack with a variable dimension. I am not as familiar with the intel compiler, so it may put things with variable dimension on the heap, but if it does some magic to try to put it on the stack you're asking for a ~6MB stack frame. This is pretty heavy-duty. Any reason not to put AO_P on the heap with an allocate rather than on the stack?

    -Lee
     
  9. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    Sorry for the double post, but this isn't exactly an edit.

    I looked at the code a tiny bit more and think it would really behoove you to delcare A0,AC,and AR in coocsr_redord as:
    Code:
    integer, allocatable,intent(in) :: AC(:)
    integer, allocatable,intent(in) :: AR(:)
    real(8), allocatable,intent(in) :: A0(:)
    
    This should force the compiler to set things up so that all of the information about these allocatable arrays are passed in (allocated, size, etc.), and it's clear that these are different than your local variables. I don't know if intent is F90 or F95, but hopefully your compiler supports it.

    I didn't notice AC_P before, so that's going to be ~3MB if your integer size is 4. This would bring the total stack usage for coocsr_redord close to 10MB. This is probably starting to stomp on the heap (they grow toward one another). There may be settings you can pass to the compiler, or maybe even OS level settings to allow for a much larger stack, but I would say that if you just offload AC_P,AR_P,ORDC,A0_P, and ORD0 to the heap (make them all allocatable and allocate them when you get into coocsr_redord, then deallocate at the end of the function) it will probably make things much happier.

    -Lee
     
  10. laura74 thread starter macrumors newbie

    Joined:
    Mar 20, 2010
    #10
    Thanks soooo much, that really helped!!! I am now allocating the vectors only inside the subroutine, and everything works fine!!!
    So from now on I will try to allocate big vectors dinamically as much as possible.
     
  11. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #11
    Glad to help. As an aside, you MIGHT be able to get away with declaring great big arrays without using allocate if you give them the save attribute:
    Code:
    integer, save :: myHugeArray(2432345)
    It may not be the best idea, but the compilers I've used implement variables with the save attribute on the heap to allow their value to be retained.

    The difference between doing this and just allocating some allocatable arrays may be negligible. If you call a routine dozens of times, and the arrays are huge, constant allocation and deallocation could cause memory fragmentation, so in that case the save attribute might be a better idea. However, if the size is going to vary from call to call, allocate is probably your only option (you could get creative with an allocatable with save and check size vs. your new size, but that seems like you're possibly playing with fire).

    -Lee
     

Share This Page