Discussion:
[eigen] eigen mis-compiling with native arch
Xanthos Papanikolaou
2021-04-28 13:13:50 UTC
Permalink
Dear all,

i have started using Eigen for navigation-related projects; it is a
great library!
While messing with my Makefiles, i have noticed the following behavior:

let's say i have a header file bar.h as follows:
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size);

an implementation file bar.cc
#include "bar.h"
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size) {
Eigen::VectorXd x = Eigen::VectorXd(size);
return x;
}

and a main function in foo.cc
#include "eigen3/Eigen/Dense"
#include "bar.h"
int main() {
int size;
for (size=1; size<9; i++) {
auto v = vbar(size);
}

return 0;
}

If i compile bar.cc using the "-march=native" flag (either with g++ or
clang++) and then link with
foo.cc without using the same flag, i get a core dump. That is:
g++ -Wall -g -std=c++17 -march=native -c bar.cc -o bar_native.o
g++ -Wall -g -std=c++17 foo.cc bar_native.o -o foo_error
./foo_error
double free or corruption (out)
Aborted (core dumped)

using backtrace with gdb, i get the following:
Program received signal SIGABRT, Aborted.
0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
#1  0x00007ffff7ab7895 in abort () from /lib64/libc.so.6
#2  0x00007ffff7b12627 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff7b19b4c in malloc_printerr () from /lib64/libc.so.6
#4  0x00007ffff7b1b190 in _int_free () from /lib64/libc.so.6
#5  0x0000000000401585 in Eigen::internal::aligned_free (ptr=0x419ec0)
at /usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:203
#6  0x0000000000401565 in
Eigen::internal::conditional_aligned_free<true> (ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:259
#7  0x000000000040152c in
Eigen::internal::conditional_aligned_delete_auto<double, true>
(ptr=0x419ec0, size=1) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:446
#8  0x00000000004014ec in Eigen::DenseStorage<double, -1, -1, 1,
0>::~DenseStorage (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/DenseStorage.h:571
#9  0x00000000004014c5 in Eigen::PlainObjectBase<Eigen::Matrix<double,
-1, 1, 0, -1, 1> >::~PlainObjectBase (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:98
#10 0x0000000000401498 in Eigen::Matrix<double, -1, 1, 0, -1,
1>::~Matrix (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:178
#11 0x00000000004013d5 in main () at foo.cc:7

I can see that my machine supports SSE/AVX,
g++ -march=native -dM -E - </dev/null | grep SSE
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __MMX_WITH_SSE__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE3__ 1

g++ -march=native -dM -E - </dev/null | grep AVX
#define __AVX__ 1
#define __AVX2__ 1

I know that i have messed up the compilation (using the native
architecture in only the first step), but what exactly goes on here?
Is it an error in an instruction? or maybe memory alignment? Am i
completely wrong? If possible, i would like to dive in a little deeper
here. Any help is
deeply appreciated.

Thanks in advance,
Xanthos
Antonio Sanchez
2021-04-28 15:15:43 UTC
Permalink
You can try setting EIGEN_MAX_ALIGN_BYTES=32. See
https://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html.
Otherwise the first will be 16-byte aligned, but the second 32-byte aligned.

On Wed, Apr 28, 2021 at 6:15 AM Xanthos Papanikolaou <
Post by Xanthos Papanikolaou
Dear all,
i have started using Eigen for navigation-related projects; it is a great
library!
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size);
an implementation file bar.cc
#include "bar.h"
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size) {
Eigen::VectorXd x = Eigen::VectorXd(size);
return x;
}
and a main function in foo.cc
#include "eigen3/Eigen/Dense"
#include "bar.h"
int main() {
int size;
for (size=1; size<9; i++) {
auto v = vbar(size);
}
return 0;
}
If i compile bar.cc using the "-march=native" flag (either with g++ or
clang++) and then link with
g++ -Wall -g -std=c++17 -march=native -c bar.cc -o bar_native.o
g++ -Wall -g -std=c++17 foo.cc bar_native.o -o foo_error
./foo_error
double free or corruption (out)
Aborted (core dumped)
Program received signal SIGABRT, Aborted.
0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
#1 0x00007ffff7ab7895 in abort () from /lib64/libc.so.6
#2 0x00007ffff7b12627 in __libc_message () from /lib64/libc.so.6
#3 0x00007ffff7b19b4c in malloc_printerr () from /lib64/libc.so.6
#4 0x00007ffff7b1b190 in _int_free () from /lib64/libc.so.6
#5 0x0000000000401585 in Eigen::internal::aligned_free (ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:203
#6 0x0000000000401565 in Eigen::internal::conditional_aligned_free<true>
(ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:259
#7 0x000000000040152c in
Eigen::internal::conditional_aligned_delete_auto<double, true>
(ptr=0x419ec0, size=1) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:446
#8 0x00000000004014ec in Eigen::DenseStorage<double, -1, -1, 1,
0>::~DenseStorage (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/DenseStorage.h:571
#9 0x00000000004014c5 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1,
1, 0, -1, 1> >::~PlainObjectBase (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:98
#10 0x0000000000401498 in Eigen::Matrix<double, -1, 1, 0, -1, 1>::~Matrix
(this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:178
#11 0x00000000004013d5 in main () at foo.cc:7
I can see that my machine supports SSE/AVX,
g++ -march=native -dM -E - </dev/null | grep SSE
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __MMX_WITH_SSE__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE3__ 1
g++ -march=native -dM -E - </dev/null | grep AVX
#define __AVX__ 1
#define __AVX2__ 1
I know that i have messed up the compilation (using the native
architecture in only the first step), but what exactly goes on here?
Is it an error in an instruction? or maybe memory alignment? Am i
completely wrong? If possible, i would like to dive in a little deeper
here. Any help is
deeply appreciated.
Thanks in advance,
Xanthos
xanthos
2021-04-28 18:21:00 UTC
Permalink
Thank you for the reply, much appreciated!

All the best,
Xanthos
You can try setting EIGEN_MAX_ALIGN_BYTES=32.  See
https://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html
<https://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html>.
Otherwise the first will be 16-byte aligned, but the second 32-byte aligned.
On Wed, Apr 28, 2021 at 6:15 AM Xanthos Papanikolaou
Dear all,
i have started using Eigen for navigation-related projects; it is
a great library!
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size);
an implementation file bar.cc
#include "bar.h"
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size) {
Eigen::VectorXd x = Eigen::VectorXd(size);
return x;
}
and a main function in foo.cc
#include "eigen3/Eigen/Dense"
#include "bar.h"
int main() {
int size;
for (size=1; size<9; i++) {
auto v = vbar(size);
}
return 0;
}
If i compile bar.cc using the "-march=native" flag (either with
g++ or clang++) and then link with
g++ -Wall -g -std=c++17 -march=native -c bar.cc -o bar_native.o
g++ -Wall -g -std=c++17 foo.cc bar_native.o -o foo_error
./foo_error
double free or corruption (out)
Aborted (core dumped)
Program received signal SIGABRT, Aborted.
0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
(gdb) bt
#0  0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
#1  0x00007ffff7ab7895 in abort () from /lib64/libc.so.6
#2  0x00007ffff7b12627 in __libc_message () from /lib64/libc.so.6
#3  0x00007ffff7b19b4c in malloc_printerr () from /lib64/libc.so.6
#4  0x00007ffff7b1b190 in _int_free () from /lib64/libc.so.6
#5  0x0000000000401585 in Eigen::internal::aligned_free
(ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:203
#6  0x0000000000401565 in
Eigen::internal::conditional_aligned_free<true> (ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:259
#7  0x000000000040152c in
Eigen::internal::conditional_aligned_delete_auto<double, true>
(ptr=0x419ec0, size=1) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:446
#8  0x00000000004014ec in Eigen::DenseStorage<double, -1, -1, 1,
0>::~DenseStorage (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/DenseStorage.h:571
#9  0x00000000004014c5 in
Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1>
Post by Xanthos Papanikolaou
::~PlainObjectBase (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:98
#10 0x0000000000401498 in Eigen::Matrix<double, -1, 1, 0, -1,
1>::~Matrix (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:178
#11 0x00000000004013d5 in main () at foo.cc:7
I can see that my machine supports SSE/AVX,
g++ -march=native -dM -E - </dev/null | grep SSE
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __MMX_WITH_SSE__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE3__ 1
g++ -march=native -dM -E - </dev/null | grep AVX
#define __AVX__ 1
#define __AVX2__ 1
I know that i have messed up the compilation (using the native
architecture in only the first step), but what exactly goes on here?
Is it an error in an instruction? or maybe memory alignment? Am i
completely wrong? If possible, i would like to dive in a little
deeper here. Any help is
deeply appreciated.
Thanks in advance,
Xanthos
Benoit Jacob
2021-05-06 03:02:15 UTC
Permalink
Post by Antonio Sanchez
You can try setting EIGEN_MAX_ALIGN_BYTES=32. See
https://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html.
Otherwise the first will be 16-byte aligned, but the second 32-byte aligned.
On Wed, Apr 28, 2021 at 6:15 AM Xanthos Papanikolaou <
Post by Xanthos Papanikolaou
Dear all,
i have started using Eigen for navigation-related projects; it is a great
library!
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size);
an implementation file bar.cc
#include "bar.h"
#include "eigen3/Eigen/Dense"
Eigen::VectorXd vbar(int size) {
Eigen::VectorXd x = Eigen::VectorXd(size);
return x;
}
and a main function in foo.cc
#include "eigen3/Eigen/Dense"
#include "bar.h"
int main() {
int size;
for (size=1; size<9; i++) {
auto v = vbar(size);
}
return 0;
}
If i compile bar.cc using the "-march=native" flag (either with g++ or
clang++) and then link with
g++ -Wall -g -std=c++17 -march=native -c bar.cc -o bar_native.o
g++ -Wall -g -std=c++17 foo.cc bar_native.o -o foo_error
./foo_error
double free or corruption (out)
Aborted (core dumped)
The first problem here is an ODR violation:
bar_native.o and foo.o contain the same Eigen symbols but with different
definitions, since one of them has Eigen compiled with __AVX__ and __AVX2__
defined, and not the other.

While it's hard to prove that that's the cause of the SIGABRT here, it's
undefined behavior and it would lead to crashes sooner or later.

The fix is to compile all your .cc files with the same compiler flags which
may enable to disable SIMD features that would cause Eigen to select
different code paths for.
Post by Antonio Sanchez
Post by Xanthos Papanikolaou
Program received signal SIGABRT, Aborted.
0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
(gdb) bt
#0 0x00007ffff7ace7d5 in raise () from /lib64/libc.so.6
#1 0x00007ffff7ab7895 in abort () from /lib64/libc.so.6
#2 0x00007ffff7b12627 in __libc_message () from /lib64/libc.so.6
#3 0x00007ffff7b19b4c in malloc_printerr () from /lib64/libc.so.6
#4 0x00007ffff7b1b190 in _int_free () from /lib64/libc.so.6
#5 0x0000000000401585 in Eigen::internal::aligned_free (ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:203
#6 0x0000000000401565 in Eigen::internal::conditional_aligned_free<true>
(ptr=0x419ec0) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:259
#7 0x000000000040152c in
Eigen::internal::conditional_aligned_delete_auto<double, true>
(ptr=0x419ec0, size=1) at
/usr/local/include/eigen3/Eigen/src/Core/util/Memory.h:446
#8 0x00000000004014ec in Eigen::DenseStorage<double, -1, -1, 1,
0>::~DenseStorage (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/DenseStorage.h:571
#9 0x00000000004014c5 in Eigen::PlainObjectBase<Eigen::Matrix<double,
-1, 1, 0, -1, 1> >::~PlainObjectBase (this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:98
#10 0x0000000000401498 in Eigen::Matrix<double, -1, 1, 0, -1, 1>::~Matrix
(this=0x7fffffffde38) at
/usr/local/include/eigen3/Eigen/src/Core/Matrix.h:178
#11 0x00000000004013d5 in main () at foo.cc:7
I can see that my machine supports SSE/AVX,
g++ -march=native -dM -E - </dev/null | grep SSE
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __MMX_WITH_SSE__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE2__ 1
#define __SSE3__ 1
g++ -march=native -dM -E - </dev/null | grep AVX
#define __AVX__ 1
#define __AVX2__ 1
I know that i have messed up the compilation (using the native
architecture in only the first step), but what exactly goes on here?
Is it an error in an instruction? or maybe memory alignment? Am i
completely wrong? If possible, i would like to dive in a little deeper
here. Any help is
deeply appreciated.
Thanks in advance,
Xanthos
Loading...