This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen

Bug 1108

Summary: setZero(), setConstant() etc. raise "Illegal Instruction" when called on Eigen::VectorXd
Product: Eigen Reporter: Dmitry Zhdanov <dm.zhdanov>
Component: Core - expression templatesAssignee: Nobody <eigen.nobody>
Status: RESOLVED FIXED    
Severity: Crash CC: chtz, gael.guennebaud, jacob.benoit.1
Priority: Normal    
Version: 3.3 (current stable)   
Hardware: x86 - AVX   
OS: Windows   
Whiteboard:
Bug Depends on:    
Bug Blocks: 558    

Description Dmitry Zhdanov 2015-11-07 05:33:50 UTC
Problem appeared after migrating from v3.2.7 to v3.3. Patches for PacketMath.h and MathFunctions.h were used to compile the code with MSVC.

Sample code:
	int dim=255;
	Eigen::VectorXd _A_Squared_vector(dim); // Worked in v3.2.7
	Eigen::VectorXd _A_Diagonal_vector(dim,1); //Expected to also work
        Eigen::VectorXd _A_Diagonal_vector2(1,dim); //Should not work but works (effectively creates 1x1 matrix)
	_A_Squared_vector.setZero(); // Crash: Unhandled exception at 0x000007F6F613FBA0 in QI++.exe: 0xC000001D: Illegal Instruction.
	_A_Diagonal_vector.setZero(); // Crash: Unhandled exception at 0x000007F6F613FBA0 in QI++.exe: 0xC000001D: Illegal Instruction.
	_A_Diagonal_vector2.setZero(); // No errors! 

Specifically, debugger complains about line 699 of of AssignEvaluator.

Note that there is no any problem with complex numbers: the same code with VectorXcd works as expected!
Comment 1 Gael Guennebaud 2015-11-10 10:48:12 UTC
Which patch are you talking about?

To go further, you should look at the assembly to see which illegal instruction has been generated. I also guess that it works fine if you disable AVX?
Comment 2 Gael Guennebaud 2015-11-10 10:54:48 UTC
some more questions:
- which version of MSVC are you using?
- Does it crash if you call .setConstant(2) (i.e., with a value different than 0)?

I'm asking because I see that for SSE we already have a workaround for MSVC 9 failing to generate valid assembly for _mm_set1_pd(0):

https://bitbucket.org/eigen/eigen/src/fce259fb9c7d163b5966e15b12cf0110a4e54f58/Eigen/src/Core/arch/SSE/PacketMath.h?at=default&fileviewer=file-view-default#PacketMath.h-164
Comment 3 Dmitry Zhdanov 2015-11-10 19:42:51 UTC
(In reply to Gael Guennebaud from comment #2)
> some more questions:
> - which version of MSVC are you using?
> - Does it crash if you call .setConstant(2) (i.e., with a value different
> than 0)?
> 
> I'm asking because I see that for SSE we already have a workaround for MSVC
> 9 failing to generate valid assembly for _mm_set1_pd(0):
> 
> https://bitbucket.org/eigen/eigen/src/
> fce259fb9c7d163b5966e15b12cf0110a4e54f58/Eigen/src/Core/arch/SSE/PacketMath.
> h?at=default&fileviewer=file-view-default#PacketMath.h-164

Gael, here are the responses to your first and second comments.

The patch:
https://bitbucket.org/eigen/eigen/commits/3bc6df26f930/
(Updated files MathFunctions.h and PacketMath.h to avoid the compiler error with AVX-related type casts of __m256 into __m256d etc.). Note that the compiler is still not entirely happy with this fix and generates warning c4005. It seems that the link you have posted in the 2nd comment points to the same fix.

And, of course, there are no errors with AVX disabled.

- which version of MSVC are you using?
MSVS 2013 express for Windows desktop.

- Does it crash if you call .setConstant(2)
Yes. 

A piece of assembly code around the crash point (for .setConstant(2.)):
000007F6B13EDE82  and         edx,3  
000007F6B13EDE85  add         rax,rdx  
000007F6B13EDE88  and         rax,0FFFFFFFFFFFFFFFCh  
000007F6B13EDE8C  jle         Eigen::internal::call_assignment<Eigen::Matrix<double,-1,1,0,-1,1>,Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>,Eigen::Matrix<double,-1,1,0,-1,1> > >+0DFh (07F6B13EDEAFh)  
000007F6B13EDE8E  xchg        ax,ax  
000007F6B13EDE90  vbroadcastsd ymm0,xmm0  <<ERROR
Comment 4 Dmitry Zhdanov 2015-11-10 20:59:02 UTC
Just have checked: the PacketMath.h file from your workaround link did not fix the issue.

Unrelated question: I have developed the special module for hypersparse matrices (DCSR and DCSC formats) and some AVX accelerators (parallel sparse-sparse and sparse-dense products, in-place transposes etc.) and have several specific questions regarding integrating them with Eigen 3.3 (mostly about changes in SparseMatrix.h file). What would be the right place to ask such a questions?
Comment 5 Christoph Hertzberg 2015-11-11 10:17:02 UTC
It appears your compiler translates _mm256_set1_pd into a AVX2-vbroadcastsd which your CPU apparently does not support. Can your compiler distinguish between generating AVX and AVX2 code? (If so make sure only to activate AVX)
Otherwise, a workaround might be to replace the implementation of pset1<...> in src/Core/arch/AVX/PacketMath.h line 114 by 
    _mm256_broadcast_sd(&from);
(analogously for float and int, if they cause the same problem)
However, this will likely prohibit some compile-optimizations
Comment 6 Gael Guennebaud 2015-11-11 16:01:47 UTC
Regarding the off-topic question, you might create a new bug-entry for each respective features and patches.
Comment 7 Dmitry Zhdanov 2015-11-12 21:11:16 UTC
Thank you, Gael! Changing compiler options (by explicitly enabling only AVX optimizations) solved the problem.
Comment 8 Nobody 2019-12-04 15:09:32 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/1108.