2013-08-30 2 views
0

Я пытаюсь проверить эффекты MPI_Send без MPI_Recv. У меня есть следующая программа, которую я компилирую и запускаю с помощью openmpi-1.4.5 и mvapich2-1.9. Я знаю, что эти варианты выполнения для 2-х разных версий стандарта MPI, но я думаю, что MPI_Send и MPI_Recv одинаковы по этим стандартам:OpenMPI v/s Mvapich2: 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 (unending), используя mvapich2?

ответ

0

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

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

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

+0

Ну, случай, который я испытываю, имеет значение для меня :) Я хочу знать, что MVAPICH2 обеспечивает, чтобы '' MPI_send' возвращался, только если он находит соответствующий 'MPI_Recv' (или что-то подобное) на другом конце или нет. Похоже, что openmpi не применяет это условие. Конечно, на другом конце должен быть «MPI_Recv», и я намеренно закодировал программу **, чтобы не было ** этого. – Keval

+0

С MPI_Isend, даже если вы ждете или проверяете завершение, нет гарантии, что сообщение получено, а скорее немедленной формы MPI_Send. Также есть синхронные немедленные версии отправки: [MPI_Issend] (http://mpich.org/static/docs/latest/www3/MPI_Issend.html) –

1

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

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

+0

Спасибо Стэн. Значит, это означает, что протоколы RDMA для чтения не реализованы в mvapich2? Или мне нужно предоставить компилятор времени/времени выполнения для включения таких протоколов? – Keval

+0

MVAPICH не является моей основной реализацией MPI. В прошлый раз, когда я проверил, InfiniBand и другое межсоединение RDMA были параметрами времени сборки для MVAPICH. Таким образом, для включения RDMA-соединения потребуется перекомпиляция/переключение источника MVAPICH. Это должно быть хорошо описано в документации. Возможно, можно найти предварительно построенные версии MVAPICH, которые уже подключены к RDMA-соединениям. –

+2

Eager протоколы не имеют ничего общего с RDMA. Протокол с нетерпением - это тот, который подталкивает (небольшие) сообщения к месту назначения до того, как операция приема будет отправлена. Он также может быть реализован через транспортные средства, не поддерживающие RDMA, такие как TCP/IP. –

0

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

Смежные вопросы