nucLeaRsc2

Untitled

Jan 13th, 2015
206
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 19.91 KB | None | 0 0
  1. #include "mpi.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6.  
  7. #define addElement(v, value) (v[++v[0]] = value)
  8. #define ctoi(x) ((x)-'0')
  9. #define itoc(x) ((x)+'0')
  10. #define max(a,b) ( (a) > (b) ? a : b)
  11. #define min(a,b) ( (a) < (b) ? a : b)
  12.  
  13. #define TRUE 1
  14. #define FALSE 0
  15.  
  16. #define ROOT 0
  17. #define NOPARENT -1
  18.  
  19. #define NONEXT -1
  20. #define BROADCAST -2
  21. #define WAKEUPMESASGE -3
  22.  
  23. #define READY 1
  24. #define END 2
  25. #define WAKEUP 3
  26.  
  27. #define SLEEP 3
  28. #define LEADER 4
  29. #define LOST 5
  30.  
  31.  
  32. int rank, size;
  33. int* neighbours, *routingTable, *ready, **graph;
  34. FILE* logFile;
  35. MPI_Status status; 
  36. MPI_Request request;
  37. int leader, adjount;
  38.  
  39. typedef struct{
  40.     int from;
  41.     int to;
  42.     char message[200]; //nu pot pune char* deoarece trimit in retea aceasta structura si nu merge cu pointer....
  43. } TMessage, *Message;
  44.  
  45. typedef struct{
  46.     Message* messages;
  47.     int allocatedMessages;
  48.     int messagesCount;
  49. } TMessageBox, *MessageBox;
  50.  
  51. MessageBox messageBox;
  52.  
  53. Message createMessage(char* message, int to){
  54.     Message newMessage = (Message)malloc(sizeof(TMessage));
  55.     //newMessage->message = strdup(message);
  56.     strcpy(newMessage->message, message);
  57.     newMessage->to = to;
  58.     newMessage->from = rank;
  59.  
  60.     return newMessage;
  61. }
  62.  
  63. MessageBox createMessageBox(){
  64.     MessageBox newBox = (MessageBox)malloc(sizeof(TMessageBox));
  65.     newBox->allocatedMessages = 10;
  66.     newBox->messages = (Message*)malloc(newBox->allocatedMessages * sizeof(Message));
  67.     newBox->messagesCount = 0;
  68.  
  69.     return newBox;
  70. }
  71.  
  72. void freeMessageBox(MessageBox *box){
  73.     free ((*box)->messages);
  74.     free(*box);
  75. }
  76.  
  77. void createMessageStructFormat(MPI_Datatype* structType){
  78.  
  79.     const int nitems=3;
  80.     int blocklengths[3] = {1, 1, 200};
  81.     MPI_Datatype types[3] = {MPI_INT, MPI_INT, MPI_CHAR};
  82.     MPI_Datatype mpi_message_type;
  83.     MPI_Aint     offsets[3];
  84.  
  85.     offsets[0] = offsetof(TMessage, from);
  86.     offsets[1] = offsetof(TMessage, to);
  87.     offsets[2] = offsetof(TMessage, message);
  88.  
  89.     MPI_Type_create_struct(nitems, blocklengths, offsets, types, structType);
  90.     MPI_Type_commit(structType);
  91.  
  92. }
  93.  
  94. void addMessageToBox(MessageBox box, Message message){
  95.     box->messages[box->messagesCount] = message;
  96.  
  97.     box->messagesCount++;
  98.     if(box->messagesCount == box->allocatedMessages){
  99.        
  100.         box->allocatedMessages *= 2;
  101.         Message* newMessages = realloc(box->messages, box->allocatedMessages * sizeof(Message*));
  102.         //Check(newMessages == NULL, "Eroare la alocarea de mai multe mesaje");
  103.         if(!newMessages){
  104.             printf("Eroare la alocare\n");
  105.             exit(0);
  106.         }
  107.  
  108.         box->messages = newMessages;
  109.     }
  110. }
  111.  
  112. char* myItoa(int x){
  113.  
  114.     char* buffer = (char*)malloc(33 * sizeof(char));
  115.     char* p = buffer;
  116.     while(x>0){
  117.         int r = x % 10;
  118.         *p = itoc(r);
  119.         p++;
  120.         x = x / 10;
  121.     }
  122.     *p = 0;
  123.     int len = p - buffer, i;
  124.     for(i=0; i<len/2; i++){
  125.         char aux = buffer[i];
  126.         buffer[i] = buffer[len-i-1];
  127.         buffer[len-i-1] = aux;
  128.     }
  129.  
  130.     return buffer;
  131. }
  132.  
  133. void printMessages(MessageBox box){
  134.     //printf("Mesajele procesului cu ID: %i\n", rank);
  135.     int i;
  136.     for(i=0; i<box->messagesCount; i++)
  137.         printf("(S:%i, D:%s I:%i): %s\n", box->messages[i]->from , (box->messages[i]->to == BROADCAST ? "BCAST" : myItoa(box->messages[i]->to)) , i, box->messages[i]->message );
  138. }
  139.  
  140. void Check(int condition, char* message){
  141.     if(condition){
  142.         if(rank == 0)
  143.             printf("%s\n", message);
  144.         MPI_Finalize();
  145.         exit(0);
  146.     }
  147. }
  148.  
  149. void neighbOR(int *a, int *b){
  150.     int i;
  151.     for(i=0; i<size; i++)
  152.         if(a[i] == NOPARENT)
  153.             a[i] = b[i];
  154. }
  155.  
  156. void printArray(int*a, int size){
  157.     int i;
  158.     for(i=0; i<size; i++)
  159.         printf("%3i", a[i]);
  160.     printf("\n");
  161. }
  162.  
  163.  
  164. void printNeighbours(int *v){
  165.     printf("%i\t", rank);
  166.     printArray(v+1, v[0]);
  167. }
  168.  
  169. void printRoutingTable(int *v){
  170.     printf("%i\t", rank);
  171.     printArray(v, size);
  172. }
  173.  
  174. void printGraph(int** graph){
  175.     int i, j;
  176.     for(i=0; i<size; i++){
  177.         int j = 0, k=1, len = graph[i][0];
  178.  
  179.         while(k<=len){
  180.             while(j < graph[i][k]){
  181.                 printf("0 ");
  182.                 j++;
  183.             }
  184.             printf("1 ");
  185.             k++;
  186.             j++;
  187.         }
  188.         while(j++ < size)
  189.             printf("0 ");
  190.         printf("\n");
  191.     }
  192. }
  193.  
  194. char* concat(char* a, char* b){
  195.     char *c = (char*)malloc(strlen(a) + strlen(b));
  196.     strcpy(c, a);
  197.     strcat(c, b);
  198.  
  199.     return c;
  200. }
  201.  
  202.  
  203. int** readGraph(char* fileName){
  204.     // function only called by ROOT!
  205.     // size * size matrix to be returned
  206.     // size lines to be read from the file (one process is a bunker -- a vertex)
  207.     Check(rank != ROOT, "Doar root are acces in aceasta functie!");
  208.     int** graph = (int**)calloc(size, sizeof(int*));
  209.     FILE *in = fopen(fileName, "rt");
  210.     Check(!in, "Eroare la deschiderea fisierului.");
  211.     int i, result;
  212.  
  213.     for(i=0; i<size; i++){
  214.         char* line;
  215.         size_t lineSize;
  216.         result = getline(&line, &lineSize, in);
  217.    
  218.         char* p = strtok(line, " ");
  219.         p = strtok(NULL, " "); // '-'-ul
  220.         graph[i] = (int*)calloc(size + 1, sizeof(int)); //conform conventiei, aloc size + 1 elemente, deoarece la [0] voi avea size-ul listei curente de vecini!! (atentie la trimiteri si alocari ulterioare)
  221.  
  222.         while(p = strtok(NULL, " "))
  223.             addElement(graph[i], atoi(p));
  224.     }
  225.  
  226.     fclose(in);
  227.     return graph;
  228. }
  229.  
  230. int* readGraphLine(char* fileName){
  231.  
  232.     FILE *in = fopen(fileName, "rt");
  233.     Check(!in, "Eroare la deschiderea fisierului.");
  234.     int* neighbours;
  235.     int i=0, result;
  236.     char line[100];
  237.     size_t lineSize;
  238.  
  239.     while(i++ != rank){
  240.         fgets(line, 100, in);
  241.         //result = getline(&line, &lincreateMessageSeSize, in);
  242.     }
  243.    
  244.     //result = getline(&line, &lineSize, in);
  245.     fgets(line, 100, in);
  246.  
  247.     char* p = strtok(line, " ");
  248.     p = strtok(NULL, " "); // '-'-ul
  249.     neighbours = (int*)calloc(size + 1, sizeof(int)); //conform conventiei, aloc size + 1 elemente, deoarece la [0] voi avea size-ul listei curente de vecini!! (atentie la trimiteri si alocari ulterioare)
  250.  
  251.     while(p = strtok(NULL, " "))
  252.         addElement(neighbours, atoi(p));
  253.  
  254.     fclose(in);
  255.     return neighbours;
  256. }
  257.  
  258. int* createSonda(){
  259.     int* sonda = (int*)malloc(sizeof(int) * size);
  260.     int i;
  261.     for(i=0; i<size; i++)
  262.         sonda[i] = NOPARENT;
  263.  
  264.     return sonda;
  265. }
  266.  
  267. void fixNeighbours(int* routingTable){
  268.     int i;
  269.     /* Recreez vecinii dupa rularea STP-ului */
  270.     neighbours[0] = 0;
  271.     for(i=0; i<size; i++)
  272.         if(routingTable[i] == rank){
  273.             neighbours[0]++;
  274.             neighbours[neighbours[0]] = i;
  275.         }
  276.     //printNeighbours(neighbours);
  277. }
  278.  
  279. void fixRoutingTable(int* routingTable, int* neighbours){
  280.     int* neighbourArray = (int*)calloc(size, sizeof(int));
  281.     int i;
  282.  
  283.     //printRoutingTable(routingTable);
  284.  
  285.     for(i=1; i<=neighbours[0]; i++)
  286.         neighbourArray[neighbours[i]] = 1;
  287.     neighbourArray[rank] = 1; //bug la root
  288.  
  289.     //neighbourArray[rank] = 0; // ma trec si pe mine
  290.  
  291.     /* Pentru a nu face O(N^2) cautari, salvez intr-un vector de vecini, lista de vecini */
  292.     /* Daca avem 0->1->2->4->8, noua ne afiseaza pe routingTable[8] = 4, nu 1, deci fac un while pana am vecin (adica 1) */
  293.     for(i=0; i<size; i++){
  294.         while(neighbourArray[routingTable[i]] != 1)
  295.             routingTable[i] = routingTable[routingTable[i]];
  296.  
  297.     }
  298.  
  299.     for(i=0; i<size; i++){
  300.         if(routingTable[i] == rank)
  301.             routingTable[i] = i;
  302.     }
  303.  
  304.     routingTable[rank] = -1;
  305.    
  306.     //printRoutingTable(routingTable);
  307.     free(neighbourArray);
  308. }
  309.  
  310. void readNeighbours( char* fileName ){
  311.  
  312.     if(rank == ROOT){
  313.         graph = readGraph(fileName);
  314.         //printGraph(graph);
  315.         neighbours = graph[0];
  316.     }
  317.     else{
  318.         neighbours = readGraphLine(fileName);
  319.     }
  320. }
  321.  
  322. void logGraph(){
  323.     int i;
  324.     if(rank == ROOT){
  325.         fprintf(logFile, "Matrice de adiacenta\n");
  326.         for(i=0; i<size; i++){
  327.             int j;
  328.             for(j=0; j<size; j++){
  329.                 fprintf(logFile, "%i ", graph[i][j]);
  330.             }
  331.             fprintf(logFile, "\n");
  332.         }
  333.     }
  334. }
  335.  
  336. void logRoutingTable(){
  337.     int i;
  338.     fprintf(logFile, "%i: ", rank);
  339.     for(i=0; i<size; i++){
  340.         fprintf(logFile, "%i ", routingTable[i]);
  341.     }
  342.     fprintf(logFile, "\n");
  343. }
  344.  
  345. void createRoutingTable(){
  346.     int i; 
  347.     if(rank == ROOT){
  348.  
  349.         //printNeighbours(neighbours);
  350.        
  351.         /* ROOT trimite catre toti vecinii sai si asteapta un vector pe care va face neighbOR */
  352.         int *sonda = createSonda();
  353.         int tmp[size];
  354.  
  355.         for(i=1; i<=neighbours[0]; i++){
  356.             MPI_Send(sonda, size, MPI_INT, neighbours[i], 0, MPI_COMM_WORLD);
  357.         }
  358.  
  359.         for(i=1; i<=neighbours[0]; i++){
  360.             MPI_Recv(tmp, size, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
  361.             neighbOR(sonda, tmp);
  362.         }
  363.        
  364.         /* Aceasta este tabela de rutare a lui ROOT. Acum trimit catre toti conectati direct ca si ei sa-si formeze tabela lor de rutare pe baza acesteia. */
  365.         routingTable = sonda;
  366.         /* Tablela de rutare imi pune last_hop in acest punct pentru orice nod. last_hop nu este neaparat un vecin cu nodul curent, deci caut next_hop. */
  367.        
  368.         for(i=0; i<size; i++){
  369.             if(routingTable[i] == rank){ // trimit celor conectati direct (root nu are parinte)
  370.                 MPI_Send(routingTable, size, MPI_INT, i, 0, MPI_COMM_WORLD);
  371.             }
  372.         }
  373.  
  374.         //printRoutingTable(routingTable);
  375.         fixNeighbours(routingTable);
  376.         fixRoutingTable(routingTable, neighbours);
  377.  
  378.     }
  379.  
  380.     else{
  381.    
  382.         int tmp[size], parent;
  383.         MPI_Recv(tmp, size, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
  384.         parent = status.MPI_SOURCE; // imi aflu parintele
  385.  
  386.         //printf("Parintele lui %i este %i\n", rank, parent);
  387.  
  388.         int *sonda = createSonda();
  389.         for(i=1; i<=neighbours[0]; i++){
  390.             if(neighbours[i] == parent)
  391.                 continue;
  392.             MPI_Isend(sonda, size, MPI_INT, neighbours[i], 0, MPI_COMM_WORLD, &request);
  393.         }
  394.  
  395.         for(i=1; i<neighbours[0]; i++){
  396.             MPI_Recv(tmp, size, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
  397.             neighbOR(sonda, tmp);
  398.         }
  399.  
  400.         sonda[rank] = parent;
  401.         MPI_Send(sonda, size, MPI_INT, parent, 0, MPI_COMM_WORLD);
  402.    
  403.         //printNeighbours(neighbours);
  404.        
  405.         // Primesc tabela de rutare de la parent si mi-o creez pe a mea de la el
  406.         MPI_Recv(sonda, size, MPI_INT, parent, 0, MPI_COMM_WORLD, &status);
  407.         sonda[parent] = rank; //ajung la parinte prin mine (dar tot retin ca el e parinte in STP in acea variabila)
  408.         sonda[rank] = NONEXT; //de la mine la mine am ajuns deja (:D)
  409.         routingTable = sonda;
  410.        
  411.         for(i=0; i<size; i++){
  412.             if(routingTable[i] == rank && i != parent) // trimit celor conectati direct (root nu are parinte)
  413.                 MPI_Send(routingTable, size, MPI_INT, i, 0, MPI_COMM_WORLD);
  414.         }
  415.        
  416.         //printRoutingTable(routingTable);
  417.         fixNeighbours(routingTable);
  418.         fixRoutingTable(routingTable, neighbours);
  419.  
  420.     }
  421.    
  422.     if(rank == ROOT)
  423.         logGraph();
  424.     logRoutingTable();
  425.    
  426. }
  427.  
  428. void readMessages(char* fileName){
  429.  
  430.     FILE *in = fopen(fileName, "rt");
  431.     Check(!in, "Eroare la deschiderea fisierului");
  432.     int i, lines, result;
  433.     size_t lineSize;
  434.     char line[100];
  435.     int source, destination;
  436.        
  437.     fgets(line, 100, in);
  438.     lines = atoi(line);
  439.  
  440.     messageBox = createMessageBox();
  441.  
  442.     for(i=0; i<lines; i++){
  443.         char *p, *q;
  444.         fgets(line, 100, in);
  445.        
  446.         p = line;
  447.         q = line;
  448.         while(*p != ' ')
  449.             p++;
  450.         *p = '\0'; // modific spatiul in 0 pentru atoi
  451.        
  452.         source = atoi(q); //atoi se opreste la primul 0 (^)
  453.         if(source != rank)
  454.             continue;
  455.  
  456.         p++;
  457.         q = p;
  458.         //printf("%i\n", source);
  459.  
  460.         while(*p != ' ')
  461.             p++;
  462.         *p = 0;
  463.        
  464.         if(strcmp(q, "B") == 0)
  465.             destination = BROADCAST;
  466.        
  467.         else
  468.             destination = atoi(q); //atoi se opreste la primul 0 (^);
  469.  
  470.         q = p+1;
  471.         if(q[strlen(q)-1] == '\n')
  472.             q[strlen(q)-1] = 0;
  473.  
  474.         addMessageToBox(messageBox, createMessage(q, destination));
  475.         //printf("Source: %i, Destination: %i, Line: %s\n", source, destination, q);
  476.     }
  477.  
  478.     fclose(in);
  479. }
  480.  
  481. void createReadyTopology(MPI_Datatype messageStructType){
  482.     int allReady = size - 1;
  483.     ready = (int*)calloc(size, sizeof(int));
  484.     ready[rank] = 1;
  485.  
  486.     /* Imi trimit confirmarea pe broadcast (catre toti la next-hop) */
  487.     int i;
  488.     Message readyMessage = createMessage("READY", BROADCAST);
  489.     Message recvMessage = (Message)malloc(sizeof(TMessage));
  490.  
  491.     //printNeighbours(neighbours);
  492.  
  493.     for(i=1; i<=neighbours[0]; i++){
  494.         MPI_Send(readyMessage, 1, messageStructType, neighbours[i], READY, MPI_COMM_WORLD);
  495.     }
  496.  
  497.     /* Cat timp mai sunt procese de la care nu am primit confirmarea de ready nu trec mai departe */
  498.     /* De asemenea, rutez toate mesajele care nu-mi sunt destinate */
  499.     while(allReady > 0){
  500.         MPI_Recv(recvMessage, 1, messageStructType, MPI_ANY_SOURCE, READY, MPI_COMM_WORLD, &status);
  501.         if(recvMessage->to == BROADCAST){
  502.              if( status.MPI_TAG == READY && ready[recvMessage->from] == 0 ){ // mi-e destinat mie ?
  503.                 ready[recvMessage->from] = 1;
  504.                 allReady--;
  505.             }              
  506.  
  507.             // Trimit mesajul tuturor vecinilor, mai putin celui care a trimis
  508.             for(i=1; i<=neighbours[0]; i++){
  509.                 if( neighbours[i] != status.MPI_SOURCE )
  510.                     MPI_Send(recvMessage, 1, messageStructType, neighbours[i], READY, MPI_COMM_WORLD);
  511.                
  512.             }
  513.         }
  514.     }
  515.  
  516.     free(readyMessage);
  517.     free(recvMessage);
  518.  
  519.     //printf("Procesul %i a terminat de rutat complet\n", rank);
  520. }
  521.  
  522. void sendMyMessages(MessageBox myMessageBox, MPI_Datatype messageStructType){
  523.     int i, j;
  524.     for(i=0; i<myMessageBox->messagesCount; i++){
  525.         fprintf(logFile, "[%i] Trimit mesajul%s prin %s\n", rank, myMessageBox->messages[i]->to == BROADCAST ? "" : concat("spre ",myItoa(myMessageBox->messages[i]->to)), myMessageBox->messages[i]->to == BROADCAST ? "BROADCAST" : myItoa(routingTable[myMessageBox->messages[i]->to]));
  526.         if(myMessageBox->messages[i]->to == BROADCAST){
  527.             for(j=1; j<=neighbours[0]; j++)
  528.                 MPI_Send(myMessageBox->messages[i], 1, messageStructType, neighbours[j], 0, MPI_COMM_WORLD);
  529.         }
  530.         else
  531.             MPI_Send(myMessageBox->messages[i], 1, messageStructType, routingTable[myMessageBox->messages[i]->to], 0, MPI_COMM_WORLD);
  532.     }
  533.     ready[rank] = 0;
  534.  
  535.     Message endMessage = createMessage("END", BROADCAST);
  536.     for(i=1; i<=neighbours[0]; i++)
  537.         MPI_Send(endMessage, 1, messageStructType, neighbours[i], END, MPI_COMM_WORLD);
  538.  
  539.     free(endMessage);
  540. }
  541.  
  542. void routeMessages(MPI_Datatype messageStructType){
  543.     int i, allDone = 1; // Mesajele mele sunt trimise
  544.     Message recvMessage = (Message)malloc(sizeof(TMessage));
  545.    
  546.     //printNeighbours(neighbours);
  547.  
  548.     while(allDone < size){ // Rutez toate mesajele care trec prin mine pana toate au inchis conexiunea.
  549.        
  550.         MPI_Recv(recvMessage, 1, messageStructType, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
  551.  
  552.         if(recvMessage->to == BROADCAST){
  553.              if( status.MPI_TAG == END && ready[recvMessage->from] == 1 ){
  554.                 ready[recvMessage->from] = 0;
  555.                 allDone++;
  556.                 //fprintf(logFile, "[%i] Am primit un mesaj de BROADCAST (END) trimis de %i\n", rank, recvMessage->from, neighbours[0]-1 );
  557.             }
  558.             else{
  559.                 fprintf(logFile, "[%i] Am primit un mesaj de BROADCAST trimis de %i: %s\n", rank, recvMessage->from, recvMessage->message);
  560.             }
  561.        
  562.  
  563.             // Trimit mesajul tuturor vecinilor, mai putin celui care a trimis
  564.             for(i=1; i<=neighbours[0]; i++){
  565.  
  566.                 if( neighbours[i] != status.MPI_SOURCE ){
  567.                     MPI_Send(recvMessage, 1, messageStructType, neighbours[i], status.MPI_TAG, MPI_COMM_WORLD);
  568.                 }
  569.  
  570.             }
  571.  
  572.         }
  573.         else{ //Mesaj destinat cuiva (eu sau cineva care routeaza prin mine)
  574.             if(recvMessage->to == rank){ // destinat mie
  575.                 fprintf(logFile, "[%i] Am primit un mesaj de la %i: %s\n", rank, recvMessage->from, recvMessage->message );
  576.             }
  577.             else{
  578.                 fprintf(logFile, "[%i] Routez un mesaj de la %i prin %i\n", rank, recvMessage->from, routingTable[recvMessage->to] );
  579.                 MPI_Send(recvMessage, 1, messageStructType, routingTable[recvMessage->to], 0, MPI_COMM_WORLD);
  580.             }
  581.         }
  582.  
  583.     }
  584.  
  585.     fprintf(logFile, "[%i] Am primit toate mesajele!\n", rank);
  586.     free(recvMessage);
  587. }
  588.  
  589. void initializeLogFile(int logPart){
  590.     if(logPart > 1)
  591.         fclose(logFile);
  592.  
  593.     char* fileName = concat(concat("log", myItoa(logPart)), ".txt");
  594.     if(rank == 0){
  595.         logFile = fopen(fileName, "wt");
  596.         fprintf(logFile, "Etapa: %i\n", logPart);
  597.         fclose(logFile);
  598.     }
  599.     logFile = fopen(fileName, "at");
  600. }
  601.  
  602. void wakeUpCall(MPI_Datatype messageStructType){
  603.  
  604.     /* Etapa de wake-up */
  605.     int ws = 0, wr = 0;
  606.     int i, r = neighbours[0], id;
  607.     leader = rank;
  608.     Message wakeUpMessage = createMessage("WAKEUP", WAKEUPMESASGE);
  609.     Message recvMessage = (Message)malloc(sizeof(TMessage));
  610.    
  611.     if(neighbours[0] == 1 && rank != ROOT) { // p este initiator
  612.         ws = TRUE;
  613.         for(i=1; i<=neighbours[0]; i++){ // fa q € vecini
  614.             MPI_Send(wakeUpMessage, 1, messageStructType, neighbours[i], WAKEUP, MPI_COMM_WORLD); //send wake-up
  615.         }
  616.     }
  617.  
  618.     do{
  619.         MPI_Recv(recvMessage, 1, messageStructType, MPI_ANY_SOURCE, WAKEUP, MPI_COMM_WORLD, &status);
  620.         fprintf(logFile, "[%i] Am primit wake-up call de la %i [%i]\n", rank, status.MPI_SOURCE, wr);
  621.         wr++;
  622.         if(ws == FALSE){
  623.             ws = TRUE;
  624.             for(i=1; i<=neighbours[0]; i++) // fa q € vecini
  625.                 MPI_Send(wakeUpMessage, 1, messageStructType, neighbours[i], WAKEUP, MPI_COMM_WORLD); //send wake-up
  626.         }
  627.     } while(wr < neighbours[0]);
  628.  
  629.     free(wakeUpMessage);
  630.     free(recvMessage);
  631. }
  632.  
  633. int leaderFunction(int a, int b){
  634.     return min(a,b);
  635. }
  636.  
  637. void selectAdjount(MPI_Datatype messageStructType){
  638.     int i;
  639.     if(rank == leader){
  640.         // Aleg adjunctul random
  641.         srand (time(NULL));
  642.         adjount = (rand() % neighbours[0]) + 1;
  643.        
  644.         Message message = createMessage(myItoa(adjount), BROADCAST);
  645.         for(i=1;i<=neighbours[0]; i++)
  646.             MPI_Send(message, 1, messageStructType, neighbours[i], 0, MPI_COMM_WORLD);
  647.         adjount = adjount;
  648.         free(message);
  649.     }
  650.     else{
  651.         Message recvMessage = (Message)malloc(sizeof(TMessage));
  652.         MPI_Recv(recvMessage, 1, messageStructType, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
  653.         for(i=1; i<=neighbours[0]; i++){
  654.             if(neighbours[i] != status.MPI_SOURCE)
  655.                 MPI_Send(recvMessage, 1, messageStructType, neighbours[i], 0, MPI_COMM_WORLD);
  656.  
  657.         }
  658.         adjount = atoi(recvMessage->message);
  659.         free(recvMessage);
  660.     }
  661. }
  662.  
  663. void selectLeader(MPI_Datatype messageStructType){
  664.  
  665.     Message recvMessage = (Message)malloc(sizeof(TMessage));
  666.  
  667.     int i, r = neighbours[0], id;
  668.     leader = rank;
  669.  
  670.     // END ETAPA WAKE-UP
  671.     int *rec = (int*)calloc(neighbours[0], sizeof(int));
  672.     int *positionsInNeighbours = (int*)calloc(size, sizeof(int));
  673.  
  674.     for( i=1; i<=neighbours[0]; i++)
  675.         positionsInNeighbours[neighbours[i]] = i;
  676.  
  677.     while( r > 1 ) {
  678.         MPI_Recv(&id, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);
  679.         r--;
  680.         rec[positionsInNeighbours[status.MPI_SOURCE]] = TRUE;
  681.         leader= leaderFunction(leader, id);
  682.     }
  683.  
  684.     int lastNeighbour;
  685.     for(i=1; i<=neighbours[0]; i++)
  686.         if(rec[i] == FALSE){
  687.             lastNeighbour = neighbours[i];
  688.             break;
  689.         }
  690.  
  691.     /* Comunic cu al n-lea vecin de la care n-am primit mesaj */
  692.     MPI_Send(&leader, 1, MPI_INT, lastNeighbour, 0, MPI_COMM_WORLD);
  693.     MPI_Recv(&id, 1, MPI_INT, lastNeighbour, 0, MPI_COMM_WORLD, &status);
  694.     leader = leaderFunction(leader, id);
  695.  
  696.     for(i=1; i<=neighbours[0]; i++){
  697.         if(neighbours[i] != lastNeighbour) // trimit catre toti vecinii mai putin last neighbour ceea ce am calculat eu.
  698.             MPI_Send(&leader, 1, MPI_INT, neighbours[i], 0, MPI_COMM_WORLD);
  699.     }
  700.  
  701.     free(recvMessage);
  702. }
  703.  
  704. void selectLeaderAndAdjount(MPI_Datatype messageStructType){
  705.     wakeUpCall(messageStructType);
  706.     selectLeader(messageStructType);
  707.     selectAdjount(messageStructType);
  708. }
  709.  
  710. int main(int argc, char* argv[]){
  711.    
  712.     MPI_Init(&argc, &argv);
  713.     Check(argc != 3, "Formatul parametrilor gresit (./a.out fis_topologie fis_mesaje)");
  714.     initializeLogFile(1); // initializez logul pentru etapa 1
  715.  
  716.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  717.     MPI_Comm_size(MPI_COMM_WORLD, &size);
  718.    
  719.     readNeighbours(argv[1]); // creez vectorul neighbours
  720.     //printNeighbours(neighbours);
  721.  
  722.     createRoutingTable(); //creez vectorul routingTable
  723.     //printRoutingTable(routingTable);
  724.    
  725.     initializeLogFile(2); // initializez logul pentru etapa 2
  726.     readMessages(argv[2]); //creez MessageBox-ul messageBox
  727.     //printMessages(messageBox);
  728.  
  729.     MPI_Datatype messageStructType;
  730.     createMessageStructFormat(&messageStructType);
  731.  
  732.     createReadyTopology(messageStructType); // dupa acest pas, tot vectorul ready[SIZE] va fi true
  733.     //printArray(ready, size);
  734.  
  735.     sendMyMessages(messageBox, messageStructType); // trimit mesajele din Message Box-ul procesului catre destinatia dorita
  736.     routeMessages(messageStructType);
  737.     freeMessageBox(&messageBox);
  738.  
  739.     initializeLogFile(3); // logul pentru etapa 3
  740.     selectLeaderAndAdjount(messageStructType);
  741.     fprintf(logFile, "[%i] Leader:%i - Adjunct:%i\n", rank, leader, adjount);
  742.     //printf("%i %i\n", leader, adjount);
  743.    
  744.     fclose(logFile);
  745.     MPI_Finalize();
  746.     return 0;
  747. }
Advertisement
Add Comment
Please, Sign In to add comment