【问题标题】:OpenCL kernel draws only on diagnoalOpenCL 内核仅在对角线上绘制
【发布时间】:2020-01-18 22:33:47
【问题描述】:

我目前正在 OSX 上开发 OpenCL 内核,我正在尝试将输入图像设置为所有 255。 我用CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTRCL_UNSIGNED_INT8 创建了一个单通道图像,我的内核和主机代码如下:

const sampler_t linear_sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_FILTER_LINEAR | CLK_ADDRESS_CLAMP_TO_EDGE;
__kernel void test(__write_only image2d_t dst)
{
    const int2 src_pos = int2(get_global_id(0), get_global_id(1));
    write_imagei(dst, src_pos, 255);
}

void clTest(cl_image2d dst)
{        
    cl_int retval;

    cl_kernel kTest = clCreateKernel(m_oclEnv.program, "test", &retval);
    CHECK_OCL(clSetKernelArg(kTest, 0, sizeof(cl_mem), (void*)&dst.mem));

    size_t grid_item_size[2] = {static_cast<size_t>(m_nFrameWidth), static_cast<size_t>(m_nFrameHeight)};
    size_t block_item_size[2] = {8, 8};
    cl_uint nDim = 2;        

    CHECK_OCL(clEnqueueNDRangeKernel(m_oclEnv.queue, kTest, nDim, NULL, grid_item_size, block_item_size, 0, NULL, NULL));

    clReleaseKernel(kTest);

}

结果输出图像如下:

显然内核只在y=x的位置绘制,那么问题出在哪里呢?谢谢。

ps:我已经尝试将图像写入GPU并立即读取并且效果很好,因此opencl上下文或环境应该没有任何问题。

【问题讨论】:

  • 可能不是问题的根源,但对于无符号类型的图像,您需要使用write_imageui
  • 问题已解决。在我的 opencl 内核的第一行。将类型int2 更改为(int2),我不知道为什么内核之前会这样,为什么opencl 没有报告任何语法错误。

标签: kernel gpu opencl


【解决方案1】:

认为,这条线

    const int2 src_pos = int2(get_global_id(0), get_global_id(1));

分解为以下子表达式:

(get_global_id(0), get_global_id(1))

这是逗号运算符!换句话说,这仅计算为get_global_id(1)。所以我们有:

const int2 src_pos = int2(get_global_id(1));

...将get_global_id(1) 复制到int2 的两个组件中。

请注意,我并不是说这种语法和解释是合理的,或者编译器应该在没有警告的情况下接受它。不幸的是,与现代 C 和 C++ 编译器相比,OpenCL 编译器在检测和警告您可能的未定义行为或可能的意外语法方面非常糟糕。

【讨论】:

  • 我已经尝试过 Intel NEO (19.25.13237)、Nvidia (CUDA 10.0.292) 和 Pocl(使用 LLVM 8.0),但三者都拒绝编译该内核。所以至少在这种情况下,问题不在于 OpenCL 编译器,而更可能是 OP 使用了来自一些古老的 OS X 实现的古老编译器,这是废话。 Apple 在正式宣布之前很久就放弃了 OpenCL,因此它们的实施是 beta 质量的也就不足为奇了。
猜你喜欢
  • 2013-08-06
  • 2013-03-13
  • 2015-10-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多