如何处理零的MPI sendcount

时间:2017-06-06 22:12:07

标签: c mpi

在设置displs参数时使用MPI_Gatherv(或需要sendcount的任何其他函数)时,处理sendcount = 0的正确方法是什么?

我有所有处理器都需要接收的数据,但所有处理器可能没有任何数据可以自行发送。作为MWE,我尝试过(只需两个处理器):

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

int main(void)
{
    int ntasks;
    int thistask;
    int n = 0;
    int i;
    int totcounts = 0;
    int *data;
    int *rbuf;
    int *rcnts;
    int *displs;
    int *master_data;
    int *master_displs;

    // Set up mpi
    MPI_Init(NULL, NULL);
    MPI_Comm_size(MPI_COMM_WORLD, &ntasks);
    MPI_Comm_rank(MPI_COMM_WORLD, &thistask);

    // Allocate memory for arrays needed by allgatherv
    rbuf = calloc(ntasks, sizeof(int));
    rcnts = calloc(ntasks, sizeof(int));
    displs = calloc(ntasks, sizeof(int));
    master_displs = calloc(ntasks, sizeof(int));

    // Initialize the counts and displacement arrays
    for(i = 0; i < ntasks; i++)
    {
        rcnts[i] = 1;
        displs[i] = i;
    }

    // Allocate data on just one task, but not others
    if(thistask == 1)
    {
        n = 3;
        data = calloc(n, sizeof(int));

        for(i = 0; i < n; i++)
        {
            data[i] = i;
        }
    }

    // Get n so each other processor knows about what others are sending
    MPI_Allgatherv(&n, 1, MPI_INT, rbuf, rcnts, displs, MPI_INT, MPI_COMM_WORLD);

    // Now that we know how much data each processor is sending, we allocate the array
    // to hold it all
    for(i = 0; i < ntasks; i++)
    {
        totcounts += rbuf[i];
    } 

    master_data = calloc(totcounts, sizeof(int));

    // Get displs for master data
    master_displs[0] = 0;
    for(i = 1; i < ntasks; i++)
    {
        master_displs[i] = master_displs[i - 1] + rbuf[i - 1];
    }

    // Send each processor's data to all others
    MPI_Allgatherv(&data, n, MPI_INT, master_data, rbuf, master_displs, MPI_INT, MPI_COMM_WORLD);

    // Print it out to see if it worked
    if(thistask == 0)
    {
        for(i = 0; i < totcounts; i++)
        {
            printf("master_data[%d] = %d\n", i, master_data[i]);
        }
    }

    // Free
    if(thistask == 1)
    {
        free(data);
    }

    free(rbuf);
    free(rcnts);
    free(displs);
    free(master_displs);
    free(master_data);

    MPI_Finalize();

    return 0;
}

我设置master_displs的方式在每个处理器都具有非零n(即,它们有要发送的数据)时起作用。在这种情况下,两个条目都将为零。但是,这个程序的结果是垃圾。我如何设置master_displs数组以确保master_data保存正确的信息(在这种情况下,只是master_data [i] = i,从任务1收到)?

0 个答案:

没有答案