首页 > 解决方案 > 如何克服错误代码 -11 cl_build_program_failure

问题描述

我正在尝试使用共享虚拟内存将链表(粒子模拟)上的函数外包给 OpenCL 内核。我尝试从简单地遍历链表并更改其中每个元素(结构)的一个值开始。

这是 .cl 文件(将 typedef 改为 real 是为了与主机代码保持一致):

//real is of type cl_double
typedef cl_double real;
typedef cl_double2 real2;

typedef struct
{

//  Mass
real m;
//  Position
real2 x;
//  Velocity
real2 v;
//  Force
real2 F;
//  Force_old
real2 F_old;
//  Bodytype
cl_char body;

} Particle;

//  Datastructure of linked list
typedef struct ParticleList
{

Particle p;
struct ParticleList *next;
} ParticleList;

//  A cell is defined as the anchor of a linked list
typedef ParticleList *Cell;

__kernel void test(
__global ParticleList *pList){

 //  Check if pList->next is NULL
if(pList->next != NULL){

    while(pList->next != NULL){

        pList->p.body = 'Z';
        pList = pList->next;
   }
}


}

关于它为什么不编译 .cl 文件的任何想法?据我了解,我可以在源代码中定义结构、typedef 和函数,并在内核函数中使用它们。

clCreateProgramWithSource 返回 CL_SUCCESS,但该程序上的 clBuildProgram 返回错误代码 -11。

也许一些调试opencl c的技巧?

编辑:调用 clGetProgramBuildInfo 产生:

1:49:19: error: assigning 'struct ParticleList *__global' to '__global 
ParticleList *' (aka '__global struct ParticleList *') changes address space
  of pointer
        pList = pList->next;
              ^ ~~~~~~~~~~~

我不确定这意味着什么,我可以不取消引用设备地址空间中的指针吗?

标签: clistkernelopencl

解决方案


指针始终指向特定的地址空间:globalconstantlocalprivate。即使指针没有注释,默认情况下也会根据上下文选择其中一个。在你的情况下,

__global ParticleList *pList

被(正确地)注释为在global空间中,而next结构中的字段没有注释:

struct ParticleList
{
  Particle p;
  struct ParticleList *next; // <--- no address space specified, defaults to `private`
}

显然,该next字段不指向分配在private内存中的结构,所以这个默认值是不正确的,你应该显式指定global.

(就个人而言,我觉得默认使用地址空间是 OpenCL 设计中的一个错误,它应该始终是明确的,但你能做什么。)


推荐阅读