This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
Bug 1389 - Unaligned assert with MSVC x64 and AVX
Summary: Unaligned assert with MSVC x64 and AVX
Status: RESOLVED FIXED
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - vectorization (show other bugs)
Version: 3.3 (current stable)
Hardware: x86 - 64-bit Windows
: Normal Crash
Assignee: Nobody
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-03 11:46 UTC by Björn Piltz
Modified: 2019-12-04 16:47 UTC (History)
4 users (show)



Attachments
Compile with /arch:AVX (1.02 KB, text/plain)
2017-02-03 11:47 UTC, Björn Piltz
no flags Details

Description Björn Piltz 2017-02-03 11:46:17 UTC
The attached example either crashes or gives me the "unaligned assert" when I use /arch:AVX.

I'm using 3.3.1.

See https://bitbucket.org/bjornpiltz/eigen_msvc_avx_test/.
Comment 1 Björn Piltz 2017-02-03 11:47:40 UTC
Created attachment 771 [details]
Compile with /arch:AVX
Comment 2 Gael Guennebaud 2017-02-03 12:21:35 UTC
I cannot reproduce, but here is my guess: MSVC is not good at aligning the stack, so fix your Ray ctor from:

  Ray(const Mat34 P_, const Vec2& p_)

to

  Ray(const Mat34& P_, const Vec2& p_)
Comment 3 Björn Piltz 2017-02-03 12:26:27 UTC
Oh, I missed that. It doesn't help though. I'm using MSVC Community 2015 Update 3 
Here's the call stack:
>	AVX_TEST.exe!Eigen::internal::pstore<double,__m256d>(double * to, const __m256d & from) Line 251	C++
 	AVX_TEST.exe!Eigen::internal::pstoret<double,__m256d,32>(double * to, const __m256d & from) Line 475	C++
 	AVX_TEST.exe!Eigen::internal::assign_op<double,double>::assignPacket<32,__m256d>(double * a, const __m256d & b) Line 28	C++
 	AVX_TEST.exe!Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0>::assignPacket<32,32,__m256d>(__int64 row, __int64 col) Line 653	C++
 	AVX_TEST.exe!Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0>::assignPacketByOuterInner<32,32,__m256d>(__int64 outer, __int64 inner) Line 667	C++
 	AVX_TEST.exe!Eigen::internal::copy_using_evaluator_innervec_CompleteUnrolling<Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0>,0,12>::run(Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0> & kernel) Line 276	C++
 	AVX_TEST.exe!Eigen::internal::dense_assignment_loop<Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0>,3,2>::run(Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::evaluator<Eigen::Matrix<double,3,4,0,3,4> >,Eigen::internal::assign_op<double,double>,0> & kernel) Line 435	C++
 	AVX_TEST.exe!Eigen::internal::call_dense_assignment_loop<Eigen::Matrix<double,3,4,0,3,4>,Eigen::Matrix<double,3,4,0,3,4>,Eigen::internal::assign_op<double,double> >(Eigen::Matrix<double,3,4,0,3,4> & dst, const Eigen::Matrix<double,3,4,0,3,4> & src, const Eigen::internal::assign_op<double,double> & func) Line 724	C++
 	AVX_TEST.exe!Eigen::internal::Assignment<Eigen::Matrix<double,3,4,0,3,4>,Eigen::Matrix<double,3,4,0,3,4>,Eigen::internal::assign_op<double,double>,Eigen::internal::Dense2Dense,void>::run(Eigen::Matrix<double,3,4,0,3,4> & dst, const Eigen::Matrix<double,3,4,0,3,4> & src, const Eigen::internal::assign_op<double,double> & func) Line 863	C++
 	AVX_TEST.exe!Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double,3,4,0,3,4>,Eigen::Matrix<double,3,4,0,3,4>,Eigen::internal::assign_op<double,double> >(Eigen::Matrix<double,3,4,0,3,4> & dst, const Eigen::Matrix<double,3,4,0,3,4> & src, const Eigen::internal::assign_op<double,double> & func) Line 820	C++
 	AVX_TEST.exe!Eigen::PlainObjectBase<Eigen::Matrix<double,3,4,0,3,4> >::_set_noalias<Eigen::Matrix<double,3,4,0,3,4> >(const Eigen::DenseBase<Eigen::Matrix<double,3,4,0,3,4> > & other) Line 722	C++
 	AVX_TEST.exe!Eigen::Matrix<double,3,4,0,3,4>::Matrix<double,3,4,0,3,4>(Eigen::Matrix<double,3,4,0,3,4> && other) Line 278	C++
 	[External Code]	
 	AVX_TEST.exe!main(int argc, char * * argv) Line 47	C++
Comment 4 Christoph Hertzberg 2017-02-03 12:33:17 UTC
You must also use:
  std::vector<Ray, Eigen::aligned_allocator<Ray> >
(you should actually also use Eigen::aligned_allocator when compiling for SSE, even though it is not necessary on most 64bit systems).
Comment 5 Björn Piltz 2017-02-03 12:37:03 UTC
Thanks, that does it! Then the documentation for "An alternative - specializing std::vector for Eigen types" is wrong:

    #include<Eigen/StdVector>
    /* ... */
    EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d)
    std::vector<Eigen::Vector2d>
Comment 6 Björn Piltz 2017-02-03 12:39:52 UTC
Or actually it seems <StdVector> needs to be fixed:

    #if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 /* MSVC auto aligns in 64 bit builds */

    #define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...)
Comment 7 Gael Guennebaud 2017-02-03 14:18:05 UTC
I see, so we should remove  EIGEN_OS_WIN64 if EIGEN_MAX_STATIC_ALIGN_BYTES>16
Comment 8 Björn Piltz 2017-02-03 14:23:19 UTC
I think the only safe case to not apply the EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION fix is:
#if EIGEN_COMP_MSVC && EIGEN_OS_WIN64 && EIGEN_MAX_STATIC_ALIGN_BYTES==16
but don't take my word for it!
Comment 9 Gael Guennebaud 2017-02-03 14:24:07 UTC
Let me know if the following truly work. If so I'll backport it.

https://bitbucket.org/eigen/eigen/commits/5430cad55312/
Summary:     Bug 1389: MSVC's std containers do not properly align in 64 bits mode if the requested alignment is larger than 16 bytes (e.g., with AVX)
Comment 10 Björn Piltz 2017-02-03 14:27:52 UTC
Yeah, that works.
Comment 11 Gael Guennebaud 2017-02-03 14:32:29 UTC
btw, in C++11 the prototype of std::vector::resize as been fixed, and it must now be:

void resize( size_type count, const value_type& value );

instead of

void resize( size_type count, const value_type value );

in c++98/03. But according to msdn:

https://msdn.microsoft.com/en-us/library/9xd04bzs.aspx#vector__resize

even with MSVC 2015, std::vector::resize still follows the broken C++98/03 standard. Could someone confirm this from the MSVC's header of vector?
Comment 12 Gael Guennebaud 2017-02-03 14:33:50 UTC
backport: https://bitbucket.org/eigen/eigen/commits/29f0625a5c72/
Comment 13 Björn Piltz 2017-02-03 14:38:06 UTC
The MSDN documentation seems to be wrong. "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\vector" has the right signature.
Comment 14 Gael Guennebaud 2017-02-03 16:07:07 UTC
ok, thank you.
Comment 15 Nobody 2019-12-04 16:47:56 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1389.

Note You need to log in before you can comment on or make changes to this bug.