繁体   English   中英

为什么这个opencl代码不确定?

[英]Why is this opencl code non-deterministic?

下面的python代码使用PyOpenCL用数组b中的元素之和填充数组a_plus_b (这不是我的实际目标,但它是我能找到的最简单的代码仍然显示问题)。

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

是什么导致了差异? 什么不是

您正在运行WIDTH x HEIGHT工作项。 对于内核中X的每个值,将有WIDTH工作项并行执行完全相同的操作:将C [X]设置为0,然后在Y循环中更新它。 所有这些WIDTH工作项将读取C [X],然后或多或少地同时更新它。 这种“或多或少”是您观察到的变化的原因。

您的算法是1D,您只需要运行HEIGHT工作项,并将WIDTH作为内核参数传递。 用寄存器“SUM”替换C [X],并在结尾处执行单个C [X] = SUM。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM