如何正确使用MPI_Gather?

How to use correctly MPI_Gather?

我读过有关 mpi 的文章,我对使用函数 MPI_Gather 很感兴趣。

现在我正在这样做,但它不起作用:

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

char *funcion (char *a) {
    sprintf(a, "asdfa%u", 2);
}

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

    MPI_Init(&argc, &argv);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    char *parcial = malloc(5*sizeof(char));
    char *total;

    if (rank == 0) {
        total = malloc(15*sizeof(char));
        parcial = "aaaaa";
    }
    else if (rank == 1) {
        parcial = "bbbbb";
    }
    else if (rank == 2) {
        parcial = "ccccc";
    }

    MPI_Gather(parcial,5,MPI_CHAR,total,15,MPI_CHAR,0,MPI_COMM_WORLD);

    if (rank == 0) {
        printf("%s",total);
    }

    MPI_Finalize();

}

它只打印 "aaaaa",而不是打印 "aaaaabbbbbccccc"。

我做错了什么?

recvcount参数指定任何单个接收的元素数,而不是总数。因此你应该使用:

MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);

请注意,您对 C 中字符串的理解从根本上是错误的。

首先,每个 C-string 都需要一个额外的字节作为终止空字符。因此,您必须分配 6 / 16 个字节。但是,您不能发送那些空终止符,否则 master 中的字符串将简单地在第一个终止符处结束。但是您必须显式设置 total[15] = 0 才能正确终止字符串。

其次,parcial = "aaaaa" 不会将字符串复制到您的 malloc 内存中(由 strncpy 完成),而是将指针简单地分配给不同的(non-writable) 内存中存储 "aaaaa[=16=]" 的部分。

效果不错:

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

char *funcion (char *a) {
    sprintf(a, "asdfa%u", 2);
}

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

    MPI_Init(&argc, &argv);
    int rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    void *total;
    void *parcial;

    if (rank == 0) {
        parcial = "aaaaa";
    }
    else if (rank == 1) {
        parcial = "bbbbb";
    }
    else if (rank == 2) {
        parcial = "ccccc";
    }

    MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);

    if (rank == 0) {
        printf("%s",(char*)total);
    }

    MPI_Finalize();

}