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_size700000 迭代的顺序。这导致内核需要很长时间才能执行。由于我的 GPU 已连接到显示器,the kernel is timing out so the UI doesn't lock up.