【发布时间】:2016-10-20 01:28:55
【问题描述】:
我的问题与这篇文章有关:
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 时,我收到错误,它无法找到 PETSc 子例程“VecDestroy”。我最近的尝试是:
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
从模块petsctest调用mainsub:
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: 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 似乎不明白这些。感谢您的任何cmets。
已解决
我发现了我的问题。我无法让 f2py 接受 -Wl,rpath 选项,但如果我定义环境变量 LD_LIBRARY_PATH=/home/costoich/Documents/AFPWork/Codes/third_party/petsc/arch-linux2-c-debug/lib 一切正常。感谢您的帮助。
【问题讨论】:
-
您必须显示您拥有的信息、导致错误消息的步骤以及错误消息本身。还有一些代码是合适的。
-
编辑问题并将代码放在那里。不要忘记生成它的命令的错误消息。
-
看起来 VecDestrou 不在您使用的 PETSC 模块中。
-
modules 和 f2py 通常不能很好地结合在一起。我建议编写一个包装器,这样你的模块只暴露给你的 fortran 编译器而不是 f2py
-
这不是真的,它们工作正常。