Skip to content

Commit 0e774e6

Browse files
authored
Merge pull request #336 from jcarpent/devel
Add full support of vectorization
2 parents 46cbde7 + d981456 commit 0e774e6

19 files changed

+199
-147
lines changed

.github/workflows/macos-linux-conda.yml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
name: CI - EigenPy for Mac OS X/Linux via Conda
1+
name: Conda-CI
22

33
on: [push,pull_request]
44

55
jobs:
66
eigenpy-conda:
7-
name: CI on ${{ matrix.os }} via Conda
7+
name: ${{ matrix.os }} - ${{ matrix.build_type }} ${{ matrix.cxx_options }}
88
runs-on: ${{ matrix.os }}
99
env:
1010
CCACHE_DIR: /github/home/.ccache # Enable ccache
@@ -13,6 +13,17 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os: ["ubuntu-latest", "macos-latest"]
16+
cxx_options: ['', '-mavx2']
17+
build_type: [Release, Debug]
18+
19+
20+
exclude:
21+
- build_type: Debug
22+
cxx_options: -mavx2
23+
os: macos-latest
24+
- build_type: Release
25+
cxx_options: -mavx2
26+
os: macos-latest
1627

1728
steps:
1829
- uses: actions/checkout@v2
@@ -29,7 +40,7 @@ jobs:
2940
- uses: actions/cache@v2
3041
with:
3142
path: ${{ env.CCACHE_DIR }}
32-
key: ccache-${{ matrix.os }}
43+
key: ccache-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_options }}
3344

3445
- name: Install cmake and update conda
3546
shell: bash -l {0}
@@ -47,7 +58,7 @@ jobs:
4758
mkdir build
4859
cd build
4960
50-
cmake .. -DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=$(which python3) -DGENERATE_PYTHON_STUBS=ON
61+
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 }}
5162
make
5263
make build_tests
5364
export CTEST_OUTPUT_ON_FAILURE=1

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2022 INRIA
2+
# Copyright (c) 2014-2019 CNRS Copyright (c) 2018-2023 INRIA
33
#
44

55
cmake_minimum_required(VERSION 3.1)
@@ -130,6 +130,7 @@ set(${PROJECT_NAME}_HEADERS
130130
${${PROJECT_NAME}_UTILS_HEADERS}
131131
${${PROJECT_NAME}_SOLVERS_HEADERS}
132132
${${PROJECT_NAME}_DECOMPOSITIONS_HEADERS}
133+
include/eigenpy/alignment.hpp
133134
include/eigenpy/computation-info.hpp
134135
include/eigenpy/eigenpy.hpp
135136
include/eigenpy/exception.hpp

include/eigenpy/alignment.hpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright 2023, INRIA
3+
*/
4+
5+
#ifndef __eigenpy_alignment_hpp__
6+
#define __eigenpy_alignment_hpp__
7+
8+
#include <boost/python/detail/referent_storage.hpp>
9+
#include <boost/python/converter/arg_from_python.hpp>
10+
#include <boost/python/converter/rvalue_from_python_data.hpp>
11+
#include <boost/type_traits/aligned_storage.hpp>
12+
13+
namespace eigenpy {
14+
15+
template <std::size_t size, std::size_t alignment = EIGENPY_DEFAULT_ALIGN_BYTES>
16+
struct aligned_storage {
17+
union type {
18+
typename ::boost::aligned_storage<size, alignment>::type data;
19+
char bytes[size];
20+
};
21+
};
22+
23+
} // namespace eigenpy
24+
25+
namespace boost {
26+
namespace python {
27+
namespace detail {
28+
29+
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
30+
int MaxCols>
31+
struct referent_storage<
32+
Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> {
33+
typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T;
34+
typedef
35+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
36+
};
37+
38+
template <typename Scalar, int Rows, int Cols, int Options, int MaxRows,
39+
int MaxCols>
40+
struct referent_storage<
41+
const Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> &> {
42+
typedef Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> T;
43+
typedef
44+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
45+
};
46+
47+
template <typename Scalar, int Options>
48+
struct referent_storage<Eigen::Quaternion<Scalar, Options> &> {
49+
typedef Eigen::Quaternion<Scalar, Options> T;
50+
typedef
51+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
52+
};
53+
54+
template <typename Scalar, int Options>
55+
struct referent_storage<const Eigen::Quaternion<Scalar, Options> &> {
56+
typedef Eigen::Quaternion<Scalar, Options> T;
57+
typedef
58+
typename eigenpy::aligned_storage<referent_size<T &>::value>::type type;
59+
};
60+
61+
} // namespace detail
62+
} // namespace python
63+
} // namespace boost
64+
65+
namespace eigenpy {
66+
67+
template <class T>
68+
struct call_destructor {
69+
static void run(void *bytes) {
70+
typedef typename boost::remove_const<
71+
typename boost::remove_reference<T>::type>::type T_;
72+
static_cast<T_ *>((void *)bytes)->~T_();
73+
}
74+
};
75+
76+
template <class T>
77+
struct rvalue_from_python_data
78+
: ::boost::python::converter::rvalue_from_python_storage<T> {
79+
#if (!defined(__MWERKS__) || __MWERKS__ >= 0x3000) && \
80+
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 245) && \
81+
(!defined(__DECCXX_VER) || __DECCXX_VER > 60590014) && \
82+
!defined(BOOST_PYTHON_SYNOPSIS) /* Synopsis' OpenCXX has trouble parsing \
83+
this */
84+
// This must always be a POD struct with m_data its first member.
85+
BOOST_STATIC_ASSERT(
86+
BOOST_PYTHON_OFFSETOF(
87+
::boost::python::converter::rvalue_from_python_storage<T>, stage1) ==
88+
0);
89+
#endif
90+
91+
// The usual constructor
92+
rvalue_from_python_data(
93+
::boost::python::converter::rvalue_from_python_stage1_data const
94+
&_stage1) {
95+
this->stage1 = _stage1;
96+
}
97+
98+
// This constructor just sets m_convertible -- used by
99+
// implicitly_convertible<> to perform the final step of the
100+
// conversion, where the construct() function is already known.
101+
rvalue_from_python_data(void *convertible) {
102+
this->stage1.convertible = convertible;
103+
}
104+
105+
// Destroys any object constructed in the storage.
106+
~rvalue_from_python_data() {
107+
if (this->stage1.convertible == this->storage.bytes) {
108+
void *storage = reinterpret_cast<void *>(this->storage.bytes);
109+
call_destructor<T>::run(storage);
110+
}
111+
}
112+
};
113+
114+
} // namespace eigenpy
115+
116+
#endif // __eigenpy_alignment_hpp__

include/eigenpy/angle-axis.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
/*
2-
* Copyright 2014-2020 CNRS INRIA
2+
* Copyright 2014-2023 CNRS INRIA
33
*/
44

55
#ifndef __eigenpy_angle_axis_hpp__
66
#define __eigenpy_angle_axis_hpp__
77

8-
#include <Eigen/Core>
9-
#include <Eigen/Geometry>
10-
118
#include "eigenpy/eigenpy.hpp"
129

1310
namespace eigenpy {

include/eigenpy/details.hpp

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,21 @@
11
/*
22
* Copyright 2014-2019, CNRS
3-
* Copyright 2018-2020, INRIA
3+
* Copyright 2018-2023, INRIA
44
*/
55

66
#ifndef __eigenpy_details_hpp__
77
#define __eigenpy_details_hpp__
88

9+
#include "eigenpy/fwd.hpp"
910
#include "eigenpy/eigen-allocator.hpp"
1011
#include "eigenpy/eigen-from-python.hpp"
1112
#include "eigenpy/eigen-to-python.hpp"
1213
#include "eigenpy/eigenpy.hpp"
1314
#include "eigenpy/exception.hpp"
14-
#include "eigenpy/fwd.hpp"
1515
#include "eigenpy/numpy-type.hpp"
1616
#include "eigenpy/registration.hpp"
1717
#include "eigenpy/scalar-conversion.hpp"
1818

19-
namespace boost {
20-
namespace python {
21-
namespace detail {
22-
23-
template <class MatType>
24-
struct referent_size<Eigen::MatrixBase<MatType>&> {
25-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
26-
};
27-
28-
template <class MatType>
29-
struct referent_size<Eigen::MatrixBase<MatType> > {
30-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
31-
};
32-
33-
template <class MatType>
34-
struct referent_size<Eigen::EigenBase<MatType>&> {
35-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
36-
};
37-
38-
template <class MatType>
39-
struct referent_size<Eigen::EigenBase<MatType> > {
40-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
41-
};
42-
43-
template <class MatType>
44-
struct referent_size<Eigen::PlainObjectBase<MatType>&> {
45-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
46-
};
47-
48-
template <class MatType>
49-
struct referent_size<Eigen::PlainObjectBase<MatType> > {
50-
BOOST_STATIC_CONSTANT(std::size_t, value = sizeof(MatType));
51-
};
52-
53-
} // namespace detail
54-
} // namespace python
55-
} // namespace boost
56-
5719
namespace eigenpy {
5820
template <typename MatType, typename EigenEquivalentType>
5921
EIGENPY_DEPRECATED void enableEigenPySpecific() {

include/eigenpy/eigen-allocator.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ struct EigenAllocator {
124124
PyArrayObject *pyArray,
125125
boost::python::converter::rvalue_from_python_storage<MatType> *storage) {
126126
void *raw_ptr = storage->storage.bytes;
127+
assert(is_aligned(raw_ptr, EIGENPY_DEFAULT_ALIGN_BYTES) &&
128+
"The pointer is not aligned.");
129+
127130
Type *mat_ptr = details::init_matrix_or_array<Type>::run(pyArray, raw_ptr);
128131
Type &mat = *mat_ptr;
129132

0 commit comments

Comments
 (0)