namespace Eigen {

/** \page TopicStructHavingEigenMembers Structures Having Eigen Members

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

\section summary Executive Summary

If you define a structure having members of \ref TopicFixedSizeVectorizable "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 TopicFixedSizeVectorizable "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.

If this approach is too intrusive, see also the \ref othersolutions.

\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 TopicFixedSizeVectorizable  "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


\section othersolutions Other solutions

In case putting the EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro everywhere is too intrusive, there exists at least two other solutions.

\subsection othersolutions1 Disabling alignment

The first is to disable alignment requirement for the fixed size members:
\code
class Foo
{
  ...
  Eigen::Matrix<double,2,1,Eigen::DontAlign> v;
  ...
};
\endcode
This has for effect to disable vectorization when using \c v.
If a function of Foo uses it several times, then it still possible to re-enable vectorization by copying it into an aligned temporary vector:
\code
void Foo::bar()
{
  Eigen::Vector2d av(v);
  // use av instead of v
  ...
  // if av changed, then do:
  v = av;
}
\endcode

\subsection othersolutions2 Private structure

The second consist in storing the fixed-size objects into a private struct which will be dynamically allocated at the construction time of the main object:

\code
struct Foo_d
{
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
  Vector2d v;
  ...
};


struct Foo {
  Foo() { init_d(); }
  ~Foo() { delete d; }
  void bar()
  {
    // use d->v instead of v
    ...
  }
private:
  void init_d() { d = new Foo_d; }
  Foo_d* d;
};
\endcode

The clear advantage here is that the class Foo remains unchanged regarding alignment issues. The drawback is that a heap allocation will be required whatsoever.

*/

}
