Ich arbeite am fraktalen Generator-Code. Der Hauptcode ist in Python geschrieben und Iterationen Teil ist in Fortran geschrieben. Ich verwende f2py, um die zwei Codes zusammen zu kleben. Hier ist die Fortran-Funktion, die ich verwende:segfault auf f2py callback
function iterate(z0, func, zmax, niter) result(n)
implicit none
complex(kind=8), intent(in) :: z0
real(kind=8), intent(in) :: zmax
integer, intent(in) :: niter
external func
complex(kind=8) :: func
integer :: n
complex(kind=8) :: z
n = 0
z = z0
do while ((n < niter) .and. (abs(z) < zmax))
z = func(z)
n = n + 1
end do
end function iterate
Hier ist die docstring für den generierten Wrapper-Code:
n = iterate(z0,func,zmax,niter,[func_extra_args])
Wrapper for ``iterate``.
Parameters
----------
z0 : input complex
func : call-back function
zmax : input float
niter : input int
Other Parameters
----------------
func_extra_args : input tuple, optional
Default:()
Returns
-------
n : int
Notes
-----
Call-back functions::
def func(z): return z
Required arguments:
z : input complex
Return objects:
z : complex
Ich erhalte Segmentation fault
Fehler, wenn zu Verwendung iterate
mit jeder Python-Callback-Funktion zu versuchen. Hier ist ein Beispiel Ergebnis, das ich bekommen:
>>> from foo import iterate
>>> iterate(1.0j, lambda x: 4.0 + x**2, 4.0, 256)
Segmentation fault
ich durch alle verfügbaren Unterlagen über Rückrufe in f2py ausgesehen haben, aber haben keine Lösung für dieses Problem gefunden. Jede Hilfe wäre willkommen.
UPDATE
ist hier ein Backtrace von GDB:
Program received signal SIGSEGV, Segmentation fault.
cb_func_in_iterate2__user__routines (return_value=0x7fffffffdbc0, z_cb_capi=0x3ff0000000000000)
at /tmp/tmpT8xG1q/src.linux-x86_64-2.7/juliamodule.c:470
470 /tmp/tmpT8xG1q/src.linux-x86_64-2.7/juliamodule.c: No such file or directory.
(gdb) backtrace
#0 cb_func_in_iterate2__user__routines (return_value=0x7fffffffdbc0, z_cb_capi=0x3ff0000000000000)
at /tmp/tmpT8xG1q/src.linux-x86_64-2.7/juliamodule.c:470
#1 0x00007ffff6b6482b in iterate2 (z0=(1,1), [email protected]=0x7ffff6b60c20 <cb_func_in_iterate2__user__routines>, zmax=4, niter=256)
at julia.f90:38
#2 0x00007ffff6b64897 in f2pywrapiterate2 (iterate2f2pywrap=0, z0=(1,1), [email protected]=0x7ffff6b60c20 <cb_func_in_iterate2__user__routines>,
zmax=4, niter=256) at /tmp/tmpT8xG1q/src.linux-x86_64-2.7/julia-f2pywrappers.f:25
#3 0x00007ffff6b61f5e in f2py_rout_julia_iterate2 (capi_self=<optimized out>, capi_args=<optimized out>, capi_keywds=<optimized out>,
f2py_func=0x7ffff6b64880 <f2pywrapiterate2>) at /tmp/tmpT8xG1q/src.linux-x86_64-2.7/juliamodule.c:811
#4 0x00000000004caaa1 in PyEval_EvalFrameEx()
#5 0x00000000004c87a1 in PyEval_EvalCodeEx()
#6 0x00000000005030ef in ??()
#7 0x00000000004f8c72 in PyRun_FileExFlags()
#8 0x00000000004f7d77 in PyRun_SimpleFileExFlags()
#9 0x00000000004982f2 in Py_Main()
#10 0x00007ffff6f12b45 in __libc_start_main (main=0x497d80 <main>, argc=2, argv=0x7fffffffe2a8, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffe298) at libc-start.c:287
#11 0x0000000000497ca0 in _start()
Kann ich nur fragen, warum versuchen Sie, zwei verschiedene Sprachen zu verwenden, um etwas zu tun, das zumindest relativ einfach scheint? Zum Beispiel, warum schreibst du nicht alles in Python? – CrazyCasta
Der Fortran-Code für die 'iterate'-Funktion ist etwa 10-mal schneller als sein Python-Äquivalent. – taras
Was Ihr Problem angeht, nur um klar zu sein, wenn Sie 'z = func (z)' mit 'z = 4.0 + z * z' Sie sagen, es wird funktionieren? Entfernen Sie die Funktion nicht aus der Parameterliste oder irgendetwas, machen Sie nur diese kleine Änderung. – CrazyCasta