Quais são os parâmetros que devem ser passados ?
Cabeçalho:
int MPI_Scatter (void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int recvcnt, 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 Scatter, vamos exemplicar por meio de uma busca de posições do elemento X
//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!
E o que significa o "void *recvbuf " ?