Repository navigation
"Illegal instruction" when running simple array additions #10330
Copy link
Copy link
Closed
Description
Numpy crashes with an "illegal instruction" when running a simple array addition (past a certain array size) when running inside a VM under Xen. It is probably somehow related to #9534. I narrowed it down the commit 37740eb, which introduced AVX2 simd code:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.__version__
'1.12.0.dev0+37740eb'
>>> a = numpy.arange(15)
>>> a[1:] + a[:-1]
Illegal instruction (core dumped)I also tried the current master, which shows the same error.
It is working fine up to the preceding commit eeb4e17:
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> numpy.__version__
'1.12.0.dev0+eeb4e17'
>>> a = numpy.arange(15)
>>> a[1:] + a[:-1]
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27])`Note that /proc/cpuinfo doesn't list AVX2:
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
stepping : 2
microcode : 0x31
cpu MHz : 2494.282
cache size : 30720 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 4
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 smep bmi2 erms invpcid
bugs :
bogomips : 4988.56
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
stepping : 2
microcode : 0x31
cpu MHz : 2494.282
cache size : 30720 KB
physical id : 0
siblings : 4
core id : 2
cpu cores : 4
apicid : 2
initial apicid : 2
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 smep bmi2 erms invpcid
bugs :
bogomips : 4988.56
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
processor : 2
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
stepping : 2
microcode : 0x31
cpu MHz : 2494.282
cache size : 30720 KB
physical id : 0
siblings : 4
core id : 4
cpu cores : 4
apicid : 4
initial apicid : 4
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 smep bmi2 erms invpcid
bugs :
bogomips : 4988.56
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 63
model name : Intel(R) Xeon(R) CPU E5-2680 v3 @ 2.50GHz
stepping : 2
microcode : 0x31
cpu MHz : 2494.282
cache size : 30720 KB
physical id : 0
siblings : 4
core id : 6
cpu cores : 4
apicid : 6
initial apicid : 6
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes rdrand hypervisor lahf_lm abm fsgsbase tsc_adjust bmi1 smep bmi2 erms invpcid
bugs :
bogomips : 4988.56
clflush size : 64
cache_alignment : 64
address sizes : 46 bits physical, 48 bits virtual
power management:
I tried to understand how numpy decides when to use the avx2 simd codepaths but failed miserably.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
ulido commentedon Jan 5, 2018
I just tried that, but it crashed again:
I should've mentioned that the problem also arises if I use the regular numpy version from pip:
I guess the pip-supplied manylinux wheel should work regardless of the presence of AVX2, correct?
seberg commentedon Jan 7, 2018
Numpy has runtime detection here. Now that works with gcc
__builtin_cpu_supports, either there is something done wrong there in numpy, or the VM is doing something weird? If you have a clue about it,git grepforNPY_CPU_SUPPORTS. GCC docs mention somecpu_initstuff, but dunno, seems weird if that was it?seberg commentedon Jan 7, 2018
I am sure you can remove the avx/avx2 target from the setup code (or pass through flags to disable it maybe). (e.g. check/modify
numpy/core/setup_common.py)ulido commentedon Jan 7, 2018
Thanks @seberg ! I'm pretty sure that the problem is that the Xen hypervisor my VM is running on is configure to mask the AVX capabilities of the host cpu (I don't know why, I don't control the hypervisor.). My guess is that __builtin_cpu_supports uses heuristics based on the cpu name or so to find which features it supports. However, that leads to trouble in this case when capabilities are masked/forbidden by the host. Here is some code to prove that (AVX is detected but not working):
Do you think it would be possible to use a custom function to set NPY_CPU_SUPPORTS_AVX / NPY_CPU_SUPPORTS_AVX2 that tries to run a corresponding instruction and catches SIGILL instead of __builtin_cpu_supports?
seberg commentedon Jan 7, 2018
As far as I understand AVX, etc. have to be enabled explicitly when compiling? So I think you can simply remove those lines that have something to do with AVX in that setup file I mentioned and recompile? That should just lead to disabling the whole stuff.
For a more general solution, I do not know.... I am sure we could have a flag or so to disable it explicitly at least during compile time, maybe even more fancy stuff. I do not really know build stuff, etc. Doing more fancy stuff during run-time seems odd to me, but thats just gut feeling.
ulido commentedon Jan 7, 2018
seberg commentedon Jan 7, 2018
Tend to agree, it seems more like a bug in either gcc or probably the VM to me as well. I don't mind making working around it easier, but doing weird things when the gcc function seems like smarter people who know this stuff wrote it….
We can make working around it easier maybe. I also wonder if (at least for manylinux numpy) the openblas won't blow up as well as soon as you use it? And I am sure adding that
__builtin_cpu_init()call does not matter?ulido commentedon Jan 8, 2018
Ok, @seberg, I followed your suggestion and removed the entries for AVX in
setup_common.py, which fixed the problem for now, but I guess it would be good to at least have a compile time option to disable AVX/AVX2.I did some testing and found that it is not a gcc bug. The cpu itself reports AVX/AVX2 capabilities via the
cpuidinstruction (which is used by__builtin_cpu_supports). Rather, Xen fails to mask the features in the response to calling cpuid (but I don't know anything about Xen, and have no control over the host system I'm running my VM on)./proc/cpuinfocorrectly reports them as absent, so it should be possible to query that as a last check after__builtin_cpu_supportsreports true.Closing the issue for now.