Skip to content

Commit 06c255a

Browse files
authored
Merge pull request #337 from jcarpent/devel
Simplify alignment procedure
2 parents 21f608d + 1697ac0 commit 06c255a

File tree

5 files changed

+85
-109
lines changed

5 files changed

+85
-109
lines changed

cmake

Submodule cmake updated 1 file

include/eigenpy/alignment.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ struct aligned_storage {
2020
};
2121
};
2222

23+
template <class Data>
24+
struct aligned_instance {
25+
PyObject_VAR_HEAD PyObject *dict;
26+
PyObject *weakrefs;
27+
boost::python::instance_holder *objects;
28+
29+
typename aligned_storage<sizeof(Data)>::type storage;
30+
};
31+
2332
} // namespace eigenpy
2433

2534
namespace boost {
@@ -62,6 +71,19 @@ struct referent_storage<const Eigen::Quaternion<Scalar, Options> &> {
6271
} // namespace python
6372
} // namespace boost
6473

74+
namespace boost {
75+
namespace python {
76+
namespace objects {
77+
78+
// Force alignment of instance with value_holder
79+
template <typename Derived>
80+
struct instance<value_holder<Derived> >
81+
: ::eigenpy::aligned_instance<value_holder<Derived> > {};
82+
83+
} // namespace objects
84+
} // namespace python
85+
} // namespace boost
86+
6587
namespace eigenpy {
6688

6789
template <class T>

include/eigenpy/fwd.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,50 @@
55
#ifndef __eigenpy_fwd_hpp__
66
#define __eigenpy_fwd_hpp__
77

8+
#if defined(__clang__)
9+
#define EIGENPY_CLANG_COMPILER
10+
#elif defined(__GNUC__)
11+
#define EIGENPY_GCC_COMPILER
12+
#elif defined(_MSC_VER)
13+
#define EIGENPY_MSVC_COMPILER
14+
#endif
15+
16+
#define EIGENPY_STRING_LITERAL(string) #string
17+
#define EIGENPY_STRINGIZE(string) EIGENPY_STRING_LITERAL(string)
18+
#define _EIGENPY_PPCAT(A, B) A##B
19+
#define EIGENPY_PPCAT(A, B) _EIGENPY_PPCAT(A, B)
20+
#define EIGENPY_STRINGCAT(A, B) A B
21+
22+
// For more details, visit
23+
// https://stackoverflow.com/questions/171435/portability-of-warning-preprocessor-directive
24+
#if defined(EIGENPY_CLANG_COMPILER) || defined(EIGENPY_GCC_COMPILER)
25+
#define EIGENPY_PRAGMA(x) _Pragma(#x)
26+
#define EIGENPY_PRAGMA_MESSAGE(the_message) \
27+
EIGENPY_PRAGMA(GCC message the_message)
28+
#define EIGENPY_PRAGMA_WARNING(the_message) \
29+
EIGENPY_PRAGMA(GCC warning the_message)
30+
#define EIGENPY_PRAGMA_DEPRECATED(the_message) \
31+
EIGENPY_PRAGMA_WARNING(Deprecated : the_message)
32+
#define EIGENPY_PRAGMA_DEPRECATED_HEADER(old_header, new_header) \
33+
EIGENPY_PRAGMA_WARNING( \
34+
Deprecated header file \
35+
: #old_header has been replaced \
36+
by #new_header.\n Please use #new_header instead of #old_header.)
37+
#elif defined(WIN32)
38+
#define EIGENPY_PRAGMA(x) __pragma(#x)
39+
#define EIGENPY_PRAGMA_MESSAGE(the_message) \
40+
EIGENPY_PRAGMA(message(#the_message))
41+
#define EIGENPY_PRAGMA_WARNING(the_message) \
42+
EIGENPY_PRAGMA(message(EIGENPY_STRINGCAT("WARNING: ", the_message)))
43+
#endif
44+
45+
#define EIGENPY_DEPRECATED_MACRO(macro, the_message) \
46+
EIGENPY_PRAGMA_WARNING( \
47+
EIGENPY_STRINGCAT("this macro is deprecated: ", the_message))
48+
#define EIGENPY_DEPRECATED_FILE(the_message) \
49+
EIGENPY_PRAGMA_WARNING( \
50+
EIGENPY_STRINGCAT("this file is deprecated: ", the_message))
51+
852
#include "eigenpy/config.hpp"
953

1054
// Silence a warning about a deprecated use of boost bind by boost python

include/eigenpy/memory.hpp

Lines changed: 9 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,111 +1,23 @@
11
/*
22
* Copyright 2014-2019, CNRS
3-
* Copyright 2018-2022, INRIA
3+
* Copyright 2018-2023, INRIA
44
*/
55

6-
#ifndef __eigenpy_memory_hpp__
7-
#define __eigenpy_memory_hpp__
8-
96
#include "eigenpy/fwd.hpp"
107

11-
#if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
12-
static inline void _Py_SET_SIZE(PyVarObject* ob, Py_ssize_t size) {
13-
ob->ob_size = size;
14-
}
15-
#define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
16-
#endif
8+
EIGENPY_DEPRECATED_FILE(
9+
"This header file is now useless and should not be included anymore.")
10+
11+
#ifndef __eigenpy_memory_hpp__
12+
#define __eigenpy_memory_hpp__
1713

1814
/**
1915
* This section contains a convenience MACRO which allows an easy specialization
2016
* of Boost Python Object allocator for struct data types containing Eigen
2117
* objects and requiring strict alignment.
22-
*
23-
* This code was proposed as an stackoverflow answer:
24-
* http://stackoverflow.com/questions/13177573/how-to-expose-aligned-class-with-boost-python/29694518
25-
* Leading to this page proposing the solution:
26-
* http://fhtagn.net/prog/2015/04/16/quaternion_boost_python.html
27-
*
2818
*/
29-
#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \
30-
namespace boost { \
31-
namespace python { \
32-
namespace objects { \
33-
template <> \
34-
struct instance<value_holder<__VA_ARGS__> > { \
35-
typedef value_holder<__VA_ARGS__> Data; \
36-
PyObject_VAR_HEAD PyObject* dict; \
37-
PyObject* weakrefs; \
38-
instance_holder* objects; \
39-
\
40-
typedef type_with_alignment< ::boost::alignment_of<Data>::value>::type \
41-
align_t; \
42-
\
43-
union { \
44-
align_t align; \
45-
char bytes[sizeof(Data) + EIGENPY_DEFAULT_ALIGN_BYTES]; \
46-
} storage; \
47-
}; \
48-
\
49-
template <class Derived> \
50-
struct make_instance_impl<__VA_ARGS__, value_holder<__VA_ARGS__>, Derived> { \
51-
typedef __VA_ARGS__ T; \
52-
typedef value_holder<__VA_ARGS__> Holder; \
53-
typedef objects::instance<Holder> instance_t; \
54-
\
55-
template <class Arg> \
56-
static inline PyObject* execute(Arg& x) { \
57-
BOOST_MPL_ASSERT((mpl::or_<is_class<T>, is_union<T> >)); \
58-
\
59-
PyTypeObject* type = Derived::get_class_object(x); \
60-
\
61-
if (type == 0) return python::detail::none(); \
62-
\
63-
PyObject* raw_result = type->tp_alloc( \
64-
type, objects::additional_instance_size<Holder>::value); \
65-
if (raw_result != 0) { \
66-
python::detail::decref_guard protect(raw_result); \
67-
instance_t* instance = (instance_t*)(void*)raw_result; \
68-
Holder* holder = \
69-
Derived::construct(&instance->storage, (PyObject*)instance, x); \
70-
holder->install(raw_result); \
71-
\
72-
Py_ssize_t holder_offset = \
73-
reinterpret_cast<Py_ssize_t>(holder) - \
74-
reinterpret_cast<Py_ssize_t>(&instance->storage) + \
75-
static_cast<Py_ssize_t>(offsetof(instance_t, storage)); \
76-
Py_SET_SIZE(instance, holder_offset); \
77-
\
78-
protect.cancel(); \
79-
} \
80-
return raw_result; \
81-
} \
82-
}; \
83-
\
84-
template <> \
85-
struct make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > \
86-
: make_instance_impl< \
87-
__VA_ARGS__, value_holder<__VA_ARGS__>, \
88-
make_instance<__VA_ARGS__, value_holder<__VA_ARGS__> > > { \
89-
template <class U> \
90-
static inline PyTypeObject* get_class_object(U&) { \
91-
return converter::registered<__VA_ARGS__>::converters \
92-
.get_class_object(); \
93-
} \
94-
\
95-
static inline value_holder<__VA_ARGS__>* construct( \
96-
void* storage, PyObject* instance, \
97-
reference_wrapper<__VA_ARGS__ const> x) { \
98-
void* aligned_storage = reinterpret_cast<void*>( \
99-
(reinterpret_cast<size_t>(storage) & \
100-
~(size_t(EIGENPY_DEFAULT_ALIGN_BYTES - 1))) + \
101-
EIGENPY_DEFAULT_ALIGN_BYTES); \
102-
value_holder<__VA_ARGS__>* new_holder = \
103-
new (aligned_storage) value_holder<__VA_ARGS__>(instance, x); \
104-
return new_holder; \
105-
} \
106-
}; \
107-
} \
108-
} \
109-
}
19+
#define EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(...) \
20+
EIGENPY_DEPRECATED_MACRO(EIGENPY_DEFINE_STRUCT_ALLOCATOR_SPECIALIZATION(), \
21+
"it is no more needed.")
11022

11123
#endif // __eigenpy_memory_hpp__

unittest/std_vector.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,24 @@
77
#include "eigenpy/eigen-from-python.hpp"
88
#include "eigenpy/std-vector.hpp"
99

10-
template <typename MatType,
11-
typename Allocator = Eigen::aligned_allocator<MatType> >
12-
void printVectorOfMatrix(const std::vector<MatType, Allocator> &Ms) {
10+
template <typename MatType>
11+
void printVectorOfMatrix(
12+
const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
1313
const std::size_t n = Ms.size();
1414
for (std::size_t i = 0; i < n; i++) {
1515
std::cout << "el[" << i << "] =\n" << Ms[i] << '\n';
1616
}
1717
}
1818

19-
template <typename MatType,
20-
typename Allocator = Eigen::aligned_allocator<MatType> >
21-
std::vector<MatType, Allocator> copy(
22-
const std::vector<MatType, Allocator> &Ms) {
23-
std::vector<MatType, Allocator> out = Ms;
19+
template <typename MatType>
20+
std::vector<MatType, Eigen::aligned_allocator<MatType> > copy(
21+
const std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
22+
std::vector<MatType, Eigen::aligned_allocator<MatType> > out = Ms;
2423
return out;
2524
}
2625

27-
template <typename MatType,
28-
typename Allocator = Eigen::aligned_allocator<MatType> >
29-
void setZero(std::vector<MatType, Allocator> &Ms) {
26+
template <typename MatType>
27+
void setZero(std::vector<MatType, Eigen::aligned_allocator<MatType> > &Ms) {
3028
for (std::size_t i = 0; i < Ms.size(); i++) {
3129
Ms[i].setZero();
3230
}

0 commit comments

Comments
 (0)