2012-09-06 2 views
1

f2py를 사용하여 3 차원에서 간단한 통합 문제를 실행하려고합니다.f2py의 malloc 오류

가 호출하는 파이썬 코드가 포트란 코드는 다음과 같다 :

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

서브 루틴 상단의 주석 (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

이런 종류의 문제는 일반적으로 f2py에 버그가 있거나 numpy 배열에 할당 된 것보다 많은 메모리를 Fortran에서 덮어 쓰는 경우와 같은 Python의 참조 횟수 오류와 함께 발생합니다. 이러한 모든 오류는 Fortran 서브 루틴이 종료 된 후, 임의의 지점에서, 보통 파이썬에서 일부 메모리를 할당 해제 할 때만 나타납니다.

디버깅하려면 포트란에있는 모든 배열을 인쇄하십시오. 즉 배열 x, w를 인쇄하여 거기에있는 모든 메모리에 액세스 할 수 있는지 확인하십시오 (f2py가 동일한 유형 등등).

Fortran에서 범위 검사 (gfortran에서 적어도 -fbounds-check 이상, 모든 문제를 검사하려면 -fcheck=all)를 사용하십시오.

디버거 또는 valgrind에서 실행할 수도 있습니다. 문제가있는 위치를 알려줍니다.

마지막으로 개인적으로 Cython을 사용하여 Fortran을 직접 랩핑하는 것을 선호합니다. 그런 다음 생성 된 모든 파일에 쉽게 액세스 할 수 있으며, 예제를 참조하여 포트란 컴파일러가 Fortran과 C (Python)간에 모든 유형이 호환되는지 확인하도록 iso_c_binding 포트란 모듈을 사용합니다.

+0

+1 포트란에 대한 다른 가능성에 대한 흥미로운 제안. 그러나 때로는 모양 배열, 키워드 인수 및 명시 적 인터페이스를 사용하여 가능한 다른 기능을 사용할 수도 있습니다. –