#include<stdio.h>
#include "mpi.h"

#define N 10

/*
 * exemple de communication en mode point-à-point.
 * L'un des processus envoi un message à l'ensemble 
 * des autres, à tour de rôle.
 */

void generationAleatoire(int *,int, int, int);
void afficher(int *,int);
int add(int *,int);


int main(int argc, char** argv) {

    int Tablo[N];
    int Tab2[N];
    int moi,nbprocs,lesautres,i,resultat;
    int tag = 4444;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&moi);
    MPI_Comm_size(MPI_COMM_WORLD,&nbprocs);
    if(moi == 0) {
	for(i=1;i<nbprocs;i++) {
	    generationAleatoire(Tablo,N,100*i,1000);
	    afficher(Tablo,N);
	    printf("%d : envoi d'un tab à %d \n",moi,i);
	    MPI_Send(Tablo,        // buffer d'envoi
		     N,            // nombre d'éléments
		     MPI_INT,      // type des éléments
		     i,    // rang du processus d'envoi
		     1111,         // tag
		     MPI_COMM_WORLD);    // communicateur
	    printf("%d : envoi à %d terminé \n",moi,i);
	}
	for(i=1;i<nbprocs;i++) {
	    MPI_Recv(&resultat,         // buffer de reception
		     1,            // nombre d'éléments
		     MPI_INT,      // type des éléments
		     i,            // rang de l'émetteur
		     2222,         // tag
		     MPI_COMM_WORLD,     // communicator
		     MPI_STATUS_IGNORE); // status
	    printf("%d : recu de %d : %d \n",moi,i,resultat);
	}
    } else {
	printf("%d : attente de reception \n",moi);
	MPI_Recv(Tab2,         // buffer de reception
		 N,            // nombre d'éléments
		 MPI_INT,      // type des éléments
		 0,            // rang de l'émetteur
		 1111,         // tag
		 MPI_COMM_WORLD,     // communicator
		 MPI_STATUS_IGNORE); // status
	printf("%d : addition en cours \n",moi);
	resultat = add(Tab2,N);
	printf("%d : addition terminée \n",moi);
	MPI_Send(&resultat,        
		 1,            
		 MPI_INT,      
		 0,    
		 2222,  
		 MPI_COMM_WORLD); 
    }
    MPI_Finalize();
    

}


/*
 * générateur aléatoire de nombres entiers compris entre min et max
 */
void generationAleatoire(int *T, int taille, int min, int max) {
    int i;
    srand(time(NULL));
    for(i=0;i<taille;i++) {
	T[i] = min+rand()%(max-min);
    }
}


/*
 * procédure qui affiche le contenu du tableau
 */
void afficher(int *T, int taille) {
    int i;
    for(i=0;i<taille;i++) {
	printf("%d : %d \n",i,T[i]);
    }
}


/*
 * fonction qui effectue l'addition des éléments du tableau d'entiers.
 */

int add(int *T, int taille) {
    int i,somme;
    somme = 0;
    for(i=0;i<taille;i++) {
	somme+=T[i];
    }
    return somme;
}
