Spec-Zone.ru › NumPy 2.0

Файл подписи

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

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

Примечание

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

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

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

Синтаксис файлов подписи

Блок модуля Python

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

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

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

Блок 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>] ]

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

Определение части <argument/variable 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> ]

и

  • <attrspec> — это список атрибутов, разделённых запятыми;
  • <arrayspec> — это список границ размерностей, разделённых запятыми;
  • <init_expr> — это C-выражение;
  • <intlen> может быть отрицательным целым числом для integer спецификаций типов. В таких случаях integer*<negintlen> представляет собой беззнаковые целые числа C;

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

Операторы

Операторы атрибутов

<argument/variable attribute statement> подобен <argument/variable type declaration>, но без <typespec>.

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

Операторы USE

  • Определение части <use statement>:

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

    где

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

Операторы COMMON блока

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

    common / <common name> / <shortentitydecl>
    

    где

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

Другие операторы

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

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

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

    • implicit операторы
      implicit none
      implicit <list of implicit maps>
      

      где

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

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

      implicit real (a-h,o-z,$_), integer (i-m)
      
    • entry операторы
      entry <entry name> [([<arguments>])]
      

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

      Примечание

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

Операторы F2PY

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

threadsafe

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

callstatement <C-expr|multi-line block>

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

Для поднятия исключения установите f2py_success = 0 в <C-expr|multi-line block>.

callprotoargument <C-typespecs>

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

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

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

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

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

usercode <multi-line block>

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

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

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

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

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

pymethoddef <multiline block>

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

Атрибуты

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

optional

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

Примечание

  • Значение по умолчанию должно быть задано как допустимое выражение языка C.
  • Всякий раз, когда используется <init_expr>, атрибут optional автоматически устанавливается F2PY.
  • Для необязательного массива-аргумента все его размерности должны быть ограничены.
required

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

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

dimension(<arrayspec>)

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

intent(<intentspec>)

Это указывает «намерение» соответствующего аргумента. <intentspec> — это список ключей, разделенных запятыми:

  • 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

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

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

  • hide

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

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

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

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

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

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

  • cache

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

  • copy

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

  • overwrite

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

  • out=<new name>

    Заменяет возвращаемое имя на <new 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_<argument name> и значением по умолчанию 0 или 1 соответственно.

    • intent(inout,inplace) равно intent(inplace);
    • intent(in,inplace) равно intent(inplace);
    • intent(hide) отключает optional и required.

check([<C-booleanexpr>])

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

Примечание

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

depend([<names>])

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

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

allocatable

Соответствующая переменная является массивом Fortran 90, выделенным в данных модуля Fortran 90.

external

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

  • в блоке модуля __user__,
  • или демонстративным (или реальным, если файл подписи — реальный код Fortran) вызовом в блоке <other 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*!# и !, соответственно. Всё, что следует за <comment char>f2py игнорируется компилятором, но считывается F2PY как обычная строка Fortran без комментариев:

Примечание

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

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

Выражения C

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

  • <init_expr> для инициализации переменных;
  • <C-booleanexpr> атрибута check;
  • <arrayspec> атрибута dimension;
  • callstatement оператора, здесь также можно использовать многострочный блок C.

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

  • стандартные конструкции C;
  • функции из math.h и Python.h;
  • переменные из списка аргументов, предположительно инициализированные перед этим в соответствии с заданными зависимостями;
  • следующие макросы CPP:

    f2py_rank(<name>)

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

    f2py_shape(<name>, <n>)

    Возвращает <n>-ю размерность массива <name>.

    f2py_len(<name>)

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

    f2py_size(<name>)

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

    f2py_itemsize(<name>)

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

    f2py_slen(<name>)

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

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

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

где _i[<i>] относится к <i>-му значению индекса и проходит от 0 до shape(<array name>,<i>)-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 расширяет спецификацию селектора символов, используемую в файле подписи или директиве F2PY, следующим образом:

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

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

© 2005–2024 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/2.0/f2py/signature-file.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API