clEnqueueNDRangeKernel 不是 运行 整个全局范围
clEnqueueNDRangeKernel Isn't running over full global range
我有一个内核。
__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)
的值检查了内核中的全局工作大小。如果我添加打印语句来检查 get_global_id(0)
的哪些项目,它 运行 超过了完整的 运行ge。
什么会导致内核无法 运行 完成整个 运行ge?
更新
要添加正在发生的事情的示例,这里是代码输出图。
如您所见,内核没有 运行 超过完整的 运行ge。为了进一步证明这一点,我 运行 一个答案建议的测试用例。我修改了我的内核以添加一个额外的参数。
__kernel void unprimed_grid_int(..., __global uint *test) {
...
if (get_global_id(0) == 5) { // Reran with 5 changed to 700000
test[0] == 10;
}
}
对于低于输出似乎截止 (2560) 的全局 ID 值,我读回了正确的值 10。对于高于截止值的全局 ID 值,我返回了不正确的值。
我认为,它实际上遍历了所有项目,但打印所有值无法正常工作,因为有很多线程。
为确保其正常工作,您还可以添加一个整数变量作为内核参数并执行以下操作:
__kernel void unprimed_grid_int(your_arguments, int test) {
if (get_global_id(0) == 734207) {
test = 10; // or any other value
}
}
然后,内核执行后,如果所有项目都处理完,应该是10或者你用的任何数字。
我弄明白了为什么我的内核不能在整个全球范围内运行。问题源于内核中的for循环。 p_size
是 700000
迭代的顺序。这导致内核需要很长时间才能执行。由于我的 GPU 已连接到显示器,the kernel is timing out so the UI doesn't lock up.
我有一个内核。
__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)
的值检查了内核中的全局工作大小。如果我添加打印语句来检查 get_global_id(0)
的哪些项目,它 运行 超过了完整的 运行ge。
什么会导致内核无法 运行 完成整个 运行ge?
更新
要添加正在发生的事情的示例,这里是代码输出图。
__kernel void unprimed_grid_int(..., __global uint *test) {
...
if (get_global_id(0) == 5) { // Reran with 5 changed to 700000
test[0] == 10;
}
}
对于低于输出似乎截止 (2560) 的全局 ID 值,我读回了正确的值 10。对于高于截止值的全局 ID 值,我返回了不正确的值。
我认为,它实际上遍历了所有项目,但打印所有值无法正常工作,因为有很多线程。
为确保其正常工作,您还可以添加一个整数变量作为内核参数并执行以下操作:
__kernel void unprimed_grid_int(your_arguments, int test) {
if (get_global_id(0) == 734207) {
test = 10; // or any other value
}
}
然后,内核执行后,如果所有项目都处理完,应该是10或者你用的任何数字。
我弄明白了为什么我的内核不能在整个全球范围内运行。问题源于内核中的for循环。 p_size
是 700000
迭代的顺序。这导致内核需要很长时间才能执行。由于我的 GPU 已连接到显示器,the kernel is timing out so the UI doesn't lock up.