OpenCL-写入缓冲区为零?

OpenCL-写入缓冲区为零?,c,struct,kernel,buffer,opencl,C,Struct,Kernel,Buffer,Opencl,我已经编写了一个内核,除了为float3的每个组件添加一个内核之外,它应该什么都不做: __kernel void GetCellIndex(__global Particle* particles) { int globalID = get_global_id(0); particles[globalID].position.x += 1; particles[globalID].position.y += 1; particles[globalID].positio

我已经编写了一个内核,除了为float3的每个组件添加一个内核之外,它应该什么都不做:

__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;
};
使用以下结构(在内核中)

我的问题是,当我将粒子阵列写入GPU时,每个组件都是零。以下是必要的代码:

(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");
}
有人能帮我解决这个问题吗? (任何线索都值得讨论……)


谢谢

您的代码片段包含一些典型的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);
您传递了一个指向
粒子
指针的指针作为第6个参数(
ptr
)。但是,这里必须传递一个指针,指向主机上包含数据的区域。因此,将
&粒子
更改为
粒子

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);
与:

由于
clCreateBuffer
返回类型为
cl\u mem
的值,表达式
sizeof(cl\u Particle)
的计算结果与
sizeof(cl\u mem)
相同。我建议始终对变量调用
sizeof()
,因此您只需要在一个地方更改数据类型:变量声明

在我的平台上,
cl\u float3
cl\u float4
相同。这在您/每个平台上可能都不正确,因此您应该始终在主机代码和内核代码中使用相同的类型。此外,在内核代码中,您应该/必须使用类型
float4
,而不是
cl\u 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()");
Particle*particles=新粒子[200];
对于(int i=0;i<200;i++)
{
//粒子[i].位置.x=5f;
粒子[i].position.s[0]=0x5f;//由于VC++编译器
}
//cl_mem cl_Particles=cl_createBuffer(上下文、cl_mem_读写、大小(粒子)*200、NULL和err);//固定的
cl::缓冲区cl_粒子(上下文、cl_MEM_读写、大小(粒子)*200、NULL和err);
checkErr(err,“Buffer::Buffer()”);
//err=clEnqueueWriteBuffer(队列,cl_粒子,cl_真,0,大小(粒子)*200,粒子,0,空,空);//固定的
queue.enqueueWriteBuffer(cl_粒子,cl_真,0,sizeof(粒子)*200,粒子,NULL,NULL);
checkErr(err,“ComamndQueue::enqueueWriteBuffer()”);
//内核初始化
cl::内核内核(程序,“GetCellIndex”、&err);
checkErr(err,“Kernel::Kernel()”);
//err=clSetKernelArg(kernel,0,sizeof(cl_粒子)和cl_粒子);//固定的
err=kernel.setArg(0,sizeof(cl_粒子)和cl_粒子);
checkErr(err,“Kernel::setArg()”);
1)可能的大小为指针的大小,2)可能由于驱动程序或硬件原因,设备端的cl_float3需要替换为cl_float4
err = clSetKernelArg(kernel, 0, sizeof(Particle) * 200, &cl_Particles);
err = clSetKernelArg(kernel, 0, sizeof(cl_Particle), &cl_Particles);
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()");