Python 使用SIMD内部崩溃的Cython

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

我正在尝试将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 (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字节对齐