我完成了一个用于热力学计算的OpenCL内核,并观察到了一个非常奇怪的错误。 我的内核看起来像这样:
__kernel void energy(... float3 dest, int nlocal, ...){
int i = get_global_id(0);
float3 ev = {0.0f, 0.0f, 0.0f};
for(...){
//some thermo calculations, adding values to evx and evy
ev.x +=...;
ev.y +=...;
}
//Then I want to save the result in dest[i].
//Program exits at next two line
dest[i].x = ev.x;
dest[i].y = ev.y;
我收到了“未映射的内存”和段错误。尝试使用printf打印出值时出现相同的错误。好像程序无法读取值。写它可以工作!(可能是因为一些编译器优化) 现在,如果我使用另一个浮点寄存器值,我会得到相同的错误。但是,如果我将最后一行改为这样的(不使用ev.x或ev.y)
dest[i].x = i/nlocal*3.1f
dest[i].y = ...;
一切都按预期进行,我没有错误。
这也有效:
int i = ...
float3 = {0.0f, ...}
dest[i].x = ev.x;
但不知怎的,经过实际计算后再也不可能了。
该程序在Nvidia K40m,Kepler架构上运行。
答案 0 :(得分:1)
这在您的代码中看起来很可疑:
kernel(... __global int* neigh
__global int* neighs = neigh+i;
...
int j = neighs[k*n];
...
好像你在neigh
传递指针数组,然后获取指针并使用它。
在CL中不允许使用指针,如果你传递指针,那么你将从GPU内存中寻址,从而导致崩溃。
您的矢量可能无法正确计算,尺寸应为:
res, nneigh = GLOBAL_SIZE
neighs = max(nneigh[])*n
x = max(neighs[])
也有可能你创建了比它们应该更小的缓冲区(记住它们是浮点数,而float3,每个元素使用32位和128位)。 CL API调用以字节为单位定义(您应该使用sizeof()
),而不是元素。
答案 1 :(得分:0)
好的,我找到了答案,上面的代码正常运行。我更改了内核参数以便更好地理解并在我在此处发布代码时不知不觉地纠正了错误。
int numneigh = nneigh[i] (stands for number of neighbors) is correct
in the original code I did this:
int numneigh = neigh[i] (the neighbors)
感谢您的帮助,并且您认为neigh / nneigh出错是正确的,即使错误不在上面的代码中:P