0

私は、すべてのスレーブがデータをマスターに送り返す MPI プロジェクトに取り組んできました。何らかの理由で、連続して 2 回送信した場合にのみマスターがデータを受信します。これは非常に奇妙で、他の奇妙な問題を引き起こしていると思います。何が原因でしょうか?最初の送信は、ある種の迷惑データか何かを送信していると思います。ただし、送信はまったく同じコード行です。

編集:以下のコード...

if (numProcs > 0)
    MPI_Barrier( MPI_COMM_WORLD ) ; //only wait if there are other processes to wait for

if (rank != 0)
{
    MPI_Send(handArray, 10, MPI_DOUBLE, 0, TAG_HAND, MPI_COMM_WORLD);
    MPI_Send(handArray, 10, MPI_DOUBLE, 0, TAG_HAND, MPI_COMM_WORLD);
}
//8. After the main loop the master process receives and sums together the hand counts array
//   from each slave process.
else
{
    int activeProcs = numProcs - 1;
    getHandsFromSlaves( activeProcs, handArray );

次に、マスターはいくつかのデータの印刷に進みます...

これが getHands FromSlaves メソッドです。同じ問題で、これにもブロッキング呼び出しを使用しようとしたことに注意してください。

void getHandsFromSlaves( int& activeCount, double handTotals[10] ){

static MPI_Request request;
static int msgBuff, recvFlag;
static double handBuff[10];
MPI_Status status;

while (activeCount > 0)
{
    if( request )
    {
        // Already listening for a message

        // Test to see if message has been received
        MPI_Test( &request, &recvFlag, &status );
        //cout << "TAG: " << status.MPI_TAG << " SOURCE: "<< status.MPI_SOURCE  << " ERROR: " << status.MPI_ERROR << endl;
        if( recvFlag )
        {
            // Message received
            if( status.MPI_TAG == TAG_HAND )
            {
                cout << "Hand Received!" << endl;

                for(int m = 0; m < 10; ++m)
                {
                    handTotals[m] += handBuff[m];
                }

                activeCount--;
            }
            else
            {
                //error report... what happened?
                cout << "TAG: " << status.MPI_TAG << " SOURCE: "<< status.MPI_SOURCE  << " ERROR: " << status.MPI_ERROR << endl;
            }

            // Reset the request handle
            request = 0;
        }
    }

    if( !request && activeCount > 0 )
        // Start listening again
        MPI_Irecv(&handBuff, 10, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &request);
}
}
4

1 に答える 1

1

ルーチンrequestに入るときに変数が定義されていないため、おそらく1つのメッセージを処理しようとしている可能性があります。getHandsFromSlaves()Enterの場合、requestほぼ確実にゼロ以外であるMPI_Testため、を投稿していなくても、すぐに何かメッセージを送信しようとしますIrecv

実際、ここに投稿されたコードの抜粋には、本当に奇妙なことがたくさんあります。なぜローカル変数なのstaticですか?MPI_Test()使用する代わりに、なぜ独自のビジーウェイトを実装するのMPI_Wait()ですか?受信の間に何も役に立たないのに、なぜ非ブロッキング受信を使用しているのですか?実際、とにかくすべての配列を合計しているだけの場合、なぜ、?を実行する代わりに、個別のポイントツーポイント受信を実行しているのMPI_Reduce()ですか?

次のはるかに短いコードは、上記で実行しようとしていることを実行するように見えます。

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


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

    int rank, numProcs;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
    double handArray[10];
    double handTotal[10];

    for (int i=0; i<10; i++)
        handArray[i] = rank + i;

    if (rank == 0)  // Since apparently rank 0 doesn't do anything
    {
        for (int i=0; i<10; i++)
            handArray[i] = 0;
    }

    MPI_Reduce(handArray, handTotal, 10, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        printf("Hand Totals= \n");
        for (int i=0; i<10; i++)
            printf(" %lf ", handTotal[i]);
        printf("\n");
    }

    MPI_Finalize();
}
于 2012-10-13T23:02:00.427 に答える