Big matrix multiplicaton crashes when linking against Xenomai 3
Submitted by Arturo Laurenzi
Assigned to Nobody
Link to original bugzilla bug (#1482)
Version: 3.3 (current stable)
Operating system: Linux
Description
Created attachment 800
Small self-contained example. Builds with cmake.
A bad crash happens when performing a multiplication between sufficiently large matrices. It happens only when
- the multiplication is done inside a (POSIX) thread, so not inside the main()
- the executable is compiled with Xenomai 3 compilation flags (as given by xeno-config --posix --cflags/--ldflags).
Such flags on my system are as follows:
CFLAGS: -I/usr/xenomai/include/cobalt -I/usr/xenomai/include -D_GNU_SOURCE -D_REENTRANT -D__COBALT__ -D__COBALT_WRAP__
LDFLAGS: -Wl,--no-as-needed -Wl,@/usr/xenomai/lib/cobalt.wrappers -Wl,@/usr/xenomai/lib/modechk.wrappers /usr/xenomai/lib/xenomai/bootstrap.o -Wl,--wrap=main -Wl,--dynamic-list=/usr/xenomai/lib/dynlist.ld -L/usr/xenomai/lib -lcobalt -lmodechk -lpthread -lrt
Compiler: GCC 5.4.0
OS: Ubuntu 16.04 + Xenomai 3 (Cobalt)
Eigen: 3.3.4
I am attaching a simple executable that show the issue (only on Xenomai 3, as specified before). More specifically, multiplying a [100x39] by a [39x100] succeeds, while [100x40] by [40x100] fails.
This is the backtrace:
Thread 3 "xeno3_tests" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7ff4700 (LWP 19199)]
0x000000000041bfa5 in Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>::run (rows=100, cols=100, depth=40, _lhs=0x7ffff00008c0,
lhsStride=100, _rhs=0x7ffff00085d0, rhsStride=40, _res=0x7ffff00102e0, resStride=100, alpha=1, blocking=..., info=0x0)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:163
163 ei_declare_aligned_stack_constructed_variable(RhsScalar, blockB, sizeB, blocking.blockB());
(gdb) bt
#0 0x000000000041bfa5 in Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>::run (rows=100, cols=100, depth=40, _lhs=0x7ffff00008c0,
lhsStride=100, _rhs=0x7ffff00085d0, rhsStride=40, _res=0x7ffff00102e0, resStride=100, alpha=1, blocking=..., info=0x0)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:163
#1 0x000000000041b13e in Eigen::internal::gemm_functor<double, long, Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::gemm_blocking_space<0, double, double, -1, -1, -1, 1, false> >::operator() (this=0x7ffff7ff3b20, row=0, rows=100, col=0, cols=100, info=0x0) at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:226
#2 0x000000000041ad8c in Eigen::internal::parallelize_gemm<true, Eigen::internal::gemm_functor<double, long, Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::gemm_blocking_space<0, double, double, -1, -1, -1, 1, false> >, long> (func=..., rows=100, cols=100, depth=40, transpose=false) at /usr/include/eigen3/Eigen/src/Core/products/Parallelizer.h:97
#3 0x000000000041a919 in Eigen::internal::generic_product_impl<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::DenseShape, Eigen::DenseShape, 8>::scaleAndAddTo<Eigen::Matrix<double, -1, -1, 0, -1, -1> > (dst=..., a_lhs=..., a_rhs=..., alpha=@0x7ffff7ff3be0: 1)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:483
#4 0x000000000041a2b4 in Eigen::internal::generic_product_impl<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::DenseShape, Eigen::DenseShape, 8>::evalTo<Eigen::Matrix<double, -1, -1, 0, -1, -1> > (dst=..., lhs=..., rhs=...) at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:435
#5 0x0000000000419cff in Eigen::internal::Assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double>, Eigen::internal::Dense2Dense, void>::run (dst=..., src=...) at /usr/include/eigen3/Eigen/src/Core/ProductEvaluators.h:148
#6 0x0000000000419753 in Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double> > (dst=..., src=..., func=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:836
#7 0x00000000004193f0 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_set_noalias<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x7ffff7ff3d50, other=...) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:728
#8 0x0000000000419251 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_init1<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x7ffff7ff3d50, other=...)
at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:812
#9 0x000000000041911b in Eigen::Matrix<double, -1, -1, 0, -1, -1>::Matrix<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (
this=0x7ffff7ff3d50, x=...) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:296
#10 0x0000000000418e90 in Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double> > (dst=..., src=..., func=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:796
#11 0x0000000000418b26 in Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (dst=..., src=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:782
#12 0x00000000004187d7 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_set<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x62b280 <H>, other=...) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:710
#13 0x00000000004184b5 in Eigen::Matrix<double, -1, -1, 0, -1, -1>::operator=<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (
this=0x62b280 <H>, other=...) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:225
#14 0x00000000004171d3 in test_mul (nrows_=100, ncols_=40) at /home/alaurenzi/Code/eigen_xeno3_test/src/main.cpp:103
#15 0x000000000041723a in regular_thread (arg=0x0) at /home/alaurenzi/Code/eigen_xeno3_test/src/main.cpp:136
#16 0x00007ffff7bc782c in cobalt_thread_trampoline () from /usr/xenomai/lib/libcobalt.so.2
#17 0x00007ffff779d6ba in start_thread (arg=0x7ffff7ff4700) at pthread_create.c:333
#18 0x00007ffff6a2a3dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
Changing the outer dimension to 20 (global variable nrows in the provided example), I see that [20x176] by [176x20] is ok, while [20x177] by [177x20] fails. Interestingly, the backtrace is different:
Thread 3 "xeno3_tests" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7ff4700 (LWP 19481)]
0x000000000041803c in Eigen::internal::pbroadcast4<double __vector(2)>(Eigen::internal::unpacket_traits<double __vector(2)>::type const*, double __vector(2)&, double __vector(2)&, double __vector(2)&, double __vector(2)&) (a=0x0, a0=..., a1=..., a2=..., a3=...) at /usr/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h:477
477 {
(gdb) bt
#0 0x000000000041803c in Eigen::internal::pbroadcast4<double __vector(2)>(Eigen::internal::unpacket_traits<double __vector(2)>::type const*, double __vector(2)&, double __vector(2)&, double __vector(2)&, double __vector(2)&) (a=0x0, a0=..., a1=..., a2=..., a3=...) at /usr/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h:477
#1 0x0000000000421bf5 in Eigen::internal::gebp_traits<double, double, false, false>::broadcastRhs(double const*, double __vector(2)&, double __vector(2)&, double __vector(2)&, double __vector(2)&) (this=0x7ffff7fe510b, b=0x7ffff7fe5990, b0=..., b1=..., b2=..., b3=...) at /usr/include/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h:403
#2 0x000000000041dddf in Eigen::internal::gebp_kernel<double, double, long, Eigen::internal::blas_data_mapper<double, long, 0, 0>, 4, 4, false, false>::operator() (
this=0x7ffff7ff377e, res=..., blockA=0x7ffff7fec850, blockB=0x7ffff7fe5990, rows=20, depth=177, cols=20, alpha=1, strideA=177, strideB=177, offsetA=0, offsetB=0)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h:1219
#3 0x000000000041c480 in Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>::run (rows=20, cols=20, depth=177, _lhs=0x7ffff00076d0,
lhsStride=20, _rhs=0x7ffff000e580, rhsStride=177, _res=0x7ffff00008c0, resStride=20, alpha=1, blocking=..., info=0x0)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:194
#4 0x000000000041b13e in Eigen::internal::gemm_functor<double, long, Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::gemm_blocking_space<0, double, double, -1, -1, -1, 1, false> >::operator() (this=0x7ffff7ff3b20, row=0, rows=20, col=0, cols=20, info=0x0) at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:226
#5 0x000000000041ad8c in Eigen::internal::parallelize_gemm<true, Eigen::internal::gemm_functor<double, long, Eigen::internal::general_matrix_matrix_product<long, double, 0, false, double, 0, false, 0>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::internal::gemm_blocking_space<0, double, double, -1, -1, -1, 1, false> >, long> (func=..., rows=20, cols=20, depth=177, transpose=false) at /usr/include/eigen3/Eigen/src/Core/products/Parallelizer.h:97
#6 0x000000000041a919 in Eigen::internal::generic_product_impl<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::DenseShape, Eigen::DenseShape, 8>::scaleAndAddTo<Eigen::Matrix<double, -1, -1, 0, -1, -1> > (dst=..., a_lhs=..., a_rhs=..., alpha=@0x7ffff7ff3be0: 1)
at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:483
#7 0x000000000041a2b4 in Eigen::internal::generic_product_impl<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::DenseShape, Eigen::DenseShape, 8>::evalTo<Eigen::Matrix<double, -1, -1, 0, -1, -1> > (dst=..., lhs=..., rhs=...) at /usr/include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h:435
#8 0x0000000000419cff in Eigen::internal::Assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double>, Eigen::internal::Dense2Dense, void>::run (dst=..., src=...) at /usr/include/eigen3/Eigen/src/Core/ProductEvaluators.h:148
#9 0x0000000000419753 in Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double> > (dst=..., src=..., func=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:836
#10 0x00000000004193f0 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_set_noalias<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x7ffff7ff3d50, other=...) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:728
#11 0x0000000000419251 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_init1<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x7ffff7ff3d50, other=...)
at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:812
#12 0x000000000041911b in Eigen::Matrix<double, -1, -1, 0, -1, -1>::Matrix<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (
this=0x7ffff7ff3d50, x=...) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:296
#13 0x0000000000418e90 in Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0>, Eigen::internal::assign_op<double, double> > (dst=..., src=..., func=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:796
#14 0x0000000000418b26 in Eigen::internal::call_assignment<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (dst=..., src=...) at /usr/include/eigen3/Eigen/src/Core/AssignEvaluator.h:782
#15 0x00000000004187d7 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> >::_set<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (this=0x62b280 <H>, other=...) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:710
#16 0x00000000004184b5 in Eigen::Matrix<double, -1, -1, 0, -1, -1>::operator=<Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, 0> > (
this=0x62b280 <H>, other=...) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:225
#17 0x00000000004171d3 in test_mul (nrows_=20, ncols_=177) at /home/alaurenzi/Code/eigen_xeno3_test/src/main.cpp:103
#18 0x000000000041723a in regular_thread (arg=0x0) at /home/alaurenzi/Code/eigen_xeno3_test/src/main.cpp:136
#19 0x00007ffff7bc782c in cobalt_thread_trampoline () from /usr/xenomai/lib/libcobalt.so.2
#20 0x00007ffff779d6ba in start_thread (arg=0x7ffff7ff4700) at pthread_create.c:333
#21 0x00007ffff6a2a3dd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109
I also tried #define EIGEN_DONT_VECTORIZE before including the headers, nothing changes.
Any clues? Please feel free to ask for further tests if you don't have a Xenomai 3 platform (dual kernel - Cobalt) available.
Attachment 800, "Small self-contained example. Builds with cmake.":
eigen_xeno3_test.zip