You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

f2py转换C/Fortran数组失败,求解决方法(附代码)

解决Fortran-Python Wrapper中的数组转换错误

问题场景

编写Fortran到Python的wrapper时,调用出现如下错误:

ValueError: failed to create intent(cache|hide)|optional array -- must have defined dimensions, but dims[0] = -1

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "wrap.py", line 12, in <module>
    test.wrap(A, B)
ValueError: failed in converting hidden `c' of test.wrap to C/Fortran array

涉及代码如下:

Python代码(原wrap.py)

import numpy as np

A = np.random.random((5,5))
B = np.random.random((5,5))
C = np.zeros((5, 5))

A = np.asfortranarray(A)
B = np.asfortranarray(B)
C = np.asfortranarray(C)

test.wrap(A, B)  # 错误:未传入输出参数C
print(C[0,0])

Fortran代码(test.f90)

subroutine wrap(A, B, C)
    implicit none
    real, intent(in) :: A(:, :), B(:, :)
    real, intent(out) :: C(:, :)
    integer :: m, n, p

    m = size(A, 1)
    n = size(A, 2)
    p = size(B, 2)
    
    if (n /= size(B, 1)) then
        print *, "Error: Incompatible dimensions for matrix multiplication"
        return
    end if

    C = matmul(A, B)
end 

编译命令:

python -m numpy.f2py -c  --f90flags='-O3'  -m test test.f90

错误原因

Fortran子程序wrap中,C是**intent(out)**的输出参数,但Python调用时未传入该参数。f2py无法自动推断输出数组C的维度(维度依赖于输入A和B的大小),因此无法创建符合要求的数组,导致转换失败。

修复方案

方案一:Python调用时传入预分配的C数组

这是最直接的解决方法:既然已经在Python中创建了C数组,只需在调用时将其传入wrap函数,让f2py直接使用已有的数组空间存储计算结果。

修改后的Python代码:

import numpy as np

A = np.random.random((5,5))
B = np.random.random((5,5))
C = np.zeros((5, 5))

A = np.asfortranarray(A)
B = np.asfortranarray(B)
C = np.asfortranarray(C)

test.wrap(A, B, C)  # 传入输出参数C
print(C[0,0])

方案二:通过f2py接口注释指定输出数组维度

如果希望Python调用时不需要手动传入C(让f2py自动创建),可以在Fortran代码中添加f2py专用注释,明确C的维度与输入参数的关系:

修改后的Fortran代码:

subroutine wrap(A, B, C)
    implicit none
    real, intent(in) :: A(:, :)
    real, intent(in) :: B(:, :)
    real, intent(out) :: C(:, :)
    integer :: m, n, p
    !f2py intent(hide) :: m, n, p
    !f2py dimension(C) = (size(A,1), size(B,2))

    m = size(A, 1)
    n = size(A, 2)
    p = size(B, 2)
    
    if (n /= size(B, 1)) then
        print *, "Error: Incompatible dimensions for matrix multiplication"
        return
    end if

    C = matmul(A, B)
end 

重新编译后,Python调用时可省略C参数,函数会直接返回计算后的C数组:

import numpy as np

A = np.random.random((5,5))
B = np.random.random((5,5))

A = np.asfortranarray(A)
B = np.asfortranarray(B)

C = test.wrap(A, B)  # 直接获取返回的C数组
print(C[0,0])

内容的提问来源于stack exchange,提问作者Chungji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:23:11