diff --git a/cmake b/cmake index 93ec987ecdc016039c8731e203943e5a83eb96d5..321eb1ccf1d94570eb564f3659b13ef3ef82239e 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 93ec987ecdc016039c8731e203943e5a83eb96d5 +Subproject commit 321eb1ccf1d94570eb564f3659b13ef3ef82239e diff --git a/include/eigenpy/numpy-allocator.hpp b/include/eigenpy/numpy-allocator.hpp index e0fd88288795df9ef4857ae3af54ab70bfc93458..fbbcab863a4b521aaa94ed96bf7d3db2edd160dd 100644 --- a/include/eigenpy/numpy-allocator.hpp +++ b/include/eigenpy/numpy-allocator.hpp @@ -40,12 +40,19 @@ namespace eigenpy typedef typename SimilarMatrixType::Scalar Scalar; enum { NPY_ARRAY_MEMORY_CONTIGUOUS = SimilarMatrixType::IsRowMajor ? NPY_ARRAY_CARRAY : NPY_ARRAY_FARRAY }; - PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(nd, shape, - NumpyEquivalentType<Scalar>::type_code, - mat.data(), - NPY_ARRAY_MEMORY_CONTIGUOUS | NPY_ARRAY_ALIGNED); - - return pyArray; + if(NumpyType::sharedMemory()) + { + PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(nd, shape, + NumpyEquivalentType<Scalar>::type_code, + mat.data(), + NPY_ARRAY_MEMORY_CONTIGUOUS | NPY_ARRAY_ALIGNED); + + return pyArray; + } + else + { + return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape); + } } }; @@ -68,12 +75,19 @@ namespace eigenpy typedef typename SimilarMatrixType::Scalar Scalar; enum { NPY_ARRAY_MEMORY_CONTIGUOUS_RO = SimilarMatrixType::IsRowMajor ? NPY_ARRAY_CARRAY_RO : NPY_ARRAY_FARRAY_RO }; - PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(nd, shape, - NumpyEquivalentType<Scalar>::type_code, - const_cast<SimilarMatrixType &>(mat.derived()).data(), - NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED); - - return pyArray; + if(NumpyType::sharedMemory()) + { + PyArrayObject * pyArray = (PyArrayObject*) call_PyArray_New(nd, shape, + NumpyEquivalentType<Scalar>::type_code, + const_cast<SimilarMatrixType &>(mat.derived()).data(), + NPY_ARRAY_MEMORY_CONTIGUOUS_RO | NPY_ARRAY_ALIGNED); + + return pyArray; + } + else + { + return NumpyAllocator<MatType>::allocate(mat.derived(),nd,shape); + } } }; diff --git a/include/eigenpy/numpy-type.hpp b/include/eigenpy/numpy-type.hpp index 3085b55e8ffe1dd33f4752900a97b934fad1a4c9..8b5cbb2419da7f0974f7079c4db3100d1b1f7bd1 100644 --- a/include/eigenpy/numpy-type.hpp +++ b/include/eigenpy/numpy-type.hpp @@ -96,6 +96,16 @@ namespace eigenpy switchToNumpyArray(); } + static void sharedMemory(const bool value) + { + getInstance().shared_memory = value; + } + + static bool sharedMemory() + { + return getInstance().shared_memory; + } + static void switchToNumpyArray() { getInstance().CurrentNumpyType = getInstance().NumpyArrayObject; @@ -162,6 +172,8 @@ namespace eigenpy CurrentNumpyType = NumpyArrayObject; // default conversion np_type = ARRAY_TYPE; + + shared_memory = true; } bp::object CurrentNumpyType; @@ -173,6 +185,8 @@ namespace eigenpy bp::object NumpyArrayObject; PyTypeObject * NumpyArrayType; NP_TYPE np_type; + + bool shared_memory; }; } diff --git a/package.xml b/package.xml index b713cf3ab74423c42deeb4ca66dc6d6a016f7d78..cc7c6eb2a6cd8f3d58ae23346774393c21dbac19 100644 --- a/package.xml +++ b/package.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <package format="2"> <name>eigenpy</name> - <version>2.1.2</version> + <version>2.2.0</version> <description>Bindings between Numpy and Eigen using Boost.Python</description> <maintainer email="justin.carpentier@inria.fr">Justin Carpentier</maintainer> <maintainer email="wolfgang.merkt@ed.ac.uk">Wolfgang Merkt</maintainer> diff --git a/src/eigenpy.cpp b/src/eigenpy.cpp index c2f49067d105f24fb919f7a5cfa0c510e0b9e58f..805581fca167dba9588500765f37b66aed62f58a 100644 --- a/src/eigenpy.cpp +++ b/src/eigenpy.cpp @@ -45,6 +45,17 @@ namespace eigenpy bp::def("switchToNumpyMatrix",&NumpyType::switchToNumpyMatrix, "Set the conversion from Eigen::Matrix to numpy.matrix."); + bp::def("sharedMemory", + (void (*)(const bool))NumpyType::sharedMemory, + bp::arg("value"), + "Share the memory when converting from Eigen to Numpy."); + + bp::def("sharedMemory", + (bool (*)())NumpyType::sharedMemory, + "Status of the shared memory when converting from Eigen to Numpy.\n" + "If True, the memory is shared when converting an Eigen::Matrix to a numpy.array.\n" + "Otherwise, a deep copy of the Eigen::Matrix is performed."); + bp::def("seed",&seed,bp::arg("seed_value"), "Initialize the pseudo-random number generator with the argument seed_value."); diff --git a/unittest/python/test_return_by_ref.py b/unittest/python/test_return_by_ref.py index 969f84672335af20ec65b1d91cb64e26c17f1830..59f6d130a9925bc772d55cd70cc5b9eed1e05e38 100644 --- a/unittest/python/test_return_by_ref.py +++ b/unittest/python/test_return_by_ref.py @@ -1,7 +1,8 @@ +import return_by_ref from return_by_ref import Matrix, RowMatrix, Vector import numpy as np -def test(mat): +def test_shared(mat): m_ref = mat.ref() m_ref.fill(0) @@ -22,6 +23,27 @@ def test(mat): except: assert True +def test_not_shared(mat): + + m_ref = mat.ref() + m_ref.fill(100.) + m_copy = mat.copy() + assert not np.array_equal(m_ref,m_copy) + + m_const_ref = mat.const_ref() + assert np.array_equal(m_const_ref,m_copy) + assert not np.array_equal(m_const_ref,m_ref) + + m_ref.fill(10.) + assert not np.array_equal(m_ref,m_copy) + assert not np.array_equal(m_const_ref,m_ref) + + try: + m_const_ref.fill(2) + assert True + except: + assert False + rows = 10 cols = 30 @@ -29,6 +51,13 @@ mat = Matrix(rows,cols) row_mat = RowMatrix(rows,cols) vec = Vector(rows,1) -test(mat) -test(row_mat) -test(vec) +test_shared(mat) +test_shared(row_mat) +test_shared(vec) + +return_by_ref.sharedMemory(False) +test_not_shared(mat) +test_not_shared(row_mat) +test_not_shared(vec) + +