Файл подписи#
Файл определения интерфейса (.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 который генерирует 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>] ]
Объявления типов#
Определение часть
является
<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;
Если аргумент не имеет , его тип определяется применением implicit правила к его имени.
Операторы#
Утверждения атрибутов#
The похож на
, но без .
Оператор атрибута не может содержать другие атрибуты, и может
быть только списком имён. См. Атрибуты для получения дополнительных сведений об атрибутах, которые могут использоваться F2PY.
Операторы использования#
Определение
часть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
часть относится к любым другим конструкциям языка Fortran, не описанным выше. F2PY игнорирует большинство из них, за исключением следующих:statement> 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.callstatementblock> Заменяет сгенерированный F2PY оператор вызова функции Fortran/C на
Обёрнутая функция Fortran/C доступна какblock> (*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 позволяет использовать произвольный
для заданной Fortran/C функции. Затем это утверждение используется дляname> .Fortran/C routine name> Если
fortrannameоператор используется безто генерируется заглушка-обертка.Fortran/C routine name> usercodeblock> Когда это используется внутри
python moduleблок, данный код C будет вставлен в сгенерированный исходный код C/API непосредственно перед определениями функций-обёрток.Здесь вы можете определить произвольные C-функции для использования при инициализации необязательных аргументов.
Например, если
usercodeиспользуется дважды внутриpython moduleблок затем второй многострочный блок вставляется после определения внешних подпрограмм.При использовании внутри
, тогда заданный C-код будет вставлен в соответствующую функцию-обёртку сразу после объявления переменных, но перед любыми C-операторами. Таким образом,signature> usercodeпоследующее сообщение может содержать как объявления, так и операторы C.При использовании внутри первого
interfaceблок, то данный C-код будет вставлен в конце функции инициализации модуля расширения. Таким образом можно изменить словарь модулей расширения, и это имеет множество применений; например, для определения дополнительных переменных.pymethoddefblock> Это многострочный блок, который будет вставлен в определение методов модуля
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Соответствующий аргумент считается возвращаемой переменной. Он добавляется к
list. Используяvariables> 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)атрибут длячтобы отключить специфичные для Fortranname> 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_и значение по умолчанию 0 или 1 соответственно.name> 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*!# и !, соответственно. Все, что следует
игнорируется компилятором, но читается F2PY как обычная строка Fortran, не являющаяся комментарием:
Примечание
Когда F2PY находит строку с директивой F2PY, директива сначала заменяется на 5 пробелов, а затем строка перечитывается.
Для кодов Fortran с фиксированным форматом, должны быть в
первом столбце файла, конечно. Для кодов 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() Возвращает длину строки
.
Для инициализации массива , F2PY генерирует цикл по
всем индексам и измерениям, который выполняет следующий
псевдооператор:
<array name>(_i[0],_i[1],...) = <init_expr>;
где _i[] относится к -е значение индекса и который выполняется от 0 to shape(.
Например, функция 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>)
См. Строки символов для использования.