Directory: | ./ |
---|---|
File: | include/pinocchio/serialization/eigen.hpp |
Date: | 2025-02-12 21:03:38 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 36 | 36 | 100.0% |
Branches: | 23 | 44 | 52.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | // | ||
2 | // Copyright (c) 2017-2020 CNRS INRIA | ||
3 | // | ||
4 | |||
5 | #ifndef __pinocchio_serialization_eigen_matrix_hpp__ | ||
6 | #define __pinocchio_serialization_eigen_matrix_hpp__ | ||
7 | |||
8 | #include <Eigen/Dense> | ||
9 | #include "pinocchio/math/tensor.hpp" | ||
10 | |||
11 | #include <boost/serialization/split_free.hpp> | ||
12 | #include <boost/serialization/vector.hpp> | ||
13 | #include <boost/serialization/array.hpp> | ||
14 | |||
15 | // If hpp-fcl < 3.0.0 The GCC Eigen/Boost.Serialization workaround | ||
16 | // is already defined. | ||
17 | // If we don't link against hpp-fcl or hpp-fcl >= 3.0.0 then we must define | ||
18 | // the workaround. | ||
19 | #if defined PINOCCHIO_WITH_HPP_FCL | ||
20 | #include <hpp/fcl/config.hh> | ||
21 | #if !HPP_FCL_VERSION_AT_LEAST(3, 0, 0) // hpp-fcl < 3.0.0 | ||
22 | #define HPP_FCL_SKIP_EIGEN_BOOST_SERIALIZATION | ||
23 | #include <hpp/fcl/serialization/eigen.h> | ||
24 | #else // hpp-fcl >= 3.0.0 | ||
25 | // Workaround a bug in GCC >= 7 and C++17. | ||
26 | // ref. https://gitlab.com/libeigen/eigen/-/issues/1676 | ||
27 | #ifdef __GNUC__ | ||
28 | #if __GNUC__ >= 7 && __cplusplus >= 201703L | ||
29 | namespace boost | ||
30 | { | ||
31 | namespace serialization | ||
32 | { | ||
33 | struct U; | ||
34 | } | ||
35 | } // namespace boost | ||
36 | namespace Eigen | ||
37 | { | ||
38 | namespace internal | ||
39 | { | ||
40 | template<> | ||
41 | struct traits<boost::serialization::U> | ||
42 | { | ||
43 | enum | ||
44 | { | ||
45 | Flags = 0 | ||
46 | }; | ||
47 | }; | ||
48 | } // namespace internal | ||
49 | } // namespace Eigen | ||
50 | #endif | ||
51 | #endif | ||
52 | #endif | ||
53 | #else // !PINOCCHIO_WITH_HPP_FCL | ||
54 | // Workaround a bug in GCC >= 7 and C++17. | ||
55 | // ref. https://gitlab.com/libeigen/eigen/-/issues/1676 | ||
56 | #ifdef __GNUC__ | ||
57 | #if __GNUC__ >= 7 && __cplusplus >= 201703L | ||
58 | namespace boost | ||
59 | { | ||
60 | namespace serialization | ||
61 | { | ||
62 | struct U; | ||
63 | } | ||
64 | } // namespace boost | ||
65 | namespace Eigen | ||
66 | { | ||
67 | namespace internal | ||
68 | { | ||
69 | template<> | ||
70 | struct traits<boost::serialization::U> | ||
71 | { | ||
72 | enum | ||
73 | { | ||
74 | Flags = 0 | ||
75 | }; | ||
76 | }; | ||
77 | } // namespace internal | ||
78 | } // namespace Eigen | ||
79 | #endif | ||
80 | #endif | ||
81 | #endif | ||
82 | |||
83 | // Similar workaround but for MSVC when C++17 is enabled. | ||
84 | // TODO Find _MSC_VER range. | ||
85 | #if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703) | ||
86 | namespace boost | ||
87 | { | ||
88 | namespace archive | ||
89 | { | ||
90 | class binary_iarchive; | ||
91 | class xml_iarchive; | ||
92 | class text_iarchive; | ||
93 | } // namespace archive | ||
94 | } // namespace boost | ||
95 | namespace Eigen | ||
96 | { | ||
97 | namespace internal | ||
98 | { | ||
99 | template<> | ||
100 | struct traits<boost::archive::binary_iarchive> | ||
101 | { | ||
102 | enum | ||
103 | { | ||
104 | Flags = 0 | ||
105 | }; | ||
106 | }; | ||
107 | template<> | ||
108 | struct traits<boost::archive::xml_iarchive> | ||
109 | { | ||
110 | enum | ||
111 | { | ||
112 | Flags = 0 | ||
113 | }; | ||
114 | }; | ||
115 | template<> | ||
116 | struct traits<boost::archive::text_iarchive> | ||
117 | { | ||
118 | enum | ||
119 | { | ||
120 | Flags = 0 | ||
121 | }; | ||
122 | }; | ||
123 | } // namespace internal | ||
124 | } // namespace Eigen | ||
125 | #endif // MSVC with C++17 | ||
126 | |||
127 | namespace boost | ||
128 | { | ||
129 | namespace serialization | ||
130 | { | ||
131 | |||
132 | template< | ||
133 | class Archive, | ||
134 | typename Scalar, | ||
135 | int Rows, | ||
136 | int Cols, | ||
137 | int Options, | ||
138 | int MaxRows, | ||
139 | int MaxCols> | ||
140 | 2773332 | void save( | |
141 | Archive & ar, | ||
142 | const Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & m, | ||
143 | const unsigned int /*version*/) | ||
144 | { | ||
145 | 2773332 | Eigen::DenseIndex rows(m.rows()), cols(m.cols()); | |
146 | if (Rows == Eigen::Dynamic) | ||
147 |
1/2✓ Branch 2 taken 506 times.
✗ Branch 3 not taken.
|
1012 | ar & BOOST_SERIALIZATION_NVP(rows); |
148 | if (Cols == Eigen::Dynamic) | ||
149 |
1/2✓ Branch 2 taken 642 times.
✗ Branch 3 not taken.
|
1284 | ar & BOOST_SERIALIZATION_NVP(cols); |
150 |
5/9✓ Branch 2 taken 834751 times.
✓ Branch 3 taken 551915 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 834608 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 552058 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 834608 times.
✗ Branch 10 not taken.
|
2773332 | ar & make_nvp("data", make_array(m.data(), (size_t)m.size())); |
151 | } | ||
152 | |||
153 | template< | ||
154 | class Archive, | ||
155 | typename Scalar, | ||
156 | int Rows, | ||
157 | int Cols, | ||
158 | int Options, | ||
159 | int MaxRows, | ||
160 | int MaxCols> | ||
161 | 2773278 | void load( | |
162 | Archive & ar, | ||
163 | Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & m, | ||
164 | const unsigned int /*version*/) | ||
165 | { | ||
166 | 2773278 | Eigen::DenseIndex rows = Rows, cols = Cols; | |
167 | if (Rows == Eigen::Dynamic) | ||
168 |
1/2✓ Branch 2 taken 479 times.
✗ Branch 3 not taken.
|
958 | ar >> BOOST_SERIALIZATION_NVP(rows); |
169 | if (Cols == Eigen::Dynamic) | ||
170 |
1/2✓ Branch 2 taken 642 times.
✗ Branch 3 not taken.
|
1284 | ar >> BOOST_SERIALIZATION_NVP(cols); |
171 |
1/2✓ Branch 1 taken 1386639 times.
✗ Branch 2 not taken.
|
2773278 | m.resize(rows, cols); |
172 |
5/9✓ Branch 2 taken 1409 times.
✓ Branch 3 taken 1385146 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1434 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1385205 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1350 times.
✗ Branch 10 not taken.
|
2773278 | ar >> make_nvp("data", make_array(m.data(), (size_t)m.size())); |
173 | } | ||
174 | |||
175 | template< | ||
176 | class Archive, | ||
177 | typename Scalar, | ||
178 | int Rows, | ||
179 | int Cols, | ||
180 | int Options, | ||
181 | int MaxRows, | ||
182 | int MaxCols> | ||
183 | 5546610 | void serialize( | |
184 | Archive & ar, | ||
185 | Eigen::Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> & m, | ||
186 | const unsigned int version) | ||
187 | { | ||
188 | 5546610 | split_free(ar, m, version); | |
189 | } | ||
190 | |||
191 | template<class Archive, typename PlainObjectBase, int MapOptions, typename StrideType> | ||
192 | void save( | ||
193 | Archive & ar, | ||
194 | const Eigen::Map<PlainObjectBase, MapOptions, StrideType> & m, | ||
195 | const unsigned int /*version*/) | ||
196 | { | ||
197 | Eigen::DenseIndex rows(m.rows()), cols(m.cols()); | ||
198 | if (PlainObjectBase::RowsAtCompileTime == Eigen::Dynamic) | ||
199 | ar & BOOST_SERIALIZATION_NVP(rows); | ||
200 | if (PlainObjectBase::ColsAtCompileTime == Eigen::Dynamic) | ||
201 | ar & BOOST_SERIALIZATION_NVP(cols); | ||
202 | ar & make_nvp("data", make_array(m.data(), (size_t)m.size())); | ||
203 | } | ||
204 | |||
205 | template<class Archive, typename PlainObjectBase, int MapOptions, typename StrideType> | ||
206 | void load( | ||
207 | Archive & ar, | ||
208 | Eigen::Map<PlainObjectBase, MapOptions, StrideType> & m, | ||
209 | const unsigned int /*version*/) | ||
210 | { | ||
211 | Eigen::DenseIndex rows = PlainObjectBase::RowsAtCompileTime, | ||
212 | cols = PlainObjectBase::ColsAtCompileTime; | ||
213 | if (PlainObjectBase::RowsAtCompileTime == Eigen::Dynamic) | ||
214 | ar >> BOOST_SERIALIZATION_NVP(rows); | ||
215 | if (PlainObjectBase::ColsAtCompileTime == Eigen::Dynamic) | ||
216 | ar >> BOOST_SERIALIZATION_NVP(cols); | ||
217 | m.resize(rows, cols); | ||
218 | ar >> make_nvp("data", make_array(m.data(), (size_t)m.size())); | ||
219 | } | ||
220 | |||
221 | template<class Archive, typename PlainObjectBase, int MapOptions, typename StrideType> | ||
222 | void serialize( | ||
223 | Archive & ar, | ||
224 | Eigen::Map<PlainObjectBase, MapOptions, StrideType> & m, | ||
225 | const unsigned int version) | ||
226 | { | ||
227 | split_free(ar, m, version); | ||
228 | } | ||
229 | |||
230 | #if !defined(PINOCCHIO_WITH_EIGEN_TENSOR_MODULE) \ | ||
231 | && ((__cplusplus <= 199711L && EIGEN_COMP_MSVC < 1900) || defined(__CUDACC__) || defined(EIGEN_AVOID_STL_ARRAY)) | ||
232 | template<class Archive, typename _IndexType, std::size_t _NumIndices> | ||
233 | void save( | ||
234 | Archive & ar, const Eigen::array<_IndexType, _NumIndices> & a, const unsigned int /*version*/) | ||
235 | { | ||
236 | ar & make_nvp("array", make_array(&a.front(), _NumIndices)); | ||
237 | } | ||
238 | |||
239 | template<class Archive, typename _IndexType, std::size_t _NumIndices> | ||
240 | void | ||
241 | load(Archive & ar, Eigen::array<_IndexType, _NumIndices> & a, const unsigned int /*version*/) | ||
242 | { | ||
243 | ar >> make_nvp("array", make_array(&a.front(), _NumIndices)); | ||
244 | } | ||
245 | |||
246 | template<class Archive, typename _IndexType, std::size_t _NumIndices> | ||
247 | void | ||
248 | serialize(Archive & ar, Eigen::array<_IndexType, _NumIndices> & a, const unsigned int version) | ||
249 | { | ||
250 | split_free(ar, a, version); | ||
251 | } | ||
252 | #else | ||
253 | template<class Archive, class T, std::size_t N> | ||
254 | 94 | void save(Archive & ar, const std::array<T, N> & a, const unsigned int version) | |
255 | { | ||
256 | typedef std::array<T, N> Array; | ||
257 | 94 | serialize(ar, const_cast<Array &>(a), version); | |
258 | 94 | } | |
259 | |||
260 | template<class Archive, class T, std::size_t N> | ||
261 | 94 | void load(Archive & ar, std::array<T, N> & a, const unsigned int version) | |
262 | { | ||
263 | 94 | serialize(ar, a, version); | |
264 | 94 | } | |
265 | #endif | ||
266 | |||
267 | #ifdef PINOCCHIO_WITH_EIGEN_TENSOR_MODULE | ||
268 | |||
269 | template<class Archive, typename _IndexType, int _NumIndices> | ||
270 | void save( | ||
271 | Archive & ar, const Eigen::DSizes<_IndexType, _NumIndices> & ds, const unsigned int version) | ||
272 | { | ||
273 | save(ar, static_cast<const Eigen::array<_IndexType, _NumIndices> &>(ds), version); | ||
274 | } | ||
275 | |||
276 | template<class Archive, typename _IndexType, int _NumIndices> | ||
277 | void load(Archive & ar, Eigen::DSizes<_IndexType, _NumIndices> & ds, const unsigned int version) | ||
278 | { | ||
279 | load(ar, static_cast<Eigen::array<_IndexType, _NumIndices> &>(ds), version); | ||
280 | } | ||
281 | |||
282 | template<class Archive, typename _IndexType, int _NumIndices> | ||
283 | void | ||
284 | 188 | serialize(Archive & ar, Eigen::DSizes<_IndexType, _NumIndices> & ds, const unsigned int version) | |
285 | { | ||
286 | 188 | split_free(ar, static_cast<Eigen::array<_IndexType, _NumIndices> &>(ds), version); | |
287 | 188 | } | |
288 | |||
289 | #endif | ||
290 | |||
291 | template<class Archive, typename _Scalar, int _NumIndices, int _Options, typename _IndexType> | ||
292 | 94 | void save( | |
293 | Archive & ar, | ||
294 | const ::pinocchio::Tensor<_Scalar, _NumIndices, _Options, _IndexType> & t, | ||
295 | const unsigned int /*version*/) | ||
296 | { | ||
297 | typedef ::pinocchio::Tensor<_Scalar, _NumIndices, _Options, _IndexType> Tensor; | ||
298 | 94 | const typename Tensor::Dimensions & dimensions = t.dimensions(); | |
299 | |||
300 |
1/2✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
|
94 | ar & BOOST_SERIALIZATION_NVP(dimensions); |
301 |
1/2✓ Branch 5 taken 47 times.
✗ Branch 6 not taken.
|
94 | ar & make_nvp("data", make_array(t.data(), (size_t)t.size())); |
302 | 94 | } | |
303 | |||
304 | template<class Archive, typename _Scalar, int _NumIndices, int _Options, typename _IndexType> | ||
305 | 94 | void load( | |
306 | Archive & ar, | ||
307 | ::pinocchio::Tensor<_Scalar, _NumIndices, _Options, _IndexType> & t, | ||
308 | const unsigned int /*version*/) | ||
309 | { | ||
310 | typedef ::pinocchio::Tensor<_Scalar, _NumIndices, _Options, _IndexType> Tensor; | ||
311 | 94 | typename Tensor::Dimensions dimensions; | |
312 | |||
313 |
1/2✓ Branch 2 taken 47 times.
✗ Branch 3 not taken.
|
94 | ar >> BOOST_SERIALIZATION_NVP(dimensions); |
314 |
1/2✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
|
94 | t.resize(dimensions); |
315 | |||
316 |
4/8✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 47 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 47 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 47 times.
✗ Branch 12 not taken.
|
94 | ar >> make_nvp("data", make_array(t.data(), (size_t)t.size())); |
317 | 94 | } | |
318 | |||
319 | template<class Archive, typename _Scalar, int _NumIndices, int _Options, typename _IndexType> | ||
320 | 188 | void serialize( | |
321 | Archive & ar, | ||
322 | ::pinocchio::Tensor<_Scalar, _NumIndices, _Options, _IndexType> & t, | ||
323 | const unsigned int version) | ||
324 | { | ||
325 | 188 | split_free(ar, t, version); | |
326 | 188 | } | |
327 | |||
328 | } // namespace serialization | ||
329 | } // namespace boost | ||
330 | |||
331 | #endif // ifndef __pinocchio_serialization_eigen_matrix_hpp__ | ||
332 |