Floating point 为什么OpenCL内核调用sin而不是cos时出现浮点异常?

Floating point 为什么OpenCL内核调用sin而不是cos时出现浮点异常?,floating-point,opencl,Floating Point,Opencl,我的OpenCL内核正在抛出一个浮点异常。我已经把它减少到了我认为引起问题的线路 如果我换线 acc.x += sin(distSqr); 与 或 或者只是 acc.x += (distSqr); 内核运行良好。为什么? 注:我的全球工作规模可以被我的本地工作规模所分割 谢谢 以下是内核: __kernel void compute_forces( __global float3 *x3a, __glob

我的OpenCL内核正在抛出一个浮点异常。我已经把它减少到了我认为引起问题的线路

如果我换线

acc.x += sin(distSqr);

或者只是

acc.x += (distSqr);
内核运行良好。为什么? 注:我的全球工作规模可以被我的本地工作规模所分割

谢谢

以下是内核:

__kernel void compute_forces(
                      __global float3 *x3a,
                      __global float3 *p3a,
                      __global float3 *x3b,
                      __global float3 *p3b,
                      __global float3 *f3a,
                      float dt,
                      float qQa,
                      float qQb,
                      float qma,
                      float qmb,
                      int n0a,
                      int n1a,
                      int n0b,
                      int n1b,
                      float xmin,
                      float ymin,
                      float epsSqr,
                      float force_fac,
                        __local float3 *localx
                      )
{


//we are going to compute the force between parts (n0a-n1a) and (n0b-n1b)
//Each particle loads the particle in the current block into local memory, so
unsigned int tid = get_local_id(0);
unsigned int gid = get_global_id(0);

unsigned int ninter=0;

// position of this work-item
float3 myPos = x3a[gid];
float3 acc = (float3)(0.0f, 0.0f, 0.0f);


    // Synchronize to make sure data is available for processing
    barrier(CLK_LOCAL_MEM_FENCE);


    for(int j = 0; j < 2; ++j)
    {

        float3 r=-myPos;
        float distSqr = r.x * r.x;


        // accumulate effect of all particles
        acc.x += sin(distSqr);

        ninter++;

    }//j

    // Synchronize so that next tile can be loaded
    barrier(CLK_LOCAL_MEM_FENCE);



f3a[gid]+=acc;
f3a[gid].x=(float)ninter;

}
编辑:我认为sin函数无法处理小于1.0e-12的float,因为行:

acc.x += sin(1.0e-12);
运行良好,但

acc.x += sin(1.0e-13);
抛出异常。这似乎表明正在调用sin_half而不是sin…我想知道这是否是优化所做的替换

如果我在上面一行的前面添加printf语句

printf("distSqr=%g\n",distSqr);

然后,错误从“浮点异常”变成“除错错误处理程序”(虽然输出文本被混淆了,很难辨认)。< /P> < P>因为Sin(x)似乎不为X的小值工作,我怀疑英伟达驱动程序是用NATEVYSIN(x)替换它。它的计算结果是直接在硬件中实现的函数,但可能不太准确或不支持完整的数字范围。我建议在对clBuildProgram的调用中添加build选项“-cl opt disable”,因为这会禁用所有优化,告诉我们编译器优化是否出错。

关于您得到的错误和使用的OpenCL SDK版本(CPU或GPU)的信息将非常有用。错误为“浮点异常(内核转储)”我正在编写我的英特尔i7。我想是英伟达SDK 4.2我正在使用。Sin(x)= x,对于席平均意味着Acx+x= x,不幸的是,这没有帮助。可能是因为我使用英伟达SDK,但在我的英特尔i7上运行?(我不再有Nvidia卡了)嗯,我错过了。我的经验是混合英伟达和AMD GPU,使用Nvidia的LIB文件和头文件应该是好的。但是,我建议如下:首先切换到使用Intel SDK头和lib文件。如果这无法解决问题,请尝试下载AMD应用程序SDK。如果这个问题也会给你带来同样的问题,那么你的代码就有问题了。我同意chippies的观点。我也会尝试使用AMD OpenCL驱动程序而不是Intel驱动程序在CPU上运行。与其说SDK有问题,不如说英特尔的OpenCL驱动程序有问题。谢谢你的建议。我将在不同的机器上安装另一个SDK,因为上次我在我的机器上安装了多个SDK(Ubuntu 12.04),这导致了问题。同时,我可以补充的是,偶尔我会遇到一个更有意义的错误:“divisionErrorHandler()中的未处理信号”。您还应该在CPU上进行测试,AMD SDK确实允许OpenCL代码在Intel CPU上运行。
acc.x += sin(1.0e-12);
acc.x += sin(1.0e-13);
printf("distSqr=%g\n",distSqr);