0

我的问题与这篇文章有关:

在用 f2py 包装的模块中包含一个已编译的模块(最小工作示例)?

海报试图用 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

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

我得到的错误是:

导入测试回溯(最近一次调用最后):文件“”,第 1 行,在 ImportError:./test.so:未定义符号:vecdestroy_

有没有人有什么建议?非常感谢您为我提供的任何帮助。

更新:myex44f.o我使用 PETSc 示例提供的 makefile 生成了原始对象。查看链接行,我推断在使用 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一切都会解决。谢谢您的帮助。

4

1 回答 1

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 一起使用,我个人在该页面中选择了选项 2。大多数现有的 PETSc 示例也遵循选项 2。

请让我澄清一下,我不鼓励您使用includeoveruse,这只是我习惯的方式。PETSc 文档有一个使用 Fortran 模块的示例,例如这里。因此,您可以选择这些方法中的任何一种/或两者都可选(请注意该示例中的预处理器选项 PETSC_USE_FORTRAN_MODULES),但仍需要添加所需的模块,具体取决于您使用的是什么。

于 2016-10-23T18:44:25.413 回答