Cython с AVX SIMD: код выполняется один раз правильно, но зависает при необходимости для повторного запуска - PullRequest
0 голосов
/ 01 апреля 2020

Я все еще очень плохо знаком с внутренностями SIMD и со второй попытки через Cython. После некоторой помощи от людей здесь (большое спасибо) у меня есть это:

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_storeu_ps (float *__P, __m256 __A) nogil  

cdef float [::1] Example_v2 (float *A, float *B, float *C, int n) :
    ### this example for A and B having more than 8 elements, possibly non-divisible by 8    
    cdef:
        __m256 mA, mB, mC
        float *out = <float*> malloc( n * sizeof(float)) 
        float [::1] out_mem = <float [:n]> out
        int i, j, m = <int>( (n-1) / 8) + 1

    with nogil:
        for i in range(m):
            j = 8*i
            mA = _mm256_loadu_ps( &A[j] )
            mB = _mm256_loadu_ps( &B[j] )
            mC = _mm256_loadu_ps( &C[j] )
            _mm256_storeu_ps( &out[j] , _mm256_fmadd_ps( mA, mB, mC ) )

    return out_mem

def run2(float [::1] A, float [::1] B, float [::1] C):
    return Example_v2( &A[0] , &B[0] , &C[0], A.shape[0] )

Если n делится на 8. numpy A * B + C и Cython идентичен, и это ТОЛЬКО хорошо Новости.

Если n не делится на 8. Он может работать только один раз, дает правильный ответ, и тогда мой Spyder выведет сообщение ниже. Второй запуск, без изменения чего-либо, приведет к остановке / зависанию или повторению первого запуска. Я не знаю, как еще это исправить.

Еще один связанный с этим вопрос: есть ли лучший способ написать раздел под «с ногилом»? Numpy все еще быстрее для N = 400, работает через l oop (100 000). Вздох ...

  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\_pswindows.py", line 679, in wrapper
    return fun(self, *args, **kwargs)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\_pswindows.py", line 933, in create_time
    user, system, created = cext.proc_times(self.pid)
ProcessLookupError: [Errno 3] No such process (originated from GetExitCodeProcess != STILL_ACTIVE)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\__init__.py", line 373, in _init
    self.create_time()
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\__init__.py", line 723, in create_time
    self._create_time = self._proc.create_time()
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\_pswindows.py", line 681, in wrapper
    raise convert_oserror(err, pid=self.pid, name=self._name)
psutil.NoSuchProcess: psutil.NoSuchProcess process no longer exists (pid=9296)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\beng_\Anaconda3\lib\site-packages\qtconsole\manager.py", line 27, in poll
    super(QtKernelRestarter, self).poll()
  File "C:\Users\beng_\Anaconda3\lib\site-packages\jupyter_client\restarter.py", line 113, in poll
    self.kernel_manager.restart_kernel(now=True, newports=newports)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\jupyter_client\manager.py", line 411, in restart_kernel
    self.shutdown_kernel(now=now, restart=True)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\jupyter_client\manager.py", line 371, in shutdown_kernel
    self._kill_kernel()
  File "C:\Users\beng_\Anaconda3\lib\site-packages\spyder\plugins\ipythonconsole\utils\manager.py", line 78, in _kill_kernel
    self.kill_proc_tree(self.kernel.pid)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\spyder\plugins\ipythonconsole\utils\manager.py", line 44, in kill_proc_tree
    parent = psutil.Process(pid)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\__init__.py", line 346, in __init__
    self._init(pid)
  File "C:\Users\beng_\Anaconda3\lib\site-packages\psutil\__init__.py", line 386, in _init
    raise NoSuchProcess(pid, None, msg)
psutil.NoSuchProcess: psutil.NoSuchProcess no process found with pid 9296

...