OpenCL内存缓冲区传输提供不正确的数据

OpenCL内存缓冲区传输提供不正确的数据,opencl,Opencl,我是openCL的新手,我试图从一个非常简单的内核开始。现在,我只是尝试将数据传输到内核并返回,以便验证是否设置了正确的数据。然而,我的行为变得非常怪异。这是我的主机代码: string PROGRAM_FILE = "C:\\Projects\\AnimatLabSDK\\OpenNeuronCL\\Libraries\\OpenNeuronCL\\Kernels\\FastSpikingNeuron.cl"; string KERNEL_FUNC = "FastSpikingNeuron";

我是openCL的新手,我试图从一个非常简单的内核开始。现在,我只是尝试将数据传输到内核并返回,以便验证是否设置了正确的数据。然而,我的行为变得非常怪异。这是我的主机代码:

string PROGRAM_FILE = "C:\\Projects\\AnimatLabSDK\\OpenNeuronCL\\Libraries\\OpenNeuronCL\\Kernels\\FastSpikingNeuron.cl";
string KERNEL_FUNC = "FastSpikingNeuron";

std::vector<cl::Platform> platforms;
std::vector<cl::Device> devices;  
int i;

// Data
cl::NDRange ndGlobal(DATA_SIZE);  
cl::NDRange ndLocal(LOCAL_SIZE);

cl_float aryVmIn[DATA_SIZE], aryVmOut[DATA_SIZE];
cl_float aryVahp[DATA_SIZE], aryTestOut[DATA_SIZE];

try {
  // Initialize data
  for(i=0; i<DATA_SIZE; i++) {
     aryVmIn[i] = i*0.1f; //0.0f;
     aryVahp[i] = i*0.1f; //0.0f;
  }

  // Place the GPU devices of the first platform into a context
  cl::Platform::get(&platforms);
  platforms[0].getDevices(CL_DEVICE_TYPE_GPU, &devices);
  cl::Context context(devices);

  // Create kernel
  std::ifstream programFile(PROGRAM_FILE);
  std::string programString(std::istreambuf_iterator<char>(programFile),
        (std::istreambuf_iterator<char>()));
  cl::Program::Sources source(1, std::make_pair(programString.c_str(),
        programString.length()+1));
  cl::Program program(context, source);

  //std::cout << "Program kernel: " << std::endl << programString << std::endl;

  try
  {
    program.build(devices);
  }
  catch(cl::Error e)
  {
      std::cout << e.what() << ": Error code " << e.err() << std::endl;   
      string buildlog;
      program.getBuildInfo( devices[0], (cl_program_build_info)CL_PROGRAM_BUILD_LOG, &buildlog );
      std::cout << "Error: " << buildlog << std::endl;   
      throw e;
  }

  cl::Kernel kernel(program, KERNEL_FUNC.c_str());

  // Create buffers
  cl::Buffer bufferVmIn(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(aryVmIn), aryVmIn);
  cl::Buffer bufferVmOut(context, CL_MEM_WRITE_ONLY, sizeof(aryVmOut), NULL);
  cl::Buffer bufferVahp(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, sizeof(aryVahp), aryVahp);
  cl::Buffer bufferTestOut(context, CL_MEM_WRITE_ONLY, sizeof(aryTestOut), NULL);

  // Set kernel arguments
  kernel.setArg(0, bufferVmIn);
  kernel.setArg(1, bufferVmOut);
  kernel.setArg(2, bufferVahp);
  kernel.setArg(3, bufferTestOut);

  // Create queue and enqueue kernel-execution command
  cl::CommandQueue queue(context, devices[0]);

  queue.enqueueWriteBuffer(bufferVmIn, CL_TRUE, 0, sizeof(aryVmIn),  aryVmIn, NULL, NULL);
  queue.enqueueWriteBuffer(bufferVahp, CL_TRUE, 0, sizeof(aryVahp),  aryVahp, NULL, NULL);

  queue.enqueueNDRangeKernel(kernel, NULL, ndGlobal, ndLocal);

  queue.enqueueReadBuffer(bufferVmOut, CL_TRUE, 0, sizeof(aryVmOut),  aryVmOut, NULL, NULL);
  queue.enqueueReadBuffer(bufferTestOut, CL_TRUE, 0, sizeof(aryTestOut),  aryTestOut, NULL, NULL);

  // Display updated buffer
  for(i=0; i<10; i++) 
  {
      printf("%6.5f, %6.5f", aryVmOut[i], aryTestOut[i]);
      printf("\n");
  }  
}
catch(cl::Error e) 
{
  std::cout << e.what() << ": Error code " << e.err() << std::endl;   
}
我只是简单地设置一些数据,然后尝试读取Vmout和TestOut,然后查看其中的一些内容。运行此应用程序时,我得到以下输出:

0.00000, 0.90000
0.10000, 0.90000
0.20000, 0.90000
0.30000, 0.90000
0.40000, 0.90000
0.50000, 0.90000
0.60000, 0.90000
0.70000, 0.90000
0.80000, 0.90000
0.90000, 0.90000
到目前为止,这对我来说毫无意义。在内核中,我将VmOut和TestOut设置为完全相同的变量,但是当我将它读回主机时,我得到了不同的结果。我在这里做错了什么,但我还没有弄清楚是什么。如果您有opencl方面的经验,我们将不胜感激

谢谢
David

内核中存在竞争条件,这是由于多个工作项将不同的值存储到同一内存位置造成的,这就是为什么会得到奇怪的结果

提醒-本地地址空间的定义为:

__local或local address space名称用于描述需要修改的变量 在本地内存中分配,并由工作组的所有工作项共享


如果希望每个工作项有不同的值,只需省略
local
修饰符。

如果交换内核的最后两行,会发生什么?
0.00000, 0.90000
0.10000, 0.90000
0.20000, 0.90000
0.30000, 0.90000
0.40000, 0.90000
0.50000, 0.90000
0.60000, 0.90000
0.70000, 0.90000
0.80000, 0.90000
0.90000, 0.90000