我有一个内核。
__kernel void unprimed_grid_int(__global double *ar_u,
__global double *ap_u,
__global double *az_u,
__global const double *x_p,
__global const double *y_p,
__global const double *z_p,
__global const double *jx_p,
__global const double *jy_p,
__global const double *jz_p,
const uint nr,
const uint nz,
const uint nv,
const double rmin,
const double dr,
const double zmin,
const double dz,
const double dv,
const double dvol,
const uint p_size,
const uint offset) {
const size_t i = get_global_id(0);
const size_t ri = (i + offset)%nr;
const size_t zi = ((i + offset)/nr)%nz;
const size_t vi = ((i + offset)/(nr*nz))%nv;
const double r = ri*dr + rmin;
const double z = zi*dz + zmin;
const double v = vi*dv;
const double x = r*cos(v);
const double y = r*sin(v);
double ax = 0.0;
double ay = 0.0;
double az = 0.0;
for (uint j = 0; j < p_size; j++) {
const double dx = x_p[j] - x;
const double dy = y_p[j] - y;
const double dz = z_p[j] - z;
const double rp = sqrt(dx*dx + dy*dy + dz*dz);
ax += jx_p[j]/rp;
ay += jy_p[j]/rp;
az += jz_p[j]/rp;
}
ax *= dvol;
ay *= dvol;
az *= dvol;
ar_u[i] += x/r*ax + y/r*ay;
ap_u[i] += -y/r*ax + x/r*ay;
az_u[i] += az;
}
我来自
const size_t offset = 0;
clEnqueueNDRangeKernel(device->queue, device->kernels["int"], 1, &offset, &device->u_chunk, NULL, static_cast<cl_uint>(wait.size()), wait.data(), &event);
全局工作大小(device->u_chunk
)为734208.但是,在我的GPU上运行时,内核只运行在前2560个工作项上。我通过打印get_global_size(0)
的值检查了内核中的全局工作大小。如果我添加一个print语句来检查get_global_id(0)
的哪些项,它会在整个范围内运行。
什么会导致内核无法在整个范围内运行?
更新
要添加一个添加例子的示例,这里是代码输出的图表。 正如您所看到的,内核并未在整个范围内运行。为了进一步证明这一点,我运行了其中一个答案建议的测试用例。我修改了我的内核以添加一个额外的参数。
__kernel void unprimed_grid_int(..., __global uint *test) {
...
if (get_global_id(0) == 5) { // Reran with 5 changed to 700000
test[0] == 10;
}
}
对于输出看起来截止的下面的全局id值(2560),我读回正确的值10.对于高于截止值的全局id值,我得到的返回值不正确。
答案 0 :(得分:2)
我认为,它实际上会遍历所有项目,但打印所有值都无法正常工作,因为有很多线程。
为了确保它有效,您还可以添加一个整数变量作为内核的参数,并执行以下操作:
{{1}}
然后,在执行内核之后,如果处理了所有项目,它应该是10或你使用的任何数字。
答案 1 :(得分:0)
我弄清楚为什么我的内核不能在全球范围内运行。问题源于内核中的for循环。 p_size
大约为700000
次迭代。这导致内核需要很长时间才能执行。由于我的GPU已连接到显示器the kernel is timing out,因此UI doesn't lock up。