Fortran 将多维数组作为一维数组传递的最佳方法
我有一个子例程,它填充任意长度的秩1数组Fortran 将多维数组作为一维数组传递的最佳方法,fortran,Fortran,我有一个子例程,它填充任意长度的秩1数组 subroutine populate_array_1D(array) implicit none integer, dimension(:), intent(out) :: array array(:) = 1 end subroutine populate_array_1D 现在我想使用重载来修改这个例程,以接受更高维度的数组 interface populate_array module procedure pop
subroutine populate_array_1D(array)
implicit none
integer, dimension(:), intent(out) :: array
array(:) = 1
end subroutine populate_array_1D
现在我想使用重载来修改这个例程,以接受更高维度的数组
interface populate_array
module procedure populate_array_1D, populate_array_2D, populate_array_3D
end interface populate_array
我想做的是将高维子程序引用回1D子程序
到目前为止,我的想法是:
subroutine populate_array_2D(array)
implicit none
integer, dimension(:,:), intent(out) :: array
integer :: i
do i = lbound(array, 2), ubound(array, 2)
call populate_array_1D(array(:, i))
end do
end subroutine populate_array_2D
重塑
:
subroutine populate_array_3D(array)
implicit none
integer, dimension(:,:,:), intent(out) :: array
integer :: tmp_array(size(array))
call populate_array_1D(tmp_array)
array = reshape(tmp_array, shape(array))
end subroutine populate_array_3D
元素
子例程,因为它不能是纯
)
或者有更好的版本,我可以将多维数组传递到一个子例程中,假装它是1D数组
(最终,我想用一个PRNG来代替对
随机数的调用,该PRNG在不同的编译器和/或机器之间尽可能具有确定性,假设它们使用相同的种子。)正如francescalus指出的,基本过程可能是不纯净的(从Fortran 2008开始)
或者,您可以使用Fortran固有的C互操作性
以获得对2D阵列内存位置的低级别访问。以下子例程生成指向2D数组的1D指针:
subroutine populate_array_2D(array)
use iso_c_binding, only: C_F_POINTER, C_LOC
integer, dimension(:,:), target, contiguous, intent(out) :: array
integer, dimension(:), pointer :: ptr_1d
call C_F_POINTER (C_LOC(array), ptr_1d, [size(array)])
call populate_array_1D(ptr_1d)
end subroutine populate_array_2D
编辑:
对c\u f\u指针的调用可以替换为
指针中的等效绑定重新映射列表:
ptr_1d(1:大小(数组))=>array
(尽管使用ifort18进行编译时给出了一个错误,即这不是Fortran 2008的有效版本)。正如francescalus指出的,基本过程可能是不纯净的(从Fortran 2008开始)
或者,您可以使用Fortran固有的C互操作性
以获得对2D阵列内存位置的低级别访问。以下子例程生成指向2D数组的1D指针:
subroutine populate_array_2D(array)
use iso_c_binding, only: C_F_POINTER, C_LOC
integer, dimension(:,:), target, contiguous, intent(out) :: array
integer, dimension(:), pointer :: ptr_1d
call C_F_POINTER (C_LOC(array), ptr_1d, [size(array)])
call populate_array_1D(ptr_1d)
end subroutine populate_array_2D
编辑:
对c\u f\u指针的调用可以替换为
指针中的等效绑定重新映射列表:
ptr_1d(1:大小(数组))=>array
(尽管使用ifort18编译时给出了一个错误,即这不是有效的Fortran 2008)。元素子例程可能是不纯净的。哇,我不知道您可以指定不纯净元素
。谢谢@francescalusElemental子例程可以是不纯净的。哇,我不知道你可以指定不纯净元素
。感谢@francescalus错误:C_LOC(1)处的参数X应具有指针或目标属性
,但假设数组
是连续的,为什么不同时给它连续
和目标
属性,这样就可以使用数组边界重新映射直接指向它的ptr_1d
ptr_1d(1:size(array))=>array
关于target
属性,您是对的,谢谢您的关注。(iPort不提供)但指针的绑定重新映射列表不符合标准。我最初打算提到这一点,但我忘了。不,您还没有阅读关于这个问题的标准。我在你的帖子中添加了一个编辑,它充实了我的想法,并在iPort和gfortran上进行了编译。您在编辑中忘记了rank2_数组
上的continuous
属性。正如@user5713492所指出的,秩-2数组可能是边界重新映射指针赋值的目标,只要它只是连续的。但这似乎需要花费大量精力来避免整数数组(*)
错误:参数X位于(1)to C_LOC应具有指针或目标属性
,但假设数组
是连续的,为什么不同时赋予它连续
和目标
属性,以便使用数组边界重新映射直接指向ptr_1d
ptr_1d(1:size(array))=>array
关于target
属性,您是对的,谢谢您的关注。(iPort不提供)但指针的绑定重新映射列表不符合标准。我最初打算提到这一点,但我忘了。不,您还没有阅读关于这个问题的标准。我在你的帖子中添加了一个编辑,它充实了我的想法,并在iPort和gfortran上进行了编译。您在编辑中忘记了rank2_数组
上的continuous
属性。正如@user5713492所指出的,秩-2数组可能是边界重新映射指针赋值的目标,只要它只是连续的。但这似乎需要花费大量精力来避免整数数组(*)
。