Я пытаюсь использовать f2py для создания модуля python для моего кода Fortran, который использует как PETSc, так и SLEPc (этот вопрос очень тесно связан с это сообщение, но обсуждение там не смогло решить мою проблему - см. комментарии внизу этого сообщения). Код состоит из множества файлов и подпрограмм, но мне нужен доступ только к самой внешней функции main/driver в python. Первым шагом, который я предпринял, было использование предоставленного SLEPc шаблона make-файла для создания всех объектных файлов (окончательная компоновка не удалась, потому что внешняя функция теперь является подпрограммой, а не основной программой, но пока я не беспокоюсь об этом, так как я я как раз после объектных файлов).
Оттуда я попробовал два подхода. Первый — просто вызвать f2py
следующим образом:
f2py -c -m modname outer_driver.f90 file1.o file2.o file3.o...
Кажется, это работает, но при попытке импорта в python объекты/функции SLEPc (и, я полагаю, PETSc) не могут быть найдены:
>>> import mod_name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(./mod_name.so, 2): Symbol not found: _epscreate_
Referenced from: ./mod_name.so
Expected in: flat namespace
in ./mod_name.so
Второй подход предполагает, что мне также нужно связать библиотеки SLEPc/PETSc. Таким образом, я добавил строку в свой make-файл:
modname.so: outer_driver.f90
f2py -c -m modname outer_driver.f90 file1.o file2.o file3.o ${SLEPC_EPS_LIB}
После запуска «make modname.so» f2py
не может работать полностью. Вот результат этого:
running build
running config_cc
unifing config_cc, config, build_clib, build_ext, build commands --compiler options
running config_fc
unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
running build_src
build_src
building extension "modname" sources
f2py options: []
f2py:> /tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7/modnamemodule.c
creating /tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7
Reading fortran codes...
Reading file 'outer_driver.f90' (format:free)
Post-processing...
Block: modname
Block: outer_driver
Post-processing (stage 2)...
Building modules...
Building module "modname"...
Constructing wrapper function "outer_driver"...
outer_driver()
Wrote C/API module "modname" to file "/tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7/modnamemodule.c"
adding '/tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7/fortranobject.c' to sources.
adding '/tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7' to include_dirs.
copying /usr/local/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7
copying /usr/local/lib/python2.7/site-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpIH70ZJ/src.macosx-10.10-x86_64-2.7
build_src: building npy-pkg config files
running build_ext
customize UnixCCompiler
customize UnixCCompiler using build_ext
customize Gnu95FCompiler
Found executable /usr/local/bin/gfortran
customize Gnu95FCompiler
customize Gnu95FCompiler using build_ext
building 'modname' extension
compiling C sources
C compiler: clang -fno-strict-aliasing -fno-common -dynamic -g -O2 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes
error: unknown file type '' (from '-Wl,-rpath,/usr/local/Cellar/slepc/3.7.3_4/real/lib')
make: *** [modname.so] Error 1
ОБНОВЛЕНИЕ. Было запрошено немного дополнительной информации об ошибке -Wl,rpath
и ее происхождении. Насколько я понимаю, эти флаги исходят от использования связи SLEPc/PETSc. Итак, в моем make-файле они берутся из переменной ${SLEPC_EPS_LIB}
. В интерпретации полная команда очень длинная, но я все равно включу ее на случай, если оттуда можно будет что-то добыть. Имейте в виду, я не использовал настоящие имена файлов в своих примерах выше — я просто упростил для ясности. Ниже имена файлов будут другими.
РЕШЕНО. В конечном итоге мне удалось найти несколько способов обойти эту проблему. Самый простой, по сути, такой же, как и второй подход (на основе make-файла), который я описываю, но я вручную удаляю каждую команду
-Wl,rpath
из переменнойSLEPC_EPS_LIB
. Кроме того, из списка рассылки PETSc я узнал, что f2py можно использовать только для создания необходимых файлов .c, .f90 и .pyc. Затем вы можете скомпилировать себя, связав необходимые библиотеки. Очевидно, что это более сложно, но это тоже вариант.
f2py
предназначался для GCC, у вас есть clang. Должно ли это работать в любом случае?
-Wl,-rpath
. В какой файл ты это поместил? Покажите нам этот файл. Я не понимаю ошибку ошибка: неизвестный тип файла '' (из '-Wl,-rpath,/usr/local/Cellar/slepc/3.7.3_4/real/lib') - person Vladimir F   schedule 23.03.2017Wl,rpath
rpath` в переменную окружения — эта переменная окружения в основном поставляется с SLEPc. Если я его не включу, то связка f2py работает и создает iga_blade_py.so, но когда я пытаюсь импортировать его в python, я получаю ту же ошибку, что и в первом описанном мной случае (объекты SLEPc/PETSc не распознаются). - person aherrema   schedule 23.03.2017-Wl,
, например, набрав _2_. Часто при программировании на разных языках хорошо иметь одного поставщика для всего (например, gcc/gfortran или icc/ifort). - person aherrema   schedule 23.03.2017