.. _program_listing_file__tmp_ws_src_eigenpy_include_eigenpy_scipy-allocator.hpp: Program Listing for File scipy-allocator.hpp ============================================ |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/eigenpy/include/eigenpy/scipy-allocator.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Copyright 2024 INRIA */ #ifndef __eigenpy_scipy_allocator_hpp__ #define __eigenpy_scipy_allocator_hpp__ #include "eigenpy/fwd.hpp" #include "eigenpy/eigen-allocator.hpp" #include "eigenpy/scipy-type.hpp" #include "eigenpy/register.hpp" namespace eigenpy { template struct scipy_allocator_impl; template struct scipy_allocator_impl_sparse_matrix; template struct scipy_allocator_impl< MatType, Eigen::SparseMatrixBase::type> > : scipy_allocator_impl_sparse_matrix {}; template struct scipy_allocator_impl< const MatType, const Eigen::SparseMatrixBase< typename remove_const_reference::type> > : scipy_allocator_impl_sparse_matrix {}; // template // struct scipy_allocator_impl > : // scipy_allocator_impl_sparse_matrix //{}; template struct scipy_allocator_impl > : scipy_allocator_impl_sparse_matrix {}; template ::type> struct ScipyAllocator : scipy_allocator_impl {}; template struct scipy_allocator_impl_sparse_matrix { template static PyObject *allocate( const Eigen::SparseCompressedBase &mat_, bool copy = false) { EIGENPY_UNUSED_VARIABLE(copy); typedef typename SimilarMatrixType::Scalar Scalar; typedef typename SimilarMatrixType::StorageIndex StorageIndex; enum { IsRowMajor = SimilarMatrixType::IsRowMajor }; typedef Eigen::Matrix DataVector; typedef const Eigen::Map MapDataVector; typedef Eigen::Matrix StorageIndexVector; typedef Eigen::Matrix ScipyStorageIndexVector; typedef const Eigen::Map MapStorageIndexVector; SimilarMatrixType &mat = mat_.const_cast_derived(); bp::object scipy_sparse_matrix_type = ScipyType::get_pytype_object(); MapDataVector data(mat.valuePtr(), mat.nonZeros()); MapStorageIndexVector outer_indices( mat.outerIndexPtr(), (IsRowMajor ? mat.rows() : mat.cols()) + 1); MapStorageIndexVector inner_indices(mat.innerIndexPtr(), mat.nonZeros()); bp::object scipy_sparse_matrix; if (mat.rows() == 0 && mat.cols() == 0) // handle the specific case of empty matrix { // PyArray_Descr* npy_type = // Register::getPyArrayDescrFromScalarType(); bp::dict args; // args["dtype"] = // bp::object(bp::handle<>(bp::borrowed(npy_type->typeobj))); // args["shape"] = bp::object(bp::handle<>(bp::borrowed(Py_None))); // scipy_sparse_matrix = // scipy_sparse_matrix_type(*bp::make_tuple(0,0),**args); scipy_sparse_matrix = scipy_sparse_matrix_type( Eigen::Matrix(0, 0)); } else if (mat.nonZeros() == 0) { scipy_sparse_matrix = scipy_sparse_matrix_type(bp::make_tuple(mat.rows(), mat.cols())); } else { scipy_sparse_matrix = scipy_sparse_matrix_type(bp::make_tuple( DataVector(data), ScipyStorageIndexVector(inner_indices.template cast()), ScipyStorageIndexVector( outer_indices.template cast()))); //, // bp::make_tuple(mat.rows(), // mat.cols()))); } Py_INCREF(scipy_sparse_matrix.ptr()); return scipy_sparse_matrix.ptr(); } }; // template // struct scipy_allocator_impl_sparse_matrix { // template // static PyArrayObject *allocate(Eigen::PlainObjectBase // &mat, // npy_intp nd, npy_intp *shape) { // typedef typename SimilarMatrixType::Scalar Scalar; // enum { // NPY_ARRAY_MEMORY_CONTIGUOUS = // SimilarMatrixType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY // }; // // if (NumpyType::sharedMemory()) { // const int Scalar_type_code = Register::getTypeCode(); // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New( // getPyArrayType(), static_cast(nd), shape, Scalar_type_code, // mat.data(), NPY_ARRAY_MEMORY_CONTIGUOUS | NPY_ARRAY_ALIGNED); // // return pyArray; // } else { // return NumpyAllocator::allocate(mat, nd, shape); // } // } // }; #if EIGEN_VERSION_AT_LEAST(3, 2, 0) // template // struct scipy_allocator_impl_sparse_matrix > { // typedef Eigen::Ref RefType; // // static PyArrayObject *allocate(RefType &mat, npy_intp nd, npy_intp *shape) // { // typedef typename RefType::Scalar Scalar; // enum { // NPY_ARRAY_MEMORY_CONTIGUOUS = // RefType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY // }; // // if (NumpyType::sharedMemory()) { // const int Scalar_type_code = Register::getTypeCode(); // const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1); // Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride() // : mat.innerStride(), // outer_stride = reverse_strides ? mat.innerStride() // : mat.outerStride(); // // const int elsize = // call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp // strides[2] = {elsize * inner_stride, elsize * outer_stride}; // // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New( // getPyArrayType(), static_cast(nd), shape, Scalar_type_code, // strides, mat.data(), NPY_ARRAY_MEMORY_CONTIGUOUS | // NPY_ARRAY_ALIGNED); // // return pyArray; // } else { // return NumpyAllocator::allocate(mat, nd, shape); // } // } // }; #endif // template // struct scipy_allocator_impl_sparse_matrix { // template // static PyArrayObject *allocate( // const Eigen::PlainObjectBase &mat, npy_intp nd, // npy_intp *shape) { // typedef typename SimilarMatrixType::Scalar Scalar; // enum { // NPY_ARRAY_MEMORY_CONTIGUOUS_RO = SimilarMatrixType::IsRowMajor // ? NPY_ARRAY_CARRAY_RO // : NPY_ARRAY_FARRAY_RO // }; // // if (NumpyType::sharedMemory()) { // const int Scalar_type_code = Register::getTypeCode(); // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New( // getPyArrayType(), static_cast(nd), shape, Scalar_type_code, // const_cast(mat.data()), // NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED); // // return pyArray; // } else { // return NumpyAllocator::allocate(mat, nd, shape); // } // } // }; #if EIGEN_VERSION_AT_LEAST(3, 2, 0) // template // struct scipy_allocator_impl_sparse_matrix< // const Eigen::Ref > { // typedef const Eigen::Ref RefType; // // static PyArrayObject *allocate(RefType &mat, npy_intp nd, npy_intp *shape) // { // typedef typename RefType::Scalar Scalar; // enum { // NPY_ARRAY_MEMORY_CONTIGUOUS_RO = // RefType::IsRowMajor ? NPY_ARRAY_CARRAY_RO : NPY_ARRAY_FARRAY_RO // }; // // if (NumpyType::sharedMemory()) { // const int Scalar_type_code = Register::getTypeCode(); // // const bool reverse_strides = MatType::IsRowMajor || (mat.rows() == 1); // Eigen::DenseIndex inner_stride = reverse_strides ? mat.outerStride() // : mat.innerStride(), // outer_stride = reverse_strides ? mat.innerStride() // : mat.outerStride(); // // const int elsize = // call_PyArray_DescrFromType(Scalar_type_code)->elsize; npy_intp // strides[2] = {elsize * inner_stride, elsize * outer_stride}; // // PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New( // getPyArrayType(), static_cast(nd), shape, Scalar_type_code, // strides, const_cast(mat.data()), // NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED); // // return pyArray; // } else { // return NumpyAllocator::allocate(mat, nd, shape); // } // } // }; #endif } // namespace eigenpy #endif // ifndef __eigenpy_scipy_allocator_hpp__