0

我正在编写一个计算 N-Body 模拟的程序,但在内核运行后获取结果时遇到问题。速度数组是由内核计算的,但问题是我不知道如何使用 JavaCL 包装器再次读取数据。

//CLBuffer generator convenience method
private CLBuffer<FloatBuffer> GenBuff(float[] dest)
{
    FloatBuffer ptrLX = ByteBuffer.allocate(numParticles * 4).asFloatBuffer();
    ptrLX.put(dest);
    return context.createBuffer(CLMem.Usage.InputOutput, ptrLX);
}

private void CalculateTimeStep(float e, float DT) {
    float[] params = { DT, e, this.particleMass, (float) this.numParticles };

    //Generates CLBuffers with a convenience method 
    CLBuffer<FloatBuffer> pLXBuffer = this.GenBuff(pLX);
    CLBuffer<FloatBuffer> pLYBuffer = this.GenBuff(pLY);
    CLBuffer<FloatBuffer> pVXBuffer = this.GenBuff(pVX);
    CLBuffer<FloatBuffer> pVYBuffer = this.GenBuff(pVY);
    CLBuffer<FloatBuffer> ParamsBuffer = this.GenBuff(params);
    //sets the kernel arguments
    this.NBodyKernel.setArg(0, pLXBuffer);
    this.NBodyKernel.setArg(1, pLYBuffer);
    this.NBodyKernel.setArg(2, pVXBuffer);
    this.NBodyKernel.setArg(3, pVYBuffer);
    this.NBodyKernel.setArg(4, ParamsBuffer);
    //enqueue the kernel 
    CLEvent evt = this.NBodyKernel.enqueueNDRange(que, new int[]{numParticles});

这是我的问题,因为这实际上并没有更新数组,而是保持原样。

    pVXBuffer.readBytes(que, 0, this.numParticles,evt).asFloatBuffer().get(pVX);
    pVYBuffer.readBytes(que, 0, this.numParticles,evt).asFloatBuffer().get(pVY);

上面的问题区域

    //And I release the temerary openCL components manualy
    pVXBuffer.release();
    pVYBuffer.release();
    pLXBuffer.release();
    pLYBuffer.release();
    ParamsBuffer.release();
    }

和 openCL 内核

__kernel void NBody(__global float *posX,__global float *posY, __global float *volX , __global float *volY, __global float *params)
{

//params
// DT -> E -> PM -> NP    
float DeltaT = params[0];
float E = params[1];
float mass = params[2];
int numPart = as_int(params[3]);

int x = get_global_id(0);
//create local variables from global variables that are used often to lower memeroy overhead
float mPosX = posX[x];
float mPosY = posY[x];
float mVolX = volX[x];
float mVolY = volY[x];
for(int i = 0; i < numPart; i++)
{
    if(i != x)
    {
        float sx = posX[i] - mPosX;
        float sy = posY[i] - mPosY;
        float r2 = sx*sx + sy*sy;
        float r = sqrt(r2);
        float r3 = r2*r;
        mVolX += sx*mass*DeltaT/(r3+E);
        mVolX += sy*mass*DeltaT/(r3+E);
    }
} 
volX[x] = mVolX;
volY[x] = mVolY;
}
4

1 回答 1

0

看起来您正在使用 JavaCL 的 JNA 版本。那是旧的,请使用 BridJ 版本 - 请参阅从 JNA 迁移到 BridJ

您真的打算在这一行中将 float 重新解释为 int 吗?

int numPart = as_int(params[3]);

这不会将 1.0f 转换为整数 1,它会直接解释该浮点数中的位,就好像它们是整数一样,给出一些数字。我想你想看看第 6.2.4.2 节:重新解释类型。我认为您实际上想要 convert_int 函数,这是将任何内容转换为整数的显式类型转换函数。

于 2013-07-18T18:40:05.930 回答