Intrinsi c для Cython и SIMD: предотвращение преобразования в python объект для аргумента функции intrinsi c SIMD - PullRequest
0 голосов
/ 06 апреля 2020

Я добился некоторого успеха в тестировании встроенных функций SIMD через Cython. Прямо сейчас я пытаюсь заставить работать функцию сравнения в AVX, потому что функция сравнения нуждалась в аргументе, который не должен быть преобразован в объект python.

cdef extern from "immintrin.h" nogil:  # in this example, we use SSE2
    ctypedef float  __m256
    const int _CMP_GT_OS

    __m256 _mm256_loadu_ps  (float *__P) nogil  
    void   _mm256_storeu_ps (float *__P, __m256 __A) nogil
    __m256 _mm256_set1_ps   (__m256 __A) nogil
    __m256 _mm256_cmp_ps    (__m256 __A, __m256 __B, _CMP_GT_OS) nogil


@cython.boundscheck(False)      # turn off bounds-checking for entire function
@cython.wraparound (False)      # turn off negative index wrapping for entire function
@cython.cdivision  (True )        
cdef void Example_v4 (float *A, float *B, float delx) :
    ### this example for A & B having exactly 8 elements

    cdef:
        __m256 mA, mB, mdelx, mOut
        float *out = <float*> malloc( 8 * sizeof(float)) 
        int i

    with nogil:
        mdelx = _mm256_set1_ps( delx )
        mA    = _mm256_loadu_ps( &A[0] )
        mB    = _mm256_loadu_ps( &B[0] )        

        mOut = _mm256_cmp_ps  ( mA, mB, _CMP_GT_OS )        
        _mm256_storeu_ps( &out[0], mOut )

    print ( " i     out  " )
    for i in range(8):
        print ( i, out[i] )
    return

Проблема в том, что когда я компилирую код Cython, эта часть подсвечивается как проблема.

        mOut = _mm256_cmp_ps  ( mA, mB, _CMP_GT_OS ) 

with  ^ symbol pointing at _CMP_GT_OS

и сообщение

Converting to Python object not allowed without gil

Я считаю, проблема не в gil, функция intrinsi c определена в официальной документации Intel, поскольку

__m256 _mm256_cmp_ps (__m256 __A, __m256 __B, const int imm8)

imm8 может относиться ко многим типам операций, причем _CMP_GT_OS является одним из них. Я не знаю, как обращаться с третьим аргументом и не допустить его преобразования в python, поскольку intrinsi c распознает только C / C ++ const int. Есть идеи, как обойти эту проблему?

1 Ответ

0 голосов
/ 06 апреля 2020

Я сделал два изменения: в внешней части cdef я добавил к нему значение. Я все еще не уверен на 100%, как использовать эту функцию. Так что это все метод проб и ошибок, но, по крайней мере, так я могу двигаться дальше, чтобы проверить и сделать еще проб и ошибок.

cdef extern from "immintrin.h" nogil:  # in this example, we use SSE2
    ctypedef float  __m256
    const int _CMP_GT_OS = 14

    ## other definition like in the question
    __m256 _mm256_cmp_ps    (__m256 __A, __m256 __B, const int _CMP_GT_OS) nogil

Изменение только объявления в части _mm256_cmp_ps не сработало. Я должен сначала присвоить ему значение.

Теперь он может компилироваться без ошибок и может вызываться и использоваться на стороне python. Что касается результата, все еще странно, поэтому я не знаю, правильно ли это на самом деле или нет. Я доложу, когда пойму больше. В то же время, не стесняйтесь присоединиться. Спасибо.

...