OpenCL内核输出NaN而不是double

时间:2014-01-23 23:44:46

标签: c opencl

我目前正在学习并行编程,并决定使用OpenCL编写一个简单的N体模拟。在尝试编程内核时,我遇到了死胡同:

__kernel void nbody_kernel (__global double* x_in, __global double* y_in, __global double* z_in,
                            __global double* x_out, __global double* y_out, __global double* z_out,
                            __global double* v_x, __global double* v_y, __global double* v_z,
                            __global double* m, int n) {
    int id = get_group_id(0)*get_local_size(0)+get_local_id(0);

    if (id < n) {
        double dx, dy, dz;
        double invr, force;

        double ax, ay, az;
        ax = ay = az = 0;

        for (int j = 0; j < n; ++j) {
            dx = x_in[j] - x_in[id];
            dy = y_in[j] - y_in[id];
            dz = z_in[j] - z_in[id];

            invr = 1.0 / sqrt(dx*dx + dy*dy + dz*dz + eps); 
            force = kappa*m[j]*invr*invr*invr; 

            ax += force*dx;
            ay += force*dy;
            az += force*dz;
        }

        x_out[id] = x_in[id] + v_x[id]*dt + 0.5*ax*dt*dt;
        y_out[id] = y_in[id] + v_y[id]*dt + 0.5*ay*dt*dt;
        z_out[id] = z_in[id] + v_z[id]*dt + 0.5*az*dt*dt;

        v_x[id] += ax*dt;
        v_y[id] += ay*dt;
        v_z[id] += az*dt;
    }
}

运行上面的代码后,x_out / y_out / z_out值似乎是NaN(至少printf似乎这么认为)。

我已经将问题诊断为for循环:如果我使用常量(例如2),则内核按预期运行。使用变量(__constant或参数)时,似乎只会出现问题。

我究竟做错了什么?

编辑:哦,如果它很重要:我正在运行OpenCL 1.1。

编辑2:我已经检查过“n”参数是否正确传递。

编辑3:计算中使用的常量在.cl文件中定义和初始化,如下所示:

__constant double kappa = 1;
__constant double eps = 0.0001;
__constant double dt = 0.1;

我正在创建和传递数据缓冲区,如下所示:

d_x0 = clCreateBuffer(context, CL_MEM_READ_WRITE, num * sizeof(double), NULL, &status);
clEnqueueWriteBuffer(command_queue, d_x0, CL_TRUE, 0, num * sizeof(double), x_in, 0, NULL, NULL);
clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_x0);

至于n,我正在使用:

clSetKernelArg(kernel, 10, sizeof(cl_int), &num);

编辑4:我玩过,如果我将加速度定义为ax = force*dx;,它似乎正常工作。在程序到达ax += force*dx;之前,ax / ay / az未设置为0会出现问题吗?

0 个答案:

没有答案