1
votes

I have an class ClusterNode which contains an Eigen::Matrix4d as a class variable. I also have a function numNodes() which tells me the total number of ClusterNodes, so that I can collect them in some sort of array, list, or vector.

However, Eigen::Matrix4d is aligned which means I cannot store objects of this type in a std::vector<ClusterNode> as per the answer to this question error C2719: '_Val': formal parameter with __declspec(align('16')) won't be aligned?

As an alternative, I have tried using an array.

However, I cannot do

const int n = numNodes();
ClusterNode array [n];

Because the return value of a function is not considered a constant.

What other options do I have?

3
ClusterNode* array = new ClusterNode[n]; - Alex F
Did you read the answer in that linked question? std::vector no longer passes the element type by value, so non-overalignment of function parameters is no longer an issue. - Ben Voigt
@Ben I must have an older compiler version, because I still get the compiler error. - Cecilia
What is your compiler version? - Ben Voigt
@Ben Visual C++ 10, the fix was added in Visual C++ 11 - Cecilia

3 Answers

2
votes

You can use Eigen's aligned_allocator. See this page for the details, but basically you can do:

std::vector<ClusterNode, Eigen::aligned_allocator<ClusterNode> >

Also don't forget to overload operator new for your class. Again, all the details are in the Eigen's documentation.

0
votes

You can try to use memalign or posix_memalign to allocate and align a variable memory space

http://man.he.net/man3/memalign

0
votes

I ended up using Alex Faber's solution

ClusterNode* array = new ClusterNode[n];

But I wanted to add the note that, in this case, the class also needs to return alligned pointers. It will only cause problems part of the time, in a very annoying and untracable way, but after much bug hunting, I finally got a useful error message that pointed me to Eigen's documentation.

A summary of the documentation: Eigen needs 16-byte aligned memory. The following cases will lead to grief.

  1. std containers containing Eigen types
  2. classes or structures containing Eigen types
  3. passing Eigen types to functions by value
  4. gcc on Windows has wrong alignment (4-byte)

If I use the dynamic array solution proposed by Alex (ClusterNode as a variable at all for that matter), I also need to use a macro provided by Eigen to ensure that the objects are aligned. For example,

class ClusterNode
{
    Eigen::Matrix4d M;

public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} 

If the macro is not included, the array declaration will sometimes silently fail.