Ядро автокорреляции OpenCL

#opencl

#opencl

Вопрос:

Я написал простую программу, которая выполняет автокорреляцию следующим образом…Я использовал директивы ускорителя pgi для переноса вычислений на графические процессоры.

 //autocorrelation
void autocorr(float *restrict A, float *restrict C, int N)
{
      int i, j;
      float sum;
      #pragma acc region
      {
        for (i = 0; i < N; i  ) {
                        sum = 0.0;
                for (j = 0; j < N; j  ) {
                    if ((i j) < N)
                      sum  = A[j] * A[i j];
                    else
                      continue;
               }
            C[i] = sum;
       }
       }
}
  

Я написал аналогичную программу на OpenCL, но я не получаю правильных результатов. Программа заключается в следующем…Я новичок в программировании на GPU, поэтому, помимо подсказок, которые могли бы исправить мою ошибку, приветствуются любые другие советы.

 __kernel void autocorrel1D(__global double *Vol_IN, __global double *Vol_AUTOCORR, int size)
{

    int j, gid = get_global_id(0);
    double sum = 0.0;

    for (j = 0; j < size; j  ) {
            if ((gid j) < size)
            {
               sum  = Vol_IN[j] * Vol_IN[gid j];
            }
            else
               continue;
               }

    barrier(CLK_GLOBAL_MEM_FENCE);
    Vol_AUTOCORR[gid] = sum;

}
  

Поскольку я передал размерность равной 1, поэтому я рассматриваю возможность того, что мой вызов get_global_size (0) выдаст мне идентификатор текущего блока, который используется для доступа к входному массиву 1d.

Спасибо,
Саян

Комментарии:

1. Какие результаты вы получаете? Если вы измените Vol_AUTOCORR[gid] = sum; на Vol_AUTOCORR[gid] = gid; , даст ли это вам ожидаемый массив увеличенных значений?

2. Я не вижу здесь проблемы? Каков ваш код хоста? Правильно ли вы передаете данные на устройство и обратно?

3. Извините за поздний ответ … никаких проблем с ядром нет, у меня была ошибка в коде хоста, из-за которой результаты были неправильными. Спасибо за оценку.

Ответ №1:

Код правильный. Насколько я знаю, это должно работать нормально и давать соответствующие результаты.

барьер (CLK_GLOBAL_MEM_FENCE); не требуется. Вы получите больше скорости без этого предложения.

Ваша проблема должна быть вне ядра, убедитесь, что вы правильно передаете входные данные, и вы извлекаете из GPU правильные данные.

Кстати, я полагаю, вы используете графический процессор с поддержкой двойной точности, поскольку выполняете двойные вычисления. Убедитесь, что вы передаете также двойные значения. Помните, что вы не можете указать указатель с плавающей точкой на значение double и наоборот. Это даст вам неправильные результаты.

Комментарии:

1. Да, я заметил, что БАРЬЕР в этом случае не требуется. Спасибо, что указали мне на тип данных.