【问题标题】:Cumulative sum with opencl与opencl的累积和
【发布时间】:2013-09-02 11:40:48
【问题描述】:

我尝试用opencl实现累积和如下:

__kernel void cumsum(__global float *a)
{
    int gid = get_global_id(0);
    int n = get_global_size(0);

    for (int i = 1; i < n; i <<= 1)
        if (gid & i)
            a[gid] += a[(gid & -i) - 1];
}

我使用 pyopencl 调用了这段代码:

import pyopencl as cl
import pyopencl.array as cl_array
import numpy as np

a = np.random.rand(50000).astype(np.float32)

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

a_dev = cl_array.to_device(queue, a)

with open("imm/cluster.cl", 'r') as f:
    prg = cl.Program(ctx, f.read()).build()

prg.cumsum(queue, a.shape, None, a_dev.data)
print(np.cumsum(a)[:33], a_dev[:33])

但是,前 32 个数字是正确的,之后它们是错误的(太低)。这与工作组规模有关吗?我该如何解决这个问题?

【问题讨论】:

    标签: opencl pyopencl


    【解决方案1】:

    i 变得足够大时,您将读取另一个工作组的输出。 OpenCL 执行模型中的任何内容都不能保证其他工作组将完成执行。

    通常情况并非如此,您将读取部分总和,最后得到的值低于预期。

    【讨论】:

    • 谢谢。我相信这些被称为“扫描算法”?你有没有机会知道一个好的教程?
    • 由于您使用的是 PyOpenCL,您可能可以看看its implementation of such algorithms
    • @bogdan:谢谢,我确实找到了那个页面,但这不是最清晰的教程。我正在阅读规范 pdf,它更完整,但不是最好的。
    • 这个答案是正确的。但是,我看到的问题发生在元素 32 上——远小于工作组大小(400)。正如 Eric 预测的那样,添加内存屏障导致问题发生在元素 400。
    猜你喜欢
    • 2011-04-15
    • 2017-06-28
    • 2013-10-29
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    相关资源
    最近更新 更多