[英]How can I check if my installed numpy is compiled with SSE/SSE2 instruction set?
[英]numpy calling sse2 via ctypes
簡而言之,我試圖從python調用一個共享庫,更具體地說,從numpy調用。 共享庫使用sse2指令在C中實現。 啟用優化,即使用-O2或-O1構建庫時,我在通過ctypes調用共享庫時遇到奇怪的段錯誤。 禁用優化(-O0),一切都按預期進行,就像直接將庫鏈接到c程序(優化與否)一樣。 附上你發現一個剪輯,顯示我的系統上描繪的行為。 啟用優化后,gdb將在emmintrin.h:113中的__builtin_ia32_loadupd(__P)中報告段錯誤。 __P的值報告為優化輸出。
test.c的:
#include <emmintrin.h>
#include <complex.h>
void test(const int m, const double* x, double complex* y) {
int i;
__m128d _f, _x, _b;
double complex f __attribute__( (aligned(16)) );
double complex b __attribute__( (aligned(16)) );
__m128d* _p;
b = 1;
_b = _mm_loadu_pd( (double *) &b );
_p = (__m128d*) y;
for(i=0; i<m; ++i) {
f = cexp(-I*x[i]);
_f = _mm_loadu_pd( (double *) &f );
_x = _mm_loadu_pd( (double *) &x[i] );
_f = _mm_shuffle_pd(_f, _f, 1);
*_p = _mm_add_pd(*_p, _f);
*_p = _mm_add_pd(*_p, _x);
*_p = _mm_mul_pd(*_p,_b);
_p++;
}
return;
}
編譯器標志:gcc -o libtest.so -shared -std = c99 -msse2 -fPIC -O2 -g -lm test.c
test.py:
import numpy as np
import os
def zerovec_aligned(nr, dtype=np.float64, boundary=16):
'''Create an aligned array of zeros.
'''
size = nr * np.dtype(dtype).itemsize
tmp = np.zeros(size + boundary, dtype=np.uint8)
address = tmp.__array_interface__['data'][0]
offset = boundary - address % boundary
return tmp[offset:offset + size].view(dtype=dtype)
lib = np.ctypeslib.load_library('libtest', '.' )
lib.test.restype = None
lib.test.argtypes = [np.ctypeslib.ctypes.c_int,
np.ctypeslib.ndpointer(np.float64, flags=('C', 'A') ),
np.ctypeslib.ndpointer(np.complex128, flags=('C', 'A', 'W') )]
n = 13
y = zerovec_aligned(n, dtype=np.complex128)
x = np.ones(n, dtype=np.float64)
# x = zerovec_aligned(n, dtype=np.float64)
# x[:] = 1.
lib.test(n,x,y)
從C調用測試按預期工作:
call_from_c.c:
#include <stdio.h>
#include <complex.h>
#include <stdlib.h>
#include <emmintrin.h>
void test(const int m, const double* x, double complex* y);
int main() {
int i;
const int n = 11;
double complex *y = (double complex*) _mm_malloc(n*sizeof(double complex), 16);
double *x = (double *) malloc(n*sizeof(double));
for(i=0; i<n; ++i) {
x[i] = 1;
y[i] = 0;
}
test(n, x, y);
for(i=0; i<n; ++i)
printf("[%f %f]\n", creal(y[i]), cimag(y[i]));
return 1;
}
編譯並致電:
gcc -std = c99 -otestc -msse2 -L。 -ltest call_from_c.c
export LD_LIBRARY_PATH = $ {LD_LIBRARY_PATH}:
./testc
......有效。
我的系統:
我已經采取了規定(參見python代碼)y對齊並且x的對齊無關緊要(我認為;明確對齊x並不能解決問題)。
另請注意,在加載b和f時,我使用_mm_loadu_pd而不是_mm_load_pd。 對於僅C版本_mm_load_pd工作(如預期的那樣)。 但是,當使用_mm_load_pd通過ctypes調用函數時,始終是segfaults(獨立於優化)。
我已經嘗試了好幾天來解決這個問題而沒有成功......我正在瀕臨監視器死亡。 歡迎任何投入。 丹尼爾
我只是因為嘗試從python調用一些SSE代碼而感到困惑,問題似乎是GCC想要假設堆棧在16字節邊界上對齊(架構上最大的本機類型,即SSE類型) ),並用該假設計算所有偏移量。 當該假設為假時,SSE指令將陷阱。
答案似乎是編譯
gcc -mstackrealign更改函數序言以始終將堆棧對齊到16個字節。
嘗試使用numpy構建系統構建擴展來折扣潛在的cflags / ldflags差異: http ://projects.scipy.org/numpy/wiki/NumpySconsExtExamples
您是否嘗試升級到Numpy 1.5.0b2。 只需運行以下命令(但要小心它可能會破壞其他東西(你將不得不重新編譯所有pyrex):
sudo easy_install -U numpy
當我嘗試使用H5PY時,我遇到了與ctypes類似的問題(我不得不重新編譯.deb以獲得最新版本的numpy),並且編織的主要問題是最新的升級修復了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.