Re: [eigen] Alignment of derived matrix class

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]




On Fri, Mar 5, 2010 at 1:58 PM, Piotr Trojanek <piotr.trojanek@xxxxxxxxx> wrote:
Gael, thanks for your suggestions!

I have verified the following:

1)  the code that breaks assertion is even the most simple variant (so this has nothing to do with inheritance):


* Eigen::Matrix<double, 6, 1> servo_real_kartez_pos;

not good!

so what about:

EIGEN_ALIGN_128 Eigen::Matrix<double, 6, 1> servo_real_kartez_pos;

??

and if that does not work:

__attribute__((aligned(16))) Eigen::Matrix<double, 6, 1> servo_real_kartez_pos;


(paranoia)


 

2) for 100% right variant of macro is used:
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
(added #error to all the other variants).


ok
 
3) my code works just fine with -DEIGEN_DONT_ALIGN switch.


yes, in that case the assertions are removed.
 
4) alignment attribute is honored by QCC compiler (which uses gcc-4.3.1 as a backend),
which I have verified with the following result of a test program attached:

# ../a.out
aligned: 8047b50
notaligned: 8047b98
In function nonaligned -- align.cc:24 (reinterpret_cast<std::size_t>(array) & 0xf) ==0 -- assertion failed
Abort (core dumped)

I will appreciate any idea... It looks like QCC compiler does align the data only when it wants (?!).

that's weird. And what if in this simple example you include Eigen, and using EIGEN_ALIGN_128 instead of the attribute ?

and then, what if you replace the member array by a Eigen::Matrix<double, 6, 1> ?

gael

 

Piotr


On Fri, Mar 5, 2010 at 09:35, Gael Guennebaud <gael.guennebaud@xxxxxxxxx> wrote:

Hi Piotr,

this sounds really strange to me. To help to understand the cause of the issue have you tried, or could you try the following:

replace B servo_real_kartez_pos; by each of the following:

* Eigen::Matrix<double, 6, 1> servo_real_kartez_pos;
* A servo_real_kartez_pos;
* EIGEN_ALIGN_128 B servo_real_kartez_pos;

Check that sizeof(B)==sizeof(Eigen::Matrix<double, 6, 1>)

gael


On Fri, Mar 5, 2010 at 12:45 AM, Piotr Trojanek <piotr.trojanek@xxxxxxxxxx> wrote:
Dear Eigen experts,

while porting some robotics matrix code to Eigen2 I have encountered the following problem
on QNX platform, but I do not think it is QNX specific.

I have the following class hierarchy, which I have created using guidelines from:
http://www.ros.org/wiki/eigen#Creating_typedefs_for_Eigen_types

// Base class (with not copy-pasted robot-specific methods)
class A : public Eigen::Matrix<double, 6, 1> {
public:
    // Copy constructor from any Eigen matrix type
    template<typename OtherDerived>
    A(const Eigen::MatrixBase<OtherDerived>& other)
        : BaseClass(other)
    {}

    // Reuse assignment operators from base class
    using BaseClass::operator=;

    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

// Derived class type, which will hold additional methods
class B : public A {
public:
    template<typename OtherDerived>
    B(const Eigen::MatrixBase<OtherDerived>& other)
        : Ft_v_vector(other)
    {}

    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

When I run this code on Linux - it works just fine.
When I run this on QNX - it fails with Unalligned Array Assert. The backtrace is here:

#0  0xb033dad1 in SignalKill () from /usr/qnx641/target/qnx6/x86/lib/libc.so.3
#1  0xb032c82e in raise () from /usr/qnx641/target/qnx6/x86/lib/libc.so.3
#2  0xb032ab08 in abort () from /usr/qnx641/target/qnx6/x86/lib/libc.so.3
#3  0xb032ad29 in __assert () from /usr/qnx641/target/qnx6/x86/lib/libc.so.3
#4  0x080534ec in ei_matrix_array (this=0x7f42db4) at /opt/qnx641/target/qnx6/mrlib/include/eigen2/Eigen/src/Core/MatrixStorage.h:43
#5  0x0805350f in ei_matrix_storage (this=0x7f42db4) at /opt/qnx641/target/qnx6/mrlib/include/eigen2/Eigen/src/Core/MatrixStorage.h:79
#6  0x0809936f in Matrix<Eigen::CwiseNullaryOp<Eigen::ei_scalar_constant_op<double>, Eigen::Matrix<double, 6, 1, 2, 6, 1> > > (
    this=0x7f42db4, other=@0x7f42ccc) at /opt/qnx641/target/qnx6/mrlib/include/eigen2/Eigen/src/Core/Matrix.h:405
#7  0x080981a4 in A (this=0x7f42db4) at mrmath/ft_v_vector.cc:28
#8  0x0809820f in B (this=0x7f42db4) at mrmath/ft_v_vector.cc:185
#9  0x08078293 in mrrocpp::edp::common::manip_effector::compute_servo_joints_and_frame (this=0x80d7fc0) at edp_e_manip.cc:55

The code, that causes the abort is just creating local, temporary variable of class B:
B servo_real_kartez_pos;

I have checked, that QNX compiler honours EIGEN_ALIGN_128 statement (I am 100% sure,
checked with gdb for very simple structure alignment with and without this statement).

The question is - where is my mistake? Is it correct to make inherit in the above way?
The problem seems to be, that in frames #8 to #4 "this" is not aligned to 128bit boundary.
I have tried adding EIGEN_ALIGN_128 and virtual inheritance, but this did not solve the problem.

Thanks in advance!

--
Piotr Trojanek
Robot Control and Recognition Systems Team,
Institute of Control & Computation Engineering,
Warsaw University of Technology






--
Piotr Trojanek



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/