diff --git a/.github/workflows/macos-linux-conda.yml b/.github/workflows/macos-linux-conda.yml index e7e55e79b9d67b819c5cc626777347cfa95cb35b..2d6f9659ff721e2e8473a76ed20b8d05a876e567 100644 --- a/.github/workflows/macos-linux-conda.yml +++ b/.github/workflows/macos-linux-conda.yml @@ -1,10 +1,10 @@ -name: CI - EigenPy for Mac OS X/Linux via Conda +name: Conda-CI on: [push,pull_request] jobs: eigenpy-conda: - name: CI on ${{ matrix.os }} via Conda + name: ${{ matrix.os }} - ${{ matrix.build_type }} ${{ matrix.cxx_options }} runs-on: ${{ matrix.os }} env: CCACHE_DIR: /github/home/.ccache # Enable ccache @@ -13,6 +13,17 @@ jobs: fail-fast: false matrix: os: ["ubuntu-latest", "macos-latest"] + cxx_options: ['', '-mavx2'] + build_type: [Release, Debug] + + + exclude: + - build_type: Debug + cxx_options: -mavx2 + os: macos-latest + - build_type: Release + cxx_options: -mavx2 + os: macos-latest steps: - uses: actions/checkout@v2 @@ -29,7 +40,7 @@ jobs: - uses: actions/cache@v2 with: path: ${{ env.CCACHE_DIR }} - key: ccache-${{ matrix.os }} + key: ccache-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_options }} - name: Install cmake and update conda shell: bash -l {0} @@ -47,7 +58,7 @@ jobs: mkdir build cd build - cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3) -DGENERATE_PYTHON_STUBS=ON + cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3) -DGENERATE_PYTHON_STUBS=ON -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_FLAGS=${{ matrix.cxx_options }} make make build_tests export CTEST_OUTPUT_ON_FAILURE=1 diff --git a/CMakeLists.txt b/CMakeLists.txt index da119a1ee92a3113d58f624b5db8f23aa6381436..6f821cc8519e6cf84400c161c2eba22be15fa920 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2022 INRIA +# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2023 INRIA # cmake_minimum_required(VERSION 3.1) @@ -130,6 +130,7 @@ set(${PROJECT_NAME}_HEADERS ${${PROJECT_NAME}_UTILS_HEADERS} ${${PROJECT_NAME}_SOLVERS_HEADERS} ${${PROJECT_NAME}_DECOMPOSITIONS_HEADERS} + include/eigenpy/alignment.hpp include/eigenpy/computation-info.hpp include/eigenpy/eigenpy.hpp include/eigenpy/exception.hpp diff --git a/include/eigenpy/alignment.hpp b/include/eigenpy/alignment.hpp new file mode 100644 index 0000000000000000000000000000000000000000..2e0c9f51d91a82492a9e756a73f1db2bdcd816b8 --- /dev/null +++ b/include/eigenpy/alignment.hpp @@ -0,0 +1,116 @@ +/* + * Copyright 2023, INRIA + */ + +#ifndef __eigenpy_alignment_hpp__ +#define __eigenpy_alignment_hpp__ + +#include <boost/python/detail/referent_storage.hpp> +#include <boost/python/converter/arg_from_python.hpp> +#include <boost/python/converter/rvalue_from_python_data.hpp> +#include <boost/type_traits/aligned_storage.hpp> + +namespace eigenpy { + +template <std::size_t size, std::size_t alignment = EIGENPY_DEFAULT_ALIGN_BYTES> +struct aligned_storage { + union type { + typename ::boost::aligned_storage<size, alignment>::type data; + char bytes[size]; + }; +}; + +} // namespace eigenpy + +namespace boost { +namespace python { +namespace detail { + +template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, + int MaxCols> +struct referent_storage< + Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> { + typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T; + typedef + typename eigenpy::aligned_storage<referent_size<T &>::value>::type type; +}; + +template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, + int MaxCols> +struct referent_storage< + const Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> { + typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T; + typedef + typename eigenpy::aligned_storage<referent_size<T &>::value>::type type; +}; + +template <typename Scalar, int Options> +struct referent_storage<Eigen::Quaternion<Scalar, Options> &> { + typedef Eigen::Quaternion<Scalar, Options> T; + typedef + typename eigenpy::aligned_storage<referent_size<T &>::value>::type type; +}; + +template <typename Scalar, int Options> +struct referent_storage<const Eigen::Quaternion<Scalar, Options> &> { + typedef Eigen::Quaternion<Scalar, Options> T; + typedef + typename eigenpy::aligned_storage<referent_size<T &>::value>::type type; +}; + +} // namespace detail +} // namespace python +} // namespace boost + +namespace eigenpy { + +template <class T> +struct call_destructor { + static void run(void *bytes) { + typedef typename boost::remove_const< + typename boost::remove_reference<T>::type>::type T_; + static_cast<T_ *>((void *)bytes)->~T_(); + } +}; + +template <class T> +struct rvalue_from_python_data + : ::boost::python::converter::rvalue_from_python_storage<T> { +#if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \ + (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \ + !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing \ + this */ + // This must always be a POD struct with m_data its first member. + BOOST_STATIC_ASSERT( + BOOST_PYTHON_OFFSETOF( + ::boost::python::converter::rvalue_from_python_storage<T>, stage1) == + 0); +#endif + + // The usual constructor + rvalue_from_python_data( + ::boost::python::converter::rvalue_from_python_stage1_data const + &_stage1) { + this->stage1 = _stage1; + } + + // This constructor just sets m_convertible -- used by + // implicitly_convertible<> to perform the final step of the + // conversion, where the construct() function is already known. + rvalue_from_python_data(void *convertible) { + this->stage1.convertible = convertible; + } + + // Destroys any object constructed in the storage. + ~rvalue_from_python_data() { + if (this->stage1.convertible == this->storage.bytes) { + void *storage = reinterpret_cast<void *>(this->storage.bytes); + call_destructor<T>::run(storage); + } + } +}; + +} // namespace eigenpy + +#endif // __eigenpy_alignment_hpp__ diff --git a/include/eigenpy/angle-axis.hpp b/include/eigenpy/angle-axis.hpp index 7bfb76e7cfdd4c53347f8bed2ce77a664cacffb9..829195e17e4a85c50bd749c007b673eaee31ff92 100644 --- a/include/eigenpy/angle-axis.hpp +++ b/include/eigenpy/angle-axis.hpp @@ -1,13 +1,10 @@ /* - * Copyright 2014-2020 CNRS INRIA + * Copyright 2014-2023 CNRS INRIA */ #ifndef __eigenpy_angle_axis_hpp__ #define __eigenpy_angle_axis_hpp__ -#include <Eigen/Core> -#include <Eigen/Geometry> - #include "eigenpy/eigenpy.hpp" namespace eigenpy { diff --git a/include/eigenpy/details.hpp b/include/eigenpy/details.hpp index c7923ca5603b743d81c54b04cd5ccecc92f06494..12be4b09465632baf367c7cfb968f0ba56023540 100644 --- a/include/eigenpy/details.hpp +++ b/include/eigenpy/details.hpp @@ -1,59 +1,21 @@ /* * Copyright 2014-2019, CNRS - * Copyright 2018-2020, INRIA + * Copyright 2018-2023, INRIA */ #ifndef __eigenpy_details_hpp__ #define __eigenpy_details_hpp__ +#include "eigenpy/fwd.hpp" #include "eigenpy/eigen-allocator.hpp" #include "eigenpy/eigen-from-python.hpp" #include "eigenpy/eigen-to-python.hpp" #include "eigenpy/eigenpy.hpp" #include "eigenpy/exception.hpp" -#include "eigenpy/fwd.hpp" #include "eigenpy/numpy-type.hpp" #include "eigenpy/registration.hpp" #include "eigenpy/scalar-conversion.hpp" -namespace boost { -namespace python { -namespace detail { - -template <class MatType> -struct referent_size<Eigen::MatrixBase<MatType>&> { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -template <class MatType> -struct referent_size<Eigen::MatrixBase<MatType> > { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -template <class MatType> -struct referent_size<Eigen::EigenBase<MatType>&> { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -template <class MatType> -struct referent_size<Eigen::EigenBase<MatType> > { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -template <class MatType> -struct referent_size<Eigen::PlainObjectBase<MatType>&> { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -template <class MatType> -struct referent_size<Eigen::PlainObjectBase<MatType> > { - BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType)); -}; - -} // namespace detail -} // namespace python -} // namespace boost - namespace eigenpy { template <typename MatType, typename EigenEquivalentType> EIGENPY_DEPRECATED void enableEigenPySpecific() { diff --git a/include/eigenpy/eigen-allocator.hpp b/include/eigenpy/eigen-allocator.hpp index 650da8dd95b0681c07de46fcf9b3291235ce4097..589159d011344df66a5a44c7ab4ee058bc13aa8d 100644 --- a/include/eigenpy/eigen-allocator.hpp +++ b/include/eigenpy/eigen-allocator.hpp @@ -124,6 +124,9 @@ struct EigenAllocator { PyArrayObject *pyArray, boost::python::converter::rvalue_from_python_storage<MatType> *storage) { void *raw_ptr = storage->storage.bytes; + assert(is_aligned(raw_ptr, EIGENPY_DEFAULT_ALIGN_BYTES) && + "The pointer is not aligned."); + Type *mat_ptr = details::init_matrix_or_array<Type>::run(pyArray, raw_ptr); Type &mat = *mat_ptr; diff --git a/include/eigenpy/eigen-from-python.hpp b/include/eigenpy/eigen-from-python.hpp index 71bfebb983333e2f8724d31e75a462884a172727..f03ae268c7f4d1956d24c4cc06a01a05d6ddbf7a 100644 --- a/include/eigenpy/eigen-from-python.hpp +++ b/include/eigenpy/eigen-from-python.hpp @@ -1,14 +1,12 @@ // -// Copyright (c) 2014-2022 CNRS INRIA +// Copyright (c) 2014-2023 CNRS INRIA // #ifndef __eigenpy_eigen_from_python_hpp__ #define __eigenpy_eigen_from_python_hpp__ -#include <boost/python/converter/rvalue_from_python_data.hpp> - -#include "eigenpy/eigen-allocator.hpp" #include "eigenpy/fwd.hpp" +#include "eigenpy/eigen-allocator.hpp" #include "eigenpy/numpy-type.hpp" #include "eigenpy/scalar-conversion.hpp" @@ -67,15 +65,9 @@ struct referent_storage_eigen_ref; template <typename MatType, int Options, typename Stride> struct referent_storage_eigen_ref { typedef Eigen::Ref<MatType, Options, Stride> RefType; -#if BOOST_VERSION / 100 % 1000 >= 77 - typedef typename ::boost::python::detail::aligned_storage< - ::boost::python::detail::referent_size<RefType &>::value, - ::boost::alignment_of<RefType &>::value>::type AlignedStorage; -#else - typedef ::boost::python::detail::aligned_storage< - ::boost::python::detail::referent_size<RefType &>::value> + typedef typename ::eigenpy::aligned_storage< + ::boost::python::detail::referent_size<RefType &>::value>::type AlignedStorage; -#endif referent_storage_eigen_ref() : pyArray(NULL), @@ -121,12 +113,8 @@ struct referent_storage<Eigen::Ref<MatType, Options, Stride> &> { typedef ::eigenpy::details::referent_storage_eigen_ref<MatType, Options, Stride> StorageType; -#if BOOST_VERSION / 100 % 1000 >= 77 - typedef - typename aligned_storage<referent_size<StorageType &>::value>::type type; -#else - typedef aligned_storage<referent_size<StorageType &>::value> type; -#endif + typedef typename ::eigenpy::aligned_storage< + referent_size<StorageType &>::value>::type type; }; template <typename MatType, int Options, typename Stride> @@ -134,13 +122,8 @@ struct referent_storage<const Eigen::Ref<const MatType, Options, Stride> &> { typedef ::eigenpy::details::referent_storage_eigen_ref<const MatType, Options, Stride> StorageType; -#if BOOST_VERSION / 100 % 1000 >= 77 - typedef - typename aligned_storage<referent_size<StorageType &>::value, - alignment_of<StorageType &>::value>::type type; -#else - typedef aligned_storage<referent_size<StorageType &>::value> type; -#endif + typedef typename ::eigenpy::aligned_storage< + referent_size<StorageType &>::value>::type type; }; #endif } // namespace detail @@ -151,69 +134,39 @@ namespace boost { namespace python { namespace converter { -template <typename MatrixReference> -struct rvalue_from_python_data_eigen - : rvalue_from_python_storage<MatrixReference> { - typedef MatrixReference T; - -#if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \ - (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \ - (!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \ - !defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing \ - this */ - // This must always be a POD struct with m_data its first member. - BOOST_STATIC_ASSERT(BOOST_PYTHON_OFFSETOF(rvalue_from_python_storage<T>, - stage1) == 0); -#endif - - // The usual constructor - rvalue_from_python_data_eigen(rvalue_from_python_stage1_data const &_stage1) { - this->stage1 = _stage1; - } - - // This constructor just sets m_convertible -- used by - // implicitly_convertible<> to perform the final step of the - // conversion, where the construct() function is already known. - rvalue_from_python_data_eigen(void *convertible) { - this->stage1.convertible = convertible; - } - - // Destroys any object constructed in the storage. - ~rvalue_from_python_data_eigen() { - typedef typename boost::remove_const< - typename boost::remove_reference<MatrixReference>::type>::type - MatrixType; - if (this->stage1.convertible == this->storage.bytes) - static_cast<MatrixType *>((void *)this->storage.bytes)->~MatrixType(); - } -}; - #define EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(type) \ - typedef rvalue_from_python_data_eigen<type> Base; \ + typedef ::eigenpy::rvalue_from_python_data<type> Base; \ \ rvalue_from_python_data(rvalue_from_python_stage1_data const &_stage1) \ : Base(_stage1) {} \ \ rvalue_from_python_data(void *convertible) : Base(convertible){}; -/// \brief Template specialization of rvalue_from_python_data +template <typename Scalar, int Rows, int Cols, int Options, int MaxRows, + int MaxCols> +struct rvalue_from_python_data< + Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> const &> + : ::eigenpy::rvalue_from_python_data<Eigen::Matrix< + Scalar, Rows, Cols, Options, MaxRows, MaxCols> const &> { + typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T; + EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(T const &) +}; + template <typename Derived> struct rvalue_from_python_data<Eigen::MatrixBase<Derived> const &> - : rvalue_from_python_data_eigen<Derived const &> { + : ::eigenpy::rvalue_from_python_data<Derived const &> { EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived const &) }; -/// \brief Template specialization of rvalue_from_python_data template <typename Derived> struct rvalue_from_python_data<Eigen::EigenBase<Derived> const &> - : rvalue_from_python_data_eigen<Derived const &> { + : ::eigenpy::rvalue_from_python_data<Derived const &> { EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived const &) }; -/// \brief Template specialization of rvalue_from_python_data template <typename Derived> struct rvalue_from_python_data<Eigen::PlainObjectBase<Derived> const &> - : rvalue_from_python_data_eigen<Derived const &> { + : ::eigenpy::rvalue_from_python_data<Derived const &> { EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Derived const &) }; diff --git a/include/eigenpy/eigen-to-python.hpp b/include/eigenpy/eigen-to-python.hpp index 5c6f5838ac29bb689eb1ef93e252efb401b9aec7..6472ff6c7939f9c7f1eb842ec8a0feb31468a564 100644 --- a/include/eigenpy/eigen-to-python.hpp +++ b/include/eigenpy/eigen-to-python.hpp @@ -7,8 +7,9 @@ #include <boost/type_traits.hpp> -#include "eigenpy/eigen-allocator.hpp" #include "eigenpy/fwd.hpp" + +#include "eigenpy/eigen-allocator.hpp" #include "eigenpy/numpy-allocator.hpp" #include "eigenpy/numpy-type.hpp" diff --git a/include/eigenpy/eigenpy.hpp b/include/eigenpy/eigenpy.hpp index 015b9f2cf77fa5d2089bcd39ba204b55dcc7a64f..57657466f113084004a159eaf018b62209f30304 100644 --- a/include/eigenpy/eigenpy.hpp +++ b/include/eigenpy/eigenpy.hpp @@ -6,9 +6,9 @@ #ifndef __eigenpy_eigenpy_hpp__ #define __eigenpy_eigenpy_hpp__ +#include "eigenpy/fwd.hpp" #include "eigenpy/deprecated.hpp" #include "eigenpy/eigen-typedef.hpp" -#include "eigenpy/fwd.hpp" #define ENABLE_SPECIFIC_MATRIX_TYPE(TYPE) \ ::eigenpy::enableEigenPySpecific<TYPE>(); diff --git a/include/eigenpy/fwd.hpp b/include/eigenpy/fwd.hpp index d1ddd249ac3a1e7e35f1340762fe995d1c69db46..0e2c54c736aafccc60f035cf125521276a7afab3 100644 --- a/include/eigenpy/fwd.hpp +++ b/include/eigenpy/fwd.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2014-2020 CNRS INRIA + * Copyright 2014-2023 CNRS INRIA */ #ifndef __eigenpy_fwd_hpp__ @@ -21,6 +21,7 @@ #undef BOOST_BIND_GLOBAL_PLACEHOLDERS #include <Eigen/Core> +#include <Eigen/Geometry> #if EIGEN_VERSION_AT_LEAST(3, 2, 90) #define EIGENPY_DEFAULT_ALIGNMENT_VALUE Eigen::Aligned16 @@ -28,6 +29,8 @@ #define EIGENPY_DEFAULT_ALIGNMENT_VALUE Eigen::Aligned #endif +#define EIGENPY_DEFAULT_ALIGN_BYTES EIGEN_DEFAULT_ALIGN_BYTES + #define EIGENPY_NO_ALIGNMENT_VALUE Eigen::Unaligned #define EIGENPY_UNUSED_VARIABLE(var) (void)(var) @@ -45,4 +48,6 @@ template <typename MatType, struct EigenFromPy; } // namespace eigenpy +#include "eigenpy/alignment.hpp" + #endif // ifndef __eigenpy_fwd_hpp__ diff --git a/include/eigenpy/geometry-conversion.hpp b/include/eigenpy/geometry-conversion.hpp index f2dcbbabc28007fad8bf7625fd028ed60b06bdbe..37b583fd7e03d7911280d0cd456db3950f4ecffa 100644 --- a/include/eigenpy/geometry-conversion.hpp +++ b/include/eigenpy/geometry-conversion.hpp @@ -1,13 +1,11 @@ /* * Copyright 2014-2019, CNRS - * Copyright 2018-2021, INRIA + * Copyright 2018-2023, INRIA */ #ifndef __eigenpy_geometry_conversion_hpp__ #define __eigenpy_geometry_conversion_hpp__ -#include <Eigen/Geometry> - #include "eigenpy/fwd.hpp" namespace eigenpy { diff --git a/include/eigenpy/memory.hpp b/include/eigenpy/memory.hpp index 447694e419dba3db69f1e0e13bb4cb578a8ab0a7..5eaf0a2a7dc733e1f0cb13130e926579f276ae40 100644 --- a/include/eigenpy/memory.hpp +++ b/include/eigenpy/memory.hpp @@ -42,7 +42,7 @@ static inline void _Py_SET_SIZE(PyVarObject* ob, Py_ssize_t size) { \ union { \ align_t align; \ - char bytes[sizeof(Data) + 16]; \ + char bytes[sizeof(Data) + EIGENPY_DEFAULT_ALIGN_BYTES]; \ } storage; \ }; \ \ @@ -96,7 +96,9 @@ static inline void _Py_SET_SIZE(PyVarObject* ob, Py_ssize_t size) { void* storage, PyObject* instance, \ reference_wrapper<__VA_ARGS__ const> x) { \ void* aligned_storage = reinterpret_cast<void*>( \ - (reinterpret_cast<size_t>(storage) & ~(size_t(15))) + 16); \ + (reinterpret_cast<size_t>(storage) & \ + ~(size_t(EIGENPY_DEFAULT_ALIGN_BYTES - 1))) + \ + EIGENPY_DEFAULT_ALIGN_BYTES); \ value_holder<__VA_ARGS__>* new_holder = \ new (aligned_storage) value_holder<__VA_ARGS__>(instance, x); \ return new_holder; \ diff --git a/include/eigenpy/quaternion.hpp b/include/eigenpy/quaternion.hpp index 88f899db18bb49c829998424a6c87dbb6507371d..241eefec9e8021022ade16512525af9562539eb0 100644 --- a/include/eigenpy/quaternion.hpp +++ b/include/eigenpy/quaternion.hpp @@ -1,15 +1,13 @@ /* - * Copyright 2014-2022 CNRS INRIA + * Copyright 2014-2023 CNRS INRIA */ #ifndef __eigenpy_quaternion_hpp__ #define __eigenpy_quaternion_hpp__ -#include <Eigen/Core> -#include <Eigen/Geometry> - #include "eigenpy/eigenpy.hpp" #include "eigenpy/exception.hpp" +#include "eigenpy/eigen-from-python.hpp" namespace boost { namespace python { @@ -18,7 +16,7 @@ namespace converter { /// \brief Template specialization of rvalue_from_python_data template <typename Quaternion> struct rvalue_from_python_data<Eigen::QuaternionBase<Quaternion> const&> - : rvalue_from_python_data_eigen<Quaternion const&> { + : ::eigenpy::rvalue_from_python_data<Quaternion const&> { EIGENPY_RVALUE_FROM_PYTHON_DATA_INIT(Quaternion const&) }; diff --git a/include/eigenpy/std-vector.hpp b/include/eigenpy/std-vector.hpp index cb6d869e0ff4d2d84f719b33fa5d6ae37c8b352d..eddf03ecfeaeb599b9497d81781edb906b15c47b 100644 --- a/include/eigenpy/std-vector.hpp +++ b/include/eigenpy/std-vector.hpp @@ -14,6 +14,7 @@ #include <string> #include <vector> +#include "eigenpy/eigenpy.hpp" #include "eigenpy/config.hpp" #include "eigenpy/copyable.hpp" #include "eigenpy/eigen-to-python.hpp" @@ -445,7 +446,7 @@ void EIGENPY_DLLAPI exposeStdVector(); template <typename MatType> void exposeStdVectorEigenSpecificType(const char *name) { - typedef std::vector<MatType> VecMatType; + typedef std::vector<MatType, Eigen::aligned_allocator<MatType> > VecMatType; std::string full_name = "StdVec_"; full_name += name; StdVectorPythonVisitor<VecMatType, false>::expose( diff --git a/python/main.cpp b/python/main.cpp index 9c5b49a82b7ca9066f1aedf41913374d3d5f4f4b..03bc2f2052f9251bbade21518d33880d7fe68096 100644 --- a/python/main.cpp +++ b/python/main.cpp @@ -28,6 +28,9 @@ BOOST_PYTHON_MODULE(eigenpy_pywrap) { "Checks if the current version of EigenPy is at least the version " "provided by the input arguments."); + bp::def("SimdInstructionSetsInUse", &Eigen::SimdInstructionSetsInUse, + "Get the set of SIMD instructions in use with Eigen."); + exposeAngleAxis(); exposeQuaternion(); exposeGeometryConversion(); diff --git a/unittest/geometry.cpp b/unittest/geometry.cpp index 8819e40952009df1bdf28123c38148959903b9b3..da9f41d4f70fd51bf0827d778c6c6654084f5442 100644 --- a/unittest/geometry.cpp +++ b/unittest/geometry.cpp @@ -1,14 +1,10 @@ /* * Copyright 2014-2019, CNRS - * Copyright 2018-2019, INRIA + * Copyright 2018-2023, INRIA */ -#include "eigenpy/geometry.hpp" - -#include <Eigen/Geometry> -#include <iostream> - #include "eigenpy/eigenpy.hpp" +#include "eigenpy/geometry.hpp" namespace bp = boost::python; diff --git a/unittest/python/test_geometry.py b/unittest/python/test_geometry.py index c2bd1b1addced6caa76040b320a672d30ba74dfc..cbcdc8ec5d50881d48cc3e207e595f52104753b2 100644 --- a/unittest/python/test_geometry.py +++ b/unittest/python/test_geometry.py @@ -32,7 +32,8 @@ assert isapprox(np.linalg.norm(q.coeffs()), 1) # Coefficient-vector initialisation verbose and print("[Quaternion] Coefficient-vector initialisation") v = np.array([0.5, -0.5, 0.5, 0.5]) -qv = Quaternion(v) +for k in range(10000): + qv = Quaternion(v) assert isapprox(qv.coeffs(), v) # Angle axis initialisation diff --git a/unittest/python/test_std_vector.py b/unittest/python/test_std_vector.py index 52fd4c0d3cb623d178831f60f12e0551c1147959..8cd6ab76887e52ce95128c61edb4e00651379ddf 100644 --- a/unittest/python/test_std_vector.py +++ b/unittest/python/test_std_vector.py @@ -53,8 +53,8 @@ def checkZero(l): print("Check setZero() works:") -print("l1:") std_vector.setZero(l1) +print("l1:") print(l1) checkZero(l1) print("-----------------") diff --git a/unittest/std_vector.cpp b/unittest/std_vector.cpp index a3679917a61916f761d0202755f935192cd2a442..12bb9e2cecf88b0a8b451d6685c03bc3f2e7a692 100644 --- a/unittest/std_vector.cpp +++ b/unittest/std_vector.cpp @@ -7,22 +7,26 @@ #include "eigenpy/eigen-from-python.hpp" #include "eigenpy/std-vector.hpp" -template <typename MatType> -void printVectorOfMatrix(const std::vector<MatType> &Ms) { +template <typename MatType, + typename Allocator = Eigen::aligned_allocator<MatType> > +void printVectorOfMatrix(const std::vector<MatType, Allocator> &Ms) { const std::size_t n = Ms.size(); for (std::size_t i = 0; i < n; i++) { std::cout << "el[" << i << "] =\n" << Ms[i] << '\n'; } } -template <typename MatType> -std::vector<MatType> copy(const std::vector<MatType> &Ms) { - std::vector<MatType> out = Ms; +template <typename MatType, + typename Allocator = Eigen::aligned_allocator<MatType> > +std::vector<MatType, Allocator> copy( + const std::vector<MatType, Allocator> &Ms) { + std::vector<MatType, Allocator> out = Ms; return out; } -template <typename MatType> -void setZero(std::vector<MatType> &Ms) { +template <typename MatType, + typename Allocator = Eigen::aligned_allocator<MatType> > +void setZero(std::vector<MatType, Allocator> &Ms) { for (std::size_t i = 0; i < Ms.size(); i++) { Ms[i].setZero(); }