通过Cython调用依赖MPI的Fortran模块

2024-09-30 01:21:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从Python调用一个使用openmpi的Fortran库。 我选择使用Cython作为Python和Fortran之间的层。在

我从this answer运行了一个最小的工作示例,但是在使用openmpi时遇到了一些问题。在

下面是我在这个例子中尝试包含MPI的部分。如果我从Fortran程序调用模块ffunc,它可以工作,但是如果我试图从Python访问它,我会得到

mca_base_component_repository_open: unable to open mca_patcher_overwrite: /path/to/mca_patcher_overwrite.so: undefined symbol: mca_patcher_base_patch_t_class (ignored)
mca_base_component_repository_open: unable to open mca_shmem_mmap: /path/to/mca_shmem_mmap.so: undefined symbol: opal_show_help (ignored)
mca_base_component_repository_open: unable to open mca_shmem_posix: /path/to/mca_shmem_posix.so: undefined symbol: opal_shmem_base_framework (ignored)
mca_base_component_repository_open: unable to open mca_shmem_sysv: /path/to/mca_shmem_sysv.so: undefined symbol: opal_show_help (ignored)

作为一个最小的工作示例,我有以下内容:

要调用ffunc.p90的Fortran模块:

^{pr2}$

Fortran-C包装器pyffunc.f90

^{3}$

C头pyffunc.h

extern void c_func(double* a, double* b, double* c);

Cython包装器pyffunc.pyx

cdef extern from 'pyffunc.h':
    void c_func(double* a, double* b, double* c)

def func(double a, double b):
    cdef:
        double c
    c_func(&a, &b, &c)
    print('cython: a = {}, b = {}, c = {}'.format(a, b, c))
    return c

Python setup.py(并从mpif90 showme获得包含和库:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
from numpy import get_include
from os import system

# compile the fortran modules without linking
fortran_mod_comp = 'mpif90 ffunc.f90 -c -o ffunc.o -O3 -fPIC'
print(fortran_mod_comp)
system(fortran_mod_comp)
shared_obj_comp = 'mpif90 pyffunc.f90 -c -o pyffunc.o -O3 -fPIC'
print(shared_obj_comp)
system(shared_obj_comp)

ext_modules = [Extension(# module name:
                         'pyffunc',
                         # source file:
                         ['pyffunc.pyx'],
                         # other compile args for gcc
                         extra_compile_args=[
                             '-fPIC',
                             '-O3',
                             '-I/usr/lib/x86_64-linux-gnu/openmpi/include',
                             '-pthread',
                             '-I/usr/lib/x86_64-linux-gnu/openmpi/lib',
                             ],
                         # other files to link to
                         extra_link_args=['ffunc.o',
                             'pyffunc.o',
                             '-pthread',
                             '-I/usr/lib/x86_64-linux-gnu/openmpi/lib',
                             '-L/usr//lib',
                             '-L/usr/lib/x86_64-linux-gnu/openmpi/lib',
                             '-lmpi_usempif08',
                             '-lmpi_usempi_ignore_tkr',
                             '-lmpi_mpifh',
                             '-lmpi',
                             ])]

setup(name = 'pyffunc',
      cmdclass = {'build_ext': build_ext},
      include_dirs = [get_include()],
ext_modules = ext_modules)

以及Python test.py文件:

from pyffunc import func


a = 5
b = 9
c = func(5, 9)

print('python: a = {}, b = {}, c = {}'.format(a, b, c))

有谁能给我一个正确方向的提示吗?-我找了各种各样的东西,但我被困在这里了。在


Tags: tofromimportbaselibopenextfunc

热门问题