Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.74 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <mpi.h>
  4.  
  5. /* Variable time out */
  6. double ErrorTime = 0.5;
  7.  
  8. /* Structure des processus */
  9. typedef struct
  10. {
  11.     int state; // 1 en cours, 0 en attente, -1 erreur + valeur non reprise, -2 erreur + valeur reprise 3 envoi en cours
  12.     double startTime;
  13.     int result;
  14.     int firstValue;
  15.     int endValue;
  16. }currentState;
  17.  
  18. /* Initialisation des différents champs de la structure currentState */
  19. void init_Struct(currentState tab[], int size)
  20. {
  21.     int i;
  22.     for(i = 0; i < size-1; i++)
  23.     {
  24.         /*if(i==3)
  25.             tab[i].state = -1;
  26.         else*/
  27.         tab[i].state = 0;
  28.        
  29.         tab[i].firstValue = 0;
  30.         tab[i].endValue = 0;
  31.         tab[i].startTime = 0;
  32.         tab[i].result = 0;
  33.     }
  34. }
  35.  
  36. /* Vérifie si les différents processus n'ont pas de "time out"*/
  37. int checkAvailabilityProcess(currentState tab[], int process)
  38. {
  39.     //int i;
  40.     double currentTime = MPI_Wtime();
  41.     double elapsedTime=0;
  42.     if(( tab[process].startTime - currentTime ) > ErrorTime )
  43.     {
  44.         printf("ERROR on process %d !\n",process);
  45.         tab[process].state = -1;
  46.         return 0;
  47.     }
  48.     return 1;
  49. }
  50.  
  51. /* Renvoi un processus dont l'état est en erreur mais donc la portion n'as pas été calculer, -1 si vide */
  52. int checkProcessFail(currentState tab[], int size)
  53. {
  54.     int i;
  55.     for(i = 0 ; i < size-1 ; i++)
  56.     {
  57.        
  58.         if(tab[i].state == -1){
  59.             tab[i].state = -2;     
  60.             return i;
  61.         }
  62.            
  63.     }
  64.     return -1; 
  65. }
  66.  
  67. /* Affichage de l'etat des processus */
  68. void displayCurrentState(currentState tab[], int size)
  69. {
  70.     int i;
  71.     for(i = 0; i < size-1; i++)
  72.     {
  73.         printf("Processus fils n°%d -- Etat : %d\n",i,tab[i].state);
  74.     }
  75. }
  76.  
  77.  
  78. void wasteTime(unsigned long ms)
  79. {
  80.     unsigned long t,t0;
  81.     struct timeval tv;
  82.     gettimeofday(&tv,(struct timezone *)0);
  83.     t0=tv.tv_sec*1000LU+tv.tv_usec/1000LU;
  84.     do
  85.     {
  86.         gettimeofday(&tv,(struct timezone *)0);
  87.         t=tv.tv_sec*1000LU+tv.tv_usec/1000LU;
  88.     } while(t-t0<ms);
  89. }
  90.  
  91.  
  92. int main(int argc, char ** argv)
  93. {
  94.    
  95.     int size, rank, operations,returnedFlag, endValue, firstValue, sourceProcess, totalResult, returnedValue, flag, split, i;
  96.     int position, returnedStatus;
  97.     double currentTime;
  98.    
  99.  
  100.     MPI_Request req;
  101.     MPI_Status status;
  102.     /* Initialisation */
  103.     MPI_Init(&argc, &argv);
  104.     /* Determination rang processus */
  105.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  106.     /* Determination taille */
  107.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  108.     /* Nombre de calculs */
  109.    
  110.     /* Tableau d'etat de chaque processus */
  111.     currentState tabState[size-1];
  112.  
  113.     operations = 10;
  114.     /* Variable résultat final */
  115.     returnedValue = 0;
  116.     /* Variable status du MPI_TAG */
  117.     flag = 0;
  118.     /* Traitement du processus pere */
  119.    
  120.     if(rank == 0)
  121.     {  
  122.         /* Initialisation des variables de la structure */
  123.         init_Struct(tabState, size);
  124.        
  125.         /* Chaque processus recevra les valeurs 2 par 2 */
  126.         split = 2;
  127.         /* Initialisation boucle */
  128.         i = 1;
  129.         firstValue = 1;
  130.         /* Tant que i est inférieur a la taille et que l'on ne depasse pas le nombre de tranches a distribuer */
  131.         while( i < size && firstValue < operations )
  132.         {
  133.             /* on envoit la valeur du début de tranche a calculer au processus i */
  134.             if(tabState[i-1].state == 0){
  135.                 //printf("Sending first Value %d to %d\n",firstValue, i);
  136.                
  137.                 /* On met jour endValue afin de vérifier si l'on a pas dépasser le nombre de tranches a distribuer */
  138.                 endValue=firstValue+split;
  139.                 if(endValue>operations)
  140.                     endValue=operations;
  141.  
  142.                 printf("\nSending [%d-%d] to %d\n",firstValue,endValue, i);
  143.  
  144.                 /* On envoit la valeur de endValue de tranche a calculer au processus i */
  145.                 MPI_Isend(&firstValue, 1, MPI_INT, i, 0, MPI_COMM_WORLD,&req);
  146.  
  147.                 MPI_Test(&req,&returnedFlag,&status);
  148.                 while(!returnedFlag)
  149.                     MPI_Test(&req,&returnedFlag,&status);
  150.  
  151.                 MPI_Isend(&endValue, 1, MPI_INT, i, 0, MPI_COMM_WORLD,&req);
  152.  
  153.                 MPI_Test(&req,&returnedFlag,&status);
  154.                 while(!returnedFlag)
  155.                     MPI_Test(&req,&returnedFlag,&status);
  156.  
  157.                 /* Mise a jour des valeurs du processus traité */
  158.                 tabState[i-1].startTime = MPI_Wtime();
  159.                 tabState[i-1].state = 1;
  160.                 tabState[i-1].firstValue = firstValue;
  161.                 tabState[i-1].endValue = endValue;
  162.  
  163.                 /* On met a jour firstValue pour que le prochain processus traite la tranche suivante */
  164.                 firstValue=endValue+1;
  165.                 /* On incrémente l'id du processus */
  166.             }
  167.                 i++;
  168.         }
  169.         /* On décrémente i pour pointer sur le dernier processus auxquel on a fournis les données de calculs */
  170.         i--;
  171.         /* Tant qu'on a pas traiter tout les processus */
  172.         while(i>0)
  173.         {
  174.  
  175.             /* On receptionne un message fourni par n'importe lequel des processus fils */
  176.             printf("%d\n",i);
  177.             returnedStatus = MPI_Irecv(&returnedValue, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &req);
  178.            
  179.             MPI_Test(&req, &returnedFlag, &status);
  180.             while(!returnedFlag || !checkAvailabilityProcess(tabState, size)){
  181.                 MPI_Test(&req, &returnedFlag, &status);
  182.             }
  183.            
  184.             printf("\nReceiving from %d ",sourceProcess);
  185.             if (returnedStatus != MPI_SUCCESS){
  186.                 tabState[sourceProcess].state = -1;
  187.                 sourceProcess=status.MPI_SOURCE-1;
  188.                 tabState[sourceProcess].result = returnedValue;
  189.             }
  190.             else
  191.                 tabState[sourceProcess].state = 0;
  192.  
  193.             returnedValue = 0;
  194.             if(tabState[sourceProcess].state == 0){
  195.                 /* On récupére le résultat et on l'additionne au total */
  196.                 totalResult+=tabState[sourceProcess].result;
  197.                
  198.                 printf("Value : %d\n\n",tabState[sourceProcess].result);   
  199.             }
  200.             i--;
  201.             /* Si il reste encore des portions a calculer */
  202.             printf("%d, %d, %d\n",firstValue, operations, i);
  203.             if(firstValue <= operations)
  204.             {
  205.                 printf("Pending operation... \n");
  206.                 position = checkProcessFail(tabState, size);
  207.                 if(position == -1){
  208.                     MPI_Isend(&firstValue, 1, MPI_INT, sourceProcess, 0, MPI_COMM_WORLD,&req);
  209.                     tabState[sourceProcess].state = 1;
  210.                     endValue = firstValue+split-1;
  211.                     if(endValue>operations)
  212.                         endValue = operations;
  213.                     MPI_Isend(&endValue, 1, MPI_INT, sourceProcess, 0, MPI_COMM_WORLD,&req);
  214.                     printf("Sending [%d - %d] to %d\n",firstValue,endValue, i);
  215.                     firstValue = endValue+1;
  216.                     i++;
  217.                 }else
  218.                 {
  219.                     printf("!!##!! Error from process %d Redirecting to process %d \n", position, sourceProcess);
  220.                     printf("firstValue : %d, endValue : %d\n",tabState[position+1].firstValue,tabState[position+1].endValue);
  221.                     MPI_Isend(&tabState[position+1].firstValue, 1, MPI_INT, sourceProcess, 0, MPI_COMM_WORLD,&req);
  222.                     MPI_Isend(&tabState[position+1].endValue, 1, MPI_INT, sourceProcess, 0, MPI_COMM_WORLD,&req);
  223.                 }
  224.             }
  225.            
  226.         }
  227.         /* Affichage resultat final */
  228.         printf("#Final result : %d\n",totalResult);
  229.         /* On envoi a tout les programmes fils un signal de fin ( içi 1 ) */
  230.         for(i=1;i<size;i++)
  231.         {
  232.             MPI_Send(&firstValue, 1, MPI_INT, i, 1, MPI_COMM_WORLD);
  233.         }
  234.     }
  235.     else /* Traitement des processus fils */
  236.     {
  237.         while(flag!=1) /* on ne sort de la boucle que lorsque le processus maitre envoie le dernier Send avec le TAG = 1 */
  238.         {
  239.             /* Récupération valeur de début de la portion de calcul */
  240.             MPI_Recv(&firstValue, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
  241.             flag=status.MPI_TAG; /* on récupère le tag du message */
  242.             if(flag==0)/* Si le tag est égale a zéro, cela veut dire que le père demande un calcul */
  243.             {
  244.                 /* Récupération valeur de fin de la portion de calcul */
  245.                 MPI_Recv(&endValue, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
  246.                 /* Init var */
  247.                 totalResult=0;
  248.                
  249.                 /* On boucle sur la portion ( calcul des carrés de firstValue a endValue */
  250.                 for(i=firstValue;i<=endValue;i++)
  251.                 {
  252.                     totalResult=totalResult+(i*i);
  253.                 }
  254.                 printf("Operation : %d to %d result = %d\n",firstValue,endValue,totalResult);
  255.                 /* On renvoi le résultat au processus 0 */
  256.                 MPI_Send(&totalResult, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
  257.             }
  258.         }
  259.     }
  260.     /* Terminaison MPI */
  261.     MPI_Finalize();
  262.  
  263.     return 0;
  264.  
  265.  
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement