Cannot pass numpy array to const std::vector<dolfin::la_index>&

Issue #452 closed
Chaffra Affouda created an issue

I have a function

void cell_indices(const std::vector<dolfin::la_index>& indices) {_cell_indices=indices;}

I am trying to pass the numpy array

indices = np.array(some_list,dtype=la_index_dtype())
cell_indices(indices)

but I am getting

NotImplementedError: Wrong number or type of arguments for overloaded function 'SimulationRegion_cell_indices'.
  Possible C/C++ prototypes are:
    semifem::SimulationRegion::cell_indices() const
    semifem::SimulationRegion::cell_indices(std::vector< dolfin::la_index > const &)

Can anyone reproduce something similar?

Comments (14)

  1. Jan Blechta

    BTW, looking to some my code, I find that const Array<la_index>& can be passed in as contiguous np.ndarray. This is in contrary to std::vector done without copying. So it is user's responsibility to take care of argument lifetime. This is probably ok for free function in your case and for class members storing the argument you can attach it to a class on Python side.

  2. Jan Blechta

    Oh, cell_indices(const std::vector<dolfin::la_index>&) isn't a free function but (non-static) class member, right? How does it then correspond to cell_indices(indices) call on Python side?

  3. Chaffra Affouda reporter

    Yes it's a member function to a class. I have a private attribute

    std::vector<la_index> _cell_indices and a function cell_indices I can call from python to set that attribute from python with a numpy array.

  4. Jan Blechta

    Yes, but a Python call cell_indices(indices) looks like call to free function, not to a member function! You should better post a minimal working example if you want to obtain help here. The typemap itself seems to be working; try for instance

    v = Vector()
    v.init(mpi_comm_world(),
           (0, 2),
           np.array((0, 1), dtype='uintp'),
           np.array((0, 1), dtype=la_index_dtype()))
    
  5. Chaffra Affouda reporter

    Ok here is a minimal example:

    class SimulationRegion: public dolfin::SubDomain {
    
    public:
    
        SimulationRegion() {dolfin::SubDomain(); };
        const std::vector<dolfin::la_index>& cell_indices() const {return _cell_indices;}
        void cell_indices(const std::vector<dolfin::la_index>& indices) {_cell_indices=indices;}
    
    private:
        std::vector<dolfin::la_index> _cell_indices;
    };
    

    I use distutils to wrap this with swig using the dolfin typemaps. In python I can do

    region = SimulationRegion()
    indices = np.array(some_list,dtype=la_index_dtype())
    region.cell_indices(indices) #DOES NOT WORK because la_index_dtype() return int32 dtype
    
    indices = np.array(some_list,dtype='int64')
    region.cell_indices(indices) #WORKS
    
    #BUT
    region.cell_indices() #returns "int32 array with garbage"
    

    so my std::vector<dolfin::la_index> accepts int64 numpy array but it returns int32 array. Something is wrong here.

  6. Jan Blechta

    It was a little bit debug it yourself example but this

    from dolfin import *
    import numpy as np
    
    SimulationRegion = compile_extension_module("""
    #include <vector>
    
    namespace dolfin {
    
    class SimulationRegion: public dolfin::SubDomain {
    
    public:
    
        SimulationRegion() {dolfin::SubDomain(); };
        const std::vector<dolfin::la_index>& cell_indices() const {return _cell_indices;}
        void cell_indices(const std::vector<dolfin::la_index>& indices) {_cell_indices=indices;}
    
    private:
        std::vector<dolfin::la_index> _cell_indices;
    };
    
    }
    """, additional_declarations='%shared_ptr(dolfin::SimulationRegion)').SimulationRegion
    
    region = SimulationRegion()
    
    indices = np.array((42, 666), dtype=la_index_dtype())
    region.cell_indices(indices)
    
    print region.cell_indices() # [42 666]
    print region.cell_indices().dtype # int32 or int64
    

    work on both of my builds where la_index is int32 and int64 respectively. As I told, make sure that you have the latest DOLFIN. There were some fixes in this area recently.

  7. Chaffra Affouda reporter

    Yes your example does work but I am still having that problem although I have the latest dolfin. Probable has to do with my swig includes. Thanks.

  8. Chaffra Affouda reporter

    Jan

    I figured it out. I was missing some new definition variables when building with disutils like -DDOLFIN_LA_INDEX_SIZE=4 and such...

  9. Log in to comment