OpenCL向量加法程序缓冲区未正确读取主机端数据问题
问题原因
代码输出异常值的核心问题是主机与OpenCL内核的数据类型不匹配:
- 主机侧用于存储计算数据的
h_a、h_b、h_c均为float类型向量,元素按照IEEE754浮点数规则编码 - OpenCL内核中三个缓冲区参数被声明为
int*类型,内核会按整数补码规则解析同一块内存的数据
两种类型虽然单元素都占4字节内存,但编码逻辑完全不同,跨类型读写必然解析出无意义的乱码值。
同时内核中的printf调用也存在格式不匹配问题:%f格式符要求传入浮点数参数,实际传入的是int类型值,触发未定义行为,所以打印出的A、B、C值全为0。
修复方案
仅需修改内核代码的参数类型,将三个缓冲区的指针类型从int改为float即可,修正后的内核代码如下:
// kernel calculates for each element C=A+B std::string kernel_code= " void kernel simple_add(global const float* A, global const float* B, global float* C){ " " int gid = get_global_id(0); " " C[gid] = A[gid] + B[gid]; " " printf(\"%f %f %f \\n\", A[gid], B[gid], C[gid]); " " } ";
其余主机侧代码无需修改,重新编译运行即可得到正确的向量加法计算结果。
补充提示
你当前使用的计算设备是Intel核显,属于GPU类设备,GPU上多个工作项并行执行,printf的输出顺序不保证和全局ID顺序一致,如果需要按索引核对计算结果,以主机端最后读回h_c后打印的数值为准。
内容的提问来源于stack exchange,提问作者Jake Calcutt
相关产品推荐
相关产品推荐

