Spec-Zone.ru › NumPy 1.20

Файл подписи

Спецификация синтаксиса для файлов подписи (.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 statements
    include '<filename>'
    include "<filename>"
    

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

  • implicit statements
    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 statements
    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

    Аргумент рассматривается как аргумент ввода/вывода или аргумент вывода «на месте». Аргументы intent(inout) могут быть только «смежными» массивами NumPy с правильным типом и размером. Здесь «смежный» может быть либо в смысле Fortran, либо в смысле C. Последний совпадает с понятием «смежности» в NumPy и эффективен только при использовании intent(c). По умолчанию предполагается смежность в смысле Fortran.

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

  • inplace

    Аргумент рассматривается как аргумент ввода/вывода или аргумент вывода «на месте». Аргументы 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 как скалярный аргумент языка 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–2021 NumPy Developers
Licensed under the 3-clause BSD License.
https://numpy.org/doc/1.20/f2py/signature-file.html

Spec-Zone.ru

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