2012-09-06 112 views
1

我想使用f2py在三维中运行一个简单的集成问题。f2py malloc错误

调用Python代码的Fortran代码如下:

#!/Library/Frameworks/EPD64.framework/Versions/Current/bin/python 
import pymods as modules 
import pygauleg as gauleg 
import pyint as integrator 
import pylab as pl 
import sys 
import math 
import time 

############################################ 
# main routine ############################# 
############################################ 
zero = 0.0 
one = 1.0 
pi = pl.pi 

Nr = 10 
Nt = 10 
Np = 2*Nt 
r0 = zero 
rf = one 
NNang = Nr*Nt*Np 

print 'Nr Nt Np = ', Nr, Nt, Np 
print 'NNang = ', NNang 
print 'r0 rf = ', r0, rf 

Nx = int(math.floor((one*NNang)**(one/3.0))) 
Ny = int(math.floor((one*NNang)**(one/3.0))) 
Nz = int(math.floor((one*NNang)**(one/3.0))) 

Nx = int(pl.floor(float(Nx)*1.75)) 
Ny = int(pl.floor(float(Ny)*1.75)) 
Nz = int(pl.floor(float(Nz)*1.75)) 

NNxyz = Nx*Ny*Nz 


print 'Nx Ny Nz = ', Nx, Ny, Nz 
print 'NNxyz = ', NNxyz 
xyz0 = -rf 
xyzf = rf 

t1 = time.time() 
xt = pl.zeros(Nt) 
wt = pl.zeros(Nt) 
gauleg.gauleg(xt, wt, 0.0, pl.pi, Nt) 
print 'outside of gauleg' 

虽然FORTRAN子程序是一个有点冗长,它的重要的部分是开始......

2 subroutine gauleg(x,w,x1,x2,n) 
    3 !Input: x1,x2,n 
    4 !Output: x,w 
    5 !implicit none 
    6 !integer, parameter :: ikind = selected_int_kind(25) 
    7 !integer, parameter :: rkind = selected_real_kind(15, 307) 
    8 ! 
    9 !real(kind = rkind), parameter :: pi = 3.14159265358979323846d00 
10 !real(kind = rkind), parameter :: one = 1.0d00 
11 !real(kind = rkind), parameter :: zero = 0.0d00 
12 use mod_gvars 
13 
14 real(kind = rkind) :: tol = 1d-15 
15 
17 integer :: n 
18 !!!!!f2py intent(in) n 
19 real(kind = rkind), dimension(n) :: x 
20 real(kind = rkind), dimension(n) :: w 
22 real :: x1, x2 
23 
24 real(kind = rkind) :: z1, z, xm, xl, pp, p3, p2, p1; 
25 
26 integer(kind = ikind) :: m 
27 integer(kind = ikind) :: i,j 
28 integer(kind = ikind) :: countmax, counter, max_counter, min_counter 
29 
30 integer(kind = ikind) :: tenth, hundredth, thousandth 
31 
32 print*, 'n = ', n 

和结束......

98 
99 print*, 'returning' 
100 
101 end subroutine 

子程序顶部的注释(第5 - 11行)是fortran模块mod_gvars中的结构。看起来好像一切都按照计划* 进行,直到 *这个子程序返回。这里是输出:

Nr Nt Np = 10 10 20 
NNang = 2000 
r0 rf = 0.0 1.0 
Nx Ny Nz = 21 21 21 
NNxyz = 1728 
n =   10 
m = 5 
returning 
python(14167) malloc: *** error for object 0x1081f77a8: incorrect checksum for freed object - object was probably modified after being freed. 
*** set a breakpoint in malloc_error_break to debug 
Abort trap 

看来只有在返回时子例程才会遇到问题。为什么会发生?

回答

3

这种问题通常发生在Python引用计数错误中,例如,如果在f2py中存在错误,或者如果在Fortran中覆盖的内存多于在numpy数组中分配的内存,则可能发生这种问题。所有这些错误仅在Fortran子程序退出后才显示,通常是在您释放Python中的某些内存时的随机点。

要调试此操作,请尝试打印所有进入Fortran的数组,即打印数组x,w,以确保可以访问其中的所有内存(测试f2py使用的是相同的类型等等)。

确保您在Fortran中使用边界检查(至少在gfortran中为-fbounds-check,最好是-fcheck=all以检查所有问题)。

你也可以在调试器或valgrind下运行它,它可能会告诉你问题出在哪里。

最后,我个人更喜欢使用Cython直接打包Fortran。然后我可以轻松访问所有生成的文件,并使用Fortran编译器模块,以便Fortran编译器检查所​​有类型在Fortran和C(Python)之间是否兼容,参见here的示例。

+0

+1对于与Fortran接口的其他可能性的有趣建议。但是,有时可能会使用明确的接口假定形状数组,关键字参数和其他特征。 –