2016-06-19 38 views
1

我有一個數組,我反覆地建立類似如下:dask.array.reshape很慢

step1.shape = (200,200) 
step2.shape = (200,200,200) 
step3.shape = (200,200,200,200) 

,然後重塑到:

step4.shape = (200,200**3) 

我這樣做是因爲dask.array.atop似乎並不允許你從這樣的形狀出發:(200,200) - >(200,200 ** 2)。我認爲這與分塊和懶惰評估有關。

當我做step4並嘗試重塑它時,dask似乎想要在重塑它之前計算矩陣,這會導致顯着的計算時間和內存使用。

有沒有辦法避免這種情況?

按照要求,這裏是一些僞代碼:

def prod_mat(matrix_a,matrix_b): 
    #mat_a.shape = (300,...,300,200) 
    #mat_b.shape = (300, 200) 
    mat_a = matrix_a.reshape(-1,matrix_a.shape[-1]) 
    #mat_a = (300**n,200) 
    mat_b = matrix_b.reshape(-1,matrix_b.shape[-1]) 
    #mat_b = (300,200) 
    mat_temp = np.repeat(mat_a,matrix_b.shape[0],axis=0)*np.tile(mat_b.T,mat_a.shape[0]).T 
    new_dim = int(math.log(mat_temp.shape[0])/math.log(matrix_a.shape[0])) 
    new_shape = [matrix_a.shape[0] for n in range(new_dim)] 
    new_shape.append(-1) 
    result = mat_temp.reshape(tuple(new_shape)) 
    #result.shape = (300,...,300,300,200) 
    return result 

b = np.random.rand(300,200) 
b = da.from_array(b,chunks=100) 
c=da.atop(prod_mat,'ijk',b,'ik',b,'jk') 
d=da.atop(prod_mat,'ijkl',c,'ijl',b,'kl') 
e=da.atop(prod_mat,'ijklm',d,'ijkm',b,'lm') 
f = e.sum(axis=-1) 
f.reshape(300,300**3) ----> This is slow, as if it is using compute() 
+0

對不起,我不明白你的問題的步驟。你能否提供一個你試圖做的失敗或緩慢的示例操作?也許隨機數據? – MRocklin

+0

我會將它添加到原始帖子中。 – simeon

回答

0

這一計算並沒有叫compute,而是卡住了做一個非常非常大的圖形。一般來說,重塑平行陣列非常緊張。很多小塊都會與很多其他小塊進行交談,造成嚴重破壞。這個例子特別糟糕。

也許還有另一種方法可以在最初產生正確形狀的輸出嗎?

翻翻看來這個故障是在開發過程中實際所預期的發展日誌:https://github.com/dask/dask/pull/758

+0

謝謝!我會盡量有點創意,看看我能如何避免它。 – simeon

+0

我顯然需要一些靈感。你有什麼建議嗎?即使這個玩具難題:'e = da.atop(lambda x,y,z:np.einsum('i,j,k-> ijk',x,y,z),'ijk',z''i ',z,'j',z,'k')'所有我想要做的事情是扁平化數組似乎花費更多的時間扁平化比計算值... – simeon

+0

我試過手動重塑它通過使用concatenate,但沒有太多的運氣。 – simeon