Spec-Zone.ru › NumPy 1.21

Файл подписи

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

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

В общем, содержимое файлов подписи чувствительно к регистру. При сканировании кода 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> может быть только списком имён.

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

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

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

где

<rename_list> := <local_name> => <use_name> [ , <rename_list> ]

В настоящее время F2PY использует оператор use только для связывания модулей обратного вызова и аргументов external (функций обратного вызова), см. Аргументы обратного вызова.

Операторы блоков общих данных:

Определение части <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 вводит следующие операторы:

  • 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>]

    Вы можете использовать произвольный <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). По умолчанию предполагается смежность в смысле Fortran.

    Использование intent(inout) обычно не рекомендуется, используйте 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 . Если ‘argument’ не в списке аргументов, он будет добавлен в оберточную функцию 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> of the ``dimension атрибута;
  • callstatement оператора, здесь также можно использовать C-многострочный блок.

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

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

    rank(<name>)

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

    shape(<name>,<n>)

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

    len(<name>)

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

    size(<name>)

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

    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;
  • как строка документации.

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

Spec-Zone.ru

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