[C++-sig] Moving "decorator" into C++ part of module

Albert Strasheim fullung at gmail.com
Mon May 21 20:54:33 CEST 2007


Hello

On Mon, 21 May 2007, Neal Becker wrote:

> This looks very good so far.  I see there is c++ ublas -> python numpy
> conversion.

With a few more templates and whatnot one can take care of things 
figuring out that for a matrix<int> the typecode should be 'i', etc. For 
now I'm just focusing on getting double working. But soon...

> Have you tried the other direction?  python numpy -> c++ ublas?

I'm trying to sort this out now. Here there are a few more 
complications:

1. Some array adaptor complications (nothing too major) to make a uBLAS 
matrix use the array's data without a copy

2. Conversion of NumPy array arguments to uBLAS

I'm currently stuck here. I was hoping to do something like:

template <
    class T,
    std::size_t arg,
    class BasePolicy_ = py::default_call_policies
>
struct convert_array : BasePolicy_
{
    BOOST_STATIC_ASSERT(arg > 0);

    template <class ArgumentPackage>
    static bool precall(ArgumentPackage const& args_)
    {
        unsigned int arity_ = PyTuple_GET_SIZE(args_);
        if (arg > arity_) {
            PyErr_SetString(
                PyExc_IndexError,
                "convert_array: argument index out of range");
            return false;
        }
        PyObject* obj = PyTuple_GetItem(args_, arg);
        if (obj == NULL) {
            return false;
        }
        if (!PyArray_Check(obj)) {
            PyErr_SetString(
                PyExc_TypeError,
                "convert_array: ndarray argument expected");
            return NULL;
        }

        // XXX magic happens here see below

        return BasePolicy_::precall(args_);
    }
};

What I wanted to attempt at XXX is to create an instance of a uBLAS 
vector/matrix/whatever inside its associated PyObject, with the 
uBLAS matrix using the memory of the NumPy array. I was hoping I could 
then do a little bait and switch on the tuple item to put this new 
uBLAS-PyObject-using-a-Numpy-array into the arguments before the 
function gets called.

You could then wrap the method something like this:

py::class_<array_test, boost::noncopyable>("array_test")
        .def("pointer_arg",
             &array_test::pointer_arg, 
             convert_array<matrix<float>, 1>())

Unfortunately, it seems checking of argument types happens before the 
the convert_array precall (not much of a *pre*call is it? ;-)), so this 
trick doesn't work (you get an ArgumentError).

Any ideas would help at this point. :-)

Regards,

Albert



More information about the Cplusplus-sig mailing list