Re: [eigen] Alignment of derived matrix class |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] Alignment of derived matrix class
- From: Piotr Trojanek <piotr.trojanek@xxxxxxxxx>
- Date: Fri, 5 Mar 2010 13:58:24 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type; bh=j/H+lVhQEiKbaM1FfecUfSKRjVJoQyB2Luy3b8mS45g=; b=qQN2dcI9RFNkuN8VNVsZWhFIz/YmGSNDLRgi5u2NfkFheXcObBOZVH3AdwrwJocLI1 CvJyjkGe48SEGz4nNmI7tNjIxWm0yDRcBQb/g0L9f/cOFNlKB9nEbg+x9rqkSEMURHbI cOxnDfZf1SeQ0qZmQeQW5DRAiCHBkEBtu3M5w=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; b=GMJqCc44C1xYR+wDdCYZt5Y0ApXlW5gIifDs18oq4pwYMvauiAemPkRWIyv0OSDggc TUHTRQX/xuOUPRrU2FjWf/u/UMBqqsWLd5iCzIIc1G5Hkn6zfcUwCFRnLQtAswq06vq6 E+l6x2iVUzRUlnOxzzMaZ9msQ2HqesGaQV59s=
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;
2) for 100% right variant of macro is used:
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
(added #error to all the other variants).
3) my code works just fine with -DEIGEN_DONT_ALIGN switch.
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 (?!).
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>)
gaelOn Fri, Mar 5, 2010 at 12:45 AM, Piotr Trojanek
<piotr.trojanek@xxxxxxxxx> 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
#include <stdio.h>
#include <assert.h>
#include <cstdlib>
struct aligned {
char c;
__attribute__((aligned(16)))
double array[8];
aligned() {
printf("aligned: %p\n", array);
assert((reinterpret_cast<std::size_t>(array) & 0xf) ==0);
}
};
struct nonaligned {
char c;
double array[7];
nonaligned() {
printf("notaligned: %p\n", array);
assert((reinterpret_cast<std::size_t>(array) & 0xf) ==0);
}
};
int
main(int argc, char *argv[])
{
aligned a;
nonaligned na;
return 0;
}