Olá pessoal, sou o Filipe Névola, este blog foi muito ativo durante 2009 enquanto eu fazia universidade,
hoje em dia estou ativo no Twitter @FilipeNevola e voltando a escrever posts agora no meu perfil do Medium (29/05/2016).

[ 15/07/2009 ] 0

Usando MPI_Gather ( Junta sub-vetores em um vetor )

MPI_Gather é o comando em MPI que junta dados de vários processos e os envia para um único processo.

Quais são os parâmetros que devem ser passados ?

Cabeçalho:
int MPI_Gather ( void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm )


Parâmetros:
sendbuf: início do endereço do dado a ser passado
sendcount: número de elementos passados (tamanho do vetor ou 1 quando não se tem um vetor)
sendtype: tipo de dados (MPI_INT, MPI_CHAR ...)
recvcount: número de elementos recebidos (tamanho do vetor ou 1 quando não se tem um vetor)
recvtype: tipo de dados (MPI_INT, MPI_CHAR ...)
root: número inteiro do processo que irá ser o enviador (a raiz)
comm: grupo de comunicação

Vamos ao código:
//Autor: Filipe Areias Névola
//Ano: 2009
//Programa: Usando Gather, vamos exemplicar por meio de uma busca de posições do elemento X, o Gather é usado para juntar todas as posições aonde o elemento X foi encontrado
//Licensa: Você pode usar e alterar, mas deve manter o Autor
//Principal

#include <mpi.h>
#include <stdio.h>
#include <string.h>
#define GROUP MPI_COMM_WORLD
#define Init(x,y) MPI_Init(x,y)
#define Finalize() MPI_Finalize()
#define Size(x) MPI_Comm_size(GROUP,x)
#define Rank(x) MPI_Comm_rank(GROUP,x)
#define Send(x, tam, tipo, destino, flag) MPI_Send(x, tam, tipo, destino, flag, GROUP)
#define Recv(onde, tam, tipo, origem, flag) MPI_Recv(onde, tam, tipo, origem, flag, GROUP, &status)
#define Bcast(m, x, tipo, emissor) MPI_Bcast(m, x, tipo, emissor, GROUP)

#define Scatter(x,tam,tipo,subx,tamrec,tipo2,enviador) MPI_Scatter(x,tam,tipo,subx,tamrec,tipo2,enviador,GROUP)
#define Gather(x,tam,tipo,subx,tamrec,tipo2,enviador) MPI_Gather(x,tam,tipo,subx,tamrec,tipo2,enviador,GROUP)

#define INT MPI_INT
#define ROOT_RANK 0

int main(int argc, char *argv[]){
    /**declarações**/
    int vetor[]={1,2,3,4,5,6,7,8,9,10,11,2,2,14,15,16,17,18,19,2,2,2,23,24,25,26,2,28,2,30,31,32};
    int rank,p,i;
    int x = 2; //elemento que desejamos saber suas posições
    int n = 32; //número total de elementos no vetor
    int n_p; //número de elementos por proc
    //ponteiros de inteiros que serão alocados
    int *vpos,*res,*subvetor;

    /**inicialização**/
    Init(&argc, &argv);
    Size(&p);
    Rank(&rank);


    /**processamento**/
    //o proc 0 (zero) faz a conta para saber
    //quantos elementos cada parte terá
    if(rank==ROOT_RANK){
        //guardando em n_p o tamanho dos subvetores
        n_p=n/p;

        //corrigindo caso tenha sido arredondado para baixo
        if(n_p*p < n) n_p++;

        //alocando o vetor de resultado (conterá as posições onde se encontra X)
        res = (int *) calloc(n,sizeof(int));
    }

    //manda o tamanho de cada sub-vetor para todos os procs através do proc 0
    Bcast(&n_p,1,INT,0);

    //todos os procs alocam seus subvetores
    subvetor = (int *) calloc(n_p,sizeof(int));

    //o proc 0 divide o vetor em subvetores de tamanho n/p
    Scatter(vetor,n_p,INT,subvetor,n_p,INT,0);

    //aloca o vetor que guardará as respostas de cada subconjunto
    vpos = (int *) calloc(n_p,sizeof(int));
    //indíce atual do vetor de respostas
    int indice=0;

    //passa por todas as posições do subvetor procurando por X
    for(i=0;i<n_p;++i){
        if( x == subvetor[i] ){ //achou X
            //guarda posicação de X no vetor de respostas
            //para ter a posição original desse elemento no vetor basta fazer
            //i é a posição no subvetor + (o número do proc * o tamanho)
            vpos[indice++] = i+(rank*n_p);
        }
    }

    //junta todos os subvetores de resposta no vetor principal de respostas
    Gather(vpos,indice,INT,res,indice,INT,0);

    /**saída de dados**/
    //o proc 0 imprime a resposta final
    if(rank==ROOT_RANK){
        //mostra todas as posições que tem X
        for(i=0;i<n;++i)
            printf("\nRes[%d]=%d",i,res[i]);
    }

    /**finalização**/
    Finalize();
    return (0);

}
Alguma dúvida ? Mande por comentário que responderei assim que possível!

Novo Comentário