当条件结果为真时,为什么OpenCL应用放在条件的else部分的代码

时间:2014-04-29 12:22:01

标签: macos opencl

我刚刚开始使用openCL进行开发,我对启动内核时的结果感到困惑。

kernel void clTest1(read_only image2d_t input, write_only image2d_t output)
{
    size_t  x           = get_global_id(0);
    size_t  y           = get_global_id(1);
    bool    yIsEven     = ((y % 2) == 0);
    int     modifiedY   = 0;

    if (yIsEven) {
    modifiedY = y;
    } else {
    modifiedY = (y - 1);
    }

    printf("Original Y:%i isEven:%i Modified Y: %i", y, yIsEven, modifiedY);

    write_imageui(output, (int2)(x,y), read_imageui(input, sampler, (int2)(x,modifiedY)));
}

如果我查看控制台日志,

我得到以下结果:
原始Y:0即使:1修改Y:0
原始Y:1是即使:0修改Y:0
原Y:2即使:1修改Y:1
原Y:3即使:0修改Y:2
原Y:4即使:1修改Y:3
原Y:5即使:0修改Y:4
原Y:6即使:1修改Y:5
原Y:7即使:0修改Y:6
原Y:8即便:1修改Y:7
原始Y:9即使:0修改Y:8

而不是
原始Y:0即使:1修改Y:0
原始Y:1是即使:0修改Y:0
原Y:2即使:1修改Y:2
原Y:3即使:0修改Y:2
原Y:4即使:1修改Y:4
原Y:5即使:0修改Y:4
原Y:6即使:1修改Y:6
原Y:7即使:0修改Y:6
原Y:8即使:1修改Y:8
原始Y:9即使:0修改Y:8

提前致谢。

4 个答案:

答案 0 :(得分:1)

您的代码很好,对我有用。鉴于它适用于CPU但不适用于GPU,这似乎是Apple的OpenCL实现中的一个错误,这一点并不罕见。

我建议您使用Apple Bug Tracking System提出错误。

答案 1 :(得分:0)

你能尝试这样做吗?

 printf("Original Y:%i isEven:%i Modified Y: %i", (int)y, (int)yIsEven, (int)modifiedY);

我真的不相信vararg适用于GPU环境和bool类型的投射。

PD:无论哪种方式,都是Apple OCL问题,结果应该没问题。

答案 2 :(得分:0)

当我使用clang进行轻微编辑(见下文)构建代码时,我获得了以下LLVM IR:

$ cat go.ll 
; ModuleID = 'go.cl'
target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
target triple = "nvptx64-nvidia-nvcl"

; Function Attrs: noinline nounwind
define void @clTest1(i32* nocapture readnone %input, i32* nocapture %output) #0 {
  %1 = tail call i64 @get_global_id(i32 0) #2
  %2 = tail call i64 @get_global_id(i32 1) #2
  %3 = and i64 %2, 1
  %4 = icmp eq i64 %3, 0
  %5 = add nsw i64 %2, 4294967295
  %modifiedY.0.in = select i1 %4, i64 %2, i64 %5
  %modifiedY.0 = trunc i64 %modifiedY.0.in to i32
  %6 = getelementptr inbounds i32* %output, i64 %1
  store i32 %modifiedY.0, i32* %6, align 4, !tbaa !3
  ret void
}

因此,您可以看到%modifiedY获得select(yIsEven, y, modifiedY)的结果。请注意,OpenCL selectLLVM IR select之间args的顺序不同。

长话短说:您编写的代码应该按照描述的方式工作。如果它没有,那么它就是你的OCL提供商或环境中的一个错误。

"轻微编辑":

$ diff -Naur go_orig.cl go.cl 
--- go_orig.cl  2014-04-29 08:14:24.453488798 -0500
+++ go.cl   2014-04-29 08:15:01.657489768 -0500
@@ -1,5 +1,5 @@

-kernel void clTest1(read_only image2d_t input, write_only image2d_t output)
+kernel void clTest1(read_only int *input, write_only int *output)
 {
     long  x           = get_global_id(0);
     long  y           = get_global_id(1);
@@ -12,7 +12,5 @@
         modifiedY = (y - 1);
     }

-    printf("Original Y:%i isEven:%i Modified Y: %i", y, yIsEven, modifiedY);
-
-    write_imageui(output, (int2)(x,y), read_imageui(input, sampler, (int2)(x,modifiedY)));
+    output[x] = modifiedY;
 }

答案 3 :(得分:0)

我通过在项目的构建设置中删除OpenCL优化来修复它。

OPENCL_OPTIMIZATION_LEVEL = 0