I have have the following C++ class, which I want to wrap around with Cython. The class contains more methods but I only included the important ones.
#include <cstdint>
#include <cassert>
#include <vector>
template<class T>
class HkCluster {
private:
std::vector<T> matrix;
std::vector<T> labels;
int n_labels{};
int cols{};
int rows{};
public:
HkCluster() = default;
HkCluster(T *matrix, int cols, int rows) {
this->cols = cols;
this->rows = rows;
this->n_labels = cols * rows / 2;
this->labels = std::vector<T>(cols * rows, 0);
this->matrix = std::vector<T>(matrix, matrix + cols * rows);
}
void setMatrix(T * matrix){
this->matrix = std::vector<T>(matrix, matrix + this->cols * this->rows);
}
void setCols(int cols) {
HkCluster::cols = cols;
}
void setRows(int rows) {
HkCluster::rows = rows;
}
};
This is how I wrap the class with Cython. This code is working but you can see that I created the object on the heap, which is not optimal
import numpy as np
cdef extern from "hk.cpp":
cdef cppclass HkCluster[T]:
HkCluster();
HkCluster(T *matrix, int cols, int rows);
T hk_cluster(T * ret);
void setMatrix(T * matrix);
void setCols(int cols);
void setRows(int rows);
def hk(a not None):
arr = a.copy()
if not arr.flags['C_CONTIGUOUS']:
arr = np.ascontiguousarray(arr)
if arr.dtype != np.int32:
arr = np.cast[np.int32](arr)
cdef int[:, ::1] a_mem_view = arr
cdef HkCluster[int] *cluster = new HkCluster[int](&(a_mem_view[0, 0]), a.shape[1], a.shape[0])
cluster.setMatrix(&(a_mem_view[0, 0]))
cluster.setRows(a.shape[0])
cluster.setCols(a.shape[1])
count = cluster.hk_cluster(&(a_mem_view[0, 0]))
del cluster
return count, arr
This is my attempt to create the object on the stack, which results in Segmentation Fault. I read the documentation of Cython from https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html and the code shall work. What am I doing wrong?
import numpy as np
cdef extern from "hk.cpp":
cdef cppclass HkCluster[T]:
HkCluster();
HkCluster(T *matrix, int cols, int rows);
T hk_cluster(T * ret);
void setMatrix(T * matrix);
void setCols(int cols);
void setRows(int rows);
def hk(a not None):
arr = a.copy()
if not arr.flags['C_CONTIGUOUS']:
arr = np.ascontiguousarray(arr)
if arr.dtype != np.int32:
arr = np.cast[np.int32](arr)
cdef int[:, ::1] a_mem_view = arr
cdef HkCluster[int] cluster
cluster.setMatrix(&(a_mem_view[0, 0]))
cluster.setRows(a.shape[0])
cluster.setCols(a.shape[1])
count = cluster.hk_cluster(&(a_mem_view[0, 0]))
return count, arr
Please login or Register to submit your answer