简体   繁体   English

Fortran 子程序中的数组分配

[英]Array allocation in Fortran subroutine

My question is about array allocation in Fortran.我的问题是关于 Fortran 中的数组分配。

I have a subroutine, say readParams , where I want to read some dynamically sized arrays from files.我有一个子程序,比如readParams ,我想从文件中读取一些动态大小的数组。 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.在 F95 中,似乎不可能在子例程内分配并将填充了值的数组传递回主程序。 But if I allocate it in the main program and use "intent(inout)" in the subroutine it also gets deallocated there.但是如果我在主程序中分配它并在子程序中使用“intent(inout)”,它也会在那里被释放。

(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^^ (我在这里使用 F90/95,但由于代码并不大,我也可以将其修改为更新版本......我对 Fortran 比较陌生,所以我不确定改进数组处理是否值得时间投入^^

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 .只有在我从子例程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 .该数组用子例程readParams 中的值填充。 Do I allocate it best in main or in readParams and how?我是在main 中还是在readParams 中最好地分配它,以及如何分配?

... 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.目前我在main 中进行分配,将数组传递给我的子例程,并删除了子例程中数组声明中的“allocable”语句。 It seems to work but I still don't really understand if this is the way to go.它似乎有效,但我仍然不明白这是否是要走的路。

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?在我看来,问题是Fortran 子例程的输入参数能否在子例程主体中释放和分配的完全重复 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?您必须满足Fortran 子例程的输入参数能否在子例程主体中释放和分配中的所有要求

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.不管你做什么,这两种方法都很好。

If anyone is still interested I'm using the Cuda compiler pgf90 and the following works:如果有人仍然感兴趣,我正在使用 Cuda 编译器 pgf90 并且以下工作:

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  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM