Не все рабочие элементы используются opencl

Поэтому я могу скомпилировать и запустить свое ядро, проблема в том, что используются только два рабочих элемента. Я в основном пытаюсь заполнить массив с плавающей точкой [8] с помощью {0,1,2,3,4,5,6,7}. Так что это очень простое приложение Hello World. Сильфон это мое ядро.

// Highly simplified to demonstrate
__kernel void rnd_float32_matrix (
  __global float * res
) {
  uint idx = get_global_id(0);

  res[idx] = idx;
}

Затем я создаю и запускаю ядро ​​со следующим кодом...

   // Some more code

   cl::Program program(context, sources, &err);
   program.build(devices, NULL, NULL, NULL);
   cl::Kernel kernel(program, "rnd_float32_matrix", &err);
   kernel.setArg(0, src_d);

   cl::CommandQueue queue(context, devices[0], 0, &err);

   cl::Event event;

   err = queue.enqueueNDRangeKernel(
      kernel,
      cl::NullRange,
      cl::NDRange(8),
      // I've tried cl::NDRange(8) as well
      cl::NDRange(1),
      NULL,
      &event
    );

   event.wait();

   err = queue.enqueueReadBuffer(
      // This is:
      //   cl::Buffer src_d(
      //     context,
      //     CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
      //     mem_size,
      //     src_h,
      //     &err);
      src_d,
      CL_TRUE,
      0,
      8,
      // This is float * src_h = new float[8];
      src_h);

   for(int i = 0; i < 8; i ++) {
    std::cout << src_h[i] << std::endl;
   }

Я не могу показать его в коде, но я также выбираю устройство GPU и с помощью context.getInfo (..) он показывает, что я использую мою карту NVidia GTX 770M, которая показывает 1024, 1024, 64 рабочих элемента, доступных в измерениях 0, 1 и 2. Когда этот массив печатается, я продолжаю получать... 0, 1, 0, 0, 0, 0, 0, 0. Я также попытался установить res[idx] = 5, и я получаю.. 5, 5, 0, 0, 0, 0, 0, 0. Таким образом, кажется, что фактически используются только два заданных рабочих элемента. Что я делаю неправильно?

1 ответ

Решение

Ваша команда для чтения данных с устройства читает только 8 байтов, что составляет два числа с плавающей запятой:

err = queue.enqueueReadBuffer(
  src_d,
  CL_TRUE,
  0,
  8, // <- This is the number of bytes, not the number of elements!
  // This is float * src_h = new float[8];
  src_h);

Чтобы прочитать 8 поплавков, вам нужно сделать это:

err = queue.enqueueReadBuffer(
  src_d,
  CL_TRUE,
  0,
  8 * sizeof(cl_float),
  // This is float * src_h = new float[8];
  src_h);
Другие вопросы по тегам