C++ OpenCL结构值在CPU上正确,但在GPU上不正确

C++ OpenCL结构值在CPU上正确,但在GPU上不正确,c++,c,floating-point,opencl,gpu,C++,C,Floating Point,Opencl,Gpu,我确实有一个包含在主机代码和内核中的文件结构 typedef struct { float x, y, z, dir_x, dir_y, dir_z; int radius; } WorklistStruct; 我在C++主机代码中构造这个结构,并通过缓冲区传递给OpenCL内核。< /P> 如果我选择CPU设备进行计算,我将得到以下结果: printf ( "item:[%f,%f,%f][%f,%f,%f]%d,%d\n", item.x, i

我确实有一个包含在主机代码和内核中的文件结构

typedef struct {
    float x, y, z,
          dir_x, dir_y, dir_z;
    int     radius;
} WorklistStruct;
我在C++主机代码中构造这个结构,并通过缓冲区传递给OpenCL内核。< /P> 如果我选择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));
主持人:

设备(CPU):

如果我选择GPU设备(AMD)进行计算,就会发生奇怪的事情:

主持人:

设备(GPU):

值得注意的是,sizeof(float)是gpu上的垃圾

我假设不同设备上的浮动布局存在问题

注意:该结构包含在此类型的结构数组中,该数组中的每个结构在GPU上都是垃圾

任何人都知道为什么会这样,我如何预测

编辑我在和处添加了一个%d,并将其替换为1,结果是:10653216

编辑:这里是我使用的两个结构

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有问题。这些价值观似乎是正确的。我将参数传递给return结构,读取它们,这些值是正确的

我不想发布所有的相关代码,这将是几百行。 如果没有人有主意,我会压缩一下

啊,对于打印,我使用的是
#pragma OPENCL扩展cl\u amd\u 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
...
3-像以前一样检查设备端的数据一致性

另外,在构建OpenCL内核时,请确保内核和主机端代码都包含的代码(可能是-header)是纯OpenCLC(AMD编译器有时会“吞咽”一些错误),并且您已经导入了用于包含搜索的目录(“clBuildProgramm阶段的-I”标志)

编辑:
在每个步骤中,请收集返回代码(或捕获异常)。除此之外,clBuildProgramm阶段的“-Werror”标志也很有用。

看起来我在编译时使用了错误的OpenCL头。如果我在英特尔平台(OpenCL1.2)上尝试代码,一切都很好。但在我的AMD平台(OpenCL1.1)上,我得到了奇怪的值


我将尝试其他标题。

%d
格式不适合打印
sizeof
的结果。对于C99兼容编译器,它应该是
%zu
。从混合中删除缓冲区传输;只需填写struct值,然后首先尝试让printf工作。为了证明sizeof(float)是4,在else之前和之后添加一个条件it==4和printf,看看采用了哪条路径。你能显示这个头吗,它包含在内核和主机端代码以及内存对象创建和读/写代码中?但这正是他正在做的,不是吗?(至少是我们认为他已经在做的事情)。我们需要知道结构定义(主机/设备)以及他如何使用数据,以便查看过程中的任何错误。是的,你是对的-我们没有关于TS代码的确切信息,所以我建议进行这样的小测试。我在问题中添加了我正在使用的结构。我从主机和设备大小代码中的同一文件导入这些。明天我将把我的数据发布到设备拷贝代码中。
item:[58.406261,57.786015,58.137501][2.000000,2.000000,2.000000]2,4
item:[58.406261,2.000000,0.000000][0.000000,0.000000,0.000000]0,0
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;
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
...
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
...