我在OpenCL中有一个简单的内核,它具有以下结构:
kernel void simple_select(global double *input, global double *output) {
size_t i = get_global_id(0);
printf("input %d\n", (int)(input[i] != 0.0));
output[i] = select((float)0.0, (float)1.0, (int)(input[i] != 0.0));
//output[i] = select((float)0.0, (float)1.0, 1);
}
同样地,这可以是:
kernel void simple_select(global double *input, global double *output) {
size_t i = get_global_id(0);
printf("input %d\n", (int)(input[i] != 0.0));
output[i] = input[i] != 0.0 ? 1.0 : 0.0;
//output[i] = 1 ? 1.0 : 0.0;
}
当我打印到命令行时,我看到:
input 1
input 1
input 1
但输出数组全部为0.0
。但是,如果我取消注释内核的最后一行并注释掉倒数第二行(意味着如果我在select语句中使用标量1
),那么它按预期工作并且输出数组包含所有内容1.0
。那么这两行之间的区别是什么导致两种不同的结果?
答案 0 :(得分:0)
这是OpenCL的一个怪癖。问题是标量的真/假值是1/0(就像printf给你看的那样),但是向量的真/假值是-1/0 - 这也是select()在最后一个参数中所期望的(更确切地说) ,它期望MSB设置,这意味着任何负整数)。
虽然我认为标量上的三元运算符仍然可以正常工作,如果不是,我会认为它是一个错误。