Использование enqueueFillBuffer в openCL 2.0 создает мусор - PullRequest
1 голос
/ 30 апреля 2020

Я использовал приведенный ниже код

 cl::Buffer intermediateBuffer = cl::Buffer(context, CL_MEM_READ_WRITE,
                    distDeviceWidth * distDeviceHeight * distDeviceDepth * sizeof(T));

  cl::Event copyEvent;

  T value = 0;
   try
  {
    queue.enqueueFillBuffer(intermediateBuffer, &value, 0,
                        distDeviceWidth * distDeviceHeight * distDeviceDepth * sizeof(T),
                        NULL, &copyEvent);
  }catch (const cl::Error& error)
  {
    std::cout << "  -> Prolongation class, Problem in enqueue fill buffer" << std::endl;
    std::cout << "  -> " << getErrorString(error) << std::endl;
    exit(0);
  }

  try
  {
    queue.finish();
  }catch (const cl::Error& error)
  {
    std::cout << "  -> Prolongation class, Problem in finishing fill buffer" << std::endl;
    std::cout << "  -> " << getErrorString(error) << std::endl;
    exit(0);
  }
  copyEvent.wait();

Но когда я читаю данные с устройства и печатаю их на хосте, функция enqueueFillBuffer генерирует мусор. Я не знаю почему. необходимо упомянуть, что я строю данные с openCL 2.0.

1 Ответ

1 голос
/ 30 апреля 2020

В исходной функции clEnqueueFillBuffer() в API OpenCL C шаблон передается в виде пары указателя и размера. В оболочке C ++, enqueueFillBuffer(), шаблон сокращается до одного параметра и обрабатывается следующим образом:

template<typename PatternType>
cl_int enqueueFillBuffer(
    const Buffer& buffer,
    PatternType pattern,
    ::size_t offset,
    ::size_t size,
    const VECTOR_CLASS<Event>* events = NULL,
    Event* event = NULL) const
{
    cl_event tmp;
    cl_int err = detail::errHandler(
        ::clEnqueueFillBuffer(
            object_, 
            buffer(),
            static_cast<void*>(&pattern),
            sizeof(PatternType), 

Обратите внимание, как оболочка внутренне принимает адрес переданных данных шаблона (&pattern) и выводит размер автоматически. (sizeof(PatternType))

Это означает, что если вы передадите значение указателя в enqueueFillBuffer(), он будет использовать значение указателя в качестве шаблона, в качестве указателя на указатель будет передано в OpenCL. Похоже, именно это и делает ваш код:

T value = 0;
//…
queue.enqueueFillBuffer(intermediateBuffer, &value, 0,
//               don't pass a pointer here--^^^^^^

Удаление & должно решить проблему.

...