2014-06-19 38 views
2

這是我正在嘗試做的一個最簡單的例子。我正在計算矩陣之間的成對距離,我將它們排列成一個堆棧數組。 idx數組保存每個子矩陣的偏移量。與Cython記憶體並行

當我刪除parallel()並將prange替換爲range時,代碼按預期工作(當然,不是平行的)。

import numpy as np 
cimport numpy as np 
cimport cython 
from cython.parallel import parallel, prange 

@cython.boundscheck(False) 
@cython.wraparound(False) 
@cython.nonecheck(False) 
def all_pairs_distance(float[:,::1] stacked, int[::1] idx): 
    cdef int n = idx.shape[0] - 1 
    cdef float[:,::1] D = np.zeros((n,n), dtype='float32') 
    cdef int i,j 
    cdef float[:,::1] t1,t2 
    cdef float d 
    with nogil, parallel(): 
    for i in prange(n): 
     t1 = stacked[idx[i]:idx[i+1],:] 
     for j in range(i+1, n): 
     t2 = stacked[idx[j]:idx[j+1],:] 
     d = nogil_cython_function(t1, t2) 
     D[i,j] = d 
     D[j,i] = d 
    return D 

cdef float nogil_cython_function(float[:,::1] a, float[:,::1] b) nogil: 
    # Function abbreviated for simplicity 
    return 0.0 

當試圖編譯該文件,我得到的每一個分配錯誤t1t2

Memoryview slices can only be shared in parallel sections 
  1. 我不知道如何解決這個錯誤。這些任務是否不在平行部分?
  2. 如何告訴編譯器我的stacked memoryview是隻讀的,並且可以在線程之間共享嗎?
+0

我想你可以給每個線程只有他們實際使用的數組部分。檢查[這個答案](http://stackoverflow.com/a/20520295/832621)這是用原始指針(我發現這個任務更直接)實現這 –

回答

7

我想通了,有點實驗後:

for i in prange(n, nogil=True): 
    for j in range(i+1, n): 
    d = nogil_cython_function(stacked[idx[i]:idx[i+1],:], 
           stacked[idx[j]:idx[j+1],:]) 

外賣是一個切片內prange memoryviews是好的,但分配這些切片的變量是沒有的。

+0

這正是我需要prange使用memoryview切片。顯然,其他地方沒有記錄你的解決方案,只是不要將片分配給變量,直接使用片。 – Matt