2013-07-18 40 views
0

我正在編寫一個計算N-Body模擬的程序,但是在運行後得到內核結果時出現問題。速度數組正在被內核計算,但事情是我不會知道如何用JavaCL封裝再次讀取數據。運行內核後從CLBuffer讀取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}); 

這是我的問題,因爲這並不actualy更新數組,但離開它,因爲它是。

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; 
} 

回答

0

看起來你正在使用JavaCL的JNA版本。那個是舊的,請使用BridJ版本 - 請參閱Migrating from JNA to BridJ

你真的打算在這一行中重新解釋一個float爲int嗎?

int numPart = as_int(params[3]); 

這將不轉換1.0F爲整數1,它會直接解釋位花車,好像他們是一個整數,給予一定的數量。我想你想看看第6.2.4.2節:重新解釋類型。我想你實際上需要convert_int函數,它是顯式類型轉換函數將任何東西轉換爲整數。

+0

好的,我修復了我的內核,並移植到BridJ,但它仍然不會讀出。任何建議,因爲在開發網站上的示例代碼不起作用... –

+0

沒有什麼跳出來對我。內核崩潰可能是由於某種原因,例如出界限內存訪問。爲防止出現這種情況,應該在'int x = get_global_id(0);'行後面加上'if(x chippies