OpenMPI v / s Mvapich2: MPI_Send без MPI_Recv

Я пытаюсь проверить влияние MPI_Send без MPI_Recv, У меня есть следующая программа, которую я компилирую и запускаю, используя openmpi-1.4.5 и mvapich2-1.9. Мне известно, что эти реализации предназначены для двух разных версий стандарта MPI, но я думаю, MPI_Send а также MPI_Recv одинаковы для всех этих стандартов:

#include <mpi.h>
#include <iostream>
#include <assert.h>

using namespace std;

MPI_Comm ping_world;
int mpi_size, mpi_rank;

void* ping(void* args)
{
int ctr = 0;
while(1)
{
char buff[6] = "PING";
++ctr;
for(int i=0; i<mpi_size; ++i)
{
cout << "[" << ctr << "] Rank " << mpi_rank << " sending " << buff << " to rank " << i << endl;
MPI_Send(buff, 6, MPI_CHAR, i, 0, ping_world);
}
}
}

int main(int argc, char *argv[])
{
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
assert(provided == MPI_THREAD_MULTIPLE);

MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);

{
MPI_Group orig_group;
MPI_Comm_group(MPI_COMM_WORLD, &orig_group);
int ranks[mpi_size];
for(int i=0; i<mpi_size; ++i)
ranks[i] = i;

MPI_Group new_group;
MPI_Group_incl(orig_group, mpi_size, ranks, &new_group);
MPI_Comm_create(MPI_COMM_WORLD, new_group, &ping_world);
}

pthread_t th_ping;
pthread_create(&th_ping, NULL, ping, (void *) NULL);

pthread_join(th_ping, NULL);

return 0;
}

С mvapich2 я всегда получаю следующий вывод (не более того). По сути, программа, кажется, зависла после 3 строк:

[1] Rank 0 sending PING to rank 0
[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1

С openmpi я получаю следующий вывод (бесконечный):

[1] Rank 1 sending PING to rank 0
[1] Rank 1 sending PING to rank 1
[1] Rank 0 sending PING to rank 0
[1] Rank 0 sending PING to rank 1
[2] Rank 0 sending PING to rank 0
[2] Rank 0 sending PING to rank 1
[3] Rank 0 sending PING to rank 0
[3] Rank 0 sending PING to rank 1
[4] Rank 0 sending PING to rank 0
[4] Rank 0 sending PING to rank 1
[5] Rank 0 sending PING to rank 0
[2] Rank 1 sending PING to rank 0
[2] Rank 1 sending PING to rank 1
[3] Rank 1 sending PING to rank 0
[3] Rank 1 sending PING to rank 1
[4] Rank 1 sending PING to rank 0
[4] Rank 1 sending PING to rank 1
[5] Rank 1 sending PING to rank 0
[5] Rank 1 sending PING to rank 1
[6] Rank 1 sending PING to rank 0

Вопросы:

  1. Почему такая разница?
  2. Как мне добиться поведения, похожего на openmpi (нескончаемое) при использовании mvapich2?

0

Решение

MPI_Send может возвращаться, когда буфер может безопасно использоваться вызывающей программой. Ничто другое не гарантируется, но есть много различных зависимых от реализации поведений. Различные реализации могут по-разному обрабатывать буферизацию сообщений. Активные протоколы также позволяют транспортировать некоторые короткие (er) сообщения в ранг приема без необходимости публикации соответствующего MPI_Recv.

Если вам нужно, чтобы MPI принудительно принимал сообщение, полученное до возвращения блокирующей отправки, посмотрите на MPI_Ssend.

1

Другие решения

Это неверная программа MPI для отправки данных без их получения. Проблема, которую вы видите, состоит в том, что ваши посылки не совпадают ни с какими получениями. В зависимости от реализации, MPI_SEND может блокироваться, пока сообщение не будет получено на другом конце. Фактически, все известные мне реализации будут делать это для достаточно больших сообщений (хотя ваше сообщение размером 6 байт, вероятно, нигде не достигает этого порога).

Если вы хотите отправлять сообщения без блокировки, вам необходимо использовать MPI_ISEND, Однако даже для этого нужно в конце концов позвонить MPI_TEST или же MPI_WAIT чтобы быть уверенным, что данные действительно были отправлены, а не просто помещены в буфер.

Я не уверен в специфике того, почему MVAPICH2 зависает, а Open MPI нет, но в конце концов это не имеет значения. Вам нужно изменить свою программу, или вы просто тестируете кейсы, которые в любом случае не должны использоваться.

0

В реализации MVAPICH2 (и MPICH) самоблокирующая отправка блокируется (не буферизируется) до тех пор, пока не будет найден соответствующий MPI_Recv. По этой причине он не зависал на уровне «Ранг 1, отправляющей PING на ранг 0». Это просто выбор реализации.

0
По вопросам рекламы [email protected]