0
votes

My question is about array allocation in Fortran.

I have a subroutine, say readParams, where I want to read some dynamically sized arrays from files. These are also used outside the subroutine. What is the best way to handle this?

In F95 it seems to be impossible to allocate within the subroutine and pass the arrays, filled with values, back to the main program. But if I allocate it in the main program and use "intent(inout)" in the subroutine it also gets deallocated there.

(I'm using F90/95 here, but since the code is not large I could also modify it to a newer version... I'm rather new to Fortran, so I'm unsure if an improvement of array handling is worthwhile the time investment^^

EDIT Thanks for the hint. I am not trying to deallocate my arrays within a subroutine though.

The problem is: I have an array which I need to allocate somewhere within my main program. The arraysize is known only after I read it from an input in subroutine readArgs. Therefore I make the array "allocatable". Once allocated that status must never change again. The array is filled with values in a subroutine readParams. Do I allocate it best in main or in readParams and how?

... I have now put my subroutines in a module and use them from there. At the moment I do the allocation in main, pass the arrays to my subroutine and have removed the "allocatable" statement in the array declaration in the subroutine. It seems to work but I still don't really understand if this is the way to go.

2
Also see some other questions, which are related, but not duplicates. They deal with some specific problems with allocatable arguments stackoverflow.com/questions/13058743/… stackoverflow.com/questions/19537974/… stackoverflow.com/questions/22169365/…Vladimir F
Modification from Fortran 95 to Fortran 2003 does not mean rewriting the whole code. Not at all!!! It just means using the modern feature in the specific place where you need it.Vladimir F
Everything is in the link, really. Also in the other examples. Ignore the deallocation. 1. Read the question in the link. 2. Make the array argument to readParams allocatable. 3. Allocate the array in readParams. Really look at stackoverflow.com/a/13810698/721644. You can also just allocate the array in the main program. If you have problems with that, show your code and error messages and explain those problems.Vladimir F
It does not matter whether you allocate it in reaArgs or readParams, it is your choice. If you believe the link is not applicable to your situation, then 1. show your code, 2. show any error messages you got when you tried to allocate the array.Vladimir F
You write it seems impossible to. Why does it seem impossible? Which specific errors did you encounter? Which code did you try?Vladimir F

2 Answers

1
votes

In my opinion the question is an exact duplicate of Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine? and if it is not, then it should be closed because you did not show any code so how can we tell you whether your code (that works) is correct???

But I am alone with this opinion against many, so if your code looks similar to this it is probably correct:

You can either read the size in a subroutine and allocate it in the main program:

module subs
contains
  subroutine readArgs(n)
    integer, intent(out) :: n
    !read n here
  end subroutine

  subroutine readParams(a)
    real :: a(:)

    do i = 1, size(a)
      !read values of a
      a(i) =
    end do
  end subroutine
end module

program main

  use subs

  integer :: n

  readArgs(n)

  allocate(a(n))

  readParams(n)
end program

Or you can allocate it in the subroutine. You must fulfil all the requirements in Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine?

module subs
contains
  subroutine readArgs(n)
    integer, intent(out) :: n
    !read n here
  end subroutine

  subroutine readParams(n, a)
    real, allocatable :: a(:)

    allocate(a(n))

    do i = 1, size(a)
      !read values of a
      a(i) =
    end do
  end subroutine
end module

program main

  use subs

  integer :: n

  readArgs(n)

  readParams(n)
end program

It doesn't matter what you do, both approaches are pefectly fine.

0
votes

If anyone is still interested I'm using the Cuda compiler pgf90 and the following works:

module subs  
implicit none  
    contains  
    subroutine load_array( b )  
        real, allocatable :: b(:)  
        allocate( b(10) )  
        b( 7 ) = 4  
    end subroutine load_array  
end module subs  

Program main  
    use subs  
    implicit none  
    real, allocatable :: a(:)  
    Call load_array( a )  
    print *, a(7)  
    deallocate( a )  
end program main