Zdrojové súbory na cvičenie si stiahnite spoločne ako archív.
Úlohy cvičenia pokrývajú problematiku preberanú na prednáške. Vašou úlohou je dokončiť kód v každej úlohe podľa TODO pokynov v komentároch.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
################################################################# # # # This file has been written as a sample solution to an # # exercise in a course given at the High Performance # # Computing Centre Stuttgart (HLRS). # # The examples are based on the examples in the MPI course of # # the Edinburgh Parallel Computing Centre (EPCC). # # It is made freely available with the understanding that # # every copy of this file must include this header and that # # HLRS and EPCC take no responsibility for the use of the # # enclosed teaching material. # # # # Authors: Joel Malard, Alan Simpson, (EPCC) # # Rolf Rabenseifner, Traugott Streicher, # # Tobias Haas (HLRS) # # # # Contact: rabenseifner@hlrs.de # # # # Purpose: A program to try MPI_Comm_split # # # # Contents: Python code, buffer send version (comm.Send) # # # ################################################################# from mpi4py import MPI import numpy as np sumA = np.empty((), dtype=np.intc) sumB = np.empty((), dtype=np.intc) comm_world = MPI.COMM_WORLD world_size = comm_world.Get_size() my_world_rank = np.array(comm_world.Get_rank(), dtype=np.intc) # TODO: Nastavte 'mycolor' tak, rozdelila uzly na 1/3 a 2/3 celkoveho poctu # uzlov 'world_size'. # Pomocka: 'mycolor' by mal byt nastaveny podla vysledku logickeho vyrazu. To # znamena, ze prva farba bude napriklad 0 ('False') a druha nenulova # ('True'). mycolor = False # TODO: Rozdelte 'comm_world' na zaklade farby 'mycolor'. Ranking by sa nemal # zmenit. Vytvorte komunikator 'sub_comm'. sub_comm = None # TODO: Zistite velkost vytvoreneho komunikatora a ulozte ju do 'sub_size'. sub_size = 0 # TODO: Alokujte a inicializujte Numpy pole s jednym prvkom (jeho hodnota bude # rank uzla v sub-komunikatore) typu 'intc'. my_sub_rank = np.array(0) # TODO: Vypocitajte sucet vsetkych rankov: # 1) my_world_rank; sucet bude ulozeny v 'sumA' # 2) my_sub_rank; sucet bude ulozeny v 'sumB' # Pouzite operaciu 'Allreduce()' na sub-komunikatore. print( "PE world:{:3d}, color={:d} sub:{:3d}, SumA={:3d}, SumB={:3d} in sub_comm".format( my_world_rank, mycolor, my_sub_rank, sumA, sumB ) ) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
################################################################# # # # This file has been written as a sample solution to an # # exercise in a course given at the High Performance # # Computing Centre Stuttgart (HLRS). # # The examples are based on the examples in the MPI course of # # the Edinburgh Parallel Computing Centre (EPCC). # # It is made freely available with the understanding that # # every copy of this file must include this header and that # # HLRS and EPCC take no responsibility for the use of the # # enclosed teaching material. # # # # Authors: Joel Malard, Alan Simpson, (EPCC) # # Rolf Rabenseifner, Traugott Streicher, # # Tobias Haas (HLRS) # # # # Contact: rabenseifner@hlrs.de # # # # Purpose: Creating a 1-dimens. topology with MPI_Cart_create # # # # Contents: Python code, buffer send version (comm.Send) # # # ################################################################# from mpi4py import MPI import numpy as np # Alokacia priestoru pre vstupne argumenty kartezianskej topologie. rcv_buf = np.empty((), dtype=np.intc) dims = np.empty(1, dtype=np.intc) periods = [False] status = MPI.Status() comm_world = MPI.COMM_WORLD size = comm_world.Get_size() my_rank = comm_world.Get_rank() # TODO # Pripravte vstupne argumenty pre vytvorenie jednorozmernej kartezianskej topologie # v kruhovom bufferi so zapnutym precislovanim rankov. dims[0] = 0 periods[0] = False reorder = False # TODO: Vytvorte karteziansku topologiu. Novy komunikator ulozte do premennej # 'new_comm'. new_comm = None # TODO: Zistite rank vytvoreneho komunikatora. my_rank = 0 # TODO: Zistite koordinaty 'my_coords' v kartezianskej topologii. my_coords = [0] # Vypocet ranku susedov. right = (my_rank + 1) % size left = (my_rank - 1 + size) % size # Komunikacia v kruhovom bufferi. sum = 0 snd_buf = np.array(my_rank, dtype=np.intc) for i in range(size): request = new_comm.Issend((snd_buf, 1, MPI.INT), right, 17) new_comm.Recv((rcv_buf, 1, MPI.INT), left, 17, status) request.Wait(status) np.copyto(snd_buf, rcv_buf) sum += rcv_buf # Vysledok. print( f"Node {my_rank}:\tSum = {sum}, Coords = {my_coords[0]}, world rank = {comm_world.Get_rank()}" ) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
################################################################# # # # This file has been written as a sample solution to an # # exercise in a course given at the High Performance # # Computing Centre Stuttgart (HLRS). # # The examples are based on the examples in the MPI course of # # the Edinburgh Parallel Computing Centre (EPCC). # # It is made freely available with the understanding that # # every copy of this file must include this header and that # # HLRS and EPCC take no responsibility for the use of the # # enclosed teaching material. # # # # Authors: Joel Malard, Alan Simpson, (EPCC) # # Rolf Rabenseifner, Traugott Streicher, # # Tobias Haas (HLRS) # # # # Contact: rabenseifner@hlrs.de # # # # Purpose: Creating a 2-dimensional topology. # # # # Contents: Python code, buffer send version (comm.Send) # # # ################################################################# from mpi4py import MPI import numpy as np max_dims = 2 rcv_buf = np.empty((), dtype=np.intc) dims = [0] * max_dims periods = [False] * max_dims coords = np.empty((max_dims), dtype=np.intc) status = MPI.Status() comm_world = MPI.COMM_WORLD size = comm_world.Get_size() # TODO: Nastavte karteziansku topologiu. # 1) Nastavte 'periods': os 0 bude cyklicka, os 1 nebude cyklicka. # periods[0] = ???; periods[1] = ??? periods[0] = False periods[1] = False # 2) Nastavte precislovanie rankov 'reorder' na 'True'. reorder = False # 3) Vypocitajte dimezie 'dims' pomocou funkcie 'Compute_dims()'. # Druhy argument musi byt tuple/zoznam dvoch nul. # Pocet prvkov v poslednom argumente urcuje na kolko dimenzii budu uzly # rozdelene. dims = [0, 0] # TODO: Vytvorte Katrteziansku topologiu. Kuminikator ulozte do premennej # 'new_comm'. new_comm = None # TODO: Zistite 'my_rank' v novom komunikatore. my_rank = 0 # TODO: Zistite koordinaty 'my_coords' v kartezianskej topologii. my_coords = [0, 0] # TODO: # Vypocitajte ranky laveho a praveho suseda podla 'my_coords', # pouzite Get_cart_rank(). Vypocitajte susedov iba pre dimenziu 0. # pomocka: Get_Cart_rank() vie spracovat pozicie mimo rozsahu pre kruhove dimenzie! for i in range(max_dims): coords[i] = my_coords[i] coords[0] = 0 left = new_comm.Get_cart_rank([0, 0]) coords[0] = 0 right = new_comm.Get_cart_rank([0, 0]) # Vypocet celkoveho suctu sum = 0 snd_buf = np.array(my_rank, dtype=np.intc) # TODO: Nastavte cyklus iba napriec dimenziou 0. for i in range(0): request = new_comm.Issend((snd_buf, 1, MPI.INT), right, 17) new_comm.Recv((rcv_buf, 1, MPI.INT), left, 17, status) request.Wait(status) np.copyto(snd_buf, rcv_buf) sum += rcv_buf print(f"{my_rank:2d}, Coords=({my_coords[0]},{my_coords[1]}): Sum = {sum}") |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
################################################################# # # # This file has been written as a sample solution to an # # exercise in a course given at the High Performance # # Computing Centre Stuttgart (HLRS). # # The examples are based on the examples in the MPI course of # # the Edinburgh Parallel Computing Centre (EPCC). # # It is made freely available with the understanding that # # every copy of this file must include this header and that # # HLRS and EPCC take no responsibility for the use of the # # enclosed teaching material. # # # # Authors: Joel Malard, Alan Simpson, (EPCC) # # Rolf Rabenseifner, Traugott Streicher, # # Tobias Haas (HLRS) # # # # Contact: rabenseifner@hlrs.de # # # # Purpose: A program with derived datatypes. # # # # Contents: Python code, buffer send version (comm.Send) # # # ################################################################# from mpi4py import MPI import numpy as np np_dtype = np.dtype([('i', np.intc), ('j', np.intc)]) snd_buf = np.empty((), dtype=np_dtype) rcv_buf = np.empty_like(snd_buf) sum = np.empty_like(snd_buf) status = MPI.Status() comm_world = MPI.COMM_WORLD my_rank = comm_world.Get_rank() size = comm_world.Get_size() right = (my_rank + 1) % size left = (my_rank - 1 + size) % size # TODO: Nastavte MPI datove typy na posielanie a prijimanie ciastocnych suctov. # 1) Odvodte typ z 'MPI.INT', v novom type budu dva prvky tohto typu. # Novy typ ulozte do premennej 'send_recv_type'. # 2) Pred prvym pouzitim nezabudnite definiciu typu zaregistrovat. send_recv_type = None sum['i'] = 0 sum['j'] = 0 snd_buf['i'] = my_rank snd_buf['j'] = 10 * my_rank for i in range(size): # TODO: upravte metody 'Issend()'/'Recv()' tak, aby pouzivali novy typ. request = comm_world.Issend((snd_buf, 1, MPI.CHAR), right, 17) comm_world.Recv((rcv_buf, 1, MPI.CHAR), left, 17, status) request.Wait(status) np.copyto(snd_buf, rcv_buf) sum['i'] += rcv_buf['i'] sum['j'] += rcv_buf['j'] print(f"PE{my_rank}:\tSum = {sum['i']}\t{sum['j']}") |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
################################################################# # # # This file has been written as a sample solution to an # # exercise in a course given at the High Performance # # Computing Centre Stuttgart (HLRS). # # The examples are based on the examples in the MPI course of # # the Edinburgh Parallel Computing Centre (EPCC). # # It is made freely available with the understanding that # # every copy of this file must include this header and that # # HLRS and EPCC take no responsibility for the use of the # # enclosed teaching material. # # # # Authors: Joel Malard, Alan Simpson, (EPCC) # # Rolf Rabenseifner, Traugott Streicher, # # Tobias Haas (HLRS) # # # # Contact: rabenseifner@hlrs.de # # # # Purpose: A program with derived datatypes. # # # # Contents: Python code, buffer send version (comm.Send) # # # ################################################################# from mpi4py import MPI import numpy as np np_dtype = np.dtype([('i', np.intc), ('f', np.single)]) snd_buf = np.empty((), dtype=np_dtype) rcv_buf = np.empty_like(snd_buf) sum = np.empty_like(snd_buf) array_of_blocklengths = [None] * 2 array_of_displacements = [None] * 2 array_of_types = [None] * 2 status = MPI.Status() comm_world = MPI.COMM_WORLD my_rank = comm_world.Get_rank() size = comm_world.Get_size() right = (my_rank + 1) % size left = (my_rank - 1 + size) % size # Nastavte datove typy MPI pre posielanie a prijimanie ciastocnych suctov. # TODO: Nastavte pole 'blocklengths'. array_of_blocklengths[0] = 0 array_of_blocklengths[1] = 0 # TODO: Ziskajte absolutne adresy premennych v nupy strukture. addr_of_int = 0 addr_of_float = 0 # TODO: Nastavte displacement pola. Prva premenna ma displacement 0. array_of_displacements[0] = 0 array_of_displacements[1] = 0 # TODO: Nastavte hodnoty v poli typov. array_of_types[0] = None array_of_types[1] = None # TODO: Vytvorte novy typ struktury v MPI. Nezabudnite zaregistrovat definiciu # typu pred jeho prvym pouzitim. send_recv_type = None sum['i'] = 0 sum['f'] = 0 snd_buf['i'] = my_rank snd_buf['f'] = 10 * my_rank for i in range(size): # TODO: upravte funkcie 'Issend()'/'Recv()' tak, aby pouzivali novy typ. request = comm_world.Issend((snd_buf, 1, MPI.CHAR), right, 17) comm_world.Recv((rcv_buf, 1, MPI.CHAR), left, 17, status) request.Wait(status) np.copyto(snd_buf, rcv_buf) sum['i'] += rcv_buf['i'] sum['f'] += rcv_buf['f'] print(f"PE{my_rank}:\tSum = {sum['i']}\t{sum['f']}") |
