问题
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?
回答1:
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.
来源:https://stackoverflow.com/questions/12309161/malloc-error-in-f2py