[Numpy-discussion] libnumarray.h and NO_IMPORT_ARRAY
David Abrahams
dave at boost-consulting.com
Thu Oct 10 10:29:05 EDT 2002
Philip Austin <paustin at eos.ubc.ca> writes:
> > What I thought I would see, was some form of direct coupling
> > between a module in boost and either the Numeric or numarray C-API.
> > However, when I search the whole source tree (*.cpp *.hpp) I can
> > find neither PyArrayObject, arrayobject.h, NDInfo, nor
> > libnumarray.h. So I'm not sure what part of any Numeric/numarray
> > C-API you're using now (if any)
>
> The answer is -- no part of the C-API if he can get away with it.
> Your move towards Numeric compatibility for numarray means that he
> now can get away with it.
I've been getting away with it already. It's easy enough to access all
that functionality through the usual Python/C API.
> numeric wraps the module pointer, and calls functions
> through it -- e.g. (from boost/libs/python/src/numeric.cpp):
>
> void array_base::resize(object const& shape)
> {
> attr("resize")(shape);
> }
>
> which invokes PyObject_CallObject to call the array's resize method,
> with the tuple shape (similar to CXX). If the method isn't part of the
> library (say for Numeric and getflat) then a python exception is
> thrown.
Slow but effective. If you want to touch the raw PyObject*, of course,
you can do this:
void f(numeric::array x)
{
PyObject* danger = x.ptr();
// Cast to whatever you like.
}
> > and in particular, what isn't
> > working for you. Note: numarray and Numeric are not totally
> > compatible at either the C or Python levels, so either area could
> > have been a source of difficulty.
>
> The problem was that, as long as a call to getNDInfo was required
> to access an array's data pointer, a Python-only approach
> like the above wouldn't work. Since it is now possible to
> do this via a cast to PyArrayObject* for a numarray, the problem
> has disappeared.
Not sure what you're saying here. I /do/ remember when I was writing
the Numeric/NumArray support that there seemed no publicly-accessible
definition of the structure of the underlying array objects.
> (there's nothing stopping you from using the C-API if you want,
> though. For example you can create a numarray with data
> copied from a C array with something like:
>
> numeric::array makeNum(int * data, int n=0){
> object obj(detail::new_reference(PyArray_FromDims(1, &n, PyArray_INT)));
> char *arr_data = ((PyArrayObject*) obj.ptr())->data;
> memcpy(arr_data, data, 4 * n);
> return numeric::array(obj);
> }
Well, this uses undocumented implementation details. The supported
approach is:
handle<> raw_array(PyArray_FromDims(1, &n, PyArray_INT));
object obj(raw_array);
Note, though, that you can also write:
handle<PyArrayObject> raw_array(PyArray_FromDims(1, &n, PyArray_INT));
Assuming, of course, that PyArray_FromDims returns a
PyArrayObject*. And now you have access to the PyArrayObject* through
raw_array.
Also note that it's probably smarter to use
extract<numeric::array>(obj)
Than
numeric::array(obj)
See the note about pitfalls at
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/doc/tutorial/doc/derived_object_types.html
for the reasons why.
--
David Abrahams * Boost Consulting
dave at boost-consulting.com * http://www.boost-consulting.com
More information about the NumPy-Discussion
mailing list