2016-08-12 22 views
1

我想在OpenCL中擁有一個全局計數器,每個工作組中的每個工作項都可以增加一個全局計數器。如何在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); 
} 

我Hostcode是排隊內核最低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)。

回答

3
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); 
} 
+0

看起來不錯,但1)不適合我,因爲我不上的OpenCL 2和2)給我的錯誤的指針參數的指針對象,以__kernel功能「無效的地址空間__kernel void test(int * counterArg)「 and 」初始化表達式不支持從地址空間「private」到地址空間「global」的隱式轉換 volatile __global int * counterPtr = counterArg; 「 – Dschoni

+0

更改爲__kernel void test(__ global int * counterArg)似乎可以做到這一點。 – Dschoni