f2py:输入不是Fortran连续的

3

我使用f2py包装了一些Fortran代码。以下是Fortran代码:

MODULE iteration
implicit none
contains

SUBROUTINE iterate(alpha, beta, e, es, rank, omega, smearing, prec, max_step)
    REAL(kind=8), INTENT(in) :: omega, smearing, prec
    INTEGER :: max_step, step, rank, cnt
    COMPLEX(kind=16) :: alpha(rank,rank), beta(rank,rank), omega_mat(rank, rank), green(rank, rank)
    COMPLEX(kind=16), INTENT(inout) ::  e(rank,rank), es(rank,rank)
    step = 0
    omega_mat = 0
    DO cnt=1, rank
        omega_mat(cnt, cnt) = 1.0
    ENDDO
    omega_mat = omega_mat * (omega + (0.0, 1.0) * smearing)
    DO WHILE (minval(abs(alpha)) .gt. prec .or.  minval(abs(beta)) .gt. prec .and. step .lt. max_step)
        green = zInverse(rank, omega_mat - e)
        e = e + matmul(alpha, matmul(green, beta)) + matmul(beta, matmul(green, alpha))
        es = es + matmul(alpha, matmul(green, beta))
        alpha = matmul(alpha, matmul(green, alpha))
        beta = matmul(beta, matmul(green, beta))
        step = step + 1
    ENDDO
END SUBROUTINE iterate

FUNCTION zInverse(n, a)  result(ra)
    INTEGER :: n,lda,ipiv(n),info,lwork
    COMPLEX(kind=16)::a(n,n),ra(n,n),work(n)
    ra=a
    lwork=n
    lda=n
    CALL zgetrf(n, n, ra, lda, ipiv, info)
    IF(info/=0) WRITE(0,*) 'Error occured in zgetrf!'
    CALL zgetri(n, ra, lda, ipiv, work, lwork, info)
    IF(info/=0) WRITE(0,*) 'Error occured in zgetri!'
END FUNCTION zInverse
END MODULE iteration

然后我使用f2py -L/usr/lib -llapack -m pyiteration -c iteration.F90编译了代码,用以下命令进行测试:

import numpy as np
import pyiteration
alpha = np.array([[1,0],[0,1]], dtype='complex')
beta = np.array([[1,0],[0,1]], dtype='complex')
e = np.array([[1,0],[0,1]], dtype='complex')
es = np.array([[1,0],[0,1]], dtype='complex')
# f2py is automatically generating rank for me
pyiteration.iteration.iterate(alpha,beta, e, es, 1.0, 0.001, 0.001, 100)

然而,我遇到了以下错误:ValueError: failed to initialize intent(inout) array -- input not fortran contiguous
我搜索了一下发现f2py应该会自动将数组转换为fortran连续的形式。那么这里出了什么问题?
3个回答

9

您需要使用order='F'创建Fortran连续有序的数组,以便:

alpha = np.array([[1,0],[0,1]], dtype='complex', order='F')
beta = np.array([[1,0],[0,1]], dtype='complex', order='F')
e = np.array([[1,0],[0,1]], dtype='complex', order='F')
es = np.array([[1,0],[0,1]], dtype='complex', order='F')

请注意,当 alpha.flags.writeable 不为 True 时,该错误也会(不适当地)被引发,您可以通过 .copy() 变量来解决这个问题。 - Jthorpe

2
Fortran创建的数组(即out)将返回为Fortran连续。然而,我的理解是所有传入的数组(即ininout)在Python中必须指定为Fortran连续。如果f2py将它们从C连续更改为F连续,那可能意味着创建一个副本,这将占用额外的内存,效率不高。
要解决此问题,您只需要为每个np.array调用添加一个order='F' kwarg即可。

0

我也遇到了这个与 fortran contiguous 相关的错误,并通过将一些 intent(intout) 改为 intent(in).pyf 签名文件中解决了它,例如:

real(kind=8) dimension(:,:),intent(in) :: kernel
integer dimension(:,:),intent(in) :: kernelmask

kernelkernelmask在代码中都是intent(in),但是f2py生成的.pyf将它们设为了intent(inout)。通过某种方式进行更正可以解决连续错误。这可能不适用于其他情况,但考虑到信息很少,如果发生类似问题,您可能想尝试一下。


你的代码不同,你假设了形状数组 (::) - Vladimir F Героям слава

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接