Раздача команд в openMp - PullRequest
       80

Раздача команд в openMp

0 голосов
/ 19 октября 2019

Я пытаюсь распараллелить этот код с openMP (4.5) «командами omp» и GPU (Nvidia GTX 1050) и CUDA (9.0), я доказываю последовательную и параллельную реализацию с (CPU i5-7400) и обаработает нормально, но версия для GPU не работает, код это матричное умножение C = A * B
Я думаю, что целевые команды #pragma omp распределяют параллельно не правильно, но я понятия не имею, где ошибка моглабыть.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>

int main(int argc, char **argv)
{
   int n;//Given by the user
   int i, j, k;
    double start, end;

   for (i=0; i<n; i++) 
      for (j=0; j<n; j++) {
         a[i][j] = ((double)rand())/((double)RAND_MAX);
         b[i][j] = ((double)rand())/((double)RAND_MAX);
         c[i][j] = 0.0;
      }


   start = omp_get_wtime();
   #pragma omp target data map(to: a[0:i][0:k], b[0:k][0:j]) map(tofrom:c[0:i][0:j]) 
   #pragma omp target teams distribute parallel for
   for (i=0; i<n; i++){ 

      for (k=0; k<n; k++) { 

         for (j=0; j<n; j++) {
            c[i][j] += a[i][k]*b[k][j];
         }
     }
  }
    #pragma omp barrier
    end = omp_get_wtime();
    printf("the total time is %5.9f\n", end - start);


   //check a random element if d - c[i][j]) equals 0 the implementation is correct
   i = rand()%n;
   j = rand()%n;
   double d = 0.0;
   for (k=0; k<n; k++)
      d += a[i][k]*b[k][j];


   printf("Check on a random element: %18.9lE\n", fabs(d-c[i][j]));

   return 0;

}

1 Ответ

0 голосов
/ 22 октября 2019

Скорее всего, решение вашей проблемы заключается в объявлении k и j частными переменными.

Несколько других комментариев:

  • Возможно, вы захотите изменить порядок циклов, инвертируяцикл на k и j, таким образом, вы сможете свернуть два внешних цикла
  • Нет необходимости иметь явный барьер в вашем коде, уже есть неявный барьер в конце цели ompрегион
  • Я бы посоветовал вам вычислить общий остаток, чтобы убедиться, что ваша реализация верна

#pragma omp target data map(to: a[0:n][0:n], b[0:n][0:n]) map(tofrom:c[0:n][0:n]) 
#pragma omp target teams distribute parallel for private(i,j,k) collapse(2)
for (i=0; i<n; i++)
  for (j=0; j<n; j++)
    for (k=0; k<n; k++)
        c[i][j] += a[i][k]*b[k][j];
...