i) Declared optional in Fortran
ii) Inferred to be optional by fwrap (e.g. array bounds, intent(out)
arrays, more below)
In both cases, the argument in question is not necessarily at the end of
the argument list. This problem is amplified because of category ii):
E.g. array bounds can sometimes be inferred, so that arguments that are
required Fortran-side (and are thus not pushed to the end of the
argument list by the Fortran programmer) can be optional Python side.
Example 1:
subroutine returnsarray(arr, m, n)
implicit none
real, dimension(m, n), intent(out) :: arr
integer, intent(in) :: m, n
...
end subroutine returnsarray
Here, arr is optional in f2py, and thus also in my fwrap branch [1]. The
wrapper will allocate an output array if not provided. Problem is,
should "arr" be moved to the end of the output list, or not?
BTW, given "arr", m and n can be inferred instearAs this is not what
f2py does it's outside my radar currently...
Choices Python-side:
a)
Keep order:
def returnsarray(arr, m, n): ...
Still possible to call as returnsarray(None, m, n) to auto-allocate
result array.
b)
Move optional arguments to end:
def returnsarray(m, n, arr=None): ...
This is what f2py does. +1 from me.
c)
def returnsarray(arr=None, m=None, n=None):
if m is None: raise ValueError("argument required: m")
if n is None: raise ValueError("argument required: n")
This allows returnsarray(m=m, n=n) in addition to returnsarray(None, m,
n). This seems to seamlessly also support
returnsarray(arr=arr) # m and n
Example 2:
subroutine takesarray(m, n, arr)
implicit none
real, dimension(m, n), intent(in) :: arr
integer, intent(in) :: m, n
...
end subroutine takesarray
Here it is only relevant to infer m and n, and the sane way to call the
function from Python is
takesarray(arr)
f2py would move the m and n arguments last in this case, so that they
can be optionally provided, corresponding to slicing; takesarray(arr, m, n).
So this makes a case for moving the optional arguments. However, a case
could be made for simply dropping the arguments altogether (which is
perhaps easier to understand than moving them around), as they are
redundant with the slicing syntax; takesarray(arr[:m, :n]).
Input most welcome.
Dag Sverre
[1] My work is here, these ones in particular in the "outarray" branch:
BTW, I actually wouldn't mind a rename too in this situation: 'Always
prefix with "out" unless the variable name already starts with "out" or
"result"'.
def returnsarray(m, n, out_arr=None):
And what f2py does is in fact to hide intent(out) arguments completely,
it doesn't accept an optional output buffer.
Dag Sverre
--
You received this message because you are subscribed to the Google Groups "Fwrap Users" group.
To post to this group, send email to fwrap...@googlegroups.com.
To unsubscribe from this group, send email to fwrap-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/fwrap-users?hl=en.
Sometimes you want to avoid allocating the out array, i.e. the output
array is already sitting in memory for some reason. There is not always
enough memory around to have a temporary. So I think keeping "arr"
around even if it is intent(out) is mandatory, but I guess I should take
this as a vote for moving it to the end?
In my opinion, if you do
real, dimension(n), intent(out) :: arr, out_arr
you deserve the trouble you get :-) We can always not rename in that
case. Or the favorite Cython solution: Provide a compiler directive to
let people choose :-)
Dag Sverre
How should fwrap deal with optional arguments? There are several kinds of optional arguments:
i) Declared optional in Fortran
ii) Inferred to be optional by fwrap (e.g. array bounds, intent(out) arrays, more below)
In both cases, the argument in question is not necessarily at the end of the argument list. This problem is amplified because of category ii): E.g. array bounds can sometimes be inferred, so that arguments that are required Fortran-side (and are thus not pushed to the end of the argument list by the Fortran programmer) can be optional Python side.
Example 1:
subroutine returnsarray(arr, m, n)
implicit none
real, dimension(m, n), intent(out) :: arr
integer, intent(in) :: m, n
...
end subroutine returnsarray
Here, arr is optional in f2py, and thus also in my fwrap branch [1]. The wrapper will allocate an output array if not provided. Problem is, should "arr" be moved to the end of the output list, or not?
BTW, given "arr", m and n can be inferred instearAs this is not what f2py does it's outside my radar currently...
Choices Python-side:
a)
Keep order:
def returnsarray(arr, m, n): ...
Still possible to call as returnsarray(None, m, n) to auto-allocate result array.
b)
Move optional arguments to end:
def returnsarray(m, n, arr=None): ...
This is what f2py does. +1 from me.
c)
def returnsarray(arr=None, m=None, n=None):
if m is None: raise ValueError("argument required: m")
if n is None: raise ValueError("argument required: n")
This allows returnsarray(m=m, n=n) in addition to returnsarray(None, m, n). This seems to seamlessly also support
returnsarray(arr=arr) # m and n
Example 2:
subroutine takesarray(m, n, arr)
implicit none
real, dimension(m, n), intent(in) :: arr
integer, intent(in) :: m, n
...
end subroutine takesarray
Here it is only relevant to infer m and n, and the sane way to call the function from Python is
takesarray(arr)
f2py would move the m and n arguments last in this case, so that they can be optionally provided, corresponding to slicing; takesarray(arr, m, n).
So this makes a case for moving the optional arguments. However, a case could be made for simply dropping the arguments altogether (which is perhaps easier to understand than moving them around), as they are redundant with the slicing syntax; takesarray(arr[:m, :n]).