namespace Eigen {

/** \eigenManualPage TopicStructHavingEigenMembers Structures Having Eigen Members

\eigenAutoToc

\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.

*/

}
