Untitled

mail@pastecode.io avatar
unknown
plain_text
3 years ago
4.3 kB
3
Indexable
Never
#include "utility.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <mpi.h>

#define PACKAGE_SIZE 10
#define DATA 0
#define RESULT 1
#define FINISH 2
#define MIN 0
#define MAX 1000
//#define DEBUG

int main(int argc,char **argv) {
  Args ins__args;
  parseArgs(&ins__args, &argc, argv);
  //DANE
  int sentcount=0;
  int range[PACKAGE_SIZE];
  int n = ins__args.arg; 
  int result[MAX+1] = {0};
  int resulttemp[MAX+1] = {0};
  MPI_Status status;
  
  struct timeval ins__tstart, ins__tstop;
  int myrank,nproc;
  MPI_Init(&argc,&argv);
  MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
  MPI_Comm_size(MPI_COMM_WORLD,&nproc);
  if(!myrank)
      gettimeofday(&ins__tstart, NULL);
      
  if(nproc<2){
  	printf("Wymagane przynajmniej dwa procesy");
 	MPI_Finalize();
 	return -1; 
  }


  if(myrank==0){//kod mastera****************************************************************************
  	int* randoms = calloc(n, sizeof(int));
  	//wygenerowanie liczb i zapisanie ich do tablicy
  	for(int i=0; i<n; i++)
  		*(randoms+i) = (rand() % (MAX-MIN+1)) + MIN;
  	
  	#ifdef DEBUG
  	//wysiwetla randoms
  	for(int i=0; i<n; i++)
  		printf("random %d: %d\n", i, *(randoms+i));
  	#endif
  	
  	//z randoms wydzielam pierwsze rozdanie 
  	for(int i=1; i<nproc; i++){
  		//wydziel z randoms do range 10 liczb i wyslij
  		for(int j=0; j<PACKAGE_SIZE; j++) {
  			if(sentcount<n)
  				range[j] = *(randoms+sentcount++);
  			else
  				range[j] = -1;
  		}
  		
  		#ifdef DEBUG
  		//wyswietla pierwsze rozdania
  		printf("Pierwsze rozdanie do %d\n", i);
  		for(int j=0; j<PACKAGE_SIZE; j++)
  			printf("range %d: %d\n", j, range[j]);

  		printf("**********\n");
  		#endif
  		
  		MPI_Send(range,PACKAGE_SIZE, MPI_INT, i, DATA, MPI_COMM_WORLD);	
  	}
  	
  	do { //wysylam dalsze zakresy jak jakis slave wroci
  		MPI_Recv(&resulttemp,MAX+1, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
  		for(int i=MIN; i<=MAX; i++)
  			result[i] += resulttemp[i];
  		#ifdef DEBUG
  		printf("Uzupełniłem result o dane od %d\n", status.MPI_SOURCE);
  		#endif
  		
  		//przygotuj nową paczkę i wyślij
  		if(sentcount<n){
  	  		//wydziel z randoms do range 10 liczb i wyslij
	  		for(int i=0; i<PACKAGE_SIZE; i++) {
	  			if(sentcount<n)
	  				range[i] = *(randoms+sentcount++);
	  			else
	  				range[i] = -1;
	  		}
	  		MPI_Send(range,PACKAGE_SIZE, MPI_INT, status.MPI_SOURCE, DATA, MPI_COMM_WORLD);	
  		}
  	} while(sentcount<n);

  	
  	//odebranie pozostałych pakietów
  	int rejProc = 1; //gdy za malo pakietow to trzeba czekac na jednego slave'a mniej???
  	if(n <= (nproc-1) * PACKAGE_SIZE)
  		rejProc = 2;
  
  	for(int i=0; i<nproc-rejProc; i++){
  		MPI_Recv(&resulttemp, MAX+1, MPI_INT, MPI_ANY_SOURCE, RESULT, MPI_COMM_WORLD, &status);
  		for(int j=MIN; j<MAX+1; j++)
  			result[j] += resulttemp[j];
  		#ifdef DEBUG
  		printf("Odebrałem ostatnie wyliczenia od %d\n", status.MPI_SOURCE);
  		#endif	
  	}
  	
  	//zamkniecie slave'ow
  	for(int i=1; i<nproc;i++)
  		MPI_Send(NULL, 0, MPI_INT, i, FINISH, MPI_COMM_WORLD);
  	
  	int resultCtr = 0;
  	for(int i=MIN; i<MAX+1; i++){
  		printf("%d -> %d razy\n", i, result[i]);
  		resultCtr += result[i];
  	}
  	printf("W sumie mamy %d liczb", resultCtr);
  		
  	free(randoms);
  } else {//kod slave'a *********************************************************************************
  	do {
  	MPI_Probe(0, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
  		if(status.MPI_TAG == DATA) {
  			//odbierz dane i pogrupuj
  			MPI_Recv(range, PACKAGE_SIZE, MPI_INT, 0, DATA, MPI_COMM_WORLD, &status);
  			//wyzerowanie wyniku;
  			for(int i=MIN; i<MAX+1; i++)
  				resulttemp[i] = 0;
  			
  			//obliczenia
			for(int i=0; i<PACKAGE_SIZE; i++){
				if(range[i]>-1)
					resulttemp[range[i]]++;
			}
			
			#ifdef DEBUG
			//wyswietlenie wynikow pracy slave'a
			printf("Wykonanie slave'a nr %d\n", myrank);
			for(int i=MIN; i<MAX+1; i++){
  				printf("ilosc %d: %d\n", i, resulttemp[i]);
  			}
  			printf("**********\n");
  			#endif
			

  			MPI_Send(&resulttemp, MAX+1, MPI_INT, 0, RESULT, MPI_COMM_WORLD);
  		}
  	} while(status.MPI_TAG!=FINISH);
  }

  if (!myrank) {
    gettimeofday(&ins__tstop, NULL);
    ins__printtime(&ins__tstart, &ins__tstop, ins__args.marker);
  }
  MPI_Finalize();
  return 0;
}