Skip to content
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

Needs C++17 over-aligned new operator #21

Closed
jlblancoc opened this issue May 25, 2019 · 9 comments · Fixed by #183
Closed

Needs C++17 over-aligned new operator #21

jlblancoc opened this issue May 25, 2019 · 9 comments · Fixed by #183

Comments

@jlblancoc
Copy link
Member

While building tests:

/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h: In instantiation of ‘gtsam::Expression<T>::Expression(const T&) [with T = gtsam::Unit3]’:
/home/jlblanco/code/gtsam-jlblancoc/gtsam/slam/tests/testEssentialMatrixFactor.cpp:149:39:   required from here
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: warning: ‘new’ of type ‘gtsam::internal::ConstantExpression<gtsam::Unit3>’ with extended alignment 32 [-Waligned-new=]
     root_(new internal::ConstantExpression<T>(value)) {
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: note: uses ‘void* operator new(std::size_t)’, which does not have an alignment parameter
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: note: use ‘-faligned-new’ to enable C++17 over-aligned new support

Need to investigate a bit more, but it's likely due to Eigen memory constraints.

Are you ok with adding -faligned-new as a private/public flag to gtsam libraries to solve this? Otherwise, I guess this may lead to random crashes if "optimizing for native" is enabled.

@dellaert
Copy link
Member

Thanks for flagging! Two concerns I have:

  • is -faligned_new cross-platform/compiler?
  • hesitant to apply a blanket flag solution before fully understanding the problem.
    I never fully understood alignment, but willing to be educated :-)

@jlblancoc
Copy link
Member Author

jlblancoc commented May 26, 2019

Hi!
It's a complex point... But basically it all has to do with special SIMD instructions used in optimized Eigen (e.g. SSE3, SSE4, AVX2) which require & assume that matrix data blocks start at addresses that are a multiple of N (with N=16, 32, ... bytes, depending on the SIMD family).

C++11 introduced alignas(N): See https://en.cppreference.com/w/cpp/language/alignas

That's great for variables in the stack (local variables), but what happens with this?

struct alignas(32) MyEigenVector { ... } ;

struct Foo
{
  MyEigenVector v;
};

auto f = std::make_shared<Foo>();

the last line calls the good old new(), which ignores the alignas constraints, leading to runtime crashes if (by chance) the returned address does not fulfill with the required alignment.

Now, that is finally fixed in C++17:

And it seems to have been well-received in Eigen: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1409

But... if the users (us) do not enable C++17, the new new(N,align) functions are not called.
That is what gcc is complaining about in the warning copied above. It seems to be a new warning, I never saw it before... but that's a good thing we are informed about the potential runtime crash!

I think there exist these solutions:

  • Either use the gcc-specific flag (and things will work on gcc only; perhaps clang has the equivalent flag);
  • Or switch to C++17 (and no special flag would be required).

Anyway, I think this issue has a low priority... unless unexpected random crashes start to show up while running optimized code (!).

@chrisbeall
Copy link
Member

What OS, compiler, and C++ standard are you using when you get this warning? I don't think I've ever seen this. (I'm mostly on Ubuntu 16.04, C++14, gcc 5.4 or clang 8.0)

Eigen already provided a way to handle alignment for SSE3, AVX2, etc. which works in C++11 & C++14. Per the instructions at
https://eigen.tuxfamily.org/dox/group__TopicUnalignedArrayAssert.html we've added the EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro in lots of our classes, avoid make_shared, etc.

I think we are probably just missing EIGEN_MAKE_ALIGNED_OPERATOR_NEW somewhere in Expressions.h?

@chrisbeall
Copy link
Member

Actually, I see Expressions.h uses make_shared. We should fix that. make_shared with structs having Eigen members will be ok starting with C++17, exactly as you explained. I think it's probably too soon to make C++17 the default for gtsam for a few more years :-)

@jlblancoc
Copy link
Member Author

jlblancoc commented May 27, 2019

I think it's probably too soon to make C++17 the default for gtsam for a few more years :-)

I guess it depends on how much you can bear people complaining about it :-)

avoid make_shared, etc.

Hmm... there's actually a workaround if you like it:

template <typename T, class... Args>
 std::shared_ptr<T> make_aligned_shared(Args&&... args)
 {
     using T_nc = typename std::remove_const<T>::type;
     return std::allocate_shared<T>(
          Eigen::aligned_allocator<T_nc>(), std::forward<Args>(args)...);
 }

@jlblancoc
Copy link
Member Author

jlblancoc commented May 27, 2019

What OS, compiler, and C++ standard are you using when you get this warning?

It took me a while to reproduce it too... it only happens when building the tests, not the regular libraries.
On Ubuntu 18.04, gcc 7.4.0, etc. Everything to defaults in cmake. Here is the complete set of flags, for reference:

/usr/bin/c++  -DBOOST_OPTIONAL_ALLOW_BINDING_TO_RVALUES 
-DBOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES 
...
-std=c++11 -Wall -march=native -O3 -DNDEBUG    -O3 -DNDEBUG   -o ...
VERBOSE=1 make testEssentialMatrixFactor 
[100%] Building CXX object gtsam/slam/tests/CMakeFiles/testEssentialMatrixFactor.dir/testEssentialMatrixFactor.cpp.o
cd /home/jlblanco/code/gtsam-jlblancoc/build/gtsam/slam/tests && /usr/bin/c++  -DBOOST_OPTIONAL_ALLOW_BINDING_TO_RVALUES -DBOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES -DTOPSRCDIR=\"/home/jlblanco/code/gtsam-jlblancoc\" -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/metis/include -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/metis/libmetis -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/metis/GKlib -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/SuiteSparse_config -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/CCOLAMD/Include -I/home/jlblanco/code/gtsam-jlblancoc -I/home/jlblanco/code/gtsam-jlblancoc/build -I/home/jlblanco/code/gtsam-jlblancoc/CppUnitLite -I/home/jlblanco/code/gtsam-jlblancoc/gtsam/3rdparty/Eigen  -std=c++11 -Wall -march=native -O3 -DNDEBUG    -O3 -DNDEBUG   -o CMakeFiles/testEssentialMatrixFactor.dir/testEssentialMatrixFactor.cpp.o -c /home/jlblanco/code/gtsam-jlblancoc/gtsam/slam/tests/testEssentialMatrixFactor.cpp
In file included from /home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression.h:302:0,
                 from /home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/ExpressionFactor.h:22,
                 from /home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/expressionTesting.h:22,
                 from /home/jlblanco/code/gtsam-jlblancoc/gtsam/slam/tests/testEssentialMatrixFactor.cpp:11:
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h: In instantiation of ‘gtsam::Expression<T>::Expression(const T&) [with T = gtsam::Unit3]’:
/home/jlblanco/code/gtsam-jlblancoc/gtsam/slam/tests/testEssentialMatrixFactor.cpp:149:39:   required from here
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: warning: ‘new’ of type ‘gtsam::internal::ConstantExpression<gtsam::Unit3>’ with extended alignment 32 [-Waligned-new=]
     root_(new internal::ConstantExpression<T>(value)) {
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: note: uses ‘void* operator new(std::size_t)’, which does not have an alignment parameter
/home/jlblanco/code/gtsam-jlblancoc/gtsam/nonlinear/Expression-inl.h:32:11: note: use ‘-faligned-new’ to enable C++17 over-aligned new support

@jlblancoc
Copy link
Member Author

I don't know why, but this is not showing up anymore, so I guess it could be closed.

@jlblancoc
Copy link
Member Author

Just found another instance of this same issue, so reopening again:

In file included from /home/jlblanco/code/gtsam/gtsam/slam/tests/testRotateFactor.cpp:8:
/home/jlblanco/code/gtsam/gtsam/slam/RotateFactor.h: In member function ‘virtual gtsam::NonlinearFactor::shared_ptr gtsam::RotateDirectionsFactor::clone() const’:
/home/jlblanco/code/gtsam/gtsam/slam/RotateFactor.h:93:58: warning: ‘new’ of type ‘gtsam::RotateDirectionsFactor::This’ {aka ‘gtsam::RotateDirectionsFactor’} with extended alignment 32 [-Waligned-new=]
   93 |         gtsam::NonlinearFactor::shared_ptr(new This(*this))); }
      |                                                          ^
/home/jlblanco/code/gtsam/gtsam/slam/RotateFactor.h:93:58: note: uses ‘void* operator new(std::size_t)’, which does not have an alignment parameter
/home/jlblanco/code/gtsam/gtsam/slam/RotateFactor.h:93:58: note: use ‘-faligned-new’ to enable C++17 over-aligned new support

This happens with g++9 under amd64 and u18.04.

@jlblancoc
Copy link
Member Author

Closed by #185

varunagrawal added a commit that referenced this issue Jan 2, 2021
62161cd20 Merge pull request #21 from borglab/feature/script-vars
93be1d9f8 set script variables and move pybind11 loading so gtwrap can be used under gtsam

git-subtree-dir: wrap
git-subtree-split: 62161cd200512e65133b7c4bc8f790b7ba769b40
varunagrawal added a commit that referenced this issue Jan 4, 2021
09f8bbf71 Merge pull request #25 from borglab/fix/function-name
0dbfb6c13 fix function name to be the correct one
f69f8b01f Merge pull request #24 from borglab/fix/pip
6519a6627 use pip install to overcome superuser issues
b11ecf4e8 Merge pull request #23 from borglab/fix/remove-pip-args
813030108 remove pip-args since we are using setup.py
498d233e0 Merge pull request #22 from borglab/fix/package-install
846212ac3 set correct flags for installing gtwrap package
62161cd20 Merge pull request #21 from borglab/feature/script-vars
93be1d9f8 set script variables and move pybind11 loading so gtwrap can be used under gtsam
8770e3c7e Merge pull request #20 from borglab/fix/pybind-include
8c3c83618 proper placement of pybind11 include
a9ad4f504 Merge pull request #19 from borglab/feature/package
99d8a12c7 added more documentation
4cbec1579 change to macro so we don't have to deal with function scopes
b83e405b8 updates to completely install the package
38a64b3de new scripts which will be installed to bin directory
bf9646235 Merge pull request #18 from borglab/fix/cmake-min
c7c280099 Consistent cmake minimum required
42df58f62 Merge pull request #17 from borglab/fix/cleanup
e580b282d version bump
4ccd66fa5 More finegrained handling of Python version
6476fd710 Merge pull request #16 from borglab/feature/better-find-python
8ac1296a0 use setup.py to install dependencies
e9ac473be install dependencies and support versions of CMake<3.12
cf272dbd2 Merge pull request #15 from borglab/feature/utils
ffc9cc4f7 new utils to reduce boilerplate
20e8e8b7a Merge pull request #11 from borglab/feature/package
04b844bd6 use new version of FindPython and be consistent
3f9d7a32a Merge pull request #13 from borglab/add_license
c791075a6 Add LICENSE
517b67c46 correct working directory for setup.py
1b22b47ae move matlab.h to root directory
37b407214 Proper source directory path for use in other projects
61696dd5d configure PybindWrap within the cmake directory
1b91fc9af add config file so we can use find_package
a1e6f4f53 small typo
da9f351be updated README and housekeeping
64b8f78d5 files needed to allow for packaging
bddda7f54 package structure

git-subtree-dir: wrap
git-subtree-split: 09f8bbf7172ba8b1bd3d2484795743f16e1a5893
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants