动态参数传递给fortran代码的python回调例程

时间:2019-02-12 11:59:29

标签: python callback fortran parameter-passing f2py

我有一些旧的fortran代码,我想用f2py包装它们,并且不允许更改。

程序的核心是一些子例程,这些子例程取决于用户定义的子例程。这些子例程的全部共享公共参数数组,以在例程之间交换用户提供的数据。这些参数数组是一维的,因此不要期望主子例程头中有任何预定义的输入大小。

但是,似乎像python回调函数标头一样,需要有关数组实际大小的精确信息。

让我们看一个例子:

这是我的fortran代码:

  Subroutine myscript(x,fun,o,n,rpar, ipar)
  external fun
  integer n
  double precision x(n,*)
  double precision o(n)
  double precision rpar(*)
  integer ipar(*)
  write(*,*) n
  !write(*,*) x(1,:)
  call fun(n,x,o,rpar,ipar)
  write(*,*) o
  write(*,*) rpar(1)
  end

这是我的python部分:

    import numpy as np
    import routine
    import ipdb
    def fun(X, rpar):
        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)
    rpar = np.array([1.,1.])

    routine.myscript(X, fun, rpar)

我使用f2py -c routine.pyf routine.f和以下标头文件

进行了编译
    !    -*- f90 -*-
    ! Note: the context of this file is case sensitive.

    python module myscript__user__routines 
    interface myscript_user_interface 
        subroutine fun(n,x,o,rpar,ipar) ! in :routine:routine.f:myscript:unknown_interface
        integer, optional,intent(hide),check(shape(x,0)==n),depend(x) :: n=shape(x,0)
        double precision dimension(n,n),intent(in) :: x
        double precision dimension(n),intent(out),depend(n) :: o
        double precision dimension(100),intent(in) :: rpar
        integer, optional, dimension(*) :: ipar
        end subroutine fun
    end interface myscript_user_interface
    end python module myscript__user__routines
    python module routine ! in 
    interface  ! in :routine
        subroutine myscript(x,fun,o,n,rpar,ipar) ! in :routine:routine.f
        use myscript__user__routines
        double precision dimension(n,*),intent(in,copy) :: x
        external fun
        double precision dimension(n),intent(out),depend(n) :: o
        integer, optional,intent(hide),check(shape(x,0)==n),depend(x) :: n=shape(x,0)
        double precision dimension(shape(rpar,0)) :: rpar
        integer, optional, dimension(2) :: ipar
        end subroutine myscript
    end interface 
    end python module routine

    ! This file was auto-generated with f2py (version:2).
    ! See http://cens.ioc.ee/projects/f2py2e/

头文件中的重要行是

   double precision dimension(100),intent(in) :: rpar

在python调试器中,rpar现在是一个100维数组,其中最后98个值是垃圾(不足为奇)。

将维度更改为*只会返回一个空数组

ipdb> rpar
array([], dtype=float64)

在主例程中将尺寸更改为shape(rpar,0)会产生错误

ValueError: negative dimensions are not allowed

是否存在让python用户动态决定参数数组rpar的尺寸的优雅方法? 示例中的期望值为2,因为它是输入数组的维。

我想我可以更改接口并添加另一个整数变量来声明此数组的大小。但是,这意味着在每次代码中更改对该子例程的所有调用。我想避免的事情

0 个答案:

没有答案