Я работаю над кодом фрактального генератора. Основной код написан на python, а часть итераций написана в fortran. Я использую f2py для склеивания двух кодов вместе. Вот Фортран функция я использую:segfault на 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
Вот строка документации для сгенерированного кода упаковщика:
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
Я получаю Segmentation fault
ошибку при попытке использования iterate
с любой функцией питона обратного вызова. Вот пример результата, который я получаю:
>>> from foo import iterate
>>> iterate(1.0j, lambda x: 4.0 + x**2, 4.0, 256)
Segmentation fault
Я просмотрел всю имеющуюся документацию на обратные вызовы в f2py но не нашли решение этой проблемы. Любая помощь будет оценена по достоинству.
UPDATE
Вот трассировка от БГДА:
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()
Могу я просто спросить, почему вы пытаетесь использовать два разных языка, чтобы сделать что-то, что по крайней мере кажется относительно простым? Например, почему бы просто не написать все это в python? – CrazyCasta
Код Fortran для функции 'iterate' примерно в 10 раз быстрее, чем его эквивалент на основе python. – taras
Что касается вашей проблемы, просто чтобы быть понятным, если вы 'z = func (z)' с 'z = 4.0 + z * z', вы говорите, что это сработает? Не удалять функцию из списка параметров или что-то еще, просто делая это небольшое изменение. – CrazyCasta