【问题标题】:Second MPI_Send is hanging if buffer size is over 256如果缓冲区大小超过 256,则第二个 MPI_Send 挂起
【发布时间】:2011-03-01 07:28:07
【问题描述】:
int n, j, i, i2, i3, rank, size,  rowChunk,  **cells, **cellChunk;


MPI_Status status;

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


if(!rank){
    printf("\nEnter board size:\n");
    fflush(stdout);
    scanf("%d", &n);

    printf("\nEnter the total iterations to play:\n");
    fflush(stdout);
    scanf("%d", &j);


    srand(3);

    rowChunk = n/size; //how many rows each process will get

    for(i=1; i<size; i++){

        MPI_Send(&n,1, MPI_INT, i, 0, MPI_COMM_WORLD);
        MPI_Send(&j,1, MPI_INT, i, 7, MPI_COMM_WORLD);
    }

    cells = (int**) malloc(n*sizeof(int*));    //create main 2D array

    for(i=0; i<n; i++){

        cells[i] = (int*) malloc(n*sizeof(int));
    }

    for(i=0; i<n; i++){
        for(i2=0; i2<n; i2++){           //fill array with random data

            cells[i][i2] = rand() % 2;
        }
    }       

    for(i=1; i<size; i++){        //send blocks of rows to each process
        for(i2=0; i2<rowChunk; i2++){ //this works for all n

            MPI_Send(cells[i2+(rowChunk*i)], n, MPI_INT, i, i2, MPI_COMM_WORLD);
        }
    }

    cellChunk = (int**) malloc(rowChunk*sizeof(int*));

    for(i=0; i<rowChunk; i++){    //declare 2D array for process zero's array chunk

        cellChunk[i] = (int*) malloc(n*sizeof(int));
    }

    for(i=0; i<rowChunk; i++){   //give process zero it's proper chunk of the array
        for(i2=0; i2<n; i2++){

            cellChunk[i][i2] = cells[i][i2];
        }
    }


    for(i3=1; i3<=j; i3++){

        MPI_Send(cellChunk[0], n, MPI_INT, size-1,1,MPI_COMM_WORLD); //Hangs here if n >256
        MPI_Send(cellChunk[rowChunk-1], n, MPI_INT, 1,2,MPI_COMM_WORLD); //also hangs if n > 256

            ... //Leaving out code that works

如果 n(数组大小)小于或等于 256,则此代码可以完美运行。任何更大,它都会挂在第一个 MPI_Send 上。此外,当将数组行块发送给其他进程时,(首先 MPI_Send)其他进程完美接收它们的数据,即使 n > 256。如果缓冲区大小超过 256,会导致这个 MPI_Send 挂起?

【问题讨论】:

  • 你能发布完整的代码吗?我没有看到您发布的 sn-p 有任何问题。

标签: c mpi


【解决方案1】:

您永远不会收到任何消息,因此代码将填充本地 MPI 缓冲区空间,然后死锁等待运行 MPI_Recv(或类似)调用。您需要插入接收操作,以便您的消息真正在接收器上发送和处理。

【讨论】:

  • 代码不完整。 MPI_Send 仅由根调用。正如您在最后一行中看到的那样,他省略了其余的代码。您可能需要重新表述您的答案。
【解决方案2】:

MPI_Send 是一个阻塞调用。该标准要求 MPI_Send 可以在可以安全地修改消息缓冲区时尽早返回控制权。或者,MPI_Send 可以等待返回,直到 MPI_Recv 开始或完成后的某个时间。

如果消息计数

如果您发布完整的复制者,您可能会得到更好的答案。

【讨论】:

    【解决方案3】:

    MPI_Send“可能会阻塞,直到收到消息。”,所以很可能匹配不到接收。您需要确保MPI_Recvs 以正确的顺序放置。由于您没有发布您的接收部分,因此无法告知详细信息。

    您可以重组您的应用程序,以确保匹配的接收是有序的。您也可以方便地使用组合的MPI_Sendrecv 或非阻塞MPI_Isend、MPI_Irecv 和MPI_Wait。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-28
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2016-07-23
      • 1970-01-01
      • 2013-05-19
      相关资源
      最近更新 更多