将可分配数组的子数组传递给具有右边界的子例程
Passing a subarray of allocatable array to a subroutine, with right bounds
在我写的并行程序中,我定义了很多多维allocatable
数组(实际上只是一维、二维或三维)分配了负下界 在执行期间。
我这样做的原因是每个进程在 2D 示例中处理 14 x 14 A
矩阵并共享一个2层与四个相邻进程的重叠,因此矩阵分配了边界(-1:12,-1:12)
,其中矩阵的 "internal" 部分对应于从 1 到 10 的索引。 (斜体表示 choice/input 依赖)。
问题是,在这样做的过程中,我没有意识到不可能依赖 this Fortran2003 feature,因此无法在调用方单元中 call mysub(A(:,i),...)
并引用虚拟对象A
在子例程中的对应物使用实际边界(-1 和 12),因为 A(:,i)
是一个表达式,而不仅仅是一个变量。
如果我将整个数组 A
传递给子例程,问题就解决了,如 previous linked answer 中所述,但这将迫使我写一个 "bigger" 并且不太通用子程序,相反,它是作用于一维子数组。
是否可以将 allocatable
数组的子数组(例如 A(:,1)
)传递给子程序,使子程序知道实际变量的边界?
据我所知:不,不可能。
请注意,很多时候,您不想关心子例程中数组的实际下限。如果你有一个对数组或类似东西求和的子程序,你只想从 1 循环到数组的大小。并且您希望能够将任何数组传递给此类子例程。
如果您需要从子程序中的特定索引开始,您总是可以
1。
将下界声明为魔法常量
real, intent(inout) :: array(-1:,-1:,-1:)
可能不太好,但我在我的主要生产代码中使用它,因为我几年前就是这样开始的。
2。
将下限声明为模块中的常量并使用它
use contants
real, intent(inout) :: array(lb:,lb:,lb:)
3。
将下限作为虚拟参数传递
integer, intent(in) :: lb
real, intent(inout) :: array(lb:,lb:,lb:)
在我写的并行程序中,我定义了很多多维allocatable
数组(实际上只是一维、二维或三维)分配了负下界 在执行期间。
我这样做的原因是每个进程在 2D 示例中处理 14 x 14 A
矩阵并共享一个2层与四个相邻进程的重叠,因此矩阵分配了边界(-1:12,-1:12)
,其中矩阵的 "internal" 部分对应于从 1 到 10 的索引。 (斜体表示 choice/input 依赖)。
问题是,在这样做的过程中,我没有意识到不可能依赖 this Fortran2003 feature,因此无法在调用方单元中 call mysub(A(:,i),...)
并引用虚拟对象A
在子例程中的对应物使用实际边界(-1 和 12),因为 A(:,i)
是一个表达式,而不仅仅是一个变量。
如果我将整个数组 A
传递给子例程,问题就解决了,如 previous linked answer 中所述,但这将迫使我写一个 "bigger" 并且不太通用子程序,相反,它是作用于一维子数组。
是否可以将 allocatable
数组的子数组(例如 A(:,1)
)传递给子程序,使子程序知道实际变量的边界?
据我所知:不,不可能。
请注意,很多时候,您不想关心子例程中数组的实际下限。如果你有一个对数组或类似东西求和的子程序,你只想从 1 循环到数组的大小。并且您希望能够将任何数组传递给此类子例程。
如果您需要从子程序中的特定索引开始,您总是可以
1。 将下界声明为魔法常量
real, intent(inout) :: array(-1:,-1:,-1:)
可能不太好,但我在我的主要生产代码中使用它,因为我几年前就是这样开始的。
2。 将下限声明为模块中的常量并使用它
use contants
real, intent(inout) :: array(lb:,lb:,lb:)
3。 将下限作为虚拟参数传递
integer, intent(in) :: lb
real, intent(inout) :: array(lb:,lb:,lb:)