【问题标题】:How to overcome Error Code -11 cl_build_program_failure如何克服错误代码 -11 cl_build_program_failure
【发布时间】:2019-04-19 15:01:31
【问题描述】:

我正在尝试使用共享虚拟内存将链表(粒子模拟)上的函数外包给 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 文件吗?据我了解,我可以在源代码中定义结构、类型定义和函数,并在内核函数中使用它们。

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;
              ^ ~~~~~~~~~~~

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

【问题讨论】:

  • 您的第一步是致电clGetProgramBuildInfo。这应该为您提供特定的源代码行和错误消息,以跟踪您的问题。 (不幸的是,我不熟悉 OpenCL 2.0/SVM,所以我不能通过查看您的代码来确定问题出在哪里。)如果对它有任何疑问,请将 clGetProgramBuildInfo 的输出添加到您的问题中意思是。
  • 谢谢,这让调试变得容易多了。我用编译器错误更新了帖子

标签: c list kernel opencl


【解决方案1】:

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

__global ParticleList *pList

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

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

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

(我个人觉得默认地址空间是 OpenCL 设计的一个错误,应该总是明确的,但是你能做什么。)

【讨论】:

  • 嘿,这确实有帮助,谢谢。但是,如果我尝试将链接列表传递给内核,它只会在列表中的第一个元素上执行。你知道我怎样才能让它访问下一个元素吗?
  • 我通过以下方式设置参数:CL_CHECK(clSetKernelArgSVMPointer(kernel[0], 0, grid[0])); (网格 [0] 是列表的头部)我通过调用 clEnqueueNDRangeKernel(cmd_queue, kernel[0], 1, NULL, &global_work_size, NULL, 0, NULL, NULL) 来执行内核我尝试让每个元素隐式知道通过遍历列表并在每个元素上调用 clSetKernelExecInfo 来获取内核。内核仍然只触及第一个元素
  • @M408 我建议提出一个新问题。您的用例非常依赖共享虚拟内存,很遗憾我没有这方面的经验。
猜你喜欢
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多