Я пытаюсь умножить квадратные матрицы параллельно с 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 и отправить / получить его?