[Numpy-discussion] f2py callback bug?
Pearu Peterson
pearu.peterson at gmail.com
Wed Nov 25 02:58:46 EST 2009
Hi,
It is not really a bug what you are seeing..
In pycalc when assigning
j = 20 * j
you create a new object `j` and the argument object `j`, that links
back to Fortran data, gets discarded.
So, you can change j inplace, for example:
j[:] = 20*j
The first argument `i` is int object that in Python is immutable,
and hence cannot be changed inplace and the corresponding Fortran
scalar object cannot be changed in the callback (in fact, `i`
is a copy of the corresponding Fortran data value).
To change `i` in Python callback, define it as an array
(similar to `j`) and do inplace operations with it.
Regarding pyreturn and assuming Fortran 77:
you cannot return arrays or multiple object in Fortran functions.
Fortran functions may return only scalars. So, the pyreturn trick will
never work. The solution is to change arguments in place as with `j`.
Hmm, regarding `intent(in, out) j`, this should work. I'll check what
is going on..
HTH,
Pearu
James McEnerney wrote:
> While using the call-back feature of f2py I stumbled across what appears
> to be a bug and I'm asking the community to look into this.
>
> Background: I'm in the middle of converting some legacy fortran to python.
> There is one routine that is particulary thorny that calls more easily
> convertible service routines and my intention is to convert the latter
> and use the callback feature of f2py to execute them within the fortran
> followed by a systematic conversion of what remains. This seems to be
> doable from what I've read on callback. I have not seen an example
> of using callback where the python actually changes parameters that are
> returned to the fortran; this is a requirement for me. While setting up
> an example to illustrate this I came across a syntactically correct
> situation(this means it compiles & executes) but gives the wrong answer.
> Here's the code:
> In fortran, source foo.f
> subroutine calc(i, j)
> Cf2py intent(callback) pycalc
> external pycalc
> Cf2py integer intent(in,out,copy):: i
> Cf2py integer dimension(1), intent(in,out):: j
> integer pyreturn
>
> integer i, j(1)
> print *, 'in fortran before pycalc ','i=',i, ' j=', j(1)
> pyreturn = pycalc(i, j)
> print *, 'in fortran after pycalc ','i=', i, ' j=', j(1)
>
> end
>
> Standard build: f2py -c -m foo foo.f
>
> In python, execute
> import foo,numpy
>
> def pycalc(i, j):
> print ' in pycalc ', 'i=',i, 'j=', j
> i=10*i
> j = 20*j
> return i, j
>
> print foo.calc.__doc__
> i=2
> j = 1+numpy.array([i])
> print foo.calc(i,j, pycalc)
>
> Here's the output:
> calc - Function signature:
> i,j = calc(i,j,pycalc,[pycalc_extra_args])
> Required arguments:
> i : input int
> j : input rank-1 array('i') with bounds (1)
> pycalc : call-back function
> Optional arguments:
> pycalc_extra_args := () input tuple
> Return objects:
> i : int
> j : rank-1 array('i') with bounds (1)
> Call-back functions:
> def pycalc(i,j): return pyreturn,i,j
> Required arguments:
> i : input int
> j : input rank-1 array('i') with bounds (1)
> Return objects:
> pyreturn : int
> i : int
> j : rank-1 array('i') with bounds (1)
>
>
> in fortran before pycalc i= 2 j= 3
> in pycalc i= 2 j= [3]
> in fortran after pycalc i= 60 j= 3
> (60, array([3]))
>
> The bug:
> on return to the fortran why is i=60 & j=3?
> shouldn't it be i=10 & j=60
>
> While that's what I expect, I might not be defining the
> interface properly; but this compiles & executes. If this
> is incorrect, what is? In the fortran, pyreturn appears
> to be an address; how do I get the retuned values?
>
> I'm running
> Redhat Linux
> python version 2.5
> f2py version 2_3979
> numpy version 1.0.3.1
> Thanks
>
> Jim McEnerney
> Lawrence Livermore National Laboratory
> 7000 East Ave.
> Livermore, Ca. 94550-9234
>
> USA
>
> 925-422-1963
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at scipy.org
> http://mail.scipy.org/mailman/listinfo/numpy-discussion
More information about the NumPy-Discussion
mailing list