vector of cpp object in cython classes from list of cython class

1,283 views
Skip to first unread message

Nikhil Garg

unread,
Jun 13, 2019, 12:46:20 PM6/13/19
to cython-users
I am trying to create a vector of cpp object under cython wrapper of c++ from a list of cython classes in python. I was wondering whether this is possible and if so, how should i go about doing it.

I have trying to create a minimal example to show what I am hoping to do.

this is my test.pyx

from libcpp.vector cimport vector
from libcpp.string cimport string

cdef extern from "raster.h" namespace "GeoStack":
    cdef cppclass Raster[T]:
        Raster() except +

cdef class cyRaster:
    cdef Raster[double] *thisptr
    cdef unsigned int raster_initialised

    def __cinit__(self):
        self.raster_initialised = 1

def run_script(bytes script, object inputRasters):
    cdef vector[Raster[double]] inp_rasters
    cdef int n_rasters
    cdef int i
    n_rasters = len(inputRasters)

    for i in range(n_rasters):
        inp_rasters.push_back(inputRasters[i].thisptr)


and this is the raster.h

#include <list>
#include <vector>
#include <memory>

namespace GeoStack{
    template <typename T>
    class Raster;

    template <typename T>
    class Raster{
    public:
        Raster();
        ~Raster();
    }
}

and the python code to call the cython class.

from test import cyRaster, run_script

testA = cyRaster()
testB = cyRaster()

script = "testC = testA + testB"

run_script(script.encode('UTF-8'), [testA, testB])



Robert Bradshaw

unread,
Jun 13, 2019, 1:30:27 PM6/13/19
to cython...@googlegroups.com
No, this isn't possible because the vector wouldn't do the correct recounting on the objects. But you can create a cdef cpp class that holds a single Python object (or subclass thereof) and put that in the the vector.

Alternatively, list is an excellent container for Python objects.

--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/55f052d7-2e64-49a7-89e3-0e1175d31dff%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nikhil Garg

unread,
Jun 14, 2019, 12:15:59 AM6/14/19
to cython-users
Enter code here...

I am attempting to do something as you suggested, however, would appreciate any pointers or fixes to my attempt.

I modified my cython script to have a vector of raster class

from libcpp.vector cimport vector
from libcpp.string cimport string
from cython.operator cimport dereference as deref
from libc.stdio cimport printf

cdef extern from "raster.h" namespace "GeoStack":
    cdef cppclass Raster[T]:
        Raster() except +

    Raster[double] run_script(string script, vector[Raster[double]] inputRasters)

ctypedef Raster[double] raster_ptr_d
ctypedef Raster[float] raster_ptr_f
ctypedef vector[raster_ptr_d] vec_of_raster

cdef class cyRaster:
    cdef raster_ptr_d *thisptr
    cdef int raster_initialised
    def __init__(self):
        self.raster_initialised = 1

cdef class VecOfRasters:
    cdef:
        vec_of_raster input_rasters
        int n_raster

    def __init__(self):
        self.n_raster = 0
        self.input_rasters = vec_of_raster()

    def add_raster(self, cyRaster other):
        self.input_rasters.push_back(other.thisptr[0])
        self.n_raster += 1

    def get_number_of_raster(self):
        printf("Number of rasters are %d", self.n_raster)

where, the c++ header for this cython script is shown below

#include <list>
#include <vector>
#include <memory>

namespace GeoStack{
    template <typename T>
    class Raster;

    template <typename T>
    class Raster{
    public:
        Raster();
        ~Raster();
    };

    template <typename T>
    Raster<T> run_script(std::string script, std::vector<Raster<T> > inputRaster);
}


I forgot to put the code for using the vector of c++ classes in earlier post.



On Friday, 14 June 2019 03:30:27 UTC+10, Robert Bradshaw wrote:
No, this isn't possible because the vector wouldn't do the correct recounting on the objects. But you can create a cdef cpp class that holds a single Python object (or subclass thereof) and put that in the the vector.

Alternatively, list is an excellent container for Python objects.

To unsubscribe from this group and stop receiving emails from it, send an email to cython...@googlegroups.com.

Robert Bradshaw

unread,
Jun 14, 2019, 3:34:18 AM6/14/19
to cython...@googlegroups.com
It would be helpful if you could describe what, at a high level,
you're trying to accomplish, e.g. what it would look like to use this
from Python.
> To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/ce144bb5-8790-4df3-8420-694e1b8d71cd%40googlegroups.com.

Nikhil Garg

unread,
Jun 14, 2019, 10:29:45 AM6/14/19
to cython-users
I am trying to wrap a c++ function which takes a std::vector of a c++ class and performs some operation on it and returns a c++ class object as an output. The c++ function performs those operations on GPU. I have managed to write a cython class which can create a std::vector of c++ class pointers held by the cython class. 

I have also tested that c++ can see that the vector indeed contains the c++ class objects. I was earlier having segmentation fault as I never initialized "thisptr" with an instance of c++ class within cython. As i did not initialize it, i was pushing NULL into a std::vector in cython. It was compiling but was giving me segmentaton fault.

However, now I am wondering that although, I am able to pass the std::vector of c++ class object from cython to c++, I am not able to run the computation from the function GPU. I have an alternative test executable in c++, which is able to perform the same operation, but I can't do that when I call the function from cython.


On Friday, 14 June 2019 17:34:18 UTC+10, Robert Bradshaw wrote:
It would be helpful if you could describe what, at a high level,
you're trying to accomplish, e.g. what it would look like to use this
from Python.

Robert Bradshaw

unread,
Jun 14, 2019, 5:06:23 PM6/14/19
to cython...@googlegroups.com
On Fri, Jun 14, 2019 at 4:29 PM Nikhil Garg <nikhilg...@gmail.com> wrote:
>
> I am trying to wrap a c++ function which takes a std::vector of a c++ class and performs some operation on it and returns a c++ class object as an output. The c++ function performs those operations on GPU. I have managed to write a cython class which can create a std::vector of c++ class pointers held by the cython class.
>
> I have also tested that c++ can see that the vector indeed contains the c++ class objects. I was earlier having segmentation fault as I never initialized "thisptr" with an instance of c++ class within cython. As i did not initialize it, i was pushing NULL into a std::vector in cython. It was compiling but was giving me segmentaton fault.

Note also that if the Cython classes own the C++ classes (that is,
they deallocate them on cleanup) you'll have to be sure to keep them
around as well for the pointers in the vector to remain valid.

> However, now I am wondering that although, I am able to pass the std::vector of c++ class object from cython to c++, I am not able to run the computation from the function GPU. I have an alternative test executable in c++, which is able to perform the same operation, but I can't do that when I call the function from cython.

What goes wrong when you try to run the computation? Perhaps an
example of the C++ code that works would be helpful in constructing
the equivalent code in Cython.
> To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/8c4e5cdc-2206-4463-b983-8f7bbfc34fef%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages