"MPI_Bcast" er во время выполнения - PullRequest
2 голосов
/ 17 апреля 2011

Как мне сделать MPI_Bcast в случае, когда вещатель определяется во время выполнения?Как мне указать корневой узел в этом случае?

Я пытаюсь найти отдельное число в массиве.Если узел находит номер, он должен передать свое местоположение всем остальным узлам.Однако, поскольку я не знаю искателя заранее, каким должно быть значение «root»:

int MPI_Bcast ( void *buffer, int count, MPI_Datatype datatype, 
                int root, MPI_Comm comm );

1 Ответ

2 голосов
/ 17 апреля 2011

Каждый должен договориться о «корне», прежде чем идти в коллектив, поэтому перед этим должно быть какое-то сотрудничество.Вот один простой подход - каждый отправляет флаг, указывающий, есть ли у него соответствующие данные, и тогда каждый может договориться, от кого получать.Это позволяет обрабатывать случаи, когда имеется несколько возможных отправителей или их нет.

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

int main(int argc, char **argv) {
    int rank, size, ierr;
    int bcaster;
    int bcasterflag, *allflags;
    int consensus;
    int globaldata, mydata;

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

    if (argc != 2) {
        if (rank == 0) fprintf(stderr,"Usage: %s rank-to-broadcast\n",argv[0]);
        MPI_Abort(MPI_COMM_WORLD,1);
    }

    bcaster = atoi(argv[1]);
    if (bcaster < 0    ) bcaster = 0;
    if (bcaster >= size) bcaster = size-1;

    /* pretend the processes didn't all know the above and had to
     * rely solely on local info to decide the broadcaster
     */

    bcasterflag = 0;     /* not the broadcaster yet */

    mydata = rank*rank;   /* the local data */
    if (mydata == bcaster*bcaster) {
        bcasterflag = 1;
        globaldata = mydata;
    }


    /* collect these local decisions */

    allflags = (int *)malloc(size * sizeof(int));
    ierr = MPI_Allgather(&bcasterflag, 1, MPI_INT,
                         allflags, 1, MPI_INT, MPI_COMM_WORLD);

    consensus = -1;
    for (int i=0; i<size; i++)
        if (allflags[i] != 0) consensus = i;

    if (consensus == -1) {
       if (rank == 0) {
          fprintf(stderr,"Error: no one found to do the broadcast.\n");
       }
    } else {
        ierr = MPI_Bcast(&globaldata, 1, MPI_INT, consensus, MPI_COMM_WORLD);
    }

    printf("%d: Received data %d from %d\n",
            rank, globaldata, consensus);

    return 0;
}
...