使用f2py传递NumPy数组至Fortran时遇维度错误求助
使用f2py封装Fortran子程序时遇到维度不匹配错误
问题详情
我用f2py封装了Fortran子程序ctp_hi_low,该子程序接收多个一维数组,返回计算值CTP和HILOW。封装过程成功,但运行测试代码时触发维度错误,即使传入形状一致的测试数据也无法解决。
报错信息
Traceback (most recent call last): File "/mnt/d/ResearchProjects/NSF-Drought/coupling-metrics/minimal/test.py", line 47, in <module> conv_trig_pot_mod.ctp_hi_low(10, arr, arr, arr, 1,1, 1) ValueError: ctp_hilow.ctp_hilow.conv_trig_pot_mod.ctp_hi_low: failed to create array from the 2nd argument `qlev_in` -- 0-th dimension must be fixed to 1 but got 10
尝试过的操作
我尝试传递多种维度的一维数组甚至列表,均得到相同错误:
arr = np.ones([10,], order='F') arr = np.ones([10,1], order='F') arr = np.ones([1,10], order='F')
Fortran子程序代码
subroutine ctp_hi_low ( nlev_in, tlev_in, qlev_in, plev_in, & t2m_in , q2m_in , psfc_in, CTP, HILOW , missing ) implicit none ! ! Input/Output Variables ! integer, intent(in ) :: nlev_in ! *** # of pressure levels real(4), intent(in ) :: missing ! *** missing value - useful for obs real(4), intent(in ), dimension(nlev_in) :: tlev_in ! *** air temperature at pressure levels [K] real(4), intent(in ), dimension(nlev_in) :: qlev_in ! *** specific humidity levels [kg/kg] real(4), intent(in ), dimension(nlev_in) :: plev_in ! *** pressure levels [Pa] real(4), intent(in ) :: psfc_in ! *** surface pressure [Pa] real(4), intent(in ) :: t2m_in ! *** 2-meter temperature [K] real(4), intent(in ) :: q2m_in ! *** 2-meter specific humidity [kg/kg] real(4), intent(out) :: CTP ! *** Convective Triggering Potential [K] real(4), intent(out) :: HILOW ! *** Low-level humidity [K] <internal variables and calculations>
解决方法
1. 修正参数传递顺序和数量
Fortran子程序的参数顺序为:nlev_in, tlev_in, qlev_in, plev_in, t2m_in, q2m_in, psfc_in, CTP, HILOW, missing。其中CTP和HILOW是输出参数,f2py会将它们作为函数返回值无需传入,但你需要传入所有输入参数(包括最后的missing)。
你的调用缺少了missing参数,导致参数顺序完全混乱,f2py错误地将tlev_in解析为qlev_in,引发维度错误。正确的调用方式应为:
import numpy as np import conv_trig_pot_mod arr = np.ones(10, order='F') # 一维F序数组即可,无需二维 CTP, HILOW = conv_trig_pot_mod.ctp_hi_low(10, arr, arr, arr, 1, 1, 1, 1) # 最后一个1是missing参数,对应Fortran子程序的第10个参数
2. 检查f2py封装命令
确保封装时使用正确的命令,比如:
f2py -c -m conv_trig_pot_mod ctp_hi_low.f90
如果你的Fortran代码使用了特定编译器选项,可以添加--f90flags参数,例如:
f2py -c --f90flags="-fdefault-real-8" -m conv_trig_pot_mod ctp_hi_low.f90
3. 验证数组维度
无需将一维数组转为二维,直接使用np.ones(10, order='F')即可满足Fortran一维数组的要求,F序(列优先)匹配Fortran的内存布局。
内容的提问来源于stack exchange,提问作者Tobias Gerken
相关产品推荐
相关产品推荐

