我如何分配输入数组与f2py? [英] How do I allocate input arrays with f2py?

查看:170
本文介绍了我如何分配输入数组与f2py?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

警告.....我是一个相对的python noob,并且完全使用f2py。



我尝试尽职调查并搜索答案在我的问题在这里和其他地方interweb,但我有运气。这很可能是由于我对这个主题的无知。



我的问题:我有一个遗留fortran(f77)子程序以及子程序使用的几个函数从数据文件中读取各种数组。这个数据文件本身是几个f77原子物理学代码之一的结果。

我想用f2py封装fortran子程序/函数,并以numpy数组的形式访问存储在文件中的数据。我被困在如何正确地分配在Python中的数组。我在Ubuntu 14.04(64位)上使用了Anaconda python distibrution(Python 3.4-64位)和gfortran编译器。



我成功(我希望)管理使用py2f创建一个python签名文件,使用 py2f -h< filename.py2f> <输入文件> 。这是签名文件的内容。我为它的长度道歉。这是一个相当长的子程序,并且有很多变量。

 ! -  *  -  f90  -  *  -  
!注意:此文件的上下文区分大小写。

子程序xxdata_04(iunit,ndlev,ndtrn,ndmet,ndqdn,nvmax,titled,iz,iz0,iz1,bwno,npl,bwnoa,lbseta,prtwta,cprta,il,qdorb,lqdorb,qdn ,IORB,IA,cstrga,ISA,ILA,XJA,WA,CPLA,NPLA,IPLA,zpla,NV,SCEF,itran,maxlev,t码,I1A,I2A,AVAL,SCOM,贝斯,iadftyp,lprn,LCPL,lorb ,lbeth,letyp,lptyp,lrtyp,lhtyp,lityp,lstyp,lltyp,itieactn,ltied)!在xxdata04_string.for
integer :: iunit
整数,可选,check(len(ia)> = ndlev),depends(ia):: ndlev = len(ia)
整数,可选,check(形状(tcode,0)== ndtrn),依赖(tcode):: ndtrn = shape(tcode,0)
整数,可选,检查(len(bwnoa)> = ndmet) (bwnoa):: ndmet = len(bwnoa)
整数,可选,check(len(qdn)> = ndqdn),depends(qdn):: ndqdn = len(qdn)
整数,可选,检查(len(scef)> = nvmax),依赖(scef):: nvmax = len(scef)
字符* 3 ::标题
integer :: iz
integer :: iz0
整数:: iz1
real * 8 :: bwno
整数:: npl
real * 8维(ndmet):: bwnoa
逻辑维(ndmet) ,依赖(ndmet):: lbseta
real * 8维(ndmet),依赖(ndmet):: prtwta
字符维(ndmet,9),依赖(ndmet):: cprta
整数:: il
real * 8维((ndqdn *(ndqdn + 1))/ 2),depends(ndqdn):: qdorb
逻辑维((ndqdn *(ndqdn + 1))/ 2),取决于(NDQ dn):: lqdorb
real * 8维(ndqdn):: qdn
整数:: iorb
整数维(ndlev):: ia
字符维(ndlev,(* )),depend(ndlev):: cstrga
整数维(ndlev),依赖(ndlev):: isa
整数维(ndlev),依赖(ndlev):: ila
real * 8维(ndlev),depends(ndlev):: xja
real * 8维(ndlev),depends(ndlev):: wa
字符维(ndlev,1),depend(ndlev):: cpla
整数维(ndlev),depends(ndlev):: npla
整数维(ndmet,ndlev),依赖(ndmet,ndlev):: ipla
real * 8维(ndmet, ndlev),depend(ndmet,ndlev):: zpla
integer :: nv
real * 8维(nvmax):: scef
整数:: itran
整数:: maxlev
字符维(ndtrn,1):: tcode
整数维(ndtrn),依赖(ndtrn):: i1a
整数维(ndtrn),依赖(ndtrn):: i2a
real * 8维(ndtrn),depends(ndtrn):: aval
real * 8角钱nsion(nvmax,ndtrn),depend(nvmax,ndtrn):: scom
real * 8维(ndtrn),depends(ndtrn):: beth
整数:: iadftyp
logical :: lprn
logical :: lcpl
logical :: lorb
logical :: lbeth
logical :: letyp
logical :: lptyp
logical :: lrtyp
logical :: lhtyp
logical :: lityp
logical :: lstyp
logical :: lltyp
integer :: itieactn
逻辑维(ndlev),depend (ndlev):: ltied
结束子程序xxdata_04
函数i4unit(iunit)!在i4unit.for
integer :: iunit
integer :: i4unit
结束函数i4unit
子程序xxword(ctext,cdelim,nfirst,iwords,ifirst,ilast,nwords)!在xxword.for
字符*(*):: ctext
字符*(*):: cdelim
integer :: nfirst
整数,可选,check(len(ifirst) > = iwords),依赖(ifirst):: iwords = len(ifirst)
整数维(iwords):: ifirst
整数维(iwords),depends(iwords):: ilast
整数:: nwords
结束子程序xxword
子程序xxslen(cstrng,ifirst,ilast)!在xxslen.for
字符*(*):: cstrng
整数:: ifirst
整数:: ilast
结束子程序xxslen
子程序xxprs1(ndmet,string_bn, wno,cpl,npt,ipla,zpla,ifail)! in xxprs1.for
integer * 4,可选,check(len(ipla)> = ndmet),depend(ipla):: ndmet = len(ipla)
字符*(*):: string_bn
real * 8 :: wno
字符* 1 :: cpl
整数* 4 :: npt
整数* 4维(ndmet):: ipla
real * 8维(ndmet),依赖(ndmet):: zpla
整数* 4 :: ifail
结束子程序xxprs1
函数r8fctn(str,iabt)!在r8fctn.for
字符*(*):: str
integer :: iabt
real * 8 :: r8fctn
结束函数r8fctn
函数i4fctn(str, iabt)!在i4fctn.for
字符*(*):: str
整数:: iabt
整数:: i4fctn
结束函数i4fctn
函数i4idfl(n,l) ! in i4idfl.for
integer :: n
integer :: l
integer :: i4idfl
end function i4idfl
子程序xxpars(ndmet,strng1,npt,bwnoa, lseta,prtwta,cprta,ifail,itype)! (bwnoa):: ndmet = len(bwnoa)
字符*(*):: strng1
integer * 4 :: npt
real * 8维(ndmet):: bwnoa
逻辑维(ndmet),depends(ndmet):: lseta
real * 8维( ndmet),depend(ndmet):: prtwta
字符维(ndmet,(*)),depends(ndmet):: cprta
整数* 4 :: ifail
整数* 4 :: itype
结束子程序xxpars
子程序xxrmve(cstrg1,cstrg2,crmve)!在xxrmve.for
字符*(*):: cstrg1
字符*(*):: cstrg2
字符* 1 :: crmve
结束子程序xxrmve
子程序xxcase(输入,输出,type_bn)!在xxcase.for
字符*(*)::输入
字符*(*)::输出
字符* 2 :: type_bn
结束子程序xxcase

!这个文件是用f2py(版本:2)自动生成的。
!见http://cens.ioc.ee/projects/f2py2e/

然后我用 f2py -c -m <输入文件> 。编译完成时只有几个警告但没有错误。生成的python共享对象是 adf04_2py.cpython-35m-x86_64-linux-gnu.so



我已经开始构建一个我想用来导入共享对象并调用'xxdata_04'子例程的python脚本。到目前为止,我的过程一直是这样的......


  1. 调用子程序。它失败了,并找出我需要传递给它的变量。

  2. 在我的python脚本中初始化并分配该变量。

  3. 重复。

我确信有更好的方法可以做到这一点,但fortran代码很多,并且有点冗长,而不是我自己的,所以这看起来是最直接的方法。



到目前为止,我的脚本如下所示:

  import adf04_2py as adf 
进口numpy为np

itieactn = 1

iunit = 19;标题='---'; iz = 18; iz0 = 0; iz1 = 0; il = 0
bwno = 0.0; npl = 0; bwnoa = 1.0; prtwta = 0.0
qdorb = 0.0; qdn = 0.0; iorb = 0; ia = 0; cstrga =' - '
isa = 0; ila = 0; xja = 0.0; wa = 0.0; cpla =' - '; npla = 0; ipla = 0
zpla = 0; nv = 0; scef = 0.0; itran = 0; maxlev = 0; tcode =' - '
ila = 0; i2a = 0; aval = 0.0; scom = 0.0; beth = 0; iadftyp = 0

cprta = np.asarray([['---------'],['---------'],[' - -------']],dtype ='c')


lbseta = False; lqdorb = False; lprn = False; lcpl = False; lorb = False
lbeth = False; letyp = False; lptyp = False; lrtyp = False; lhtyp = False
lityp = False; lstyp = False; lltyp = False; ltied = False


adf04_dat = adf.xxdata_04(iunit,标题为iz,iz0,iz1,bwno,npl,bwnoa,
lbseta,prtwta,cprta,il,qdorb ,lqdorb,
qdn,iorb,ia,cstrga,isa,ila,xja,wa,
cpla,npla,ipla,zpla,nv,scef,itran,
maxlev,tcode,ila ,i2a,aval,scom,beth,
iadftyp,lprn,lcpl,lorb,lbeth,letyp,lptyp,
lrtyp,lhtyp,lityp,lstyp,lltyp,itieactn,

目前,它失败:

  runfile('/ home / ivan / GoogleDrive / AUAMO / codes / read_adf04_2py / xxdata_04 / read_adf2py.py',wdir ='/ home / ivan / GoogleDrive / AUAMO / codes / read_adf04_2py / xxdata_04')

文件/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py,行699,在运行文件
execfile(f ilename,namespace)

执行文件$ b $中的文件/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py,第88行b exec(compile(open(filename,'rb').read(),filename,'e​​xec'),namespace)

文件/ home / ivan / GoogleDrive / AUAMO / codes / read_adf04_2py / xxdata_04 / read_adf2py.py,第32行,位于< module>
ltied)

错误:未能将adf04_2py.xxdata_04的第11个参数`cprta'转换为C / Fortran数组

根据签名文件,cprta应该是形状的字符数组((ndmet),(#字符数)),其中ndmet是亚稳状态的数量和#字符数是9.我试图通过使用np.asarray分配这个。我还是得到了将adf04_2py.xxdata_04的第11个参数`cprta'转换为C / Fortran数组失败。

任何帮助?我完全意识到我不知道我在做什么。

解决方案

感谢CT Zhu为此问题提供的解决方案。

  0维度必须固定为1,但得到3( 
Traceback(最近一次调用的最后一个):
在< module>文件中,第33行的文件read_adf2py.py
ltied)
adf04_2py.error:未能将adf04_2py.xxdata_04的第11个参数`cprta'转换为C / Fortran数组

我重新分配了字符串数组,使其维度为1 x 9,并且该错误消失。

  cprta = np.asarray(['---------'],dtype ='c') 

现在我收到了段错误,但我认为这是一个单独的问题。



感谢CT Zhu!

Warning..... I am a relative python noob, and completely new to using f2py.

I have tried to exercise due diligence and search for the answer to my questions here and elsewhere on the interweb, but I've had little luck. This is very likely due to my own ignorance on this subject.

My problem: I have a legacy fortran (f77) subroutine along with several functions that are used by the subroutine to read in various arrays from a data file. This data file is itself the result of one of several f77 atomic physics codes.

I would like to wrap the fortran subroutines/functions using f2py, and have access to the data stored in the file in the form of numpy arrays. I'm stuck at how to properly allocate the arrays in python. I am using the Anaconda python distibrution (Python 3.4 - 64 bit) and the gfortran compiler on Ubuntu 14.04 (64 bit).

I've successfully (I hope) managed to create a python signature file using py2f, using py2f -h <filename.py2f> <input files>. Here's the contents of the signature file. I apologize for its length. This is a fairly lengthy subroutine and has a lot of variables.

!    -*- f90 -*-
! Note: the context of this file is case sensitive.

subroutine xxdata_04(iunit,ndlev,ndtrn,ndmet,ndqdn,nvmax,titled,iz,iz0,iz1,bwno,npl,bwnoa,lbseta,prtwta,cprta,il,qdorb,lqdorb,qdn,iorb,ia,cstrga,isa,ila,xja,wa,cpla,npla,ipla,zpla,nv,scef,itran,maxlev,tcode,i1a,i2a,aval,scom,beth,iadftyp,lprn,lcpl,lorb,lbeth,letyp,lptyp,lrtyp,lhtyp,lityp,lstyp,lltyp,itieactn,ltied) ! in xxdata04_string.for
    integer :: iunit
    integer, optional,check(len(ia)>=ndlev),depend(ia) :: ndlev=len(ia)
    integer, optional,check(shape(tcode,0)==ndtrn),depend(tcode) :: ndtrn=shape(tcode,0)
    integer, optional,check(len(bwnoa)>=ndmet),depend(bwnoa) :: ndmet=len(bwnoa)
    integer, optional,check(len(qdn)>=ndqdn),depend(qdn) :: ndqdn=len(qdn)
    integer, optional,check(len(scef)>=nvmax),depend(scef) :: nvmax=len(scef)
    character*3 :: titled
    integer :: iz
    integer :: iz0
    integer :: iz1
    real*8 :: bwno
    integer :: npl
    real*8 dimension(ndmet) :: bwnoa
    logical dimension(ndmet),depend(ndmet) :: lbseta
    real*8 dimension(ndmet),depend(ndmet) :: prtwta
    character dimension(ndmet,9),depend(ndmet) :: cprta
    integer :: il
    real*8 dimension((ndqdn*(ndqdn+1))/2),depend(ndqdn) :: qdorb
    logical dimension((ndqdn*(ndqdn+1))/2),depend(ndqdn) :: lqdorb
    real*8 dimension(ndqdn) :: qdn
    integer :: iorb
    integer dimension(ndlev) :: ia
    character dimension(ndlev,(*)),depend(ndlev) :: cstrga
    integer dimension(ndlev),depend(ndlev) :: isa
    integer dimension(ndlev),depend(ndlev) :: ila
    real*8 dimension(ndlev),depend(ndlev) :: xja
    real*8 dimension(ndlev),depend(ndlev) :: wa
    character dimension(ndlev,1),depend(ndlev) :: cpla
    integer dimension(ndlev),depend(ndlev) :: npla
    integer dimension(ndmet,ndlev),depend(ndmet,ndlev) :: ipla
    real*8 dimension(ndmet,ndlev),depend(ndmet,ndlev) :: zpla
    integer :: nv
    real*8 dimension(nvmax) :: scef
    integer :: itran
    integer :: maxlev
    character dimension(ndtrn,1) :: tcode
    integer dimension(ndtrn),depend(ndtrn) :: i1a
    integer dimension(ndtrn),depend(ndtrn) :: i2a
    real*8 dimension(ndtrn),depend(ndtrn) :: aval
    real*8 dimension(nvmax,ndtrn),depend(nvmax,ndtrn) :: scom
    real*8 dimension(ndtrn),depend(ndtrn) :: beth
    integer :: iadftyp
    logical :: lprn
    logical :: lcpl
    logical :: lorb
    logical :: lbeth
    logical :: letyp
    logical :: lptyp
    logical :: lrtyp
    logical :: lhtyp
    logical :: lityp
    logical :: lstyp
    logical :: lltyp
    integer :: itieactn
    logical dimension(ndlev),depend(ndlev) :: ltied
end subroutine xxdata_04
function i4unit(iunit) ! in i4unit.for
    integer :: iunit
    integer :: i4unit
end function i4unit
subroutine xxword(ctext,cdelim,nfirst,iwords,ifirst,ilast,nwords) ! in xxword.for
    character*(*) :: ctext
    character*(*) :: cdelim
    integer :: nfirst
    integer, optional,check(len(ifirst)>=iwords),depend(ifirst) :: iwords=len(ifirst)
    integer dimension(iwords) :: ifirst
    integer dimension(iwords),depend(iwords) :: ilast
    integer :: nwords
end subroutine xxword
subroutine xxslen(cstrng,ifirst,ilast) ! in xxslen.for
    character*(*) :: cstrng
    integer :: ifirst
    integer :: ilast
end subroutine xxslen
subroutine xxprs1(ndmet,string_bn,wno,cpl,npt,ipla,zpla,ifail) ! in xxprs1.for
    integer*4, optional,check(len(ipla)>=ndmet),depend(ipla) :: ndmet=len(ipla)
    character*(*) :: string_bn
    real*8 :: wno
    character*1 :: cpl
    integer*4 :: npt
    integer*4 dimension(ndmet) :: ipla
    real*8 dimension(ndmet),depend(ndmet) :: zpla
    integer*4 :: ifail
end subroutine xxprs1
function r8fctn(str,iabt) ! in r8fctn.for
    character*(*) :: str
    integer :: iabt
    real*8 :: r8fctn
end function r8fctn
function i4fctn(str,iabt) ! in i4fctn.for
    character*(*) :: str
    integer :: iabt
    integer :: i4fctn
end function i4fctn
function i4idfl(n,l) ! in i4idfl.for
    integer :: n
    integer :: l
    integer :: i4idfl
end function i4idfl
subroutine xxpars(ndmet,strng1,npt,bwnoa,lseta,prtwta,cprta,ifail,itype) ! in xxpars.for
    integer*4, optional,check(len(bwnoa)>=ndmet),depend(bwnoa) :: ndmet=len(bwnoa)
    character*(*) :: strng1
    integer*4 :: npt
    real*8 dimension(ndmet) :: bwnoa
    logical dimension(ndmet),depend(ndmet) :: lseta
    real*8 dimension(ndmet),depend(ndmet) :: prtwta
    character dimension(ndmet,(*)),depend(ndmet) :: cprta
    integer*4 :: ifail
    integer*4 :: itype
end subroutine xxpars
subroutine xxrmve(cstrg1,cstrg2,crmve) ! in xxrmve.for
    character*(*) :: cstrg1
    character*(*) :: cstrg2
    character*1 :: crmve
end subroutine xxrmve
subroutine xxcase(input,output,type_bn) ! in xxcase.for
    character*(*) :: input
    character*(*) :: output
    character*2 :: type_bn
end subroutine xxcase

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

I then compiled with f2py -c -m <filename> <input files> . Compilation completed with a few warnings but no errors. The resulting python shared object is adf04_2py.cpython-35m-x86_64-linux-gnu.so

I have started building a python script that I would like to use to import the shared object and call the 'xxdata_04' subroutine. My process so far has been this.....

  1. Call the subroutine.
  2. Let it fail, and figure out what variable I need to pass to it.
  3. Initialize and allocate that variable in my python script.
  4. repeat.

I'm sure there's a better way to do this, but the fortran code(s) are many and somewhat lengthy, and not my own, so this seemed like the most direct method.

So far my script looks like this:

import adf04_2py as adf
import numpy as np

itieactn = 1

iunit = 19 ; titled = '---' ; iz = 18 ; iz0 = 0 ; iz1 = 0 ; il = 0
bwno = 0.0 ; npl = 0 ; bwnoa = 1.0 ; prtwta = 0.0
qdorb = 0.0 ; qdn =0.0 ; iorb = 0 ; ia = 0 ; cstrga = '-'
isa = 0 ; ila = 0 ; xja = 0.0 ; wa = 0.0 ; cpla = '-' ; npla = 0 ; ipla = 0
zpla = 0 ; nv = 0 ; scef = 0.0 ; itran = 0 ; maxlev = 0 ; tcode = '-'
ila = 0 ; i2a = 0 ; aval = 0.0 ; scom = 0.0 ; beth = 0 ; iadftyp = 0

cprta = np.asarray([['---------'],['---------'],['---------']],dtype='c')


lbseta = False ; lqdorb = False ; lprn = False ; lcpl= False ; lorb = False
lbeth = False ; letyp = False ; lptyp = False ; lrtyp = False ; lhtyp = False
lityp = False ; lstyp = False ; lltyp = False ; ltied = False


adf04_dat = adf.xxdata_04(iunit, titled, iz, iz0, iz1 , bwno, npl, bwnoa ,
                          lbseta , prtwta , cprta , il , qdorb , lqdorb ,
                          qdn , iorb , ia , cstrga , isa , ila , xja , wa ,
                          cpla , npla, ipla , zpla , nv , scef , itran , 
                          maxlev , tcode , ila , i2a , aval , scom , beth ,
                          iadftyp , lprn, lcpl , lorb , lbeth , letyp, lptyp ,
                          lrtyp , lhtyp , lityp , lstyp , lltyp , itieactn ,

Currently, it fails with:

runfile('/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04/read_adf2py.py', wdir='/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04')

  File "/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 699, in runfile
    execfile(filename, namespace)

  File "/home/ivan/anaconda3/lib/python3.5/site-packages/spyderlib/widgets/externalshell/sitecustomize.py", line 88, in execfile
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace)

  File "/home/ivan/GoogleDrive/AUAMO/codes/read_adf04_2py/xxdata_04/read_adf2py.py", line 32, in <module>
    ltied )

error: failed in converting 11st argument `cprta' of adf04_2py.xxdata_04 to C/Fortran array

according to the signature file, cprta should be a character array of shape((ndmet),(# of characters)), where ndmet is the number of metastable states and # of characters is 9. I've tried to allocate this by using np.asarray. I still get the "failed in converting 11st argument `cprta' of adf04_2py.xxdata_04 to C/Fortran array" error.

Any help? I am fully aware that I have no clue what I'm doing.

解决方案

Thanks to CT Zhu for the solution to this problem. Running the script from a terminal gave a more informative error message.

0-th dimension must be fixed to 1 but got 3 (real index=0)
Traceback (most recent call last):
  File "read_adf2py.py", line 33, in <module>
    ltied )
adf04_2py.error: failed in converting 11st argument `cprta' of adf04_2py.xxdata_04 to C/Fortran array

I reallocated the string array to have dimension 1 x 9 and that error vanished.

cprta = np.asarray(['---------'],dtype='c')

Now I'm getting a segfault, but I think that's a separate issue.

Thanks CT Zhu!

这篇关于我如何分配输入数组与f2py?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆