Comment MPI Scatter et MPI Gather sont-ils utilisés à partir de C?

jusqu'à présent, mon application lit dans un fichier txt avec une liste d'entiers. Ces entiers doit être stocké dans un tableau par le maître-processus du processeur avec le rang 0. Cela fonctionne bien.

maintenant, quand j'exécute le programme, j'ai une instruction if qui vérifie si c'est le processus maître et si c'est le cas, j'exécute le MPI_Scatter la commande.

D'après ce que j'ai compris, ceci subdivisera le tableau avec les nombres et le transmettra aux processus esclaves, c'est-à-dire tous avec rang > 0 . Cependant, je ne sais pas comment gérer le MPI_Scatter. Comment l'esclave processus de "s'abonner" pour obtenir le sous-ensemble? Comment puis-je dire aux processus non maîtres de faire quelque chose avec le sous-tableau?

quelqu'un Peut-veuillez fournir un exemple simple pour me montrer comment le processus maître envoie les éléments du tableau et ensuite les esclaves ajouter la somme, et le renvoyer au maître, qui ajoute que toutes les sommes ensemble et l'imprime?

mon code so loin:

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

//A pointer to the file to read in.
FILE *fr;

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

int rank,size,n,number_read;
char line[80];
int numbers[30];
int buffer[30];

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

fr = fopen ("int_data.txt","rt"); //We open the file to be read.

if(rank ==0){
printf("my rank = %dn",rank);

//Reads in the flat file of integers  and stores it in the array 'numbers' of type int.
n=0;
while(fgets(line,80,fr) != NULL) {
  sscanf(line, "%d", &number_read);
  numbers[n] = number_read;
  printf("I am processor no. %d --> At element %d we have number: %dn",rank,n,numbers[n]);
  n++;
}

fclose(fr);

MPI_Scatter(&numbers,2,MPI_INT,&buffer,2,MPI_INT,rank,MPI_COMM_WORLD);

}
else {
MPI_Gather ( &buffer, 2, MPI_INT, &numbers, 2, MPI_INT, 0, MPI_COMM_WORLD); 
printf("%d",buffer[0]);
}
MPI_Finalize();
return 0;
}
26
demandé sur DSF 2012-12-14 00:20:28

1 réponses

il s'agit d'une mauvaise compréhension commune du fonctionnement des opérations dans le MPI avec des gens nouveaux; en particulier avec les opérations collectives, où les gens essaient de commencer à utiliser la diffusion (MPI_Bcast) juste à partir du rang 0, s'attendant à ce que l'appel "pousse" d'une manière ou d'une autre les données vers les autres processeurs. Mais ce n'est pas vraiment comme ça que fonctionnent les routines MPI; la plupart des communications MPI nécessitent à la fois l'expéditeur et le destinataire pour faire des appels MPI.

En particulier, MPI_Scatter() et MPI_Gather() (et MPI_Bcast, et beaucoup d'autres) collectif opérations; elles doivent être appelées par des tâches du communicateur. Tous les processeurs du communicateur font le même appel, et l'opération est effectuée. (C'est pourquoi la dispersion et la collecte des deux requièrent comme l'un des paramètres le processus "root", d'où toutes les données vont / viennent). En le faisant de cette façon, L'implémentation du MPI a beaucoup de latitude pour optimiser les modèles de communication.

voici donc un exemple simple (mise à Jour pour inclure rassembler):

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

int main(int argc, char **argv) {
    int size, rank;

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

    int *globaldata=NULL;
    int localdata;

    if (rank == 0) {
        globaldata = malloc(size * sizeof(int) );
        for (int i=0; i<size; i++)
            globaldata[i] = 2*i+1;

        printf("Processor %d has data: ", rank);
        for (int i=0; i<size; i++)
            printf("%d ", globaldata[i]);
        printf("\n");
    }

    MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD);

    printf("Processor %d has data %d\n", rank, localdata);
    localdata *= 2;
    printf("Processor %d doubling the data, now has %d\n", rank, localdata);

    MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if (rank == 0) {
        printf("Processor %d has data: ", rank);
        for (int i=0; i<size; i++)
            printf("%d ", globaldata[i]);
        printf("\n");
    }

    if (rank == 0)
        free(globaldata);

    MPI_Finalize();
    return 0;
}

en cours d'Exécution, il donne:

gpc-f103n084-$ mpicc -o scatter-gather scatter-gather.c -std=c99
gpc-f103n084-$ mpirun -np 4 ./scatter-gather
Processor 0 has data: 1 3 5 7 
Processor 0 has data 1
Processor 0 doubling the data, now has 2
Processor 3 has data 7
Processor 3 doubling the data, now has 14
Processor 2 has data 5
Processor 2 doubling the data, now has 10
Processor 1 has data 3
Processor 1 doubling the data, now has 6
Processor 0 has data: 2 6 10 14
58
répondu Jonathan Dursi 2012-12-13 21:26:52