malloc错误在f2py中 [英] malloc error in f2py

查看:155
本文介绍了malloc错误在f2py中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用f2py在三维中运行一个简单的集成问题。


$ b 调用 fortran代码的python代码是如下所示:

 #!/ Library / Frameworks / EPD64.framework / Versions / Current / bin / python 
import pymods as modules
导入pygauleg作为gauleg
导入pyint作为集成商
导入pylab作为pl
导入sys sys $ b $导入数学
导入时间

############################################
#主程序#############################
############# ###############################
zero = 0.0
one = 1.0
pi = pl.pi

Nr = 10
Nt = 10
Np = 2 * Nt
r0 = 0
rf = 1
NNang = Nr * Nt * Np

print'Nr Nt Np =',Nr,Nt,Np
print'NNang =',NNang
print'r0 rf =',r0 (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'gauleg '

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

  2子程序gauleg(x,w,x1,x2,n)
3!输入:x1,x2, n
4!输出:x,w
5!隐式无
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使用mod_gvars
13
14 real(kind = rkind):: tol = 1d-15
15
17整数:: n
18 !!!!! f2py intent(in)n
19 real(kind = rkind),dimension(n):: x
20 real(kind = rkind) ,维(n):: w
22 real :: x1,x2
23
24 real(kind = rkind):: z1,z,xm,xl,pp,p3,p2 ,p1;
25
26整数(kind = ikind):: m
27整数(kind = ikind):: i,j
28整数(kind = ikind):: countmax,计数器,max_counter,min_counter
29
30整数(kind = ikind)::十,百分之一,千分之一
31
32打印*,'n =',n

结束......

  98 
打印*,'返回'
100
101结束子程序

子例程顶部的注释(第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
返回
python(14167)malloc:***对象0x1081f77a8错误:释放对象的校验和不正确 - 对象可能在释放后被修改。
***在malloc_error_break中设置一个断点来调试
中止陷阱

它看起来像子程序只有在返回时才会遇到问题。为什么会发生这种情况?

解决方案

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



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

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

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



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


I am trying to use f2py to run a simple integration problem in 3 dimensions.

The python code which calls the fortran code is as follows:

#!/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'

While the fortran subroutine is a bit lengthy, the important parts of it are the beginning ...

  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

and the end ...

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

The comments at the top of the subroutine (lines 5 - 11) are structures which exist in the fortran module mod_gvars. It seems like everything is going according to plan *until* this subroutine returns. Here is the output:

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

It seems like the subroutine runs into a problem only upon returning. Why would this happen?

解决方案

This kind of problem typically happens with a reference count error in Python, which might happen for example if there is a bug in f2py, or if you overwrite more memory in Fortran than is allocated in the numpy arrays. All these errors only show after the Fortran subroutine exits, at a random point, typically when you deallocate some memory in Python.

To debug this, try to print all the arrays that you get into Fortran, that is, print the arrays x, w, to make sure that you can access all the memory in there (testing that f2py used the same types and so on).

Make sure you use bounds checking in Fortran (at least -fbounds-check in gfortran, preferably just -fcheck=all to check all problems).

You can also run this under debugger or valgrind, it might tell you where the problem is.

Finally, I personally prefer to just use Cython to wrap Fortran directly. Then I have easy access to all the generated files and I use the iso_c_binding Fortran module so that the Fortran compiler checks that all types are compatible between Fortran and C (Python), see here for an example.

这篇关于malloc错误在f2py中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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