[SciPy-Dev] google releases ceres solver
Dag Sverre Seljebotn
d.s.seljebotn at astro.uio.no
Thu May 3 05:03:02 EDT 2012
On 05/02/2012 07:25 PM, Keir Mierle wrote:
> We spent some time thinking about how to integrate Python with Ceres,
> and our current thinking is that we should implement a CostFunction with
> Cython, then pass that into Ceres. If one of you could take a peek at
> the Ceres API and offer thoughts on how to do this, we might get started
> on it.
You would essentially write this in Cython:
cdef class CostFunction:
cpdef void evaluate(args...): raise NotImplementedError
cdef int call_CostFunction_evaluate(args..., void* ctx) with gil:
try:
(<CostFunction>ctx).evaluate(args...)
return 0
except:
# somehow save sys.exc_info to where the
# Ceres entry point can find it
return -1
If you do not release the GIL while inside Ceres one can remove the
"with gil" part.
Then you subclass the C++-CostFunction in C++, have it save the
PyObject* that corresponds to the Cython-CostFunction instance, and have
it call call_CostFunction_evaluate (which should likely be passed as a
function pointer to a function initializing the C++ part of the wrapper).
The C++ part of the wrapper can be written in a header file and included
verbatim in Cython:
cdef extern from "cpp_part_of_wrapper.hpp": pass
Finally: For wrapping the double* arguments one may want to play with
the new memoryviews in Cython 0.16. Alternatively, change "cpdef" to
"cdef" and just pass the pointers along.
For Python implementations of CostFunction, you likely want the double*
wrapped as NumPy arrays. Constructing such arrays on each evaluate()
would be rather expensive (whether this matters depends on the vector
size of course), so if it is possible to somehow pass in to Ceres the
buffers to use, and just hold on to the same NumPy arrays Python-side,
and ignore the arguments to evaluate(), that would save some overhead.
Dag
More information about the SciPy-Dev
mailing list