malloc错误在f2py中 [英] malloc error in 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中使用边界检查(至少 你也可以在调试器或valgrind下运行它,它可能会告诉你问题出在哪里。 最后,我个人更喜欢使用Cython直接打包Fortran。然后,我可以轻松访问所有生成的文件,并使用 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: While the fortran subroutine is a bit lengthy, the important parts of it are the beginning ... and the end ... The comments at the top of the subroutine (lines 5 - 11) are structures which exist in the fortran module 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 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 这篇关于malloc错误在f2py中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! -fcheck = all
来检查所有问题)。
iso_c_binding
Fortran模块,以便Fortran编译器检查所有类型在Fortran和C(Python)之间是否兼容,请参阅此处为例。#!/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'
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
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
-fbounds-check
in gfortran, preferably just -fcheck=all
to check all problems).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.