python - 如何调试 f2py 错误“无法创建意图(缓存|隐藏)|可选数组 - 必须已定义尺寸但得到 (-1,)”
问题描述
是否有调试错误的一般方法
ValueError: failed to create intent(cache|hide)|optional array-- must have defined dimensions but got (-1,)
对于用 f2py 包装的 fortran 函数?
这是一个简单的例子。这是我的模块routine.f
:
Subroutine myscript(x,fun,o,n)
external fun
integer n
double precision x(n,*)
double precision o(*)
write(*,*) n
!write(*,*) x(1,:)
call fun(n,x,o)
write(*,*) "done with function call"
write(*,*) o(1)
end
这是相应的头文件routine.pyf
:
! -*- f90 -*-
! Note: the context of this file is case sensitive.
python module myscript__user__routines
interface myscript_user_interface
subroutine fun(n,x,o) ! in :routine:routine.f:myscript:unknown_interface
integer,intent(in) :: n
double precision dimension(n,0) :: x
double precision dimension(0),intent(out) :: o
end subroutine fun
end interface myscript_user_interface
end python module myscript__user__routines
python module routine ! in
interface myscript ! in :routine
subroutine myscript(x,fun,o,n) ! in :routine:routine.f
use myscript__user__routines
double precision dimension(n,*) :: x
intent(callback) fun
external fun
double precision dimension(*),intent(out) :: o
integer,intent(in) :: n
end subroutine myscript
end interface myscript
end python module routine
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
和对应的python文件
import numpy as np
import routine
import ipdb
def fun(n, X):
print("In Callback function")
ipdb.set_trace()
print(X)
O = X[1,:]
print(O)
return O
O = np.array([1.,0.])
X = np.identity(2)
n=2
routine.myscript(X, fun)
我编译f2py -c routine.pyf routine.f
然后运行python脚本。
另一方面,如果我编译并运行 fortran 文件
Subroutine fun(n,x,o)
integer n
double precision x(n,*)
double precision o(*)
write(*,*) "in function"
o(1) = 3. *x(1,1)
end
program main
external fun
double precision x(2,2)
double precision o(2)
integer n
n=2
write(*,*) "bla"
x(1,1) = 1.
x(2,1) = 0.
x(1,2) = 0.
x(2,2) = 1.
o(1) = 1.
o(2) = 2.
call myscript(x,fun,o,n)
end
然后一切都按预期工作并且没有错误。
旧版:
我得到了一些旧的、相当复杂的 fortran 代码,我目前正在尝试用 f2py 包装这些代码。我已经创建了一个 f2py 头文件并调整了很多功能。但是,现在我被这个错误困住了,真的不知道如何继续,因为有很多可能的数组负责这个错误。不幸的是,错误消息没有提示我某个数组。
我猜有问题的部分是该模块foo
依赖于三个外部子模块edif
,adif
和fdif
它们都共享一些数组rpar
和ipar
. 我真的不在乎使用这些,因为它们仅用于例程之间的可选通信。
python module __user__routines
interface
subroutine edif(n,t,idif,e,lde,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(lde,*) :: e
integer, optional,check(shape(e,0)==lde),depend(e) :: lde=shape(e,0)
integer dimension(1),intent(hide) :: ipar
double precision dimension(1), intent(hide) :: rpar
integer,intent(out) :: ierr
end subroutine edif
subroutine adif(n,t,idif,a,lda,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(lda,*) :: a
integer, optional,check(shape(a,0)==lda),depend(a) :: lda=shape(a,0)
integer dimension(1),intent(hide) :: ipar
double precision dimension(1), intent(hide) :: rpar
integer,intent(out) :: ierr
end subroutine adif
subroutine fdif(n,t,idif,f,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(*) :: f
integer dimension(1),intent(hide) :: ipar
double precision dimension(1), intent(hide) :: rpar
integer,intent(out) :: ierr
end subroutine fdif
end interface
end python module __user__routines
python module foo
interface
subroutine ffoo(edif,adif,fdif,neq,t,tout,x,xprime,cval,ipar,rpar,iwork,liw,rwork,lrw,rtol,atol,method,info,iwarn,ierr) ! in :test:SRC/dgelda.f
use __user__routines, edif=>edif, adif=>adif, fdif=>fdif
external edif
external adif
external fdif
integer,intent(in) :: neq
double precision,intent(inout) :: t
double precision,intent(in) :: tout
double precision dimension(*),intent(inout),optional :: x
double precision dimension(*),intent(out) :: xprime
integer dimension(4),intent(out) :: cval
integer dimension(1),intent(hide) :: ipar = 0
double precision dimension(1),intent(hide) :: rpar =0.
integer dimension(liw),intent(cache),depend(liw) :: iwork
integer,intent(hide),depend(iwork) :: liw=20+6*neq
double precision dimension(lrw),intent(cache),depend(lrw) :: rwork
integer,intent(hide),depend(rwork) ::: lrw = 1000*neq*neq
double precision dimension(*),intent(in) :: rtol
double precision dimension(*),intent(in) :: atol
integer,intent(in),optional :: method=1
integer dimension(20),intent(in),optional :: info
integer,intent(out) :: iwarn
integer,intent(out) :: ierr
end subroutine dgelda
end interface
end python module foo
更新:我还是不明白。我从定义中删除了每个intent(hide|cache|optional)
数组,它仍然抛出相同的错误。这是我的更新版本(我将某些数组大小设置为常量):
python module __user__routines
interface
subroutine edif(n,t,idif,e,lde,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(lde,*),intent(out) :: e
integer, optional,check(shape(e,0)==lde),depend(e) :: lde=shape(e,0)
integer dimension(8) :: ipar
double precision dimension(8) :: rpar
integer,intent(out) :: ierr
end subroutine edif
subroutine adif(n,t,idif,a,lda,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(lda,*),intent(out) :: a
integer, optional,check(shape(a,0)==lda),depend(a) :: lda=shape(a,0)
integer dimension(8) :: ipar
double precision dimension(8) :: rpar
integer,intent(out) :: ierr
end subroutine adif
subroutine fdif(n,t,idif,f,ipar,rpar,ierr)
integer,intent(in) :: n
double precision,intent(in) :: t
integer,intent(in) :: idif
double precision dimension(*),intent(out) :: f
integer dimension(8) :: ipar
double precision dimension(8) :: rpar
integer,intent(out) :: ierr
end subroutine fdif
end interface
end python module __user__routines
python module foo
interface
subroutine foo(edif,adif,fdif,neq,t,tout,x,xprime,cval,ipar,rpar,iwork,liw,rwork,lrw,rtol,atol,method,info,iwarn,ierr) ! in :test:SRC/dgelda.f
use __user__routines, edif=>edif, adif=>adif, fdif=>fdif
external edif
external adif
external fdif
integer,intent(in) :: neq
double precision,intent(inout) :: t
double precision,intent(in) :: tout
double precision dimension(*),intent(inout) :: x
double precision dimension(*),intent(out) :: xprime
integer dimension(4),intent(out) :: cval
integer dimension(8) :: ipar
double precision dimension(8) :: rpar
integer dimension(liw),depend(liw) :: iwork
integer,intent(hide) :: liw=20+6*neq
double precision dimension(lrw),depend(lrw) :: rwork
integer,intent(hide) :: lrw = 1000*neq*neq
double precision dimension(*),intent(in) :: rtol
double precision dimension(*),intent(in) :: atol
integer,intent(in),optional :: method=1
integer dimension(20),intent(in),optional :: info
integer,intent(out) :: iwarn
integer,intent(out) :: ierr
end subroutine foo
end interface
end python module foo
! This file was auto-generated with f2py (version:2).
! See http://cens.ioc.ee/projects/f2py2e/
解决方案
推荐阅读
- kubernetes - 重新创建另一个服务时重新启动 pod
- python - 不和谐机器人的命令不起作用(Python)
- php - 如果传递null,则php函数获取默认值
- javascript - 如何使用javascript插入和获取动态创建的输入字段的值?
- spring-cloud-stream - Spring 云流消息传递。消息为空
- encryption - Python AES 解密初始化向量和键值大小问题
- python - 我在第 20 行出现错误“TypeError: 'float' object is not subscriptable”
- python - 圆形列表、列表列表、numpy 数组或其他维护其结构的结构
- python - 每组重叠间隔切片之间的总和值
- vue.js - How to add icon to the Header in vuetify DataTable