-
Notifications
You must be signed in to change notification settings - Fork 287
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eigen aligned memory allocator #414
Conversation
i lifted the following from MRPT and put it in the Utils namespace :
and then map declarations go from something like this : to this : and this seemed to work nicely. Edit: this also serves as a 1-stop solution for allocators for any stl containers. |
also, don't forget the following : |
Eigen::aligned_allocator<std::pair<const _Key, _Tp>>>; | ||
|
||
template<typename _Tp, typename... _Args> | ||
inline std::shared_ptr<_Tp> make_aligned_shared() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not clear on what the purpose of this overload is. Normally with variadic templates, an argument-free overload is used to terminate the template recursion, but we're not actually using template recursion in this case.
Also, this version is using regular std::make_shared
instead of std::allocate_shared
, which seems to defeat the entire purpose, doesn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's not for template recursion.
I found that make_aligned_shared(...)
doesn't work for WeldJoint::Property
; there was compiler error as:
/usr/include/eigen3/Eigen/src/Core/util/Memory.h:731: error: call to implicitly-deleted copy constructor of 'std::_Sp_counted_ptr_inplace<dart::dynamics::WeldJoint::Properties, Eigen::aligned_allocator<dart::dynamics::WeldJoint::Properties>, __gnu_cxx::_Lock_policy::_S_atomic>'
::new( p ) T( value );
^ ~~~~~
I put this argument-free overloaded function to make make_aligned_shared(...)
looks like working with WeldJoint::Property
temporally. Once the solution is found, this function should be removed.
It seems this error is present on gcc but not on clang. I've tried to figure out the reason of errors but couldn't find yet. Could you take a look at this problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not getting that issue on GCC with 64-bit Ubuntu 14.04. Was there a particular platform it was happening on with GCC? I've tried constructing it in a variety of ways with a variety of different arguments for WeldJoint::Properties, but it's not triggering a compilation error for me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And is it only WeldJoint?
One thing we could try is adding WeldJoint(const WeldJoint& _other) = default;
to the definition of WeldJoint. If it's really nothing more than an implicitly deleted copy constructor, then that should do the trick.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. The implicitly deleted copy constructor belongs to the templated class inside of <Eigen/.../util/Memory.h>
, not to WeldJoint::Properties. It seems really strange that this is happening specifically for WeldJoint::Properties. I'm thinking this must be an internal compiler error.
What happens when we make the no-argument version of Eigen::make_aligned_shared()
use std::allocate_shared<_Tp>( Eigen::aligned_allocator<_Tp>() )
? Does the same error happen? I'm kind of concerned that using regular make_shared
defeats the point of having the Eigen::make_aligned_shared()
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when we make the no-argument version of Eigen::make_aligned_shared() use std::allocate_shared<_Tp>( Eigen::aligned_allocator<_Tp>() )? Does the same error happen?
Yes. It seems the variadic template function generates exactly same function with no-argument version of Eigen::make_aligned_shared()
when there is no argument, which should do.
I tracked down the history of Eigen's aligned_allocator
since the error is caused in it. I found that the Eigen::aligned_allocator
is not compatible with C++11 yet. Here are the related issues: [1], [2].
There was an intermediate patch for this in Eigen 3.1.0 but removed in Eigen 3.2.1, and the new patch is applied to the default branch but not to any released version yet. Ubuntu 14.04 is fine since it has Eigen 3.1.0. But Ubuntu 14.10 and 15.04 causes compilation error since they have Eigen 3.2.1 and Eigen 3.2.2, respectively.
I copied new aligned_allocator from Eigen's default branch and made DART to use it if the installed Eigen is greater than 3.2.1. This should be removed once the new aligned_allocator
is released.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahhhh, well that explains a lot of things. I should have known better than to think it was internal compiler error; I'm just getting too accustomed to compilers having bizarre bugs or incompatibility related to C++11.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I thought that too. So I double checked it with clang on linux and mac because clang seems more compatible than others to me. Once I observed that clang also complains similarly, I started to investigate on Eigen.
Beside on the compilation issue, I confirmed that the memory alignment issue is also resolved on Ubuntu 32-bit 15.04. So I believe this PR is ready to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
I've added the alignment macro in a couple more places that it happened to be needed and changed a couple more STL containers to their aligned versions. I also added a copy constructor for MultiDofJoint::UniqueProperties, because it turns out that VS2013 doesn't properly support copy construction for std::array yet. It's not related to the Eigen alignment issue, but it is related to the incomplete C++11 support in Visual Studio (and it seemed a bit too small for its own pull request). |
Eigen aligned memory allocator
This pull request resolves memory alignment issues with Eigen objects in DART.
Also, some helper types and functions are defined for convenience such as
Eigen::aligned_vector
andEigen::make_aligned_shared()
. One thing I'm not sure is the namespace and names of them.dart::aligned_vector
ordart::aligned::vector
are alternatives I can imagine. Any thought on this?Related issues: #413