Простой вопрос MPI - получите от любого процесса, ЕСЛИ есть сообщение, ожидающее получения - PullRequest
1 голос
/ 25 июля 2011

В C у меня есть сообщение о том, что процесс может или не может передавать другим процессам:

MPI_Bcast(outmsg, 128, MPI_CHAR, 0, MPI_COMM_WORLD);

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

Есть идеи?Спасибо:).

Ответы [ 2 ]

3 голосов
/ 25 июля 2011

Вы можете использовать MPI_Iprobe для проверки сообщения в «Входящие» и, если проверка прошла успешно, получите сообщение с MPI_Recv.Но с Iprobe вы не можете использовать Bcast, и вам следует переключиться на ручной MPI_Isend с ручным переключением по коммуникатору.Также добавьте MPI_Wait() после Isend.Вот пример для двух процессов (но здесь есть код отправки и получения) http://mpi.deino.net/mpi_functions/MPI_Iprobe.html (в самом низу).

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

#include "mpi.h"
#include <stdio.h>

int main( int argc, char * argv[] )
{
    int rank;
    int sendMsg = 123;
    int recvMsg = 0;
     int flag = 0;
    int count;
     MPI_Status status;
     MPI_Request request;
    int errs = 0;

     MPI_Init( 0, 0 );

     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     if(rank == 0)  /* There is something incorrect with ranks in this code, please correct */
     {
         MPI_Isend( &sendMsg, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &request );  //sender

        while(!flag)
         {
             MPI_Iprobe( 0, 0, MPI_COMM_WORLD, &flag, &status ); // receiver
         }
         MPI_Get_count( &status, MPI_INT, &count ); // receiver
        if(count != 1)
         {
             errs++;
         }
         MPI_Recv( &recvMsg, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status ); // receiver
         if (recvMsg != 123)
         {
             errs++;
         }

         MPI_Wait( &request, &status ); // sender

     }

     MPI_Finalize();
     return errs;
 }
1 голос
/ 06 мая 2017

Есть лучший пример, важный момент - проверить с MPI_Iprobe() несколько раз:

#include "mpi.h"
#include <cstdlib>
#include <vector>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{

    int myrank,size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
    MPI_Comm_size(MPI_COMM_WORLD,&size);

    vector<int> destination;

    if(myrank==0)
    {
        destination.push_back(1);
    }
    else if(myrank==1)
    {
        destination.push_back(0);
    }


    for(uint i=0; i < destination.size(); i++)
    {
        //cout << myrank << " " << destination.at(i) << endl;
    }

    MPI_Status status;
    MPI_Request request;

    int rcvbuff;
    //int buff[2]
    int sendbuff=myrank+10;
    for(uint i=0;i<destination.size() ;i++)
    {
        MPI_Isend(&sendbuff,1,MPI_INT, destination.at(i),0, MPI_COMM_WORLD, &request);

    }

    int count;
    int flag=0;
    while(flag==0)
    {
        MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag,&status);
        cout << "Process " << myrank << ", flag " << flag << endl;
    }
    if(flag)
    {
        MPI_Get_count(&status, MPI_INT, &count);
        MPI_Irecv(&rcvbuff,count, MPI_INT,destination.at(0),0, MPI_COMM_WORLD, &request);
    }

    /*    enter code here     */

    MPI_Wait(&request,&status);

    cout << "The message received by " << myrank << " is '" << rcvbuff << "'" << endl;

    MPI_Finalize();
}
...