我刚开始通过 Python 的 PyOpenCL 接口使用 OpenCL。我试图创建一个非常简单的“循环”程序,其中每个内核中每个循环的结果取决于上一个循环周期中另一个内核的输出,但我遇到了同步问题:
__kernel void part1(__global float* a, __global float* c)
{
unsigned int i = get_global_id(0);
c[i] = 0;
barrier(CLK_GLOBAL_MEM_FENCE);
if (i < 9)
{
for(int t = 0; t < 2; t++){
c[i] = c[i+1] + a[i];
barrier(CLK_GLOBAL_MEM_FENCE);
}
}
}
主机应用程序是
import pyopencl as cl
from numpy import *
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
#read in the OpenCL source file as a string
f = open('recurrent.cl', 'r')
fstr = "".join(f.readlines())
#create the program
program = cl.Program(ctx, fstr).build()
mf = cl.mem_flags
#initialize client side (CPU) arrays
a = array(range(10), dtype=float32)
#create OpenCL buffers
a_buf = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a)
dest_buf = cl.Buffer(ctx, mf.WRITE_ONLY, a.nbytes)
#execute program
program.part1(queue, a.shape, None, a_buf, dest_buf)
c = empty_like(a)
cl.enqueue_read_buffer(queue, dest_buf, c).wait()
print "a", a
print "c", c
结果是
a [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
c [ 0. 1. 5. 3. 4. 18. 13. 7. 8. 0.]
如您所见,一些结果值是正确的。例如,第三个位置 = 5 = 3 + 2,但例如第二个位置是 2 = 0 + 2。因此,尽管存在障碍,但总和超过了其他线程在不同时间点的结果。我认为屏障会确保所有线程都到达它并将它们的结果写入全局内存?
这可能是非常简单的事情,我将不胜感激任何提示和评论!
PS:我正在使用 Intel SDK 在 Sandy Bridge CPU 上运行它。