JayKimDevolved's picture
JayKimDevolved/deepseek
c011401 verified
\section{Signature file}
\label{sec:signaturefile}
The syntax of a signature file is borrowed from the Fortran~90/95
language specification. Almost all Fortran~90/95 standard constructs
are understood. Recall that Fortran~77 is a subset of Fortran~90/95.
This tool introduces also some new attributes that are used for
controlling the process of Fortran to Python interface construction.
In the following, a short overview of the constructs
used in signature files will be given.
\subsection{Module block}
\label{sec:moduleblock}
A signature file contains one or more \texttt{pythonmodule} blocks. A
\texttt{pythonmodule} block has the following structure:
\begin{verbatim}
python module <modulename>
interface
<routine signatures>
end [interface]
interface
module <F90/95 modulename>
<F90 module data type declarations>
<F90 module routine signatures>
end [module [<F90/95 modulename>]]
end [interface]
end [pythonmodule [<modulename>]]
\end{verbatim}
For each \texttt{pythonmodule} block \fpy will generate a C-file
\texttt{<modulename>module.c} (see step (iii)). (This is not true if
\texttt{<modulename>} contains substring \texttt{\_\_user\_\_}, see
Sec.~\ref{sec:cbmodule} and \texttt{external} attribute).
\subsection{Signatures of Fortran routines and Python functions}
\label{sec:routineblock}
The signature of a Fortran routine has the following structure:
\begin{verbatim}
[<typespec>] function|subroutine <routine name> [([<arguments>])] \
[result (<entityname>)]
[<argument type declarations>]
[<argument attribute statements>]
[<use statements>]
[<common block statements>]
[<other statements>]
end [function|subroutine [<routine name>]]
\end{verbatim}
Let us introduce also the signature of the corresponding wrapper
function:
\begin{verbatim}
def <routine name>(<required arguments>[,<optional arguments>]):
...
return <return variables>
\end{verbatim}
Before you edit the signature file, you should first decide what is the
desired signature of the corresponding Python function. \fpy offers
many possibilities to control the interface construction process: you
may want to insert/change/remove various attributes in the
declarations of the arguments in order to change the appearance
of the arguments in the Python wrapper function.
\begin{itemize}
\item
The definition of the \texttt{<argument type declaration>} is
\begin{verbatim}
<typespec> [[<attrspec>]::] <entitydecl>
\end{verbatim}
where
\begin{verbatim}
<typespec> := byte | character[<charselector>]
| complex[<kindselector>] | real[<kindselector>]
| double complex | double precision
| integer[<kindselector>] | logical[<kindselector>]
\end{verbatim}
\begin{verbatim}
<charselector> := *<charlen> | ([len=]<len>[,[kind]<kind>])
| (kind=<kind>[,len=<len>])
<kindselector> := *<intlen> | ([kind=]<kind>)
\end{verbatim}
(there is no sense to modify \texttt{<typespec>}s generated by \fpy).
\texttt{<attrspec>} is a comma separated list of attributes (see
Sec.~\ref{sec:attributes});
\begin{verbatim}
<entitydecl> := <name> [[*<charlen>][(<arrayspec>)]
| [(<arrayspec>)]*<charlen>]
| [/<init_expr>/ | =<init_expr>] [,<entitydecl>]
\end{verbatim}
where \texttt{<arrayspec>} is a comma separated list of dimension
bounds; \texttt{<init\_expr>} is a C-expression (see
Sec.~\ref{sec:C-expr}). If an argument is not defined with
\texttt{<argument type declaration>}, its type is determined by
applying \texttt{implicit} rules (if it is not specifyied, then
standard rules are applied).
\item The definition of the \texttt{<argument attribute statement>} is
a short form of the \texttt{<argument type declaration>}:
\begin{verbatim}
<attrspec> <entitydecl>
\end{verbatim}
\item \texttt{<use statement>} is defined as follows
\begin{verbatim}
use <modulename> [,<rename_list> | ,ONLY:<only_list>]
<rename_list> := local_name=>use_name [,<rename_list>]
\end{verbatim}
Currently the \texttt{use} statement is used to link call-back
modules (Sec.~\ref{sec:cbmodule}) and the \texttt{external}
arguments (call-back functions).
\item \texttt{<common block statement>} is defined as follows
\begin{verbatim}
common /<commonname>/ <shortentitydecl>
\end{verbatim}
where
\begin{verbatim}
<shortentitydecl> := <name> [(<arrayspec>)] [,<shortentitydecl>]
\end{verbatim}
One \texttt{module} block should not contain two or more
\texttt{common} blocks with the same name. Otherwise, the later ones
are ignored. The types of variables in \texttt{<shortentitydecl>} can
be defined in \texttt{<argument type declarations>}. Note that there
you can specify also the array specifications; then you don't need to
do that in \texttt{<shortentitydecl>}.
\end{itemize}
\subsection{Attributes}
\label{sec:attributes}
The following attributes are used by \fpy:
\begin{description}
\item[\texttt{optional}] --- the variable is moved to the end of
optional argument list of the wrapper function. Default value of an
optional argument can be specified using \texttt{<init\_expr>} in
\texttt{entitydecl}. You can use \texttt{optional} attribute also for
\texttt{external} arguments (call-back functions), but it is your
responsibility to ensure that it is given by the user if Fortran
routine wants to call it.
\item[\texttt{required}] --- the variable is considered as a required
argument (that is default). You will need this in order to overwrite
the \texttt{optional} attribute that is automatically set when
\texttt{<init\_expr>} is used. However, usage of this attribute
should be rare.
\item[\texttt{dimension(<arrayspec>)}] --- used when the variable is
an array. For unbounded dimensions symbols `\texttt{*}' or
`\texttt{:}' can be used (then internally the corresponding
dimensions are set to -1; you'll notice this when certain exceptions
are raised).
\item[\texttt{external}] --- the variable is a call-back function. \fpy will
construct a call-back mechanism for this function. Also call-back
functions must be defined by their signatures, and there are several
ways to do that. In most cases, \fpy will be able to determine the signatures
of call-back functions from the Fortran source code; then it
builds an additional \texttt{module} block with a name containing
string `\texttt{\_\_user\_\_}' (see Sec.~\ref{sec:cbmodule}) and
includes \texttt{use} statement to the routines signature. Anyway,
you should check that the generated signature is correct.
Alternatively, you can specify the signature by inserting to the
routines block a ``model'' how the call-back function would be called
from Fortran. For subroutines you should use\\
\hspace*{2em}\texttt{call <call-back name>(<arguments>)}\\
and for functions\\%
\hspace*{2em}\texttt{<return value> = <call-back name>(<arguments>)}\\
The variables in \texttt{<arguments>} and \texttt{<return value>}
must be defined as well. You can use the arguments of the main
routine, for instance.
\item[\texttt{intent(<intentspec>)}] --- this specifies the
``intention'' of the variable. \texttt{<intentspec>} is a comma
separated list of the following specifications:
\begin{description}
\item[\texttt{in}] --- the variable is considered to be an input
variable (default). It means that the Fortran function uses only
the value(s) of the variable and is assumed not to change it.
\item[\texttt{inout}] --- the variable is considered to be an
input/output variable which means that Fortran routine may change
the value(s) of the variable. Note that in Python only array
objects can be changed ``in place''. (\texttt{intent(outin)} is
\texttt{intent(inout)}.)
\item[\texttt{out}] --- the value of the (output) variable is
returned by the wrapper function: it is appended to the list of
\texttt{<returned variables>}. If \texttt{out} is specified alone,
also \texttt{hide} is assumed.
\item[\texttt{hide}] --- use this if the variable \emph{should not}
or \emph{need not} to be in the list of wrapper function arguments
(not even in optional ones). For example, this is assumed if
\texttt{intent(out)} is used. You can ``hide'' an argument if it
has always a constant value specified in \texttt{<init\_expr>},
for instance.
\end{description}
The following rules apply:
\begin{itemize}
\item if no \texttt{intent} attribute is specified, \texttt{intent(in)} is
assumed;
\item \texttt{intent(in,inout)} is \texttt{intent(in)};
\item \texttt{intent(in,hide)}, \texttt{intent(inout,hide)} are \texttt{intent(hide)};
\item \texttt{intent(out)} is \texttt{intent(out,hide)};
\item \texttt{intent(inout)} is NOT \texttt{intent(in,out)}.
\end{itemize}
In conclusion, the following combinations are ``minimal'':
\texttt{intent(in)}, \texttt{intent(inout)}, \texttt{intent(out)},
\texttt{intent(hide)}, \texttt{intent(in,out)}, and
\texttt{intent(inout,out)}.
\item[\texttt{check([<C-booleanexpr>])}] --- if
\texttt{<C-booleanexpr>} evaluates to zero, an exception is raised
about incorrect value or size or any other incorrectness of the
variable. If \texttt{check()} or \texttt{check} is used then \fpy
will not try to guess the checks automatically.
\item[\texttt{depend([<names>])}] --- the variable depends on other
variables listed in \texttt{<names>}. These dependence relations
determine the order of internal initialization of the variables. If
you need to change these relations then be careful not to break the
dependence relations of other relevant variables. If
\texttt{depend()} or \texttt{depend} is used then \fpy will not try
to guess the dependence relations automatically.
\item[\texttt{note(<LaTeX text>)}] --- with this attribute you can
include human readable documentation strings to the LaTeX document
that \fpy generates. Do not insert here information that \fpy can
establish by itself, such as, types, sizes, lengths of the
variables. Here you can insert almost arbitrary LaTeX text. Note
that \texttt{<LaTeX text>} is mainly used inside the LaTeX
\texttt{description} environment. Hint: you can use
\texttt{\bs{}texttt\{<name>\}} for typesetting variable \texttt{<name>}
in LaTeX. In order to get a new line to the LaTeX document, use
\texttt{\bs{}n} followed by a space. For longer text, you may want
to use line continuation feature of Fortran 90/95 language: set
\texttt{\&} (ampersand)
to be the last character in a line.
\item[\texttt{parameter}] --- the variable is parameter and it must
have a value. If the parameter is used in dimension specification,
it is replaced by its value. (Are there any other usages of
parameters except in dimension specifications? Let me know and I'll
add support for it).
\end{description}
\subsection{C-expressions}
\label{sec:C-expr}
The signature of a routine may contain C-expressions in
\begin{itemize}
\item \texttt{<init\_expr>} for initializing particular variable, or in
\item \texttt{<C-booleanexpr>} of the \texttt{check} attribute, or in
\item \texttt{<arrayspec>} of the \texttt{dimension} attribute.
\end{itemize}
A C-expression may contain
\begin{itemize}
\item standard C-statement,
\item functions offered in \texttt{math.h},
\item previously initialized variables (study
the dependence relations) from the argument list, and
\item the following CPP-macros:
\begin{description}
\item[\texttt{len(<name>)}] --- the length of an array \texttt{<name>};
\item[\texttt{shape(<name>,<n>)}] --- the $n$-th dimension of an array
\texttt{<name>};
\item[\texttt{rank(<name>)}] --- the rank of an array \texttt{<name>};
\item[\texttt{slen(<name>)}] --- the length of a string \texttt{<name>}.
\end{description}
\end{itemize}
In addition, when initializing arrays, an index vector \texttt{int
\_i[rank(<name>)];}
is available: \texttt{\_i[0]} refers to
the index of the first dimension, \texttt{\_i[1]} to the index of
the second dimension, etc. For example, the argument type declaration\\
\hspace*{2em}\texttt{integer a(10) = \_i[0]}\\
is equivalent with the following Python statement\\
\hspace*{2em}\texttt{a = array(range(10))}
\subsection{Required/optional arguments}
\label{sec:reqoptargs}
When \texttt{optional} attribute is used (including the usage of
\texttt{<init\_expr>} without the \texttt{required} attribute), the
corresponding variable in the argument list of a Fortran routine is
appended to the optional argument list of the wrapper function.
For optional array argument all dimensions must be bounded (not
\texttt{(*)} or \texttt{(:)}) and defined at the time of
initialization (dependence relations).
If the \texttt{None} object is passed in in place of a required array
argument, it will be considered as optional: that is, the memory is
allocated (of course, if it has unbounded dimensions, an exception
will be raised), and if \texttt{<init\_expr>} is defined,
initialization is carried out.
\subsection{Internal checks}
\label{sec:intchecks}
All array arguments are checked against the correctness of their rank.
If there is a mismatch, \fpy attempts to fix that by constructing an
array with a correct rank from the given array argument (there will be
no performance hit as no data is copied). The freedom to do so is
given only if some dimensions are unbounded or their value is 1. An
exception is raised when the sizes will not match.
All bounded dimensions of an array are checked to be larger or equal
to the dimensions specified in the signature.
So, you don't need to give explicit \texttt{check} attributes to check
these internal checks.
\subsection{Call-back modules}
\label{sec:cbmodule}
A Fortran routine may have \texttt{external} arguments (call-back
functions). The signatures of the call-back functions must be defined
in a call-back \texttt{module} block (its name contains
\texttt{\_\_user\_\_}), in general; other possibilities are described
in the \texttt{external} attribute specification (see
Sec.~\ref{sec:attributes}). For the signatures of call-back
functions the following restrictions apply:
\begin{itemize}
\item Attributes \texttt{external}, \texttt{check(...)}, and
initialization statements are ignored.
\item Attribute \texttt{optional} is used only for changing the order
of the arguments.
\item For arrays all dimension bounds must be specified. They may be
C-expressions containing variables from the argument list.
Note that here CPP-macros \texttt{len}, \texttt{shape},
\texttt{rank}, and \texttt{slen} are not available.
\end{itemize}
\subsection{Common blocks}
\label{sec:commonblocks}
All fields in a common block are mapped to arrays of appropriate sizes
and types. Scalars are mapped to rank-0 arrays. For multi-dimensional
fields the corresponding arrays are transposed. In the type
declarations of the variables representing the common block fields,
only \texttt{dimension(<arrayspec>)}, \texttt{intent(hide)}, and
\texttt{note(<LaTeX text>)} attributes are used, others are ignored.
\subsection{Including files}
\label{sec:include}
You can include files to the signature file using
\begin{verbatim}
include '<filename>'
\end{verbatim}
statement. It can be used in any part of the signature file.
If the file \texttt{<filename>} does not exists or it is not in the path,
the \texttt{include} line is ignored.
\subsection{\fpy directives}
\label{sec:directives}
You can insert signature statements directly to Fortran source codes
as comments. Anything that follows \texttt{<comment char>f2py} is
regarded as normal statement for \fpy.
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "f2py2e"
%%% End: