是否有调试错误的一般方法
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/