2013-04-11 21 views
5

下面的python代碼使用PyOpenCL來填充數組b(這不是我的實際目標,但它是我能找到的最簡單的代碼仍然顯示問題)的數組a_plus_b爲什麼這個opencl代碼不確定?

import pyopencl as cl 
import numpy as np 
import numpy.linalg as la 

height = 50 
width = 32 

b = np.arange(width,dtype=np.int32) 

ctx = cl.create_some_context() 
queue = cl.CommandQueue(ctx) 

mf = cl.mem_flags 
b_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=b) 
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, height*4) 

prg = cl.Program(ctx, """ 
    __kernel void sum(__global const int *b, __global int *c) 
    { 
     int x = get_global_id(1); 
     int y; 
     c[x] = 0; 
     for(y=0;y<get_global_size(0);y++) { 
      c[x] += b[y]; 
     } 
    } 
    """).build() 

prg.sum(queue, (width,height), None, b_buf, dest_buf) 

a_plus_b = np.empty(height,dtype=np.int32) 
cl.enqueue_copy(queue, a_plus_b, dest_buf) 

print(np.sum(b)) 
print(a_plus_b) 
print(np.sum(a_plus_b-np.sum(b))) 

給出的輸出:

496 
[496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 
496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 496 
496 496 496 496 496 496 496 496 496 496 496 496 496 496] 
0 

然而,如果我改變寬度從32到33,所述陣列是不再一遍又一遍相同的元件。

528 
[555 557 555 559 560 528 560 560 528 528 528 528 528 528 528 528 528 528 
528 528 528 531 540 569 581 528 705 591 560 560 545 560 560 528 560 528 
528 528 528 528 528 528 528 528 528 528 528 532 533 535] 
752 

實際上,每次代碼運行時,它都會產生不同的結果。

528 
[560 560 559 560 560 560 560 528 528 528 528 528 528 528 528 528 528 528 
528 528 528 560 528 514 565 553 621 650 560 560 560 560 560 528 528 528 
528 528 528 528 528 528 528 528 549 528 528 544 528 537] 
724 

是什麼引起了差異?什麼不是

回答

2

您正在運行WIDTH x HEIGHT工作項目。對於內核中的每個X值,都會有WIDTH工作項並行執行完全相同的操作:將C [X]設置爲0,然後在Y循環中更新它。所有這些WIDTH工作項目都將讀取C [X],然後同時更新或多或少地更新它。這或多或少是你觀察到的變化的原因。

您的算法是1D,您只需要運行HEIGHT工作項,並將WIDTH作爲內核參數傳遞。將C [X]替換爲一個寄存器「SUM」,並在最後執行一個C [X] = SUM。

+0

解決了這個問題。我想這是我得到的懶惰,而不是作爲一個實際參數傳遞數組的長度。 – user640078 2013-04-11 22:00:43