具有 3d 全局大小和 3d 局部大小的 OpenCL NDrangekernel
OpenCL NDrangekernel with 3d global size and 3d local size
我正在尝试通过识别 3d 体积位置和组 ID 来计算每个组的局部总和。
我的想法是将space分成几组,然后用atomic_add计算local_sum。
但是因为我是并行计算的新手,所以很难找到代码和指令之间的相关性。
我当前的内核是这样的:
__kernel void TestAtomicAddLocal(__global *int src, int3 size, __global int *res)
{
int x = get_global_id(0);
int y = get_global_id(1);
int z = get_global_id(2);
if( x >= vol_dim.x || y >= vol_dim.y || z >= vol_dim.z ){ return; }
int id = x + y * vol_dim.x + z * vol_dim.x * vol_dim.y;
// local mem shared by all work items in work group,
//so this can be accessed by all items in current workgroup
__local int local_sum;
local_sum= 0;
// use global_id to access the value of input array
int local_offset = atomic_add(&local_sum, src[id]);
barrier(CLK_LOCAL_MEM_FENCE);
int global_offset = atomic_add(&num_verts[0], local_sum);
barrier(CLK_GLOBAL_MEM_FENCE);
}
主机部分,我的设置是
enqueueNDrangeKernel( cq, kn_testAtomicAddLocal, 3, 0, cl::size3(256,256,256), cl::size3(64, 64, 64), 0, 0, 0);
对于内核参数,*src 为 cl_mem
,大小为 256*256*256*sizeof(cl_int)
,大小为 4 * sizeof(cl_int)
,*res 为 cl_mem
,大小为 4*sizeof(int)
.
然后我得到 CL_OUT_OF_RESOURCE 和 CL_INVALID_GROUP_SIZE 的错误,根据我的理解,我的设备最大组大小是 1024,但这里总组 = (256/64)^3 = 64 < 1024。
我的 gpu 最大工作项大小是 1024x1024x64,这也可以。所以我认为我理解的一定是错误的。我希望有人能帮助我。
最大组大小限制了您的 64 * 64 * 64 部分。
而且我猜你使用的是 CUDA 卡。你最好在 CUDA 卡上使用 CUDA。 OpenCL 或多或少在 CUDA 卡上被模拟。如果不是,我认为所有 AMD 卡的组大小限制为 256。编辑:嗯...我忘记了英特尔的。如果是,请忽略此部分。
还有一点很重要,你最好先去网上查一些归约逻辑的实现例子。原子非常昂贵,像您所做的那样使用它们几乎可以肯定会使您的 GPU 代码比 CPU 慢。
我正在尝试通过识别 3d 体积位置和组 ID 来计算每个组的局部总和。
我的想法是将space分成几组,然后用atomic_add计算local_sum。 但是因为我是并行计算的新手,所以很难找到代码和指令之间的相关性。 我当前的内核是这样的:
__kernel void TestAtomicAddLocal(__global *int src, int3 size, __global int *res)
{
int x = get_global_id(0);
int y = get_global_id(1);
int z = get_global_id(2);
if( x >= vol_dim.x || y >= vol_dim.y || z >= vol_dim.z ){ return; }
int id = x + y * vol_dim.x + z * vol_dim.x * vol_dim.y;
// local mem shared by all work items in work group,
//so this can be accessed by all items in current workgroup
__local int local_sum;
local_sum= 0;
// use global_id to access the value of input array
int local_offset = atomic_add(&local_sum, src[id]);
barrier(CLK_LOCAL_MEM_FENCE);
int global_offset = atomic_add(&num_verts[0], local_sum);
barrier(CLK_GLOBAL_MEM_FENCE);
}
主机部分,我的设置是
enqueueNDrangeKernel( cq, kn_testAtomicAddLocal, 3, 0, cl::size3(256,256,256), cl::size3(64, 64, 64), 0, 0, 0);
对于内核参数,*src 为 cl_mem
,大小为 256*256*256*sizeof(cl_int)
,大小为 4 * sizeof(cl_int)
,*res 为 cl_mem
,大小为 4*sizeof(int)
.
然后我得到 CL_OUT_OF_RESOURCE 和 CL_INVALID_GROUP_SIZE 的错误,根据我的理解,我的设备最大组大小是 1024,但这里总组 = (256/64)^3 = 64 < 1024。
我的 gpu 最大工作项大小是 1024x1024x64,这也可以。所以我认为我理解的一定是错误的。我希望有人能帮助我。
最大组大小限制了您的 64 * 64 * 64 部分。
而且我猜你使用的是 CUDA 卡。你最好在 CUDA 卡上使用 CUDA。 OpenCL 或多或少在 CUDA 卡上被模拟。如果不是,我认为所有 AMD 卡的组大小限制为 256。编辑:嗯...我忘记了英特尔的。如果是,请忽略此部分。
还有一点很重要,你最好先去网上查一些归约逻辑的实现例子。原子非常昂贵,像您所做的那样使用它们几乎可以肯定会使您的 GPU 代码比 CPU 慢。