2016-01-12 84 views
1

我寫了一個內核,它應該做的什麼都沒有,除了從添加一個到FLOAT3的每個組件:OpenCL - 寫入緩衝區爲零?

__kernel void GetCellIndex(__global Particle* particles) { 

    int globalID = get_global_id(0); 
    particles[globalID].position.x += 1; 
    particles[globalID].position.y += 1; 
    particles[globalID].position.z += 1; 
}; 

與下面的結構(內核)

typedef struct _Particle 
{ 
    cl_float3 position; 
}Particle; 

我的問題是,當我將我的粒子數組寫入GPU時,每個分量都是零。這裏是neccassary代碼:

(Particle*) particles = new Particle[200]; 
for (int i = 0; i < 200; i++) 
{ 
    particles[i].position.x = 5f; 
} 

cl_Particles = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(Particle)*200, NULL, &err); 
if (err != 0) 
{ 
    std::cout << "CreateBuffer does not work!" << std::endl; 
    system("Pause"); 
} 

clEnqueueWriteBuffer(queue, cl_Particles, CL_TRUE, 0, sizeof(Particle) * 200, &particles, 0, NULL, NULL); 


//init of kernel etc. 



err = clSetKernelArg(kernel, 0, sizeof(Particle) * 200, &cl_Particles); 
if (err != 0) { 
    std::cout << "Error: setKernelArg 0 does not work!" << std::endl; 
    system("Pause"); 
} 

,這是我在CPU上的結構:

typedef struct _Particle 
{ 
    cl_float4 position; 
}Particle; 

有人可以幫我解決這個問題? (任何線索是值得討論...)

感謝

+0

1)的可能尺寸爲您提供了指針的大小,2)也許cl_float3需要由cl_float4被替換,因爲驅動程序或硬件 –

回答

1

你的代碼段包含了一些典型的C編程錯誤。起初,

(Particle*) particles = new Particle[200]; 

不聲明一個新的變量particle爲指針Particle。它必須是:

Particle *particles = new Particle[200]; 

至於未來,在你的

clEnqueueWriteBuffer(queue, cl_Particles, CL_TRUE, 0, sizeof(Particle) * 200, &particles, 0, NULL, NULL); 

打電話給你傳遞一個指針的指針particles作爲第6個參數(ptr)。但是,在這裏,您必須將指針傳遞到包含數據的主機上的區域。因此,改變&particlesparticles

clEnqueueWriteBuffer(queue, cl_Particles, CL_TRUE, 0, sizeof(Particle) * 200, particles, 0, NULL, NULL); 

的內核參數的設置也是錯誤的。在這裏,您必須通過使用clCreateBuffer創建的OpenCL緩衝區。因此,更換

err = clSetKernelArg(kernel, 0, sizeof(Particle) * 200, &cl_Particles); 

與:

err = clSetKernelArg(kernel, 0, sizeof(cl_Particle), &cl_Particles); 

作爲clCreateBuffer返回cl_mem類型的值,表達sizeof(cl_Particle)計算結果爲相同sizeof(cl_mem)。我建議始終在變量上調用sizeof(),所以您只需要在一個地方更改數據類型:變量聲明。

在我的平臺上,cl_float3與​​相同。這可能不適用於您的/每個平臺,因此您應始終在主機代碼和內核代碼中使用相同的類型。另外,在您的內核代碼中,您應該/必須使用類型float4而不是​​。

我希望我的C調用是正確的,因爲我實際上是用這個C++代碼來測試它的。這段代碼包含了固定C調用的評論:

Particle *particles = new Particle[200]; 
for (int i = 0; i < 200; i++) 
{ 
    //particles[i].position.x = 5f; 
    particles[i].position.s[0] = 0x5f; // due to VC++ compiler 
} 

//cl_mem cl_Particles = cl_createBuffer(context, CL_MEM_READ_WRITE, sizeof(Particle)*200, NULL, &err); // FIXED 
cl::Buffer cl_Particles(context, CL_MEM_READ_WRITE, sizeof(Particle)*200, NULL, &err); 
checkErr(err, "Buffer::Buffer()"); 

//err = clEnqueueWriteBuffer(queue, cl_Particles, CL_TRUE, 0, sizeof(Particle) * 200, particles, 0, NULL, NULL); // FIXED 
queue.enqueueWriteBuffer(cl_Particles, CL_TRUE, 0, sizeof(Particle) * 200, particles, NULL, NULL); 
checkErr(err, "ComamndQueue::enqueueWriteBuffer()"); 

//init of kernel 
cl::Kernel kernel(program, "GetCellIndex", &err); 
checkErr(err, "Kernel::Kernel()"); 

//err = clSetKernelArg(kernel, 0, sizeof(cl_Particle), &cl_Particles); // FIXED 
err = kernel.setArg(0, sizeof(cl_Particles), &cl_Particles); 
checkErr(err, "Kernel::setArg()"); 
+0

的設備側謝謝爲了這個真棒幫助!它現在有效! – 3DExtended