【问题标题】:Have to Send MPI Message Twice for Some Reason由于某种原因必须两次发送 MPI 消息
【发布时间】:2012-10-13 20:53:21
【问题描述】:

我一直在做一个 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 );

然后master继续打印一些数据......

这里是 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);
}
}

【问题讨论】:

  • 添加了代码。如果您还需要什么,请告诉我。
  • 有人可以帮忙吗?非常感谢任何帮助!

标签: c++ c multiprocessing mpi


【解决方案1】:

好吧,您可能正在尝试处理太多消息,因为您的 request 变量在进入您的 getHandsFromSlaves() 例程时未定义。因为在输入时,request 几乎可以肯定是非零的,即使您没有发布 Irecv,您也会立即尝试 MPI_Test 获取消息。

事实上,这里发布的代码摘录有很多非常奇怪的地方。为什么局部变量是static?为什么要在MPI_Test() 上实现自己的busywait,而不是使用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();
}

【讨论】:

  • 包括进程 0 在内的所有进程都添加到它们自己的手数组中。最后,进程 0 汇总所有总数并打印数据。我只是没有发布所有进程都在工作时发生的代码。 handArray 的每个元素都存储它找到的每种类型的扑克手的数量。感谢您的帮助,我将检查 MPI_Reduce 并查看是否可以使其正常工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-03
  • 2018-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多