Ошибка сегментации Cython при вызове библиотеки Fortran с помощью оператора WRITE (*, FMT_STR) - PullRequest
0 голосов
/ 15 марта 2020

При попытке обернуть некоторый код Fortran в Python с помощью Cython, я обнаружил, что оператор Fortran WRITE может заставить сгенерированный Python модуль обработать sh (ошибка сегментации).

Если быть точным, оператор WRITE вызывает cra sh, только если он содержит строку формата. Без форматной строки он не сможет обработать sh. А именно, WRITE(*,*) "xxx" не создает sh, а WRITE(*,"(A)") "xxx" делает. При вызове обычной процедурой на языке Fortran или C ++ соответствующая подпрограмма работает должным образом и не имеет cra sh.

. Ниже приведен пример. Он содержит несколько файлов:

1. fortran_write.f90
2. testwrite.pyx
3. header.hpp
4. setup.py

Файл fortran_write.f90:

module mod_write
use, intrinsic :: ISO_C_BINDING
implicit none

contains

subroutine fwrite(flag) bind(C, name="write_f")
    integer*4, intent(in) :: flag
    write(*, *) "In fwrite: flag=", flag
    if (flag .eq. 0) then
      write(*, *) "Message from fwrite (write_f)."
    else if (flag .eq. 1) then
      write(*, *) "MSG", 1234, 12.34
    else if (flag .eq. 2) then
      write(*, "(A40)") "Message from fwrite (write_f)."
    else if (flag .eq. 3) then
      write(*, "(I6)") 1234
    else if (flag .eq. 4) then
      write(*, "(F6.2)") 12.34
    end if
end subroutine fwrite
end module mod_write

Файл testwrite.pyx:

# distutils: language = c++

cdef extern from "header.hpp":
  void write_f(int* flag)

cdef writef(flag):
  cdef int f;
  f = flag
  write_f(&f)

def run():
  writef(0)
  writef(1)
  writef(2)
  writef(3)
  writef(4)

Файл header.hpp:

extern "C" {
  void write_f(int* flag);
}

Файл setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize

extension = Extension(
    name="testwrite",
    sources=["testwrite.pyx"],
    libraries=["testwrite", "gfortran"],
    library_dirs=["./", "/usr/local/Cellar/gcc/9.2.0_1/lib/gcc/9/"],
    include_dirs=["./"],
    depends=['fortran_write.f90', 'header.hpp'],
    extra_compile_args=["-std=c++11"])

setup(
    name="testwrite",
    ext_modules=cythonize([extension], language_level="3")
)

Процедура компиляции:

gfortran -c fortran_write.f90
ar rcs libtestwrite.a fortran_write.o
python setup.py build_ext --inplace

Процедура тестирования :

python -c "import testwrite;testwrite.run()"

Вывод:

 In fwrite: flag=           0
 Message from fwrite (write_f).
 In fwrite: flag=           1
 MSG        1234   12.3400002
 In fwrite: flag=           2
[1]    7631 segmentation fault  python -c "import testwrite;testwrite.run()"

Ожидаемый вывод:

In fwrite: flag=           0
 Message from fwrite (write_f).
 In fwrite: flag=           1
 MSG        1234   12.3400002
 In fwrite: flag=           2
          Message from fwrite (write_f).
 In fwrite: flag=           3
  1234
 In fwrite: flag=           4
 12.34

Кстати, f2py отлично работает.

Процедура компиляции:

f2py -c -m testwrite fortran_write.f90

Процедура тестирования:

python -c "import testwrite;testwrite.mod_write.fwrite(2)"

Системная информация

macOS Version 10.15.3

gfortran -v:

Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/9.2.0_1/libexec/gcc/x86_64-apple-darwin18/9.2.0/lto-wrapper
Target: x86_64-apple-darwin18
Configured with: ../configure --build=x86_64-apple-darwin18 --prefix=/usr/local/Cellar/gcc/9.2.0_1 --libdir=/usr/local/Cellar/gcc/9.2.0_1/lib/gcc/9 --disable-nls --enable-checking=release --enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-9 --with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr --with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl --with-system-zlib --with-pkgversion='Homebrew GCC 9.2.0_1' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues --disable-multilib --with-native-system-header-dir=/usr/include --with-sysroot=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk
Thread model: posix
gcc version 9.2.0 (Homebrew GCC 9.2.0_1)

g++ -v:

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.33.16)
Target: x86_64-apple-darwin19.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

cython --version Cython version 0.29.14

python --version: Python 3.7.4

f2py версия 2

...