OpenCL在NVidia硬件上生产QNaN 我用C++绑定编程在OpenCL中。我有一个问题,在NVidia硬件上,我的OpenCL代码会自动生成非常大的数字,然后在下一次运行1.QNaN。我的代码基本上是一个简单的物理模拟,使用方程x=vt*.5at^2。我注意到唯一奇怪的是粒子的速度突然上升到6e+34,我猜这是机器上的最大浮点值。然而,在此之前的速度/力非常小,通常值小于1

OpenCL在NVidia硬件上生产QNaN 我用C++绑定编程在OpenCL中。我有一个问题,在NVidia硬件上,我的OpenCL代码会自动生成非常大的数字,然后在下一次运行1.QNaN。我的代码基本上是一个简单的物理模拟,使用方程x=vt*.5at^2。我注意到唯一奇怪的是粒子的速度突然上升到6e+34,我猜这是机器上的最大浮点值。然而,在此之前的速度/力非常小,通常值小于1,c++,opencl,gpgpu,C++,Opencl,Gpgpu,我使用的特定GPU是特斯拉M2050,带有最新的驱动程序。我在我的笔记本电脑上使用我的AMD Fusion CPU作为一个平台,它没有一个专用的GPU,也没有出现问题。我不确定这是否是NVidia驱动程序的问题,我的计算问题,或者完全是其他问题 以下是内核代码注释:我相当确定质量始终为非零: 下面是我如何将信息存储到内核中的。PutData只使用std::vector::push_back函数将原子的位置、速度和力转换为相应的向量,而kernel只是我为OpenCL库编写的一个包装类。您可以相信

我使用的特定GPU是特斯拉M2050,带有最新的驱动程序。我在我的笔记本电脑上使用我的AMD Fusion CPU作为一个平台,它没有一个专用的GPU,也没有出现问题。我不确定这是否是NVidia驱动程序的问题,我的计算问题,或者完全是其他问题

以下是内核代码注释:我相当确定质量始终为非零:

下面是我如何将信息存储到内核中的。PutData只使用std::vector::push_back函数将原子的位置、速度和力转换为相应的向量,而kernel只是我为OpenCL库编写的一个包装类。您可以相信我,我为排队函数将正确的参数放在了正确的位置

void LoadAtoms(int kernelNum, bool blocking)
{
    std::vector<cl_float4> atomPos;
    std::vector<cl_float4> atomVel;
    std::vector<cl_float4> atomForce;
    for(int i = 0; i < numParticles; i++)
        atomList[i].PutData(atomPos, atomVel, atomForce);
    kernel.EnqueueWriteBuffer(kernelNum, posBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomPos[0]);
    kernel.EnqueueWriteBuffer(kernelNum, velBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomVel[0]);
    kernel.EnqueueWriteBuffer(kernelNum, forceBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomForce[0]);
}

void LoadAtomTypes(int kernelNum, bool blocking)
{
    std::vector<cl_float> mass;
    std::vector<cl_float> radius;
    int type;
    for(int i = 0; i < numParticles; i++)
    {
        type = atomList[i].GetType();
        mass.push_back(atomTypes[type].mass);
        radius.push_back(atomTypes[type].radius);
    }
    kernel.EnqueueWriteBuffer(kernelNum, massBuf, blocking, 0, numParticles*sizeof(cl_float), &mass[0]);
    kernel.EnqueueWriteBuffer(kernelNum, radiusBuf, blocking, 0, numParticles*sizeof(cl_float), &radius[0]);
}
和往常一样,我的代码还有很多,但这是与内核相关的内容

我看到了,这很相似,但我在任何地方都使用cl_float4,所以我不认为这是一个对齐问题。实际上没有任何其他相关问题


我意识到这可能不是一个简单的问题,但在我们能够在办公室里安装新的硬件进行测试之前,我已经没有什么想法了。有人能帮我吗?

既然没有人回答,我想我就把我学到的东西贡献出来

我没有一个明确的结论,但至少,我明白了为什么它经常这么做。因为我正在运行这个和其他类似的内核来计算时间顺序的估计值,所以我清理列表,调整它们的大小,然后重新运行计算。然而,我没有做的是调整缓冲区的大小。这导致线程拉取了一些未定义的数字


然而,这并不能解决我在长时间运行程序时遇到的问题。这些只是自发出现的。也许我忽略了一个类似的问题,但我不能说。如果有人对此问题有进一步的意见,我们将不胜感激。

事实上,我认为问题出在我编写的另一个内核中。我还没有解决这个问题,甚至在我运行另一个内核之前,这个问题就已经出现了,所以观察是值得赞赏的。正如一般的编码风格观察一样:通过使用向量运算,您可以使代码缩短很多。它会更容易阅读,也可能跑得更快。e、 加速度=浮力[i].x/质量[i],力[i].y/质量[i],力[i].z/质量[i],0.0f;加速度=力[i]/质量[i];啊,我甚至不知道OpenCL支持这样的操作。谢谢
void LoadAtoms(int kernelNum, bool blocking)
{
    std::vector<cl_float4> atomPos;
    std::vector<cl_float4> atomVel;
    std::vector<cl_float4> atomForce;
    for(int i = 0; i < numParticles; i++)
        atomList[i].PutData(atomPos, atomVel, atomForce);
    kernel.EnqueueWriteBuffer(kernelNum, posBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomPos[0]);
    kernel.EnqueueWriteBuffer(kernelNum, velBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomVel[0]);
    kernel.EnqueueWriteBuffer(kernelNum, forceBuf, blocking, 0, numParticles*sizeof(cl_float4), &atomForce[0]);
}

void LoadAtomTypes(int kernelNum, bool blocking)
{
    std::vector<cl_float> mass;
    std::vector<cl_float> radius;
    int type;
    for(int i = 0; i < numParticles; i++)
    {
        type = atomList[i].GetType();
        mass.push_back(atomTypes[type].mass);
        radius.push_back(atomTypes[type].radius);
    }
    kernel.EnqueueWriteBuffer(kernelNum, massBuf, blocking, 0, numParticles*sizeof(cl_float), &mass[0]);
    kernel.EnqueueWriteBuffer(kernelNum, radiusBuf, blocking, 0, numParticles*sizeof(cl_float), &radius[0]);
}