【问题标题】:Reshape an outer layer of a 3D array to 1D array将 3D 阵列的外层重塑为 1D 阵列
【发布时间】:2014-03-03 00:01:35
【问题描述】:

我有一个 3D 数组,例如 msh(0:m+1,0:n+1,0:l+1),它可以代表笛卡尔网格。 我想将外层重塑为一维数组。最好的方法是什么(从内存的角度来看是有效的)?

目前我会从 -z,+z, 开始逐个平面重塑:

array(1:m*n)=reshape(msh(1:m,1:n,0),m*n)   
array(m*n+1:2*m*n)=reshape(msh(1:m,1:n,l+1),m*n) 

我的第一个问题是,这种重塑是以一种内存有效的方式进行的!或者还有其他方法,比如使用更快、内存效率更高的 do 循环(数组的大小很大)。

其次,如果我在不同的处理器中有几个这样的数组,那么使用 MPI 在主节点(例如 rank=0)中收集这些外层的最佳方法是什么。

【问题讨论】:

  • 这些是幽灵(守卫)细胞吗?如果您只是重塑数组以便在主节点上收集它们,而不进行任何要求它们为一维的处理,您可能需要考虑创建 MPI 类型。创建 3D 数组的任意 2D 切片并收集它们非常容易。
  • 谢谢,不,它们不是幽灵单元(某些平面可能是幽灵单元的一部分),我必须对这些一维数组进行一些计算。我必须将这些数组保留几个时间步并对其进行计算
  • 你的方法看起来不错。你在第二行代码中有错字,顺便说一句,它应该是array(m*n+1:2*m*n)。您是否需要为 3D 网格中的每个平面创建一个新阵列?如果是这样,您是否同时需要它们?
  • 感谢@Yossarian,错字已更正。
  • 一般来说,索引数组时最好不要使用小写字母l。使用这个字母会降低代码的可读性并使其更容易出错。

标签: arrays parallel-processing fortran mpi


【解决方案1】:

这是一个O(2*m*n+2*l*m+2*l*n) 的问题,不管你怎么做,但一个选项是做一系列循环:

allocate(array(2*m*n+2*l*m+2*l*n))
h = 1
do j=1,n
   do i=1,m
      array(h) = msh(i,j,0)
      array(h+m*n+1) = msh(i,j,l+1)
      h = h+1
   enddo
enddo
do k=1,l
   do i=1,m
      array(h) = msh(i,0,k)
      array(h+m*l+1) = msh(i,n+1,k)
      h = h + 1
   enddo
enddo
do k=1,l
   do j=1,n
      array(h) = msh(0,j,k)
      array(h+l*n+1) = msh(m+1,j,k)
      h = h + 1
   enddo
enddo

然后使用普通的 mpi 子程序将array 传递给master

【讨论】:

  • 没看懂,先用循环比用reshape功能好?其次,您的建议是先转移到一维数组然后聚集到主节点?或者有没有其他方法可以在不使它们成为一维的情况下收集它们!
  • @user3244667: 像大多数内部例程一样,reshape 比循环更快,但这完全取决于您的数组的 大小正在使用(自己测试确实是找出一个比另一个更有利的最佳选择)。就个人而言,我喜欢循环,因为与内在函数相比,我可以更清楚地看到 我在做什么
  • 您可以使用任何一种方式调用 mpi,但了解 1D 数组的哪些索引属于哪些边界或每个 3D 立方体相对于主处理器中的其他立方体属于哪个位置是您将面临的挑战必须努力。
猜你喜欢
  • 2017-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-16
  • 2023-01-03
  • 1970-01-01
  • 2011-01-16
相关资源
最近更新 更多