我的文件中有一个结构体,它包含在主机代码和内核中
typedef struct {
float x, y, z,
dir_x, dir_y, dir_z;
int radius;
} WorklistStruct;
我正在我的 C++ 主机代码中构建此结构,并通过缓冲区将其传递到 OpenCL 内核。
如果我选择 CPU 设备进行计算,我将得到以下结果:
printf ( "item:[%f,%f,%f][%f,%f,%f]%d,%d\n", item.x, item.y, item.z, item.dir_x, item.dir_y,
item.dir_z , item.radius ,sizeof(float));
主持人:
item:[20.169043,7.000000,34.933712][0.000000,-3.000000,0.000000]1,4
设备(CPU):
item:[20.169043,7.000000,34.933712][0.000000,-3.000000,0.000000]1,4
如果我选择 GPU 设备 (AMD) 进行计算,就会发生奇怪的事情:
主持人:
item:[58.406261,57.786015,58.137501][2.000000,2.000000,2.000000]2,4
设备(GPU):
item:[58.406261,2.000000,0.000000][0.000000,0.000000,0.000000]0,0
值得注意的是 sizeof(float) 在 GPU 上是垃圾。
我认为不同设备上的 float 布局存在问题。
注意:该结构体包含在该类型的结构体数组中,该数组中的每个结构体在 GPU 上都是垃圾
有人知道为什么会出现这种情况以及我如何预测这一点吗?
编辑我在 and 处添加了 %d 并将其替换为 1,结果是:1065353216
编辑:这是我正在使用的两个结构
typedef struct {
float x, y, z,//base coordinates
dir_x, dir_y, dir_z;//directio
int radius;//radius
} WorklistStruct;
typedef struct {
float base_x, base_y, base_z; //base point
float radius;//radius
float dir_x, dir_y, dir_z; //initial direction
} ReturnStruct;
我测试了一些其他的东西,看起来像是 printf 的问题。这些值(value)观似乎是正确的。我将参数传递给返回结构,读取它们,这些值是正确的。
我不想发布所有相关代码,这将是几百行。 如果没有人有想法,我会稍微压缩一下。
啊,对于打印,我使用#pragma OPENCL EXTENSION cl_amd_printf:enable
。
编辑: 看起来确实是 printf 的问题。我根本就不再使用它了。
最佳答案
有一个简单的方法可以检查发生了什么:
1 - 创建主机端数据并初始化它:
int num_points = 128;
std::vector<WorklistStruct> works(num_points);
std::vector<ReturnStruct> returns(num_points);
for(WorklistStruct &work : works){
work = InitializeItSomehow();
std::cout << work.x << " " << work.y << " " << work.z << std::endl;
std::cout << work.radius << std::endl;
}
// Same stuff with returns
...
2 - 使用 COPY_HOST_PTR 标志创 build 备端缓冲区,映射它并检查数据一致性:
cl::Buffer dev_works(..., COPY_HOST_PTR, (void*)&works[0]);
cl::Buffer dev_rets(..., COPY_HOST_PTR, (void*)&returns[0]);
// Then map it to check data
WorklistStruct *mapped_works = dev_works.Map(...);
ReturnStruct *mapped_rets = dev_rets.Map(...);
// Output values & unmap buffers
...
3 - 像之前一样检查设备端的数据一致性。
此外,请确保内核和主机端代码包含的代码(可能是 header )是纯 OpenCL C(AMD 编译器有时会“吞掉”一些错误)并且您已导入包含目录构建 OpenCL 内核时进行搜索(clBuildProgramm 阶段的“-I”标志)
已编辑: 在每一步中,请收集返回码(或捕获异常)。除此之外,clBuildProgramm 阶段的“-Werror”标志也很有帮助。
关于c++ - OpenCL 结构体值在 CPU 上正确,但在 GPU 上不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24450831/