我的问题与这篇文章有关:
Including a compiled module in module that is wrapped with f2py (Minimum working example)?
其中海报试图用f2py编译Fortran代码(Test.f90)并将其链接到预编译库(或者在我的情况下,对象,myex44f.o)。答案使我能够编译Fortran代码并生成python模块。
我的问题与上述海报问题的不同之处在于我的对象与PETSc相关联。当我尝试将我的f2py生成的库导入python时,我得到错误,它无法找到'VecDestroy',一个PETSc子例程。我最近的尝试是:
f2py -c --fcompiler = gfortran -I。 myex44f.o ../../../Codes/third_party/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(最近一次调用last):ImportError中的文件“”,第1行:./ test.so:undefined symbol:vecdestroy _
有没有人有任何建议?非常感谢您提供给我的任何帮助。
更新
我使用随PETSc示例提供的makefile生成了原始的myex44f.o
对象。看一下链接线,我推断在编译f2py时我可能需要链接petsc库。我目前的尝试是:
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
,一切都会成功。谢谢你的帮助。
答案 0 :(得分:0)
@VladimirF,有一点。
看起来VecDestrou不在您正在使用的PETSC模块中。
在我的模块中需要以下部分PETSc。
#include <petsc/finclude/petscsysdef.h>
#include <petsc/finclude/petscvecdef.h>
! Optional
#include <petsc/finclude/petscdef.h>
#include <petsc/finclude/petscdm.h>
#include <petsc/finclude/petscvec.h>
#include <petsc/finclude/petscvec.h90>
#include <petsc/finclude/petscmat.h>
#include <petsc/finclude/petscmat.h90>
! might be not completed
! Or
use petscksp
use petscdm
use petscvec
use petscmat
!might be not completed
如何将PETSc与Fortran一起使用here,我个人在该页面中选择2。大多数现有的PETSc示例也遵循选项2。
请让我澄清 I am not encouraging you to use include
over use
,这就是我以前的做法。 PETSc文档中有一个使用Fortran模块的示例,例如here。所以你可以选择这些方法中的任何一个/或者两者都选择(请在那个例子中实现预处理器选项,PETSC_USE_FORTRAN_MODULES),但是仍然需要添加所需的模块取决于你使用的是什么。