0

質問があります 。np 個のプロセスがあると仮定します。プロセスごとに、入力ファイルに基づいて、他のすべてのプロセス (0 から ...) に送信する必要があるメッセージの数を計算し、この数を送信したいと考えています。問題は、直接接続されたノードを介して作成したトポロジからのみ送信できることです。したがって、基本的には、各プロセスが他のすべてのプロセスに int を送信するようにします。次のアルゴリズムがあります (疑似コードを使用します)。

for(i=1,np){
    if(i!=rankID){
        MPI_Send(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD);
        MPI_SEND(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int 
    }
}
while(1){
    MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
    MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
    if(destination == rankID){
        ireceive+=recvInt;
        receivedFrom++;
        //normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ?
    }
    else{
        MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
        MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
    }

}

これについてもう少し説明します。この小さなアルゴリズムの最後に、次のステップで受け取るメッセージの数を各プロセスに知らせたいと思います。

このメッセージを各ノードから各ノードに送信するには、以前に作成したルーティング テーブルを使用します。コード)。

各ノードは np 個のプロセスがあることを認識しているため、各ノードは np-1 メッセージを受信する必要があります (宛先はノードです)。

私が抱えている問題は、np-1 メッセージを受信した後、他のプロセスの next_hop である可能性があり、メッセージが送信されないため、中断できないことです。だから私はこのようなことをしたい、MPI_TESTまたは別の命令を使用して、Recvが実際に何かを受信して​​いるかどうか、またはプログラムが1〜2秒間ブロックされている場合、受信しないことが明らかであるため、そこに座っているだけかどうかを確認しますこれ以上(最大20〜30プロセスの大きなトポロジがないため)。

問題は、MPI_Test やその他の構文を使用したことがなく、これを行う方法がわからないことです。誰かが Recv のタイムアウトを作成するのを手伝ってくれますか? ありがとう、長い文章でごめんなさい

4

1 に答える 1

0

おそらく最も効率的なコードではありませんが、動作するはずです (テストする機会がありませんでした)。

MPI_Request request;
MPI_Status status;
for(i=1,np){
    if(i!=rankID){
        MPI_ISend(&nr,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM_WORLD);
        MPI_ISend(&i,1,MPI_INT,topology[i][nexthop],DATA,MPI_COMM,WORLD); //i send the destination along with the int 
    }
}
while(1){
    bool over = false;
    if(over == true)
        break;
    if(recievedFrom < np){
        MPI_Recv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
        MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
        if(destination == rankID){
            ireceive+=recvInt;
            receivedFrom++;
            //normally i would break if i received all np-1 messages but what if someone sends a message through me for another process ?
        }
        else{
            MPI_Send(&recvInt,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
            MPI_Send(&destination,1,MPI_INT,topology[destination][nexthop],DATA,MPI_COMM_WORLD);
        }
    }
    else {
        MPI_Irecv(&recvInt,1,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD, request); // non blocking recieve call after you finished receiving everything addressed to you
        time_t now = time(NULL);
        while(time(NULL) < now + time_you_set_until_timeout){
            over = true;
            int flag = 0;
            MPI_Test(req, flag, status);
            if(flag){
                over = false;
                break; //exit timeout loop if something was received
            }
        }
    }
    if(!over){
            MPI_Recv(&destination,MPI_INT,MPI_ANY_SOURCE,DATA,MPI_COMM,WORLD);
            //route the message and continue
    }
}

いずれにせよ、メッセージがトポロジを通過するまでにどれくらいの時間がかかるかわからないため、タイムアウトに選択する時間には注意する必要があります。ノードに宛てられたすべてのメッセージを受信したことをノードに通知するメッセージをブロードキャストするなど、他の種類のシグナリングメカニズムを実装しようとすることができます。確かに、送信されるメッセージの数は増えますが、全員が確実にすべてを受信できるようになります。また、送信するデータをパックまたはシリアル化して、Send/Recv 呼び出しを 1 つだけにすることもできます。これにより、コードの操作が簡単になります (私の意見では)。

于 2013-01-21T21:41:14.120 に答える