Файл подписи#

Файл определения интерфейса (.pyf) позволяет тонко настроить интерфейс между Python и Fortran. Спецификация синтаксиса для файлов сигнатур (.pyf files) основан на спецификации языка Fortran 90/95. Почти все стандартные конструкции Fortran поддерживаются, как в свободном, так и в фиксированном формате (напомним, что Fortran 77 является подмножеством Fortran 90/95). F2PY вводит некоторые расширения к спецификации языка Fortran 90/95, которые помогают в проектировании интерфейса Fortran к Python, делая его более "питоническим".

Файлы сигнатур могут содержать произвольный код Fortran, чтобы любой код Fortran 90/95 мог обрабатываться как файлы сигнатур. F2PY молча игнорирует конструкции Fortran, которые не имеют значения для создания интерфейса. Однако это также означает, что синтаксические ошибки не перехватываются F2PY и будут обнаружены только при сборке библиотеки.

Примечание

В настоящее время F2PY может завершиться ошибкой с некоторыми корректными конструкциями Fortran. Если это произойдет, вы можете проверить Трекер проблем NumPy на GitHub для возможных обходных путей или идей в разработке.

В целом, содержимое файлов сигнатур чувствительно к регистру. При сканировании кодов Fortran для создания файла сигнатуры F2PY автоматически преобразует все символы в нижний регистр, кроме многострочных блоков или когда --no-lower опция используется.

Синтаксис файлов сигнатур представлен ниже.

Синтаксис файлов сигнатур#

Блок модуля Python#

Файл сигнатуры может содержать одну (рекомендуется) или несколько python module блоков. python module блок описывает содержимое модуля расширения Python/C module.c который генерирует F2PY.

Предупреждение

Исключение: если содержит подстроку __user__, тогда соответствующий python module блок описывает сигнатуры функций обратного вызова (см. Аргументы обратного вызова).

A python module блок имеет следующую структуру:

python module <modulename>
  [<usercode statement>]...
  [
  interface
    <usercode statement>
    <Fortran block data signatures>
    <Fortran/C routine signatures>
  end [interface]
  ]...
  [
  interface
    module <F90 modulename>
      [<F90 module data type declarations>]
      [<F90 module routine signatures>]
    end [module [<F90 modulename>]]
  end [interface]
  ]...
end [python module [<modulename>]]

Здесь скобки [] указывают на необязательный раздел, точки ... указывают на один или несколько предыдущих разделов. Итак, []... следует читать как ноль или более повторений предыдущего раздела.

Сигнатуры подпрограмм Fortran/C#

Сигнатура подпрограммы Fortran имеет следующую структуру:

[<typespec>] function | subroutine <routine name> \
              [ ( [<arguments>] ) ] [ result ( <entityname> ) ]
  [<argument/variable type declarations>]
  [<argument/variable attribute statements>]
  [<use statements>]
  [<common block statements>]
  [<other statements>]
end [ function | subroutine [<routine name>] ]

Из сигнатуры подпрограммы Fortran F2PY генерирует функцию расширения Python/C, которая имеет следующую сигнатуру:

def <routine name>(<required arguments>[,<optional arguments>]):
     ...
     return <return variables>

Сигнатура блока данных Fortran имеет следующую структуру:

block data [ <block data name> ]
  [<variable type declarations>]
  [<variable attribute statements>]
  [<use statements>]
  [<common block statements>]
  [<include statements>]
end [ block data [<block data name>] ]

Объявления типов#

Определение type declaration> часть является

<typespec> [ [<attrspec>] :: ] <entitydecl>

где

<typespec> := byte | character [<charselector>]
           | complex [<kindselector>] | real [<kindselector>]
           | double complex | double precision
           | integer [<kindselector>] | logical [<kindselector>]

<charselector> := * <charlen>
               | ( [len=] <len> [ , [kind=] <kind>] )
               | ( kind= <kind> [ , len= <len> ] )
<kindselector> := * <intlen> | ( [kind=] <kind> )

<entitydecl> := <name> [ [ * <charlen> ] [ ( <arrayspec> ) ]
                      | [ ( <arrayspec> ) ] * <charlen> ]
                     | [ / <init_expr> / | = <init_expr> ] \
                       [ , <entitydecl> ]

и

  • представляет собой список, разделённый запятыми, атрибуты;

  • представляет собой список границ размерностей, разделенных запятыми;

  • является C выражение;

  • может быть отрицательным целым числом для integer спецификации типов. В таких случаях integer* представляет беззнаковые целые числа C;

Если аргумент не имеет type declaration>, его тип определяется применением implicit правила к его имени.

Операторы#

Утверждения атрибутов#

The attribute statement> похож на type declaration>, но без .

Оператор атрибута не может содержать другие атрибуты, и может быть только списком имён. См. Атрибуты для получения дополнительных сведений об атрибутах, которые могут использоваться F2PY.

Операторы использования#

  • Определение statement> часть

    use <modulename> [ , <rename_list> | , ONLY : <only_list> ]
    

    где

    <rename_list> := <local_name> => <use_name> [ , <rename_list> ]
    
  • В настоящее время F2PY использует use операторы только для связывания модулей обратного вызова и external аргументы (функции обратного вызова). См. Аргументы обратного вызова.

Общие блоки операторов#

  • Определение block statement> часть

    common / <common name> / <shortentitydecl>
    

    где

    <shortentitydecl> := <name> [ ( <arrayspec> ) ] [ , <shortentitydecl> ]
    
  • Если python module блок содержит два или более common блоки с тем же именем, переменные из дополнительных объявлений добавляются. Типы переменных в определяются с помощью type declarations>. Обратите внимание, что соответствующий type declarations> может содержать спецификации массивов; тогда их не нужно указывать в .

Другие утверждения#

  • The statement> часть относится к любым другим конструкциям языка Fortran, не описанным выше. F2PY игнорирует большинство из них, за исключением следующих:

    • call операторы и вызовы функций external аргументы (см. подробнее о внешних аргументах);

    • include утверждения
      include ''
      include ""
      

      Если файл не существует, include оператор игнорируется. В противном случае файл включен в файл подписи. include операторы могут использоваться в любой части файла сигнатур, также вне блоков сигнатур подпрограмм Fortran/C.

    • implicit утверждения
      implicit none
      implicit <list of implicit maps>
      

      где

      <implicit map> := <typespec> ( <list of letters or range of letters> )
      

      Неявные правила используются для определения спецификации типа переменной (по первой букве её имени), если переменная не определена с помощью type declaration>. Правила по умолчанию задаются неявно:

      implicit real (a-h,o-z,$_), integer (i-m)
      
    • entry утверждения
      entry <entry name> [([<arguments>])]
      

      F2PY генерирует обёртки для всех имён входов, используя сигнатуру блока подпрограммы.

      Примечание

      The entry оператор может использоваться для описания сигнатуры произвольной подпрограммы или функции, позволяя F2PY генерировать несколько обёрток из одной сигнатуры блока процедуры. Существует несколько ограничений при этом: fortranname не может быть использован, callstatement и callprotoargument могут использоваться только если они действительны для всех процедур ввода и т.д.

F2PY statements#

Кроме того, F2PY вводит следующие операторы:

threadsafe

Использует Py_BEGIN_ALLOW_THREADS .. Py_END_ALLOW_THREADS блок вокруг вызова функции Fortran/C.

callstatement block>

Заменяет сгенерированный F2PY оператор вызова функции Fortran/C на block>Обёрнутая функция Fortran/C доступна как (*f2py_func).

Чтобы вызвать исключение, установите f2py_success = 0 в block>.

callprotoargument

Когда callstatement используется оператор, F2PY может не генерировать правильные прототипы для функций Fortran/C (поскольку может содержать вызовы функций, и F2PY не может определить, каким должен быть правильный прототип).

С помощью этого оператора вы можете явно указать аргументы соответствующего прототипа:

extern <return type> FUNC_F(<routine name>,<ROUTINE NAME>)(<callprotoargument>);
fortranname [ Fortran/C routine name>]

F2PY позволяет использовать произвольный name> для заданной Fortran/C функции. Затем это утверждение используется для Fortran/C routine name>.

Если fortranname оператор используется без Fortran/C routine name> то генерируется заглушка-обертка.

usercode block>

Когда это используется внутри python module блок, данный код C будет вставлен в сгенерированный исходный код C/API непосредственно перед определениями функций-обёрток.

Здесь вы можете определить произвольные C-функции для использования при инициализации необязательных аргументов.

Например, если usercode используется дважды внутри python module блок затем второй многострочный блок вставляется после определения внешних подпрограмм.

При использовании внутри signature>, тогда заданный C-код будет вставлен в соответствующую функцию-обёртку сразу после объявления переменных, но перед любыми C-операторами. Таким образом, usercode последующее сообщение может содержать как объявления, так и операторы C.

При использовании внутри первого interface блок, то данный C-код будет вставлен в конце функции инициализации модуля расширения. Таким образом можно изменить словарь модулей расширения, и это имеет множество применений; например, для определения дополнительных переменных.

pymethoddef block>

Это многострочный блок, который будет вставлен в определение методов модуля PyMethodDef-array. Это должен быть список C-массивов, разделённых запятыми (см. Расширение и встраивание Документация Python для подробностей). pymethoddef оператор может использоваться только внутри python module блок.

Атрибуты#

Следующие атрибуты могут использоваться F2PY.

optional

Соответствующий аргумент перемещается в конец arguments> список. Значение по умолчанию для необязательного аргумента может быть указано через (см. entitydecl определение)

Примечание

  • Значение по умолчанию должно быть задано как корректное C-выражение.

  • Всякий раз, когда используется, optional атрибут устанавливается автоматически F2PY.

  • Для необязательного аргумента-массива все его размерности должны быть ограничены.

required

Соответствующий аргумент с этим атрибутом считается обязательным. Это значение по умолчанию. required должен быть указан только если есть необходимость отключить автоматический optional настройка, когда используется.

Если Python None объект используется как обязательный аргумент, аргумент рассматривается как необязательный. То есть в случае аргументов массива память выделяется. Если задан, то выполняется соответствующая инициализация.

dimension()

Соответствующая переменная рассматривается как массив с размерностями, заданными в .

intent()

Это указывает "намерение" соответствующего аргумента. это список, разделённый запятыми, из следующих ключей:

  • in

    Соответствующий аргумент считается только входным. Это означает, что значение аргумента передается в функцию Fortran/C, и ожидается, что функция не изменит значение этого аргумента.

  • inout

    Соответствующий аргумент помечен как входной/выходной или как in situ аргумент вывода. intent(inout) аргументы могут быть только непрерывный Массивы NumPy (в смысле Fortran или C) с правильным типом и размером. Последнее совпадает с концепцией смежности по умолчанию, используемой в NumPy, и эффективно только если intent(c) используется. F2PY по умолчанию предполагает аргументы с непрерывностью Fortran.

    Примечание

    Используя intent(inout) обычно не рекомендуется, так как может привести к неожиданным результатам. Например, скалярные аргументы, использующие intent(inout) предполагаются объектами массива, чтобы иметь in situ изменения вступят в силу. Используйте intent(in,out) вместо этого.

    См. также intent(inplace) атрибут.

  • inplace

    Соответствующий аргумент считается входным/выходным или in situ аргумент вывода. intent(inplace) аргументы должны быть массивами NumPy соответствующего размера. Если тип массива не "правильный" или массив не непрерывный, то массив будет изменен на месте, чтобы исправить тип и сделать его непрерывным.

    Примечание

    Используя intent(inplace) также обычно не рекомендуется.

    Например, когда срезы были взяты из intent(inplace) аргумент, то после изменений на месте указатели данных для срезов могут указывать на невыделенную область памяти.

  • out

    Соответствующий аргумент считается возвращаемой переменной. Он добавляется к variables> list. Используя intent(out) наборы intent(hide) автоматически, если только intent(in) или intent(inout) также указаны.

    По умолчанию возвращаемые многомерные массивы являются Fortran-непрерывными. Если intent(c) атрибут используется, то возвращаемые многомерные массивы являются C-непрерывными.

  • hide

    Соответствующий аргумент удаляется из списка обязательных или необязательных аргументов. Обычно intent(hide) используется с intent(out) или когда полностью определяет значение аргумента, как в следующем примере:

    integer intent(hide),depend(a) :: n = len(a)
    real intent(in),dimension(n) :: a
    
  • c

    Соответствующий аргумент обрабатывается как скаляр C или аргумент массива C. В случае скалярного аргумента его значение передается в функцию C как скалярный аргумент C (напомним, что скалярные аргументы Fortran фактически являются указателями C). Для аргументов массива предполагается, что функция-обертка обрабатывает многомерные массивы как смежные массивы C.

    Нет необходимости использовать intent(c) для одномерных массивов, независимо от того, является ли обёрнутая функция на Fortran или C. Это потому, что концепции непрерывности Fortran и C перекрываются в одномерных случаях.

    Если intent(c) используется как оператор, но без списка объявления сущностей, тогда F2PY добавляет intent(c) атрибут ко всем аргументам.

    Также при обёртке C-функций необходимо использовать intent(c) атрибут для name> чтобы отключить специфичные для Fortran F_FUNC(..,..) макросы.

  • cache

    Соответствующий аргумент рассматривается как неиспользуемая память. Проверки на смежность Fortran или C не выполняются. Использование intent(cache) имеет смысл только для аргументов массива, также в сочетании с intent(hide) или optional атрибуты.

  • copy

    Гарантирует, что исходное содержимое intent(in) аргумент сохраняется. Обычно используется с intent(in,out) атрибут. F2PY создает необязательный аргумент overwrite_ name> со значением по умолчанию 0.

  • overwrite

    Это указывает, что исходное содержимое intent(in) аргумент может быть изменён функцией Fortran/C. F2PY создаёт опциональный аргумент overwrite_ name> со значением по умолчанию 1.

  • out= name>

    Заменяет возвращаемое имя на name> в __doc__ строка функции-обертки.

  • callback

    Создаёт внешнюю функцию, подходящую для вызова функций Python из Fortran. intent(callback) должен быть указан перед соответствующим external оператор. Если 'аргумент' отсутствует в списке аргументов, то он будет добавлен в обертку Python, но только путем инициализации внешней функции.

    Примечание

    Используйте intent(callback) в ситуациях, когда код Fortran/C предполагает, что пользователь реализовал функцию с заданным прототипом и связал её с исполняемым файлом. Не используйте intent(callback) если функция появляется в списке аргументов процедуры Fortran.

    С intent(hide) или optional указанные атрибуты и использование функции-обёртки без указания аргумента обратного вызова в списке аргументов; тогда предполагается, что функция обратного вызова находится в пространстве имён сгенерированного модуля расширения F2PY, где она может быть установлена как атрибут модуля пользователем.

  • aux

    Определяет вспомогательную переменную C в функции-обертке, сгенерированной F2PY. Полезно для сохранения значений параметров, чтобы к ним можно было обращаться в выражениях инициализации других переменных.

    Примечание

    intent(aux) неявно подразумевает intent(c).

Применяются следующие правила:

  • Если ни один из intent(in | inout | out | hide) указаны, intent(in) предполагается.

    • intent(in,inout) является intent(in);

    • intent(in,hide) или intent(inout,hide) является intent(hide);

    • intent(out) является intent(out,hide) если только intent(in) или intent(inout) указан.

  • Если intent(copy) или intent(overwrite) используется, тогда вводится дополнительный необязательный аргумент с именем overwrite_ name> и значение по умолчанию 0 или 1 соответственно.

    • intent(inout,inplace) является intent(inplace);

    • intent(in,inplace) является intent(inplace);

    • intent(hide) отключает optional и required.

check([])

Выполняет проверку согласованности аргументов путём вычисления ; если возвращает 0, возникает исключение.

Примечание

Если check(..) не используется, то F2PY автоматически генерирует несколько стандартных проверок (например, в случае аргумента-массива проверяет правильность формы и размера). Используйте check() для отключения проверок, сгенерированных F2PY.

depend([])

Это объявляет, что соответствующий аргумент зависит от значений переменных в список. Например, может использовать значения других аргументов. Используя информацию, предоставленную depend(..) атрибуты, F2PY гарантирует, что аргументы инициализируются в правильном порядке. Если depend(..) атрибут не используется, тогда F2PY автоматически определяет отношения зависимости. Используйте depend() чтобы отключить зависимости, создаваемые F2PY.

При редактировании зависимостей, изначально сгенерированных F2PY, будьте осторожны, чтобы не нарушить зависимости других соответствующих переменных. Еще одна вещь, на которую стоит обратить внимание, — циклические зависимости. F2PY способен обнаруживать циклические зависимости при построении оберток и сообщает об ошибке, если они найдены.

allocatable

Соответствующая переменная — это распределяемый массив Fortran 90, определённый как данные модуля Fortran 90.

external

Соответствующий аргумент — это функция, предоставленная пользователем. Сигнатура этой callback-функции может быть определена

  • в __user__ блок модуля,

  • или с помощью демонстративного (или реального, если файл сигнатуры является реальным кодом Fortran) вызова в statements> блок.

Например, F2PY генерирует из:

external cb_sub, cb_fun
integer n
real a(n),r
call cb_sub(a,n)
r = cb_fun(4)

следующие сигнатуры обратных вызовов:

subroutine cb_sub(a,n)
    real dimension(n) :: a
    integer optional,check(len(a)>=n),depend(a) :: n=len(a)
end subroutine cb_sub
function cb_fun(e_4_e) result (r)
    integer :: e_4_e
    real :: r
end function cb_fun

Соответствующая предоставленная пользователем функция Python:

def cb_sub(a,[n]):
    ...
    return
def cb_fun(e_4_e):
    ...
    return r

См. также intent(callback) атрибут.

parameter

Это указывает, что соответствующая переменная является параметром и должна иметь фиксированное значение. F2PY заменяет все вхождения параметра их соответствующими значениями.

Расширения#

Директивы F2PY#

Директивы F2PY позволяют использовать конструкции файла подписи F2PY в исходных кодах Fortran 77/90. С этой функцией можно (почти) полностью пропустить промежуточное создание файла подписи и применять F2PY напрямую к исходным кодам Fortran.

Директивы F2PY имеют следующий вид:

<comment char>f2py ...

где разрешённые символы комментариев для кодов Fortran фиксированного и свободного формата cC*!# и !, соответственно. Все, что следует char>f2py игнорируется компилятором, но читается F2PY как обычная строка Fortran, не являющаяся комментарием:

Примечание

Когда F2PY находит строку с директивой F2PY, директива сначала заменяется на 5 пробелов, а затем строка перечитывается.

Для кодов Fortran с фиксированным форматом, char> должны быть в первом столбце файла, конечно. Для кодов Fortran со свободным форматом, директивы F2PY могут появляться где угодно в файле.

Выражения C#

C-выражения используются в следующих частях файлов сигнатур:

  • для инициализации переменных;

  • из check атрибут;

  • из dimension атрибут;

  • callstatement оператор, здесь также может использоваться многострочный блок C.

Выражение на C может содержать:

  • стандартные конструкции C;

  • функции из math.h и Python.h;

  • переменные из списка аргументов, предположительно инициализированные ранее в соответствии с заданными зависимостями;

  • следующие макросы CPP:

    f2py_rank()

    Возвращает ранг массива .

    f2py_shape(, )

    Возвращает -е измерение массива .

    f2py_len()

    Возвращает длину массива .

    f2py_size()

    Возвращает размер массива .

    f2py_itemsize()

    Возвращает размер элемента массива .

    f2py_slen()

    Возвращает длину строки .

Для инициализации массива name>, F2PY генерирует цикл по всем индексам и измерениям, который выполняет следующий псевдооператор:

<array name>(_i[0],_i[1],...) = <init_expr>;

где _i[] относится к -е значение индекса и который выполняется от 0 to shape( name>,)-1.

Например, функция myrange(n) сгенерировано из следующей сигнатуры

subroutine myrange(a,n)
  fortranname        ! myrange is a dummy wrapper
  integer intent(in) :: n
  real*8 intent(c,out),dimension(n),depend(n) :: a = _i[0]
end subroutine myrange

эквивалентно numpy.arange(n,dtype=float).

Предупреждение

F2PY может также преобразовывать регистр в выражениях C при сканировании кода Fortran (см. --[no]-lower опция).

Многострочные блоки#

Многострочный блок начинается с ''' (тройные одинарные кавычки) и заканчивается ''' в некоторых строго последующей строке. Многострочные блоки могут использоваться только в файлах .pyf. Содержимое многострочного блока может быть произвольным (за исключением того, что оно не может содержать ''') и никакие преобразования (например, приведение к нижнему регистру) к нему не применяются.

В настоящее время многострочные блоки могут использоваться в следующих конструкциях:

  • как выражение C из callstatement оператор;

  • как спецификация типа C для callprotoargument оператор;

  • как блок кода C в usercode оператор;

  • в виде списка C-массивов pymethoddef оператор;

  • как строка документации.

Расширенный селектор символов#

F2PY расширяет спецификацию селектора char, используемую в файле сигнатуры или директиве F2PY, следующим образом:

<extended-charselector> := <charselector>
                        | (f2py_len= <len>)

См. Строки символов для использования.