1 / 32

Najczęstsze błędy i wypaczenia przy stosowaniu komunikacji zbiorowej

Komunikacja zbiorowa: część II. Najczęstsze błędy i wypaczenia przy stosowaniu komunikacji zbiorowej Grupy procesów i podział komunikatorów Operacje na grupach procesów Komunikacja wewnątrzgrupowa i komunikatory wewnętrzne Komunikacja międzygrupowa i komunikatory zewnętrzne.

yonah
Download Presentation

Najczęstsze błędy i wypaczenia przy stosowaniu komunikacji zbiorowej

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Komunikacja zbiorowa: część II • Najczęstsze błędy i wypaczenia przy stosowaniu komunikacji zbiorowej • Grupy procesów i podział komunikatorów • Operacje na grupach procesów • Komunikacja wewnątrzgrupowa i komunikatory wewnętrzne • Komunikacja międzygrupowa i komunikatory zewnętrzne

  2. Błędy i wypaczenia w komunikacji zbiorowej • Wywołanie procedury komunikacji zbiorowej tylko dla części procesorów zawartych w zaspecyfikowanym komunikatorze. • W szczególności zapomnienie o tym, że w przypadku MPI_Bcast zarówno procesor źródłowy jak i wszyscy odbiorcy muszą zawołać tę procedurę. • Założenie, że wszystkie procesory jednocześnie zakończą wykonywanie danej procedury komunikacji zbiorowej. • Użycie tego samego bufora wejściowego i wyjściowego w wywołaniu MPI_Reduce (MPI_Allreduce).

  3. 1 i 2. Wywołanie w zależności od procesora (BARDZO POWAŻNY błąd, bo nie powoduje zatrzymania programu i przez to znakomicie utrudnia jego odrobaczenie). if (rank == 0) { MPI_Bcast(dane, ..., Master, ..., MPI_COMM_WORLD); do_masters_work(); else { do_work(dane,wyniki); MPI_Gather(wyniki,...,Master,...,MPI_COMM_WORLD); } W takim przypadku master wyśle dane do pozostałych procesorów ale dane te nigdy nie zostaną odebrane, natomiast wyniki wysłane przez robotników nigdy nie zostaną odebrane przez mastera. Należy napisać tak: MPI_Bcast(dane, ..., Master, ..., MPI_COMM_WORLD); if (rank == 0) { do_masters_work(); else do_work(dane,wyniki); } MPI_Gather(wyniki,...,Master,...,MPI_COMM_WORLD);

  4. 4. Użycie tego samego bufora wejściowego i wyjściowego w MPI_Reduce call MPI_Allreduce(a, a, 1, MPI_REAL, MPI_SUM, comm, ierr); Spowoduje to natychmiastowy bład wykonania i przerwanie programu, więc błąd taki jest łatwy do wykrycia. Wymóg, aby bufor wyjściowy był różny od wyjściowego zapewnia kompatybilność ze standartem FORTRANu (przekazywanie zmiennej przez adres a nie przez wartość); w związku z tym ograniczenie obowiązuje również przy wołaniu MPI_Reduce w programach w C. Poprawny kod: call MPI_Allreduce(a, a_sum, 1, MPI_REAL, MPI_SUM, comm, ierr);

  5. Grupy procesów i podział komunikatorów • Grupa procesów: zbiór procesorów uporządkowany według rzędu. W MPI zdefiniowano „pustą” grupę: MPI_GROUP_EMPTY oraz dwie stałe: MPI_GROUP_EMPTY (odnośnik do grupy pustej) oraz MPI_GROUP_NULL (odnośnik do grupy zdefiniowanej niewłaściwie). • Podział komunikatorów: • Komunikatory wewnętrzne (intrakomunikatory): służą do komunikacji w obrębie grupy; możliwa jest komunikacja punktowa i zbiorowa. • Komunikatory zewnętrzne (interkomunikatory): służą do komunikacji pomiędzy dwoma grupami. W standarcie MPI-1 możliwa jest jedynie komunikacja punktowa (MPI_Send i MPI_Receive).

  6. Funkcjonalność Intrakomunikator Interkomunikator Liczba grup 1 2 Bezpieczeństwo Tak Tak Komunikacja zbiorowa Tak Nie Topologie Tak Nie Kaszowanie Tak Tak Charakterystyka intra- i interkomunikatorów

  7. Operacje na grupach MPI_GROUP_SIZE(group, size): zwraca liczbę procesorów w grupie. MPI_Group_size(MPI_Group group, int *size) MPI_GROUP_SIZE(GROUP, SIZE, IERROR) INTEGER GROUP, SIZE, IERROR group - grupa size - liczba procesorów w grupie MPI_GROUP_RANK(group, rank): zwraca rząd danego procesora w grupie; jeżeli procesor nie jest w grupie jest zwracany rząd MPI_UNDEFINED. group - grupa rank - rząd procesora w grupie. MPI_Group_rank(MPI_Group group, int *rank) MPI_GROUP_RANK(GROUP, RANK, IERROR) INTEGER GROUP, RANK, IERROR

  8. MPI_GROUP_TRANSLATE_RANKS(group1, n, ranks1, group2, ranks2) podaje rzędy procesorów z jednej grupy w innej grupie; w przypadku, gdy któryś z procesorów nie należy do drugiej grupy zwraca w tym miejscu MPI_UNDEFINED. group1 - grupa pierwsza n - liczba procesorów w tablicach ranks1 i ranks2 ranks1 - tablica rzędów w grupie pierwszej group2 - grupa druga ranks2 - tablica rzędów w grupie drugiej MPI_Group_translate_ranks (MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2) MPI_GROUP_TRANSLATE_RANKS(GROUP1, N, RANKS1, GROUP2, RANKS2, IERROR) INTEGER GROUP1, N, RANKS1(*), GROUP2, RANKS2(*), IERROR

  9. MPI_GROUP_COMPARE(group1, group2, result) • porównuje dwie grupy zwracając wynik w zmiennej result: • MPI_IDENT: grupy są identyczne; • MPI_SIMILAR: grupy zawierają te same procesory ale w innym porządku; • MPI_UNEQUAL: grupy są różne.

  10. Kreatory grup MPI_COMM_GROUP(comm, group) uzyskiwanie wskaźnika grupy (group) odpowiadającej komunikatorowi comm. MPI_Comm_group(MPI_Comm comm, MPI_Group *group) MPI_COMM_GROUP(COMM, GROUP, IERROR) INTEGER COMM, GROUP, IERROR

  11. Trzy standardowe operacje mnogościowe: MPI_GROUP_UNION(group1, group2, newgroup) MPI_GROUP_INTERSECTION(group1, group2, newgroup) MPI_GROUP_DIFFERENCE(group1, group2, newgroup)

  12. MPI_GROUP_INCL(group, n, ranks, newgroup) tworzenie nowej grupy z elementów starej. group - stara grupa; n - liczba procesorów ze starej grupy, które mają być włączone do nowej; ranks - tablica zawierająca te rzędy; newgroup - nowa grupa. MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup) MPI_GROUP_INCL(GROUP, N, RANKS, NEWGROUP, IERROR) INTEGER GROUP, N, RANKS(*), NEWGROUP, IERROR MPI_GROUP_EXCL(group, n, ranks, newgroup) tworzy nową grupę ze starej poprzez wyłączenie n procesorów o rzędach podanej w tablicy ranks. Składnia analogiczna do MPI_GROUP_INCL.

  13. MPI_GROUP_RANGE_INCL(group, n, ranges, newgroup) MPI_GROUP_RANGE_EXCL(group, n, ranges, newgroup) Wygodniejsze formy poprzednich. Tablica ranges(3,*) zawiera zakresy włączanych/wyłączanych procesorów; ranges(1,i) i ranges(2,i) definiują odpowiednio pierwszy i ostatni procesorów w i-tym zakresie, ranges(3,i) mówi z jakim krokiem włącza/wyłącza się procesory (1 - każdy, 2 - co drugi, itd.). Destruktor grupy MPI_GROUP_FREE(group) MPI_Group_free(MPI_Group *group) MPI_GROUP_FREE(GROUP, IERROR) INTEGER GROUP, IERROR

  14. Komunikacja wewnątrzgrupowa i komunikatory wewnętrzne Komunikacja wewnątrzgrupowa: wymiana informacji w obrębie procesorów należących do jednej grupy. Możliwe jest tutaj stosowanie zarówno procedur komunikacji punktowej jak i zbiorowej.

  15. Operacje na komunikatorach MPI_COMM_SIZE(comm, size) MPI_COMM_RANK(comm, rank) MPI_COMM_COMPARE(comm1, comm2, result) Wartości zwracane przez MPI_COMM_COMPARE w zmiennej result są podobne jak w przypadku MPI_GROUP_COMPARE z wyjątkiem, że w przypadku identyczności grup odpowiadających komunikatorom comm1 i comm2 zwracana jest wartość MPI_CONGRUENT. Standardowe komunikatory MPI_COMM_WORLD: wszystkie procesory przydzielone zadaniu; MPI_COMM_SELF: dany procesor (zawsze ma rząd 0). MPI_COMM_NULL: pusty komunikator.

  16. Kreatory komunikatorów MPI_COMM_DUP(comm, newcomm) tworzenie duplikatu komunikatora. comm - stary komunikator; newcomm - nowy komunikator. MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm) MPI_COMM_DUP(COMM, NEWCOMM, IERROR) INTEGER COMM, NEWCOMM, IERROR

  17. MPI_COMM_CREATE(comm, group, newcomm) tworzenie („pączkowanie”) nowego komunikatora. comm - stary komunikator (może być MPI_COMM_WORLD); group - grupa procesorów, które mają utworzyć nowy komunikator; newcomm - nowy komunikator. int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm) MPI_COMM_CREATE(COMM, GROUP, NEWCOMM, IERROR) INTEGER COMM, GROUP, NEWCOMM, IERROR

  18. MPI_COMM_SPLIT(comm, color, key, newcomm) tworzenie nowych komunikatorów poprzez podział starego według przypisania zawartego w zmiennej color. comm - stary komunikator; color - kolor; procesory o różnych kolorach będą tworzyły różne komunikatory; key - klucz; wskazuje, jak ma wzrastać rząd procesorów (jeżeli dla dwóch procesorów w nowej grupie jest taki sam, kolejność rzędów jest tak jak kolejność rzędów w starej grupie); newcomm - nowy komunikator, w którym znajdzie się wywołujący procesor. Jeżeli nie chcemy, żeby dany procesor znalazł się w jakimkolwiek z nowych komunikatorów, nadajemy mu kolor MPI_UNDEFINED. MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm) MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERROR) INTEGER COMM, COLOR, KEY, NEWCOMM, IERROR

  19. Rozważmy grupę procesorów a-j o rzędach (w starym komunikatorze) od 0-9 (┴ oznacza kolor MPI_UNDEFINED): rząd 0 1 2 3 4 5 6 7 8 9 procesor a b c d e f g h i j kolor 0 3 0 3 0 0 5 3 klucz 3 1 2 5 1 1 1 2 1 0 ┴ ┴ • Wywołanie MPI_COMM_SPLIT dla tego układu spowoduje powstanie trzech nowych komunikatorów: • {f,g,a,d} (kolor 0); rzędy będą wynosiły odpowiednio 0, 1, 2, 3. • {e,i,c} (kolor 3); rzędy będą wynosiły 0, 1, 2. • {h} (kolor 5); rząd oczywiście 0. • Procesory b oraz j nie będą należały do żadnego z komunikatorów.

  20. Destruktor komunikatora MPI_COMM_FREE(comm) MPI_Comm_free(MPI_Comm *comm) MPI_COMM_FREE(COMM, IERROR) INTEGER COMM, IERROR

  21. Przykład: Obliczanie liczby p metodą Monte Carlo Algorytm obliczania liczby p: losujemy pary liczb (x,y) należące do przedziału [-1..1] a następnie obliczamy przybliżenie ze stosunku liczby wylosowanych punktów leżących w kole scentrowanym w punkcie (0,0) i o promieniu 1 do liczby wszystkich wylosowanych punktów.

  22. Dedykujemy procesor o najwyższym rzędzie jako serwer liczb losowych dla pozostałych procesorów. • Z pozostałych procesorów tworzymy grupę przy pomocy procedury MPI_GROUP_EXCL oraz MPI_COMM_CREATE grupę „robotników” i definiujemy odpowiedni komunikator workers. • „Robotnicy” obliczają ile przysłanych losowych punktów leży w kole (N_in) a ile poza nim (N_out), następnie wykorzystując proceduręMPI_ALLREDUCE działająca w obrębie komunikatora workers. • Jeżeli obliczone przybliżenie liczby różni się od wartości prawdziwej o mniej niż zadeklarowaną dokładność (pobierana z linii polecenia) lub przekroczono maksymalną zadeklarowaną liczbę kroków, program się kończy. Jeżeli nie, każdy z „robotników” wysyła do serwera żądanie inicjalizacji generatora liczb losowych i procedura jest powtarzana od punktu 3. • Kod źródłowy programu w języku C • Wyniki (4 procesory)

  23. Przykład zastosowania procedury MPI_Comm_split Źródło programu w C Wyniki

  24. Komunikacja międzygrupowa Komunikacja międzygrupowa: wymiana informacji pomiędzy procesami należącymi do rozłącznych grup. Komunikację międzygrupową stosuje się dla zadań modularnych, gdzie informacje muszą przepływać pomiędzy kolejnymi grupami (rura) lub, w bardziej ogólnym przypadku, płynąć po grafie zdefiniowanym przez interkomunikatory.

  25. Cechy komunikacji międzygrupowej: • Można stosować jedynie procedury komunikacji punktowej. • Pomiędzy grupami procesów definiuje się skierowane interkomunikatory; zbiór interkomunikatorów tworzy graf połączeń. • Procesy identyfikuje się poprzez ich rzędy w lokalnych grupach.

  26. Kreator interkomunikatorów MPI_INTERCOMM_CREATE(local_comm, local_leader, bridge_comm, remote_leader, tag, newintercomm) local_comm - komunikator lokalny local_leader - rząd procesora będącego „bazą” komunikatora lokalnego; musi być w bridge_comm bridge_comm - komunikator mostkujący; musi zawierać procesory obu łączonych grup (na ogół MPI_COMM_WORLD) remote_leader - rząd procesora-bazy komunikatora odległego (w bridge_comm) tag – „pieczątka” interkomunikatora newintercomm - nowo postały interkomunikator

  27. MPI_Intercomm_create(MPI_Comm local_comm, int local_leader, MPI_Comm bridge_comm, int remote_leader, int tag, MPI_Comm *newintercomm) MPI_INTERCOMM_CREATE(LOCAL_COMM, LOCAL_LEADER, PEER_COMM, REMOTE_LEADER, TAG, NEWINTERCOMM, IERROR) INTEGER LOCAL_COMM, LOCAL_LEADER, PEER_COMM, REMOTE_LEADER, TAG, NEWINTERCOMM, IERROR

  28. Tworzenie intrakomunikatora z dwóch interkomunikatorów MPI_INTERCOMM_MERGE(intercomm, high, newintracomm) intercomm - interkomunikator high - kolejność procesorów w tworzonej grupie newintracomm - utworzony intrakomunikator MPI_Intercomm_merge(MPI_Comm intercomm, int high, MPI_Comm *newintracomm) Sprawdzanie, czy komunikator jest intra- czy interkomunikatorem MPI_COMM_TEST_INNER(comm, flag) comm - komunikator flag - flaga; true jeżeli komunikator jest interkomunikatorem MPI_Comm_test_inter(MPI_Comm comm, int *flag)

  29. Uzyskiwanie rozmiaru, rzędu procesora oraz grupy odpowiadającej „lokalnej” części interkomunikatora: MPI_COMM_RANK (comm, rank) MPI_COMM_SIZE (comm, size) MPI_COMM_GROUP (comm, group) Uzyskiwanie rozmiaru oraz grupy odpowiadającej „odległej” części interkomunikatora: MPI_COMM_REMOTE_SIZE (comm, size) MPI_COMM_REMOTE_GROUP (comm, group)

  30. Przykład: Symulacja układu ocean: atmosfera call MPI_COMM_SIZE( MPI_COMM_WORLD, nprocs, ierr ) call MPI_COMM_RANK( MPI_COMM_WORLD, rank, ierr ) if (rank .lt. Size/2 ) then color = OCEAN else color = ATMOS endif call MPI_COMM_SPLIT( MPI_COMM_WORLD, color, rank, ocean_or_atmos_comm, ierr) call MPI_INTERCOMM_CREATE( ocean_or_atoms_comm, 0, MPI_COMM_WORLD, 0, 0, intercomm, ierr) if (color .eq. OCEAN) then ocean_comm = ocean_or_atmos_comm call do_ocean( ocean_comm ) else atmos_comm = ocean_or_atmos_comm call do_atmos( atmos_comm ) endif call ocean_and_atmos( intercomm )

  31. Przykład bardziej konkretny: przepływ danych pomiędzy grupami procesorów („rura”) Grupę 12 procesorów dzielimy na 3 podgrupy po 4 procesory w każdej, jak na rysunku. Dane są wymieniane w obie strony pomiędzy grupami 0 i 1 oraz 1 i 2. W tym celu dla grup 0 i 2 musimy zdefiniować po jednym komunikatorze, natomiast dla grupy 1 musimy zdefiniować 2 interkomunikatory - odpowiednio do komunikacji z grupą 0 i 2.

  32. Źródło programu w C Wyniki (12 procesorów)

More Related