繁体   English   中英

f2py - 防止数组重新排序

[英]f2py — prevent array reordering

我有一个数组,它通过f2py从fortran子程序读取为1D数组。 然后在python中,该数组被重新整形:

a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nz,ny,nx)  #in fortran, the order is a(nx,ny,nz), C/Python it is reversed

现在我想将该数组作为3D数组传递回fortran。

some_data=fortran_routine(a)

问题是f2py在传递给fortran_routine之前一直试图转置一个。 fortran例程看起来像:

subroutine fortran_routine(nx,ny,nz,a,b)
real a
real b
integer nx,ny,nz
!f2py intent(hidden) nx,ny,nz
!f2py intent(in) a
!f2py intent(out) b
...
end subroutine

如何防止所有来回移调? (我很高兴在两种语言中使用不同的数组索引约定)。

编辑

似乎np.asfortranarraynp.flags.f_contiguous应该在解决方案中有一些部分,我似乎无法弄清楚它是什么部分(或者可能是一个ravel后跟一个reshape(shape,order='F')

编辑

看来这篇文章引起了一些混乱。 这里的问题是f2py试图保留索引方案而不是内存布局 所以,如果我有一个带有形状(nz, ny, nx)的numpy数组(按C顺序),那么f2py也试图使该数组在fortran中具有形状(nz, ny, nx) 如果f2py保留了内存布局 ,那么数组将在python中具有形状(nz, ny, nx) ,在fortran中具有(nx, ny ,nz)形状。 我想保留内存布局。

Fortran不会反转轴顺序,它只是将数据存储在内存中,与C / Python不同。 您可以告诉numpy以Fortran顺序存储数据,这与反转轴不同。

我会像这样重写你的代码

a=np.zeros(nx*ny*nz)
read_fortran_array(a)
a=a.reshape(nx,ny,nz, order='F') # It is now in Fortran order

现在,f2py在传递时不会尝试重新排序数组。

作为旁注,这也将起作用

a=a.reshape(nx,ny,nz) # Store in C order

因为在幕后,当您将C顺序数组传递给Fortran例程时,f2py会执行这些操作:

a=a.flatten() # Flatten array (Make 1-D)
a=a.reshape(nx,ny,nz, order='F')  # Place into Fortran order

但是,从一开始就以Fortran顺序存储更有效。

通常,您不必担心数组排序,除非您有一个性能关键部分,因为f2py会为您解决这个问题。

看起来答案相当简单:

b=np.ravel(a).reshape(tuple(reversed(a.shape)),order='F')

有效,但显然,这与以下内容相同:

b=a.T

因为转置返回一个视图并快速查看b.flagsb.flags相比, a.flags表明这就是我想要的。 b.flags是F_CONTIGUOUS)。

暂无
暂无

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

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