Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/azure/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 将一维阵列传递到三维阵列_Arrays_Multidimensional Array_Fortran_Subroutine - Fatal编程技术网

Arrays 将一维阵列传递到三维阵列

Arrays 将一维阵列传递到三维阵列,arrays,multidimensional-array,fortran,subroutine,Arrays,Multidimensional Array,Fortran,Subroutine,我正在使用Fortran中的API,它提供了一个写入数据的例程。假设它的名字是api\u write\u data。此例程需要一个数组作为参数,其维数可以是1、2或3 我想写一个子例程,作为这个API例程的包装器。但因此,我有必要编写一个例程,它可以处理1D、2D或3D数组,并可以将它们正确地传递给API例程。我该怎么做?我能做到吗 我的方法是这样的,但不起作用: subroutine write_data(array) implicit none integer, dimension(:,:,

我正在使用Fortran中的API,它提供了一个写入数据的例程。假设它的名字是
api\u write\u data
。此例程需要一个数组作为参数,其维数可以是1、2或3

我想写一个子例程,作为这个API例程的包装器。但因此,我有必要编写一个例程,它可以处理1D、2D或3D数组,并可以将它们正确地传递给API例程。我该怎么做?我能做到吗

我的方法是这样的,但不起作用:

subroutine write_data(array)
implicit none
integer, dimension(:,:,:), intent(in):: array

call api_write_data(array)

end subroutine write_data
但是,当我使用1D数组调用此例程时,会得到已知错误:

Error: Rank mismatch in argument 'array' at (1) (rank-3 and rank-1)
用Fortran有没有办法做这种事情?对于我来说,有必要将数组作为1D、2D或3D数组传递给
write_data
例程。但是,我可以将数组作为1D数组传递给
api\u write\u data


你知道我该怎么做吗?

你可以使用Fortran接口定义多个版本的例程:

interface write_data
  module procedure write_data_1d
  module procedure write_data_2d
  module procedure write_data_3d
end interface write_data

然后这些过程可以处理不同类型的输入。然后,在这些过程中,您可以使用重塑函数将输入转换为方便的形状,以便三者都可以调用一个通用子例程来实现您所做的任何事情的逻辑

重塑功能的另一种替代方法可能是将1D指针指向多维数组:

p(1:size(c)) => c(:,:,:)
可以将指针作为一维数组传递,而无需复制。事实上,它应该和通过数组本身一样快。 当然,您需要某种方法来告诉子例程数组的形状:

module test_mod
contains
  subroutine print_arr( arr, dimX, dimY, dimZ )
    integer,intent(in)  :: arr(:)
    integer,intent(in)  :: dimX, dimY, dimZ

    if ( dimZ == 0 ) then
      if ( dimY == 0 ) then
        ! 1D
        print *, "1D array provided"
        print *, "a(4) =", arr(4)
      else
        ! 2D
        print *, "2D array provided"
        print *, "a(1,2) =", arr((2-1)*dimX+1)
      endif
    else
      ! 3D
      print *, "3D array provided"
      print *, "a(1,2,1) =", arr( ((1-1)*dimY + (2-1))*dimX+1)
    endif
  end subroutine
end module

program test
use test_mod
  integer :: i
  integer, target   :: a(8)
  integer, target   :: b(4,2) 
  integer, target   :: c(2,2,2)
  integer, pointer  :: p(:)

  a = [ (i,i=1,8) ]
  b = reshape( a, [4,2] )
  c = reshape( a, [2,2,2] )

  p(1:size(a)) => a(:)
  call print_arr( p, 8, 0, 0 )

  p(1:size(b)) => b(:,:)
  call print_arr( p, 4, 2, 0 )

  p(1:size(c)) => c(:,:,:)
  call print_arr( p, 2, 2, 2 )
end program
这也反过来起作用。。。可以将一维数组映射到三维指针:

integer, pointer  :: p2(:,:,:)
!...
p2(1:4,1:2,1:1) => a

然而,
重塑
确实提供了复制的可能性。这将是一种选择,但这将导致大量代码。因为我有6个不同版本的例程,总共有18个例程。@francescalus这是什么意思?@francescalus意味着函数重塑可能会复制原始数据,这可能会影响性能。这可能发生,也可能不会发生。如果您在一维数组中存储数据的方式与存储多维数据的方式相同,那么一个足够好的编译器可能会看到这一点并生成优化的代码。@Skyy2010是的,我的意思与前面的注释相同。也就是说,
reformate
返回一个结果,并且只有当编译器能够绝对确定该结果和原始结果在联合寿命期间未被修改时,才能进行任何非复制优化。许多人甚至都不想费心去确定这一点。没有fortran 90的限制,还会有其他的可能性吗?可能有新的语言功能,也可以通过ifort和gfort编译.f90文件