Используя MPI_Type_Vector и MPI_Gather, в C - PullRequest
0 голосов
/ 05 июня 2010

Я пытаюсь умножить квадратные матрицы параллельно с MPI.

Я использую MPI_Type_vector для отправки квадратных подматриц (массивов с плавающей точкой) в процессы, чтобы они могли вычислять субпродукты. Затем для следующих итераций эти подматрицы отправляются соседним процессам как MPI_Type_contiguous (отправляется вся подматрица). Эта часть работает как положено, и локальные результаты исправляются.

Затем я использую MPI_Gather со смежными типами для отправки всех локальных результатов обратно в корневой процесс. Проблема в том, что окончательная матрица строится (очевидно, этим методом) построчно, а не подматрицей по подматрице.

Я написал некрасивую процедуру, переставляющую конечную матрицу, но мне хотелось бы знать, существует ли прямой способ выполнения «обратной» операции отправки MPI_Type_vectors (т. Е. Отправки массива значений и непосредственного размещения его в подмассиве) форма в получающем массиве).

Пример, чтобы попытаться уточнить мой длинный текст:

A [16] и B [16]

Это действительно двумерные массивы, A [4] [4] и B [4] [4].

- это умножаемые матрицы 4х4; C [4] [4] будет содержать результат; Используются 4 процесса (Pi с i от 0 до 3):

Pi получает две подматрицы 2x2: subAi [4] и subBi [4]; их продукт хранится локально в subCi [4].

Например, P0 получает:

subA0 [4], содержащий A [0], A [1], A [4] и A [5];
subB0 [4], содержащий B [0], B [1], B [4] и B [5].

После того, как все рассчитано, корневой процесс собирает все subCi [4].

Тогда C [4] [4] содержит:

[
subC 0 [0], subC 0 [1], subC 0 [2], subC 0 [3],
subC1 [0], subC1 [1], subC1 [2], subC1 [3],
subC2 [0], subC2 [1], subC2 [2], subC2 [3],
subC3 [0], subC3 [1], subC3 [2], subC3 [3]]

и мне бы хотелось, чтобы это было:

[
subC 0 [0], subC 0 [1], subC1 [0], subC1 [1],
subC 0 [2], subC 0 [3], subC1 [2], subC1 [3],
subC2 [0], subC2 [1], subC3 [0], subC3 [1],
subC2 [2], subC2 [3], subC3 [2], subC3 [3]]

без дальнейшей работы. Кто-нибудь знает способ?

Спасибо за советы.

Добавление информации в ответ на 'High Performance Mark':

1 Ну, мои исходные матрицы - это двумерные массивы (в форме A [4] [4]). Я хотел коротко написать свой вопрос, теперь я вижу, что это плохая идея ...

Я определил MPI_Type_vector следующим образом, например:

MPI_Type_vector(2, 2, 4, MPI_FLOAT, &subMatrix);

(Кстати, я не вижу никакой разницы для уплощенного массива).

2 Я далеко не эксперт по MPI, поэтому могу делать странные вещи. Вот немного моего кода, примененного к примерам (рассматривается только A, B очень похож):

Отправка подматриц из корневых в подчиненные процессы:

Master {
    for (i = 0 ; i < 2 ; i++)
        for (j = 0 ; j < 2 ; j++)
            MPI_Send(&A[j * 2][(i + j) % 2 * 2], 1, subMatrix, i + j * 2, 42, MPI_COMM_WORLD);
}

Рабы получают:

MPI_Recv(subA, 4, MPI_FLOAT, 0, 42, MPI_COMM_WORLD, &status);

Затем обмен между процессами осуществляется через MPI_Send и MPI_Recv из subMatrixLocal, а именно:

MPI_Type_contiguous(4, MPI_FLOAT, &subMatrixLocal);

После того, как все локальные операции выполнены, я собираю все матрицы subC в C:

MPI_Gather(subC, 1, subMatrixLocal, C, 1, subMatrixLocal, 0, MPI_COMM_WORLD);

и я получаю ранее заявленный результат, который мне нужно изменить ...

А по поводу предложенного вами алгоритма: следующим шагом будет умножение матриц на графические процессоры, где эффективны продукты с квадратными матрицами. MPI будет использоваться только для передачи матриц из процессоров в процессоры. Конечно, тогда будет проверена глобальная эффективность.

0 Вы сказали, что «то же самое определение типа должно быть применимо для обратной операции». Тем не менее, мой MPI_Vector_type работает нормально на «большой» матрице, но использование его непосредственно в подматрице невозможно (применение MPI_Vector_type (2, 2, 4) к матрице 2x2 приведет к неверным результатам, так как для последние два значения "вне" определенного массива ...). Вы имеете в виду, что я должен создать еще один тип MPI_Vector_type и отправить / получить его?

1 Ответ

1 голос
/ 06 июня 2010

Ответ на ваш вопрос заключается в том, что существует прямой способ выполнить обратную операцию отправки MPI_Type_vectors - да. Если вы уже определили вектор типа для отправки подматрицы из одного процесса в другой, то же самое определение типа должно быть применимо для обратной операции.

Однако меня несколько смущают ваши объяснения, и у меня есть еще вопросы к вам. Если вы ответите на них, я смогу дать лучший совет.

  1. Вы пишете свои матрицы как A [16], B [16] и говорите, что они 4x4. Вы их уже сгладили? Я ожидал, что они будут A [4] [4] и т. Д. Если вы сгладили матрицы, почему вы это сделали? Вы, безусловно, можете определить mpi_type_vector для определения подматрицы двумерной матрицы.
  2. Мне кажется немного странным, не обязательно неправильным, но странным, совпадение посылок со сборками. Я обычно ожидал бы увидеть собрания, сопоставленные разбросанными и отправленными получателями. Возможно, вы могли бы опубликовать достаточно своего кода, чтобы уточнить, какие операции вы используете.

Наконец, я думаю, что умножение матриц путем умножения подматриц, вероятно, неэффективный подход с MPI. Если вы делаете это как упражнение, продолжайте. Но лучший алгоритм, и, вероятно, тот, который легче реализовать, будет

  1. матрица mpi_broadcast B для всех процессов;
  2. процесс-директор отправляет строки A рабочим процессам в цикле;
  3. рабочий процесс вычисляет строку C и отправляет ее обратно в директорский процесс;
  4. Директор процесса получает строки C и помещает их в нужное место.
...