Мой вопрос связан с этим постом:
Включение скомпилированного модуля в модуль который завернут в f2py (минимальный рабочий пример)?
в котором постер пытался скомпилировать код Fortran (Test.f90) с помощью f2py и связать его с предварительно скомпилированной библиотекой (или, в моем случае, с объектом, myex44f.o). Ответ позволил мне скомпилировать код Fortran и сгенерировать модуль Python.
Моя проблема отличается от описанной выше проблемы с плакатами тем, что мой объект связан с PETSc. Когда я пытаюсь импортировать мою библиотеку, сгенерированную f2py, в python, я получаю сообщение об ошибке, что она не может найти «VecDestroy», подпрограмму PETSc. Моя последняя попытка была:
f2py -c --fcompiler=gfortran -I. myex44f.o ../../../Коды/третья_сторона/petsc/include/petsc/finclude/petscdef.h -m test Test.f90
Вот код Test.f90:
subroutine test
USE petsctest
call mainsub
end subroutine test
который вызывает mainsub
из модуля petsctest
:
module petsctest ! Solves the linear system J x = f
#include <petsc/finclude/petscdef.h>
contains
subroutine mainsub
use petscksp; use petscdm
Vec x,f
Mat J
DM da
KSP ksp
PetscErrorCode ierr
call PetscInitialize(PETSC_NULL_CHARACTER,ierr)
call DMDACreate1d(MPI_COMM_WORLD,DM_BOUNDARY_NONE,8,1,1, &
& PETSC_NULL_INTEGER,da,ierr)
call DMCreateGlobalVector(da,x,ierr)
call VecDuplicate(x,f,ierr)
call DMSetMatType(da,MATAIJ,ierr)
call DMCreateMatrix(da,J,ierr)
call ComputeRHS(da,f,ierr)
call ComputeMatrix(da,J,ierr)
call KSPCreate(MPI_COMM_WORLD,ksp,ierr)
call KSPSetOperators(ksp,J,J,ierr)
call KSPSetFromOptions(ksp,ierr)
call KSPSolve(ksp,f,x,ierr)
call MatDestroy(J,ierr)
call VecDestroy(x,ierr)
call VecDestroy(f,ierr)
call KSPDestroy(ksp,ierr)
call DMDestroy(da,ierr)
call PetscFinalize(ierr)
end
Ошибка, которую я получаю:
import test Traceback (последний последний вызов): Файл "", строка 1, в ImportError: ./test.so: неопределенный символ: vecdestroy_
У кого-нибудь есть предложения? Большое спасибо за любую помощь, которую вы можете мне оказать.
ОБНОВЛЕНИЕ: я сгенерировал исходный объект myex44f.o
, используя make-файл, прилагаемый к примерам PETSc. Глядя на строку ссылок, я подумал, что мне может понадобиться связать библиотеку petsc при компиляции с помощью f2py. Моя текущая попытка:
f2py -c --fcompiler=gfortran -m test Test.f90 -I. myex44f.o -I/home/costoich/Documents/AFPWork/Codes/third_party/petsc/include -I/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/include -L/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/lib -lpetsc
Кажется, это правильно связывается на этапах компиляции (если я просто напишу -lpetsc
без пути, компилятор выйдет из строя). Однако, когда я набираю ldd test.so
, я получаю:
linux-vdso.so.1 => (0x00007ffe09886000)
libpetsc.so.3.7 => not found
libgfortran.so.3 => /usr/lib/x86_64-linux-gnu/libgfortran.so.3 (0x00007fc315be5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc31581b000)
libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007fc3155dc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc3152d3000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc3150bc000)
/lib64/ld-linux-x86-64.so.2 (0x000055a3fad27000)
Нужно ли использовать два флага ссылок Wl,rpath? f2py, кажется, не понимает этого. Спасибо за любые комментарии.
РЕШЕНО Проблема найдена. Я не могу заставить f2py принять параметры -Wl,rpath
, но если я определю переменную среды LD_LIBRARY_PATH=/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/lib
, все получится. Спасибо за помощь.