Скомпилируйте модуль Fortran с помощью f2py

У меня есть модуль Fortran, который я пытаюсь скомпилировать с помощью f2py (указан ниже). Когда я удаляю объявление модуля и оставляю подпрограмму в файле отдельно, все работает нормально. Однако, если модуль объявлен, как показано ниже, я получаю следующие результаты:

> f2py.py -c -m its --compiler=mingw itimes-s2.f
...
Reading fortran codes...
    Reading file 'itimes-s2.f' (format:fix,strict)
crackline: groupcounter=1 groupname={0: '', 1: 'module', 2: 'interface', 3: 'subroutine'}
crackline: Mismatch of blocks encountered. Trying to fix it by assuming "end" statement.
...
c:\users\astay13\appdata\local\temp\tmpgh5ag8\Release\users\astay13\appdata\local\temp\tmpgh5ag8\src.win32-3.2\itsmodule.o:itsmodule.c:(.data+0xec): undefined reference to `itimes_'
collect2: ld returned 1 exit status

Чем отличается компиляция модуля или подпрограммы в f2py? Не упустил ли я что-то важное в модуле, из-за которого возникают проблемы с f2py? Обратите внимание, что модуль компилируется нормально, когда я использую только gfortran.

Программное обеспечение: Windows 7; gcc, gfortran 4.6.1 (MinGW); python 3.2.2; f2py v2

itimes-s2.f:

  module its

  contains

  subroutine itimes(infile,outfile)

    implicit none

    ! Constants
    integer, parameter :: dp = selected_real_kind(15)

    ! Subroutine Inputs
    character(*), intent(in) :: infile
    character(*), intent(in) :: outfile

    ! Internal variables
    real(dp) :: num
    integer :: inu
    integer :: outu
    integer :: ios

    inu = 11
    outu = 22

    open(inu,file=infile,action='read')
    open(outu,file=outfile,action='write',access='append')

    do
      read(inu,*,IOSTAT=ios) num
      if (ios < 0) exit

      write(outu,*) num**2
    end do

  end subroutine itimes

  end module its

person astay13    schedule 19.12.2011    source источник


Ответы (3)


Вы пытаетесь включить модуль Fortran в модуль Python. Если вы этого хотите, имена должны быть разными, например

 f2py.py -c -m SOMEDIFFERENTNAME itimes-s2.f

Результат будет называться pythonmodule.fortranmodule.yourfunction().

Вы также можете импортировать его как

from pythonmodule import fortranmodule
fortranmodule.yourfunction()

В остальном это сработало на моей машине.

person Vladimir F    schedule 20.12.2011
comment
Я попытался запустить f2py -c --compiler=mingw32 -m itsm itimes-s2.f, но сообщения об ошибках остались прежними. - person astay13; 20.12.2011
comment
Попробуйте переименовать файл, чтобы он имел суффикс .f90. Кажется, что компилятор предполагает, что это файл фиксированного формата (по крайней мере, на моей машине). Я использую f2py -c -m itsm itimes-s2.f90, и он работает. Я тестировал его на двух разных Linux-компьютерах. - person Vladimir F; 21.12.2011
comment
Спасибо, Владимир! Как только я переименовал его в расширение .f90, он отлично работал, даже если у модулей Python и Fortran были одинаковые имена. - person astay13; 21.12.2011
comment
Можем ли мы превратить модуль fortran в одноуровневый модуль Python, который будет использоваться как module.function()? - person Jonatan Öström; 30.07.2018

Для работы f2py вам необходимо иметь файл подписи для управления созданием интерфейса или изменить исходный код с помощью комментариев f2py, чтобы помочь с интерфейсом. См. http://cens.ioc.ee/projects/f2py2e/usersguide/#signature-file для получения дополнительной информации.

С этого сайта:

C FILE: FIB3.F
      SUBROUTINE FIB(A,N)
C
C     CALCULATE FIRST N FIBONACCI NUMBERS
C
      INTEGER N
      REAL*8 A(N)
Cf2py intent(in) n
Cf2py intent(out) a
Cf2py depend(n) a
      DO I=1,N
         IF (I.EQ.1) THEN
            A(I) = 0.0D0
         ELSEIF (I.EQ.2) THEN
            A(I) = 1.0D0
         ELSE 
            A(I) = A(I-1) + A(I-2)
         ENDIF
      ENDDO
      END
C END FILE FIB3.F

Теперь сборку модуля расширения можно выполнять одной командой:

f2py -c -m fib3 fib3.f
person WombatPM    schedule 19.12.2011
comment
Верно, но моя проблема в том, что f2py отлично работает, когда подпрограмма указана сама по себе в файле, но выдает ошибку, когда я включаю ее в модуль. Из вашей ссылки кажется, что я смогу использовать свой источник (возможно, с некоторыми дополнительными директивами) в качестве файла моей подписи. Какие дополнительные директивы мне нужно включить, чтобы модуль принял модуль? - person astay13; 19.12.2011

Чтобы обернуть модуль F90 с помощью f2py, вам нужно указать, какие функции могут быть доступны извне модуля. Для этого у вас есть частные и общедоступные ключевые слова fortran90. Вам также следует изменить расширение с .f на .F90 или .f90. Я внес некоторые изменения в ваш код, демонстрирующий использование ключевых слов public и private.

Прежде всего создайте файл сигнатуры, в котором хранятся интерфейсы fortran для объектов модуля:

f2py -h interface.pyf -m module_name module_its.f90 --overwrite-signature

Затем скомпилируйте модуль:

f2py interface.pyf -c module_its.f90 

Ваш код изменен и назван module_its.f90:

module its   
  ! use other modules
  implicit none
  private          ! everything in this module is private by standard 
                   ! (it can be used only inside this F90 module)
  public :: itimes ! Make you subroutine public
 
  contains

  subroutine itimes(infile,outfile)
    ! use other modules here to

    !implicit none holds for everthing in this module

    ! Constants
    integer, parameter :: dp = selected_real_kind(15)

    ! Subroutine Inputs
    character(*), intent(in) :: infile
    character(*), intent(in) :: outfile

    ! Internal variables
    real(dp) :: num
    integer :: inu
    integer :: outu
    integer :: ios

    inu = 11
    outu = 22

    open(inu,file=infile,action='read')
    open(outu,file=outfile,action='write',access='append')

    do
      read(inu,*,IOSTAT=ios) num
      if (ios < 0) exit

      write(outu,*) num**2
    end do

  end subroutine itimes

end module its
person JoaoDarela    schedule 16.09.2020