Методы приближения функций

MPI

Рассылка матрицы (работа над ошибками)

Передача сообщений: случай, когда получатель = отправителю

Полезные советы

В функциях приёма в качестве аргумента типа MPI_Status можно указывать MPI_STATUS_IGNORE — в этом случае объявлять отдельную переменную типа MPI_Status не нужно.

Рассылка матрицы

Предложенный в прошлой презентации метод с использованием MPI_Type_vector не работает, т.к. элементы вектора в такой схеме лежат не плотно.

Корректно реализовать такой метод рассылки было бы с использованием MPI_Type_darray (http://mpi.deino.net/mpi_functions/MPI_Type_create_darray.html).

При разделении по столбцам, если сама матрица при этом хранится по строкам, проще всего рассылать «пакетами» по \(P\) элементов с помощью MPI_Scatter.

Рассылка матрицы

Как и раньше, в примере рассмотрен только случай \(N ⋮ P\), для использования в программе нужно модифицировать для случая деления с остатком (например, добавить выравнивание).

double *matrix_buffer = calloc(N*N/P, sizeof(double));
// только в 0-м процессе
double *row_buffer = calloc(N, sizeof(double));
// ...
for (int row=0; row < N; row++) {
  // считать/сгенерировать
  // строку row размера N в row_buffer
  read_row(N, row, row_buffer);
  // считать из row_buffer части строки через P элементов
  // записать в matrix_buffer подряд
  for (int col = 0; col < N; col += P) {
    MPI_Scatter(row_buffer+col, 1, MPI_DOUBLE,
      0, MPI_COMM_WORLD);
  }
}

Передача сообщений

Для лаконичности кода часто при пересылках «точка-точка» удобно бывает не рассматривать отдельно случай, когда отправитель и получатель — один и тот же процесс (например, при \(P=1\)). В общем случае это не рекомендуется (лучше проверять if-ом). buff1 и buff2 должны быть разными участками памяти.

Источник: http://stackoverflow.com/a/20143164

MPI_Request req;
// Start a non-blocking receive
MPI_Irecv(buff2, count, datatype, sender, 0, comm, &req);
// Send to everyone
MPI_Send(buff1, count, datatype, receiver, 0, comm);
// Complete the non-blocking receive
MPI_Wait(&req, MPI_STATUS_IGNORE);