【问题标题】:How to atomic increment a global counter in OpenCL如何在 OpenCL 中原子增加全局计数器
【发布时间】:2016-08-12 16:52:45
【问题描述】:

我希望在 OpenCL 中有一个全局计数器,可以通过每个工作组中的每个工作项来增加。

在我的内核中我这样做:

#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable

void increase(volatile __global int* counter)
{
    atomic_inc(counter);
}

__kernel void test()
{  
    volatile __global int* counter = 0; 
    increase(counter);
    printf("Counter: %i",&counter);
}

我的主机代码是最小的 pyopencl 以使内核入队:

import pyopencl as cl

platform = cl.get_platforms()[0]
devs = platform.get_devices()
device = devs[0]
ctx = cl.Context([device])
queue = cl.CommandQueue(ctx)
mf = cl.mem_flags

f = open('Minimal.cl', 'r')
fstr = "".join(f.readlines())
prg = cl.Program(ctx, fstr).build()
test_knl = prg.test

def f():
     cl.enqueue_nd_range_kernel(queue,test_knl,(1,1,2),None)
f()

我希望输出显示"Counter: i" 的(可能是随机排序的)外观,其中i 是总工作项的数量(在我的情况下为 2)。 相反,我没有得到打印输出。当我重新运行程序时,它失败了

pyopencl.cffi_cl.LogicError: clcreatecontext failed: <unknown error -9999>

彻底杀死我的 IDE (Spyder)。

【问题讨论】:

    标签: opencl global atomic pyopencl


    【解决方案1】:
    volatile __global int* counter = 0; 
    

    创建一个指向全局内存的指针是不够的。后面一定有一些全局内存存储。

    至少有两种选择:

    1) 如果使用 OpenCL 2.0 实现,则可以创建程序范围变量:

    void increase(volatile __global int* counter)
    {
      atomic_inc(counter);
    }
    
    __global int counter = 0;
    
    __kernel void test()
    {  
      volatile __global int* counterPtr = &counter; 
      increase(counterPtr); // or increase(&counter);
      printf("Counter: %i",*counterPtr);
    }
    

    2) 创建一个 OpenCL 缓冲区并通过内核参数传递它:

    void increase(volatile __global int* counter)
    {
      atomic_inc(counter);
    }
    
    __kernel void test(__global int *counterArg)
    {  
      volatile __global int* counterPtr = counterArg; 
      increase(counterPtr); // or increase(counterArg);
      printf("Counter: %i",*counterPtr);
    }
    

    【讨论】:

    • 看起来不错,但是 1) 对我不起作用,因为我不在 OpenCL 上 2 和 2) 给我错误“__kernel 函数 __kernel void test 的指针参数指针的地址空间无效(int counterArg)”和“从地址空间“私有”到地址空间“全局”的隐式转换在初始化表达式中不受支持 volatile __global int counterPtr = counterArg;“
    • 更改为 __kernel void test(__global int *counterArg) 似乎可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    相关资源
    最近更新 更多