Апарапи добавить образец

Я изучаю Aparapi (https://code.google.com/p/aparapi/ ) и имеют странное поведение одного из включенных образцов. Проба первая, "добавочная". Построение и выполнение - это нормально. Я также помещаю следующий код для проверки, действительно ли используется графический процессор.

if(!kernel.getExecutionMode().equals(Kernel.EXECUTION_MODE.GPU)){
    System.out.println("Kernel did not execute on the GPU!");
}

и это работает нормально. Но если я попытаюсь изменить размер массива с 512 на число больше 999 (например, 1000), у меня будет следующий вывод:

!!!!!!! clEnqueueNDRangeKernel() failed invalid work group size
after clEnqueueNDRangeKernel, globalSize[0] = 1000, localSize[0] = 128
Apr 18, 2013 1:31:01 PM com.amd.aparapi.KernelRunner executeOpenCL
WARNING: ### CL exec seems to have failed. Trying to revert to Java ###
JTP

Kernel did not execute on the GPU!

Вот мой код:

  final int size = 1000;

  final float[] a = new float[size];
  final float[] b = new float[size];

  for (int i = 0; i < size; i++) {
     a[i] = (float)(Math.random()*100);
     b[i] = (float)(Math.random()*100);
  }

  final float[] sum = new float[size];

  Kernel kernel = new Kernel(){
     @Override public void run() {
        int gid = getGlobalId();
        sum[gid] = a[gid] + b[gid];
     }
  };

  Range range = Range.create(size);
  kernel.execute(range);

  System.out.println(kernel.getExecutionMode());
  if (!kernel.getExecutionMode().equals(Kernel.EXECUTION_MODE.GPU)){
     System.out.println("Kernel did not execute on the GPU!");
  }

  kernel.dispose();

}

Я попытался указать размер, используя

Range range = Range.create(size, 128);

как было предложено в группе Google, но ничего не изменилось.

В настоящее время я работаю на Mac OS X 10.8 с Java 1.6.0_43. Версия Aparapi является последней (2012-01-23).

Я что-то упускаю? Любые идеи?

заранее спасибо


person besil    schedule 18.04.2013    source источник


Ответы (1)


Aparapi наследует «стиль сетки» реализации от OpenCL. Когда вы указываете диапазон выполнения (скажем, 1024), OpenCL разбивает этот «диапазон» на группы одинакового размера. Возможно 4 группы по 256 или 8 групп по 128.

Размер группы должен быть фактором диапазона (так что assert(range%groupSize==0)).

По умолчанию Aparapi самостоятельно выбирает размер группы.

Но вы решили полностью указать диапазон и размер группы для использования

Диапазон r= Диапазон.диапазон(n,128)

Вы несете ответственность за то, чтобы n%128==0.

Судя по ошибке, вы выбрали Range.range(1000,128).

К сожалению, 1000 % 128 != 0, поэтому этот диапазон не работает.

Если вы укажете

Диапазон r = Диапазон.диапазон(n)

Aparapi выберет допустимый размер группы, найдя наибольший общий делитель n.

Попробуйте отбросить 128 в качестве второго аргумента.

Гэри

person gfrost    schedule 20.04.2013
comment
Спасибо за ответ. Я сбросил 128 в Range.create(), и все работает нормально, используя значение, кратное 128, в качестве переменной «размер». Вы сказали, что Aparapi внутренне выбирает размер группы, который должен быть фактором диапазона. Тогда почему код работает при выборе size=999? 999%128=103, но выполняется на GPU без ошибок. Должен ли я всегда использовать размер, кратный моему локальному размеру? Как узнать значение localsize? Большое спасибо - person besil; 20.04.2013
comment
Просто используйте версию Range.range(size) с одним аргументом. Aparapi выберет для вас наибольший общий множитель. Для 999 это должно быть что-то вроде 9*111. Вы решаете взять на себя управление и вынуждаете Aparapi использовать localsize 128 с фабричным методом Range.range(X, 128). Здесь Aparapi «соблюдает» ваш запрос, но OpenCL (правильно) отклоняет запрос во время выполнения и не может выполниться. Имейте в виду, что в MacOSX были различные сообщения о проблемах с устройством (GPU), сообщающим о неправильных размерах групп. Я не уверен, что вы попали в это. У меня Mac OSX, и ваш код отлично работает для меня. - person gfrost; 21.04.2013