在python中使用Pandas和Numpy庫創建一個Pandas DataFrame是一個常見的操作,但就是這一個常見的操作也會在特定的場景下遇到問題。
筆者在使用Pandas DataFrame時,遇到了core dump的問題。去掉不相關的代碼后,基本斷定是如下代碼引起core dump。
import numpy as np
np.random.seed(7)
import pandas as pd
df = pd.DataFrame(np.random.randn(1, 32))
經過驗證后,發現只有在column大于31時,會crash。
經過搜索資料,發現原來是Numpy在某些虛擬機環境下的bug。具體原因在Numpy的git issue中描述。https://github.com/numpy/numpy/issues/9532
本文作一簡單歸納:
root cause
- 宿主機CPU并不支持AVX或者AVX2標簽,但是在創建虛擬機時,給系統打上了AVX/AVX2的tag。
- 當Pandas創建的DataFrame列大于31時,會走到AVX/AVX2的路徑,因為虛擬機有AVX/AVX2的標簽,但是執行到AVX/AVX2的邏輯時,因為宿主機并不支持,所以core dump Illegal instruction。
- core棧如下:
Program received signal SIGILL, Illegal instruction.
0xb61338a8 in LONG_greater_avx2 (args=args@entry=0xbfffe52c,
dimensions=dimensions@entry=0xbfffe538, steps=steps@entry=0xbfffe544,
__NPY_UNUSED_TAGGEDfunc=__NPY_UNUSED_TAGGEDfunc@entry=0x0)
at numpy/core/src/umath/loops.c.src:936
936 numpy/core/src/umath/loops.c.src: No such file or directory.
(gdb) bt
#0 0xb61338a8 in LONG_greater_avx2 (args=args@entry=0xbfffe52c,
dimensions=dimensions@entry=0xbfffe538, steps=steps@entry=0xbfffe544,
__NPY_UNUSED_TAGGEDfunc=__NPY_UNUSED_TAGGEDfunc@entry=0x0)
at numpy/core/src/umath/loops.c.src:936
解決方法
- 刪除系統已有的numpy庫
pip uninstall numpy
- 下載numpy源代碼
git clone https://github.com/numpy/numpy.git numpy
-
修改Numpy庫文件 numpy/core/include/numpy/npy_common.h, 將AVX/AVX2 設為0.code diff
編譯并安裝numpy
python setup.py build
python setup.py install
安裝后在新的shell下重新執行python腳本,問題解決。