namespace Eigen {

/** \page StructHavingEigenMembers Troubleshooting - Structures Having Eigen Members

\b Table \b of \b contents
  - \ref summary
  - \ref what
  - \ref how
  - \ref why
  - \ref movetotop
  - \ref bugineigen
  - \ref conditional

\section summary Executive Summary

If you define a structure having members of \ref FixedSizeVectorizable "fixed-size vectorizable Eigen types", you must overload its "operator new" so that it generates 16-bytes-aligned pointers. Fortunately, Eigen provides you with a macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW that does that for you.

\section what What kind of code needs to be changed?

The kind of code that needs to be changed is this:

\code
class Foo
{
  ...
  Eigen::Vector2d v;
  ...
};

...

Foo *foo = new Foo;
\endcode

In other words: you have a class that has as a member a \ref FixedSizeVectorizable "fixed-size vectorizable Eigen object", and then you dynamically create an object of that class.

\section how How should such code be modified?

Very easy, you just need to put a EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro in a public part of your class, like this:

\code
class Foo
{
  ...
  Eigen::Vector2d v;
  ...
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

...

Foo *foo = new Foo;
\endcode

This macro makes "new Foo" always return an aligned pointer.

\section why Why is this needed?

OK let's say that your code looks like this:

\code
class Foo
{
  ...
  Eigen::Vector2d v;
  ...
};

...

Foo *foo = new Foo;
\endcode

A Eigen::Vector2d consists of 2 doubles, which is 128 bits. Which is exactly the size of a SSE packet, which makes it possible to use SSE for all sorts of operations on this vector. But SSE instructions (at least the ones that Eigen uses, which are the fast ones) require 128-bit alignment. Otherwise you get a segmentation fault.

For this reason, Eigen takes care by itself to require 128-bit alignment for Eigen::Vector2d, by doing two things:
\li Eigen requires 128-bit alignment for the Eigen::Vector2d's array (of 2 doubles). With GCC, this is done with a __attribute__ ((aligned(16))).
\li Eigen overloads the "operator new" of Eigen::Vector2d so it will always return 128-bit aligned pointers.

Thus, normally, you don't have to worry about anything, Eigen handles alignment for you...

... except in one case. When you have a class Foo like above, and you dynamically allocate a new Foo as above, then, since Foo doesn't have aligned "operator new", the returned pointer foo is not necessarily 128-bit aligned.

The alignment attribute of the member v is then relative to the start of the class, foo. If the foo pointer wasn't aligned, then foo->v won't be aligned either!

The solution is to let class Foo have an aligned "operator new", as we showed in the previous section.

\section movetotop Should I then put all the members of Eigen types at the beginning of my class?

That's not required. Since Eigen takes care of declaring 128-bit alignment, all members that need it are automatically 128-bit aligned relatively to the class. So code like this works fine:

\code
class Foo
{
  double x;
  Eigen::Vector2d v;
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
\endcode

\section dynamicsize What about dynamic-size matrices and vectors?

Dynamic-size matrices and vectors, such as Eigen::VectorXd, allocate dynamically their own array of coefficients, so they take care of requiring absolute alignment automatically. So they don't cause this issue. The issue discussed here is only with \ref FixedSizeVectorizable  "fixed-size vectorizable matrices and vectors".

\section bugineigen So is this a bug in Eigen?

No, it's not our bug. It's more like an inherent problem of the C++98 language specification, and seems to be taken care of in the upcoming language revision: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">see this document</a>.

\section conditional What if I want to do this conditionnally (depending on template parameters) ?

For this situation, we offer the macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign). It will generate aligned operators like EIGEN_MAKE_ALIGNED_OPERATOR_NEW if NeedsToAlign is true. It will generate operators with the default alignment if NeedsToAlign is false.

Example:

\code
template<int n> class Foo
{
  typedef Eigen::Matrix<float,n,1> Vector;
  enum { NeedsToAlign = (sizeof(Vector)%16)==0 };
  ...
  Vector v;
  ...
public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
};

...

Foo<4> *foo4 = new Foo<4>; // foo4 is guaranteed to be 128bit-aligned
Foo<3> *foo3 = new Foo<3>; // foo3 has only the system default alignment guarantee
\endcode

*/

}
