2013-04-11 43 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