Advertisement
m4ly

PVM silnia

Sep 29th, 2014
248
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.28 KB | None | 0 0
  1. /**
  2.  [dawid@freeone ~/silnia]$ cat kompiluj.sh
  3. #!/bin/sh
  4.  
  5. DIR="/home/dawid/silnia"
  6. WORKER="silnia_worker"
  7. MASTER="silnia"
  8.  
  9. echo "Kompiluje"
  10. /usr/local/bin/gcc47 -lpvm3 "$DIR/$MASTER.c" -o "$DIR/$MASTER"
  11. /usr/local/bin/gcc47 -lpvm3 "$DIR/$WORKER.c" -o "$DIR/$WORKER"
  12.  
  13. echo "Kopiowanie do freetwo.com"
  14. scp "$DIR/$WORKER" [email protected]:$DIR
  15.  
  16. echo "Kopiowanie do freethree.com"
  17. scp "$DIR/$WORKER" [email protected]:$DIR
  18. */
  19.  
  20. /***
  21.  * [dawid@freeone ~/silnia]$ cat config.h
  22.  */
  23. // n zostawiam na 99 bo to i tak za duzo a pvm nie obsluguje jako tako unsigned long long - jest tyko unsigned long
  24. #define N 20
  25. #define FLAGA_ROZPOZNAWCZA_WORKERA 1111
  26. #define FLAGA_ROZPOZNAWCZA_MASTERA 999
  27. #define WORKER_PATH "/home/dawid/silnia/silnia_worker"
  28.  
  29. // zatem nasz typ dla talibcy z silniami jest taki: ulong
  30. typedef unsigned long ulong;
  31.  
  32.  
  33. /***
  34.  * [dawid@freeone ~/silnia]$ cat silnia.c
  35.  *
  36.  * Master
  37.  * Dawid Mocek
  38.  *
  39.  *
  40.  */
  41.  
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <pvm3.h>
  46. #include <sys/unistd.h>
  47. #include <limits.h>
  48. #include "config.h"
  49.  
  50. int *podziel_na_czesci(int liczba_elementow, int liczba_hostow) {
  51.     int i, j, k,  *tab = NULL;
  52.     tab = (int *)calloc(liczba_hostow, sizeof(int));
  53.  
  54.     // tu mamy po rowno elementow
  55.     if ((liczba_elementow % liczba_hostow) == 0) {
  56.         k = (liczba_elementow / liczba_hostow);
  57.         for (i = 0; i < liczba_hostow; ++i)
  58.             tab[i] = k;
  59.     }
  60.     // a tu nie
  61.     else {
  62.         k = liczba_elementow / liczba_hostow;
  63.         for (i = 0; i < liczba_hostow ; ++i)
  64.             tab[i] = k;
  65.         tab[i - 1] += liczba_elementow - (k * liczba_hostow);
  66.     }
  67.     return tab;
  68. }
  69.  
  70. int main(void) {
  71.     int ilhost, ilarch, mytid, indeks, id_procesu, i, j, len, pvm_res, bytes, msgtag;
  72.     ulong silnia;
  73.  
  74.     int *nasze_procesy = NULL;
  75.     int *ilosc = NULL;
  76.     struct pvmhostinfo *info = NULL;
  77.     char hostname[128];
  78.  
  79.     // Tablica z liczbami = unsgined long
  80.     ulong *liczby = NULL;
  81.  
  82.     liczby = (ulong *)calloc(N, sizeof(ulong));
  83.  
  84.     // Wypelniamy tablice
  85.     for(i = 0; i < N; i++)
  86.  liczby[i] = i;
  87.  
  88.     // Dla wiedzy skad gdzie co leci
  89.     gethostname(hostname, sizeof hostname);
  90.  
  91.     //  PVM
  92.     mytid = pvm_mytid();
  93.  
  94.     // Dla debugu - lapiemy co rzygajaja spawn'owane procesy
  95.     pvm_catchout(stdout);
  96.  
  97.     // Pobieram  konfig. pvma - najwazniesza stad to ilosc hostow(ILe HOSTow) i struct info
  98.     pvm_config(&ilhost, &ilarch, &info);
  99.  
  100.     // Musimy rozlozyc ilosc liczb jakie wysylamy w zaleznosci od ilosc hostow(bo kazdy host ma tylko 1 proces)
  101.     ilosc = podziel_na_czesci(N, ilhost);
  102.  
  103.     // Tu trzymamy id procesow
  104.     nasze_procesy = (int *)calloc(ilhost, sizeof(int));
  105.  
  106.     indeks = 0;
  107.     for(i = 0; i < ilhost; i++) {
  108.  
  109.         // Spawn`ujemy proces na remote hoscie
  110.  printf("[%s] Spawnuje proces na hoscie: %s\n", hostname, info[i].hi_name);
  111.  pvm_spawn(WORKER_PATH, (char **)0, PvmTaskHost, info[i].hi_name, 1, &id_procesu);
  112.  
  113.  // Zapamietuje id procesu
  114.  printf("[%s] Numer procesu: %d @ %s\n", hostname, id_procesu, info[i].hi_name);
  115.  nasze_procesy[i] = id_procesu;
  116.  
  117.         // Przygotowujemy sie do wysylki danych
  118.         pvm_initsend(PvmDataDefault);
  119.  
  120.  printf("[%s] Iteracja = %d. Wysylam liczb = %d\n", hostname, i, ilosc[i]);
  121.  
  122.         // Nasz worker musi wiedziec ile pakietow do niego dojdzie
  123.         pvm_pkint(&ilosc[i], 1, 1);
  124.         printf("[%s] Pakuje ilosc: %d\n", hostname, ilosc[i]);
  125.  
  126.  for(j = 0; j < ilosc[i]; indeks++, j++) {
  127.  
  128.      // Pakuje indeks tablicy *liczby
  129.             pvm_pkint(&indeks, 1, 1);
  130.  
  131.             // Pakuje liczbe - to jej liczmy silnie
  132.      pvm_pkulong(&liczby[indeks], 1, 1); // mozemy pakwoac unsigned long bo taak funk. jest dostepna w pvm
  133.  
  134.      // unsigned long printjumey za pomoca %lu:
  135.      printf("[%s] Pakuje liczbe: '%lu' z pod indeksu: %d\n", hostname, liczby[indeks], indeks);
  136.  
  137.  }
  138.   // Wysylam
  139.         pvm_send(id_procesu, FLAGA_ROZPOZNAWCZA_MASTERA);
  140.      }
  141.  
  142.  
  143.     // koniec wysylania
  144.     // teraz czas to odebrac
  145.  
  146.     // Czekamy na rezultaty
  147.     printf("[%s] Odbieram dane...\n", hostname);
  148.     for(i = 0; i < N; i++) {
  149.  
  150.  // Pobieram
  151.  pvm_res = pvm_recv(-1, -1);
  152.  
  153.  // Informacje skad odebralismy i ile
  154.  pvm_bufinfo(pvm_res, &bytes, &msgtag, &id_procesu);
  155.  
  156.  // Sam worker musi nam opdowiedziec dwoma pakietami - indeksem i wynikiem
  157.  printf("[%s] Dostalem bajtow: %d od procesu: %d z tagiem %d\n", hostname, bytes, id_procesu, msgtag);
  158.  
  159.         // Wypakowuje indeks:
  160.         pvm_upkint(&indeks, 1, 1);
  161.  
  162.         // Wypakowuje wygenerowa silnie
  163.         pvm_upkulong(&silnia, 1, 1);
  164.  
  165.         // Zapisuje
  166.         liczby[indeks] = silnia;
  167.  
  168.         // zabijam proces
  169.         pvm_kill(id_procesu);
  170.     }
  171.  
  172.     // Druk wyniku
  173.     printf("--------------------\n");
  174.     for(j = 0; j < N; ++j)
  175.  printf("Silnia dla '%d' = '%lu'\n", j, liczby[j]);
  176.  
  177.     free(nasze_procesy);
  178.     free(info);
  179.     free(ilosc);
  180.     free(liczby);
  181.     pvm_exit();
  182. }
  183.  
  184. /**
  185.  * [dawid@freeone ~/silnia]$ cat silnia_worker.c
  186.  */
  187. #include <stdlib.h>
  188. #include <stdio.h>
  189. #include <string.h>
  190. #include <sys/unistd.h>
  191. #include <pvm3.h>
  192. #include "config.h"
  193. ulong factorial(int);
  194.  
  195. // silnia
  196. ulong factorial(int liczba) {
  197.     int c;
  198.     ulong wynik = 1;
  199.  
  200.     for(c = 1; c <= liczba; c++)
  201.  wynik *= c;
  202.  
  203.     return wynik;
  204. }
  205.  
  206. int main(void) {
  207.  
  208.     int mytid;
  209.     int  i, j, cnt;
  210.     ulong silnia, liczba;
  211.     int indeks, master, pvm_res;
  212.     char hostname[128];
  213.  
  214.     gethostname(hostname, sizeof hostname);
  215.  
  216.     // Ja
  217.     mytid = pvm_mytid();
  218.  
  219.     // Odbieramy dane
  220.     pvm_recv(-1, -1);
  221.  
  222.     // Ilosc pakietow
  223.     pvm_upkint(&cnt,1 ,1);
  224.     printf("[%s][%d] Dostalem pakietow %d.\n", hostname, mytid, cnt);
  225.  
  226.     for(j = 0; j < cnt; j++) {
  227.  
  228.         // Wypakowuje indeks
  229.  pvm_upkint(&indeks, 1, 1);
  230.  
  231.  // Wypakowuje liczbe
  232.         pvm_upkulong(&liczba, 1, 1);
  233.  
  234.  printf("[%s][%d] Dostalem liczbe: '%lu' z pod indeksu: %d\n", hostname, mytid, liczba, indeks);
  235.  
  236.  // Licze  silnie
  237.  silnia = factorial(liczba);
  238.  
  239.         // Master
  240.         master = pvm_parent();
  241.         pvm_initsend(PvmDataDefault);
  242.  
  243.  // Pakuje indeks
  244.         pvm_pkint(&indeks, 1, 1);
  245.  
  246.  // Pakuje silnie
  247.         pvm_pkulong(&silnia, 1, 1);
  248.  
  249.  // Wysylam
  250.         pvm_res = pvm_send(master, FLAGA_ROZPOZNAWCZA_WORKERA);
  251.     }
  252.  
  253.     pvm_exit();
  254. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement