Эффективное параллельное тензорное сжатие с векторизованными данными - PullRequest
1 голос
/ 17 июня 2020

Шаг моего кода, определяющий время, представляет собой тензорное сжатие следующей формы

  #pragma omp parallel for schedule(dynamic)
  for(int i = 0; i < no; ++i){
    for(int j = 0; j < no; ++j){
      X.middleCols(i*nv,nv) += Y.middleCols(j*nv,nv) * this->getIJMatrix(j,i);
    }
  }

, где X и Y - большие матрицы размерности (nx, no * nv) и функция getIJMatrix(j,i) возвращает матрицу (nv * nv) для пары индексов ij тензора четвертого ранга. Также no < nv << nx. Распараллеливание здесь простое. Тем не менее, я могу использовать симметрию относительно i и j

  #pragma omp parallel for schedule(dynamic)
  for(int i = 0; i < no; ++i){
    for(int j = i; j < no; ++j){
      auto ij = this->getIJMatrix(j,i);
      X.middleCols(i*nv,nv) += Y.middleCols(j*nv,nv) * ij;
      if(i!=j) X.middleCols(j*nv,nv) += Y.middleCols(i*nv,nv) * ij.transpose();
    }
  }

, оставив меня в состоянии гонки. Поскольку X велико, использование сокращения здесь невозможно.

Если я правильно понимаю, нет никакого способа обойти каждый поток, ожидающий других во внутреннем l oop. Что для этого рекомендуется, чтобы сделать это как можно быстрее?

edit: исправлены очевидные ошибки

...