Python 使用SIMD内部崩溃的Cython
我正在尝试将Cython用于SIMD(AVX2)。我的CPU确实支持它。我在这里找到了这段代码,它执行SSE 所以我为AVX制作了一个名为AVX_test5.pyx的程序Python 使用SIMD内部崩溃的Cython,python,cython,simd,avx2,Python,Cython,Simd,Avx2,我正在尝试将Cython用于SIMD(AVX2)。我的CPU确实支持它。我在这里找到了这段代码,它执行SSE 所以我为AVX制作了一个名为AVX_test5.pyx的程序 from libc.stdlib cimport malloc, free, calloc cdef extern from "immintrin.h": # in this example, we use AVX2 ctypedef float __m256 __m256 _mm256_loadu_ps
from libc.stdlib cimport malloc, free, calloc
cdef extern from "immintrin.h": # in this example, we use AVX2
ctypedef float __m256
__m256 _mm256_loadu_ps (float *__P) nogil
__m256 _mm256_add_ps (__m256 __A, __m256 __B) nogil
__m256 _mm256_mul_ps (__m256 __A, __m256 __B) nogil
__m256 _mm256_fmadd_ps (__m256 __A, __m256 __B, __m256 __C) nogil
void _mm256_store_ps (float *__P, __m256 __A) nogil
cdef void Example_v1 (float *A, float *B, float *C) :
### this example for A and B having exactly 8 elements
cdef:
__m256 mA, mB, mC
float[8] out1, out2
int i
with nogil:
mA = _mm256_loadu_ps( &A[0] )
mB = _mm256_loadu_ps( &B[0] )
mC = _mm256_loadu_ps( &C[0] )
_mm256_store_ps( &out1[0], _mm256_add_ps ( mA, mB ) )
_mm256_store_ps( &out2[0], _mm256_fmadd_ps( mA, mB, mC ) )
for i in range(8):
print( "out1 out2 : ", i, out1[i], out2[i], sep=", " )
def run1(float [::1] A, float [::1] B, float [::1] C):
Example_v1( &A[0] , &B[0] , &C[0] )
在我的python代码中,我称它们为:
import numpy as np
print ("Hello World")
from avx_test7 import run1
np.random.seed(1)
A = np.ones(8 , dtype=np.float32)
B = np.random.rand(8).astype(np.float32)
C = np.random.rand(8).astype(np.float32)
print ( A + B)
print ( A * B + C)
run1(A, B, C)
当我运行它们时,我的spyder崩溃或卡住了。并没有错误消息,并没有什么,只是挂起,虽然我可以重新启动内核
我已经多次扫描cython文件,没有发现任何错误。有人能帮忙吗?我使用了MSVC 2017编译器,cython文件编译正常。我不知道cython,但似乎您对本地数组变量(自动存储)调用了
free(out1)
,而不是动态分配的。这将打破正常的C。同样,你在循环它们之前也这样做,这看起来非常错误。如果不是这样,请在调试器下运行您的代码以查看崩溃的位置。对不起,当事情已经出现问题时,添加了“free”,并且打印内容当时已被注释掉。我重新打开它只是为了让它看起来像示例_v1生成了一些可以检查的东西,我将对它进行一些编辑。它似乎在Linux上的GCC上对我有效。显然,这对你帮助不大。我确实必须将CFLAGS更改为-march=native
才能编译它-我不知道msvc是否需要类似的更改您可以尝试\u mm256\u storeu\u ps
而不是\u mm256\u store\u ps
?您的数据可能仅与16字节对齐。@chtz可能是对的:在Win64上堆栈指针仅与16字节对齐,崩溃的几率为50%,因为out1、out2不必是32字节对齐的。我不知道Cython,但您似乎对本地数组变量(自动存储)调用了free(out1)
,而不是动态分配的。这将打破正常的C。同样,你在循环它们之前也这样做,这看起来非常错误。如果不是这样,请在调试器下运行您的代码以查看崩溃的位置。对不起,当事情已经出现问题时,添加了“free”,并且打印内容当时已被注释掉。我重新打开它只是为了让它看起来像示例_v1生成了一些可以检查的东西,我将对它进行一些编辑。它似乎在Linux上的GCC上对我有效。显然,这对你帮助不大。我确实必须将CFLAGS更改为-march=native
才能编译它-我不知道msvc是否需要类似的更改您可以尝试\u mm256\u storeu\u ps
而不是\u mm256\u store\u ps
?您的数据可能仅与16字节对齐。@chtz可能是对的:在Win64上堆栈指针仅与16字节对齐,崩溃的几率为50%,因为out1、out2不必与32字节对齐