Λ10 Παράλληλος & Κατανεμημένος Προγραμματισμός Μάθημα 8 ο & 9 ο 1 & 8/12/2009

Σχετικά έγγραφα
Κεφάλαιο VIΙΙ Β. Δημακόπουλος

3/5/2012 Συστήματα κατανεμημένης μνήμης και ο προγραμματισμός τους (ΙI) Β. Δημακόπουλος

Υ07 Παράλληλα Συστήματα /5/2016 Προγραμματισμός με μεταβίβαση μηνυμάτων

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Μεταβίβαση μηνυμάτων. Κεφάλαιο 5 (νέο βιβλίο) Κεφάλαιο 8 (παλιές σημειώσεις)

30/4/2012 Συστήματα κατανεμημένης μνήμης και ο προγραμματισμός τους (Ι) Β. Δημακόπουλος

Λ10 Παράλληλος & Κατανεμημένος Προγραμματισμός 2009

MPI: Βαςικζσ Εντολζσ Επικοινωνίασ. Κώςτασ Διαμαντάρασ Τμιμα Πλθροφορικισ ΤΕΙ Θεςςαλονίκθσ 2011

Non-blocking Επικοινωνίεσ και Buffering. Κώςτασ Διαμαντάρασ ΤΕΙ Θεςςαλονίκθσ 2011

ύο μηχανισμοί απαιτούνται: 1. Μία μέθοδος για τη δημιουργία διεργασιών

Προγραμματισμός με Μεταβίβαση Μηνυμάτων

17. Πολυδιάςτατοι πίνακεσ

Ανταλλαγι Μθνυμάτων. Κϊςτασ Διαμαντάρασ Τμιμα Πλθροφορικισ ΤΕΙ Θεςςαλονίκθσ

ςυςτιματα γραμμικϊν εξιςϊςεων

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Δείκτεσ Διαχείριςθ Μνιμθσ. Βαγγζλθσ Οικονόμου Διάλεξθ 8

Τφποι δεδομζνων MPI. Κώςτασ Διαμαντάρασ Τμιμα Πλθροφορικισ ΤΕΙ Θεςςαλονίκθσ

Αρχιτεκτονική κοινής μνήμης

16. Πίνακεσ και Συναρτήςεισ

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Κατανεμημένος και Παράλληλος Προγραμματισμός MPI. MPI Απλές εντολές 03/13/2016. Οδηγίες αποστολής / παραλαβής μηνυμάτων, Υπολογισμός του π (

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

ΕΡΓΑΣΗΡΙΑΚΗ ΑΚΗΗ 4.1

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Δομθμζνοσ Προγραμματιςμόσ. Βαγγζλθσ Οικονόμου Εργαςτιριο 9

Ένα πρόβλθμα γραμμικοφ προγραμματιςμοφ βρίςκεται ςτθν κανονικι μορφι όταν:

Αςφάλεια και Προςταςία Δεδομζνων

5 ΜΕΘΟΔΟΙ - ΠΑΡΑΜΕΤΡΟΙ

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Συστήματα Παράλληλης και Κατανεμημένης Επεξεργασίας

ΛΕΙΣΟΤΡΓΙΚΆ ΤΣΉΜΑΣΑ. 3 ο Εργαςτιριο υγχρονιςμόσ Διεργαςιϊν

Παράςταςη ςυμπλήρωμα ωσ προσ 1

Πωσ δθμιουργώ φακζλουσ;

Message Passing Interface (MPI)

Κάνουμε κλικ ςτθν επιλογι του οριηόντιου μενοφ «Get Skype»για να κατεβάςουμε ςτον υπολογιςτι μασ το πρόγραμμα του Skype.

Παράςταςη ακεραίων ςτο ςυςτημα ςυμπλήρωμα ωσ προσ 2

Multi Logo. Προγραμματιςμόσ Η/Υ με Multi Logo. Σχεδίαςη και ανάπτυξη εφαρμογήσ κίνηςησ αντικειμζνου

Συστήματα Παράλληλης & Κατανεμημένης Επεξεργασίας

Γράφοι. Δομζσ Δεδομζνων Διάλεξθ 9

Προγραμματιςμόσ Μεκόδων Επίλυςθσ Προβλθμάτων. 15. Πίνακεσ ΙI. Ιωάννθσ Κατάκθσ. ΕΠΛ 032: Προγραμματιςμόσ Μεκόδων Επίλυςθσ Προβλθμάτων

Διαδικαςία Διαχείριςθσ Στθλϊν Βιβλίου Εςόδων - Εξόδων. (v.1.0.7)

Δομζσ Αφαιρετικότθτα ςτα Δεδομζνα

Message Passing Interface (MPI)

Υπολογισμοί Μεταβίβασης Μηνυμάτων

ΕΦΑΡΜΟΓΕ ΒΑΕΩΝ ΔΕΔΟΜΕΝΩΝ ΣΗ ΝΟΗΛΕΤΣΙΚΗ. Φιλιοποφλου Ειρινθ

Συστήµατα Παράλληλης Επεξεργασίας. Message Passing Interface (MPI)

ΕΝΟΤΗΤΑ 2: ΤΟ ΛΟΓΙΣΜΙΚΟ ΤΟΥ ΥΠΟΛΟΓΙΣΤΗ. ΚΕΦΑΛΑΙΟ 5: Γνωριμία με το λογιςμικό του υπολογιςτι

ΑΝΣΙΣΡΟΦΗ ΤΝΑΡΣΗΗ. f y x y f A αντιςτοιχίηεται ςτο μοναδικό x A για το οποίο. Παρατθριςεισ Ιδιότθτεσ τθσ αντίςτροφθσ ςυνάρτθςθσ 1. Η. f A τθσ f.

ΗΛΕΚΣΡΟΝΙΚΗ ΤΠΗΡΕΙΑ ΑΠΟΚΣΗΗ ΑΚΑΔΗΜΑΪΚΗ ΣΑΤΣΟΣΗΣΑ

Άςκθςθ 1θ: Να γραφεί αλγόρικμοσ που κα δθμιουργεί με τθ βοικεια διπλοφ επαναλθπτικοφ βρόχου, τον ακόλουκο διςδιάςτατο πίνακα:

Εγχειρίδιο Χρήςησ Προςωποποιημζνων Υπηρεςιών Γ.Ε.ΜΗ. (Εθνικό Τυπογραφείο)

Προγραμματιςμόσ Μεκόδων Επίλυςθσ Προβλθμάτων. 19. Αλφαριθμητικά II. Ιωάννθσ Κατάκθσ. ΕΠΛ 032: Προγραμματιςμόσ Μεκόδων Επίλυςθσ Προβλθμάτων

Η γλώςςα προγραμματιςμού C

ΛΕΙΣΟΤΡΓΙΚΆ ΤΣΉΜΑΣΑ. 7 θ Διάλεξθ Διαχείριςθ Μνιμθσ Μζροσ Γ

ΕΦΑΡΜΟΓΖσ ΒΆΕΩΝ ΔΕΔΟΜΖΝΩΝ ΚΑΙ ΔΙΑΔΙΚΣΥΟΤ. Ειρινθ Φιλιοποφλου

Εγχειρίδιο Χρήςησ Προςωποποιημζνων Υπηρεςιών Γ.Ε.ΜΗ. (Περιφέρειες)

Εγχειρίδιο Χρήςησ Προςωποποιημζνων Υπηρεςιών Γ.Ε.ΜΗ. (Εθνικό Τυπογραφείο)

Μάκθςθ Κατανομϊν Πικανότθτασ και Ομαδοποίθςθ

Δομζσ Δεδομζνων Πίνακεσ

ΕΝΟΣΗΣΑ 1: ΓΝΩΡIΖΩ ΣΟΝ ΤΠΟΛΟΓΙΣΗ. ΚΕΦΑΛΑΙΟ 3: Εργονομία

ΘΕΜΑ Α /25 (A1)Χαρακτηρίςτε τισ παρακάτω προτάςεισ ωσ (Σ)ωςτζσ ή (Λ)άθοσ

MPI: Message Passing Interface

Δζντρα. Δομζσ Δεδομζνων

Σ ΤΑΤ Ι Σ Τ Ι Κ Η. Statisticum collegium V


Ηλεκτρονικι Υπθρεςία Ολοκλθρωμζνθσ Διαχείριςθσ Συγγραμμάτων και Λοιπϊν Βοθκθμάτων

Τοπολογίεσ. Κώςτασ Διαμαντάρασ Τμιμα Πλθροφορικισ ΤΕΙ Θεςςαλονίκθσ

ΕΚΔΟΣΗ 1.0 ΟΚΤΩΒΡΙΟΣ, 2017 ΕΙΣΑΓΩΓΗ ΣΤΑ ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ ΕΙΣΑΓΩΓΗ ΣΤO MESSAGE PASSING INTERFACE - MPI ΕΠΙΜΕΛΕΙΑ: Β. ΤΣΑΚΑΝΙΚΑΣ, Β.

ΕΝΟΤΗΤΑ 2: ΕΠΙΚΟΙΝΩΝΩ ΜΕ ΤΟΝ ΥΠΟΛΟΓΙΣΤΗ. ΚΕΦΑΛΑΙΟ 5: Αρχεία - Φάκελοι

Κατανεμημένος και Παράλληλος Προγραμματισμός MPI. Γρήγορος οδηγός αναφοράς 1/4/2017

Ε-85: Ειδικά Θέµατα Λογισµικού

Επικοινωνία. Message-Passing Interface (MPI) Βασικές Κλήσεις για Sockets. Μοντέλο Μεταβίβασης Μηνυµάτων. Μοντέλα Παράλληλου Υπολογισµού

ΕΡΓΑΣΗΡΙΟ ΕΦΑΡΜΟΜΕΝΗ ΠΛΗΡΟΦΟΡΙΚΗ

Virtualization. Στο ςυγκεκριμζνο οδηγό, θα παρουςιαςτεί η ικανότητα δοκιμήσ τησ διανομήσ Ubuntu 9.04, χωρίσ την ανάγκη του format.

ΘΥ101: Ειςαγωγι ςτθν Πλθροφορικι

Εγχειρίδιο Χρήςησ Support

Μάθημα 9 ο ΤΕΧΝΙΚΕΣ ΔΙΑΧΕΙΡΙΣΗΣ ΕΙΚΟΝΙΚΗΣ ΜΝΗΜΗΣ

Εισαγωγή. E-03: Λειτουργικά Συστήµατα ΙΙ 6. Εαρινό Εξάµηνο SUN RPC. Κλήση Αποµακρυσµένων ιαδικασιών (RPC) Σύνδεση: Port Mapper.

Ειςαγωγι ςτο Δομθμζνο Προγραμματιςμό. Βαγγζλθσ Οικονόμου

Οδηγίεσ προσ τουσ εκπαιδευτικοφσ για το μοντζλο τησ Αριθμογραμμήσ

ΟΔΗΓΙΕ ΓΙΑ ΣΗΝ ΕΙΑΓΩΓΗ ΕΚΔΡΟΜΩΝ & ΝΕΩΝ - ΑΝΑΚΟΙΝΩΕΩΝ ΣΗΝ ΙΣΟΕΛΙΔΑ ΣΗ Δ.Δ.Ε. ΘΕΠΡΩΣΙΑ

Πολυπλέκτες. 0 x 0 F = S x 0 + Sx 1 1 x 1

Ειδικά Θζματα Βάςεων Δεδομζνων

Διαχείριςθ του φακζλου "public_html" ςτο ΠΣΔ

Ρρογραμματιςμόσ Μεκόδων Επίλυςθσ Ρροβλθμάτων. 18. Αλφαριθμητικά. Ιωάννθσ Κατάκθσ. ΕΡΛ 032: Ρρογραμματιςμόσ Μεκόδων Επίλυςθσ Ρροβλθμάτων

Ειςαγωγι ςτθν Επιςτιμθ Υπολογιςτϊν. Ειςαγωγι ςτθν Python

Πανεπιςτιμιο Κφπρου ΟΙΚ 223: Μακθματικά για οικονομολόγουσ ΙΙ Διδάςκων:

Οδηγίεσ προσ τουσ εκπαιδευτικοφσ για το μοντζλο του Άβακα

ΛΕΙΤΟΥΓΙΚΆ ΣΥΣΤΉΜΑΤΑ. 5 ο Εργαςτιριο Ειςαγωγι ςτθ Γραμμι Εντολϊν

Οδηγίεσ για την πρόςβαςη των δικαιοφχων ςτο ΟΠΣΑΑ

MPI: Message Passing Interface

HY437 Αλγόριθμοι CAD

Ονοματεπϊνυμο.. ΔΙΑΓΩΝΙΣΜΑ ΑΕΠΠ

Visual C Express - Οδηγός Χρήσης

ΛΕΙΣΟΤΡΓΙΚΆ ΤΣΉΜΑΣΑ. 2 ο Εργαςτιριο Διαχείριςθ Διεργαςιϊν

ΟΔΗΓΙΕ ΔΗΜΙΟΤΡΓΙΑ ΚΑΙ ΡΤΘΜΙΗ ΔΩΡΕΑΝ ΗΛΕΚΣΡΟΝΙΚΟΤ ΣΑΧΤΔΡΟΜΕΙΟΤ ΣΟ GOOGLE (G-MAIL)

Εγκατάσταση & Διαχείριση Joomla στο Π.Σ.Δ. ΣΥΜΒΟΥΛΟ ΡΛΗΟΦΟΙΚΗΣ Ν. ΣΕΩΝ & ΚΕ.ΡΛΗ.ΝΕ.Τ. Ν. ΣΕΩΝ

ΧΗΥΙΑΚΟ ΔΚΠΑΙΔΔΤΣΙΚΟ ΒΟΗΘΗΜΑ «ΥΤΙΚΗ ΘΔΣΙΚΗ ΚΑΙ ΣΔΦΝΟΛΟΓΙΚΗ ΚΑΣΔΤΘΤΝΗ» ΦΥΣΙΚΗ ΘΔΤΙΚΗΣ ΚΑΙ ΤΔΧΝΟΛΟΓΙΚΗΣ ΚΑΤΔΥΘΥΝΣΗΣ ΘΔΜΑ Α ΘΔΜΑ Β

Διαδικασία με βήματα. 1. Αλλάηω το χρϊμα ςκθνικοφ ςε γκρι(#3333).

ΦΤΛΛΟ ΕΡΓΑΙΑ ΤΠΗΡΕΙΑ ΗΛΕΚΣΡΟΝΙΚΟΤ ΣΑΥΤΔΡΟΜΕΙΟΤ

Ιδιότθτεσ πεδίων Γενικζσ.

Transcript:

Λ10 Παράλληλος & Κατανεμημένος Προγραμματισμός 2009 Μάθημα 8 ο & 9 ο 1 & 8/12/2009 Προγραμματισμός με MPI Β. Δημακόπουλος

Τα βασικά

Βαςικζσ δομζσ Διεργαςίεσ Η πιο κοινι περίπτωςθ είναι να δθμιουργοφνται εξωτερικά mpirun np 10 a.out «SPMD» Για διαφοροποίθςθ των διεργαςιϊν: MPI_Comm_rank(MPI_COMM_WORLD, &myid); Ακολουκιακι αρίκμθςθ (0, 1, 2, ) MPI_Comm_size(MPI_COMM_WORLD, &nproc); Πλικοσ διεργαςιϊν ςυνολικά (το -np που δόκθκε παραπάνω) Αποςτολι μθνυμάτων MPI_Send(buf, n, dtype, torank, tag, MPI_COMM_WORLD); Λιψθ μθνυμάτων MPI_Recv(buf, n, dtype, fromrank, tag, MPI_COMM_WORLD, status); Παραλαβι ΜΟΝΟ ΕΦΟΟΝ: το μινυμα όντωσ ιρκε από τθ διεργαςία fromtag το μινυμα είχε όντωσ τθν ετικζτα tag #3

Βαςικι τεχνικι Επειδι δεν υπάρχει τίποτε κοινό ανάμεςα ςτισ διεργαςίεσ, κα υπάρχει αναγκαςτικά μία διεργαςία θ οποία: αρχικοποιεί τισ δομζσ μοιράηει τα δεδομζνα ςε άλλεσ ςυλλζγει τα επιμζρουσ αποτελζςματα και ίςωσ τα δείχνει ςτον χριςτθ τυλ προγραμματιςμοφ SPMD (Single-Program Multiple Data) Όλεσ οι διεργαςίεσ εκτελοφν το ίδιο πρόγραμμα Τπάρχει διαφοροποίθςθ μόνο με βάςθ το ID (rank) τθσ κάκε διεργαςίασ Λόγω τθσ διαμοίραςθσ των δεδομζνων, κάκε μία εργάηεται ςε διαφορετικά δεδομζνα #4

Παράδειγμα: υπολογιςμόσ του π #include <mpi.h> /* Μετάφραςη με mpicc */ main(int argc, char *argv[]) { float W, result = 0.0, temp; int N, i, myid, nproc; MPI_status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &nproc); /* Αρχικοποίηςη διαμοίραςη */ if (myid == 0) { printf( Enter number of divisions: ); scanf( %d\n, &N); for (i = 1; i < nproc; i++) MPI_Send(&N, 1, MPI_INT, i, 0, MPI_COMM_WORLD); else MPI_Recv(&N, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); /* Ο υπολογιςμόσ τησ κάθε διεργαςίασ */ W = 1.0 / N; for (i = myid; i < N; i += nproc) result += 4*W / (1 + (i+0.5)*(i+0.5)*w*w); /* Συλλογή αποτελεςμάτων */ if (myid == 0) { for (i = 1; i < nproc; i++) { MPI_Recv(&temp, 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD, &status); result += temp; printf( pi = %f\n, result); else MPI_Send(&temp, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD); MPI_Finalize(); #5

Τπολογιςμόσ του π Βελτίωςθ: Παραλαβι μθνυμάτων όπωσ καταφκάνουν Βελτίωςθ ςτθν ταχφτθτα, μείωςθ ανάγκθσ για buffering κλπ., αρκεί να το επιτρζπει ο αλγόριθμοσ. /* Συλλογή αποτελεςμάτων */ if (myid == 0) { for (i = 1; i < nproc; i++) { MPI_Recv(&temp, 1, MPI_FLOAT, i, 0, MPI_COMM_WORLD, &status); result += temp; printf( pi = %f\n, result); else MPI_Send(&temp, 1, MPI_FLOAT, 0, 0 MPI_COMM_WORLD); /* Συλλογή αποτελεςμάτων */ if (myid == 0) { for (i = 1; i < nproc; i++) { MPI_Recv(&temp, 1, MPI_FLOAT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); result += temp; printf( pi = %f\n, result); else MPI_Send(&result, 1, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Finalize(); MPI_Finalize(); #6

Παράδειγμα: πίνακασ επί διάνυςμα ειριακά: float A[N][N], v[n], res; for (i = 0; i < Ν; i++) { sum = 0.0; for (j = 0; j < Ν; j++) sum += Α[i][j]*v[j]; res[i] = sum; Θα χρθςιμοποιιςουμε τμθματικι δρομολόγθςθ ςτον βρόχο του i Όπωσ και ςτο μοντζλο κοινοφ χϊρου διευκφνςεων, θ κάκε διεργαςία κα εκτελζςει το παρακάτω: WORK = N / nprocs; /* Στοιχεία ανά διεργαςία */ sum = 0.0; for (i = 0; i < WORK; i++) { for (j = 0; j < Ν; j++) sum += Α[myid*WORK+i][j]*v[j]; #7

Πίνακασ επί διάνυςμα, ςυνζχεια Επίςθσ θ διεργαςία 0 κα «ςυλλζξει» όλα τα επιμζρουσ ςτοιχεία του αποτελζςματοσ από τισ άλλεσ διεργαςίεσ για να ςχθματίςει τθν τελικι απάντθςθ. Επομζνωσ, κάκε διεργαςία κα πρζπει ςτο τζλοσ να κάνει: /* Το sum έχει το (myid*work+i)-οςτό ςτοιχείο του αποτελέςματοσ */ MPI_Send(&sum, 1, MPI_FLOAT, 0, myid*work+i, MPI_COMM_WORLD); Σζλοσ, θ διεργαςία 0 κα πρζπει να κάνει τθν αρχικοποίθςθ, δθλαδι: να αρχικοποιιςει (π.χ. να διαβάςει από το πλθκτρολόγιο, από αρχείο) τα Α*+*+ και v[]. Να τα ςτείλει ςε όλεσ τισ άλλεσ διεργαςίεσ (υπενκφμιςθ: δεν υπάρχουν κοινζσ μεταβλθτζσ!) #8

Σελικόσ κϊδικασ: πίνακασ επί διάνυςμα (Ι) #define N 100 /* Η διάςταςη του πίνακα */ matrix_times_vector() { int i, j; int WORK = N / nprocs; /* Στοιχεία ανά διεργαςία */ float sum, v[ν]; MPI_Status status; if (myid == 0) /* Διεργαςία 0 */ { float A[N][N], res[n]; else /* του if (myid == 0) */ /* Υπόλοιπεσ διεργαςίεσ */ { float B[WORK][N]; initialize_elements(a, v); /* Κάποια αρχικοποίηςη */ for (i = 1; i < numprocs(); i++) { MPI_Send(A[i*WORK], WORK*N, MPI_FLOAT, i, 0, MPI_COMM_WORLD); MPI_Send(v, N, MPI_FLOAT, i, 0, MPI_COMM_WORLD); for (i = 0; i < WORK; i++) { for (sum = 0.0, j = 0; j < Ν; j++) sum += Α[i][j]*v[j]; res[i] = sum; /* Συλλογή των ςτοιχείων του αποτελέςματοσ */ for (i = WORK; i < WORK*nprocs; i++) { MPI_Recv(&sum, 1, MPI_FLOAT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); res[ status.mpi_tag ] = sum; /* Εξαγωγή τησ ετικέτασ */ show_result(res); /* Παρουςίαςη αποτελέςματοσ */ MPI_Recv(B, WORK*N, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &status); MPI_Recv(v, N, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &status); for (i = 0; i < WORK; i++) { for (j = 0; j < Ν; j++) sum += B[i][j]*v[j]; /* Το sum έχει το (myid*work+i)-οςτό ςτοιχείο του αποτελ. */ MPI_Send(&sum, 1, MPI_FLOAT, 0, myid*work+i, MPI_COMM_WORLD); #9

Βελτιςτοποίθςθ Οι επικοινωνίεσ είναι ο εχκρόσ τθσ ταχφτθτασ! Κοιτάμε να τισ αποφεφγουμε όςο γίνεται. Καλφτερα λίγα και μεγάλα μθνφματα, παρά πολλά και μικρά. Ομαδοποίθςθ μθνυμάτων όςο γίνεται. Διεργαςίεσ εκτόσ τθσ 0: { float B[WORK][N], mypart[n]; MPI_Recv(B, WORK*N, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, &status); MPI_Recv(v, N, MPI_FLOAT, 0, 0, MPI_COMM_WORLD, status); for (i = 0; i < WORK; i++) { for (j = 0; j < Ν; j++) sum += B[i][j]*v[j]; mypart[i] = sum; /* Το mypart περιέχει WORK ςτοιχεία, αρχίζοντασ από το (myid*work)-οςτό */ MPI_Send(mypart, WORK, MPI_FLOAT, 0, myid*work, MPI_COMM_WORLD); Διεργαςία 0: if (myid == 0) {... /* Συλλογή ςτοιχείων του αποτελέςματοσ */ for (i = 1; i < nprocs; i++) { /* Παραλαβή και εξαγωγή WORK ςτοιχείων */ MPI_Recv(v, WORK, MPI_FLOAT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); for (j = 0; j < WORK; j++) res[ j + status.mpi_tag ] = v[j]; show_result(res); #10

Τα συλλογικά

υλλογικζσ επικοινωνίεσ (collective communications) Εκτόσ από τθν επικοινωνία ενόσ ηεφγουσ διεργαςιϊν ( unicast communication ), υπάρχει πολφ ςυχνά ανάγκθ για επικοινωνία μεταξφ όλων των διεργαςιϊν μαηί. collective communications διάφορων ειδϊν Εκπομπι (broadcasting, one-to-all) ίδιο μινυμα από μία διεργαςία προσ όλεσ τισ άλλεσ #12

υλλογικζσ επικοινωνίεσ Διαςκόρπιςθ (scattering, personalized one-to-all) διαφορετικά μθνφματα από μία διεργαςία προσ όλεσ τισ άλλεσ υλλογι (gathering, personalized all-to-one) ( αντίκετο τθσ διαςκόρπιςθσ ) μία διεργαςία λαμβάνει ζνα μινυμα από κάκε μία από τισ υπόλοιπεσ #13

υλλογικζσ επικοινωνίεσ??? Πολλά πικανά ονόματα: πολλαπλι εκπομπι (multinode ι all-to-all broadcasting) Όλεσ εκτελοφν εκπομπι (ι όλεσ εκτελοφν το ίδιο gather) το MPI λζγεται allgather #14

υλλογικζσ επικοινωνίεσ??? Πικανά ονόματα: ολικι ανταλλαγι (multinode gather/scatter ι all-to-all personalized ι total exchange) ( όλεσ οι διεργαςίεσ εκτελοφν τθ δικι τουσ διαςκόρπιςθ ) κάκε διεργαςία ζχει διαφορετικό μινυμα για κάκε άλλθ το MPI λζγεται alltoall #15

Παράδειγμα ε πολλζσ εφαρμογζσ απαιτείται θ λφςθ ενόσ ςυςτιματοσ εξιςϊςεων και θ ςυνικθσ τακτικι για τθ λφςθ του είναι οι λεγόμενεσ «επαναλθπτικζσ μζκοδοι». Αυτζ πολφ απλά προςεγγίηουν ςταδιακά τθ λφςθ x(), μζςω επαναλιψεων τθσ μορφισ: x(t+1) = A x(t) ξεκινϊντασ από μία αρχικι εκτίμθςθ x(0). To x() είναι διάνυςμα με Ν ςτοιχεία και το Α είναι πίνακασ ΝxΝ. Άρα ςε κάκε επανάλθψθ απαιτείται πολλαπλαςιαςμόσ πίνακα επί διάνυςμα. #16

Παράδειγμα, ςυνζχεια Μία ςτρατθγικι αποκικευςθσ των Α και x(): Κατά γραμμζσ ο Α (π.χ. θ διεργαςία i ζχει τθ γραμμι i του Α) Κάκε διεργαςία ζχει όλο το τρζχον x() Αρχικά, κάποια διεργαςία πρζπει: να ςτείλει ςε όλεσ τισ άλλεσ τθν αρχικι εκτίμθςθ (το x(0)). (εκπομπή) να ςτείλει ςτθν διεργαςία i τθν i-οςτι γραμμι του Α (για κάκε i). (διαςκόρπιςη) #17

Παράδειγμα, ςυνζχεια ε κάκε επανάλθψθ: Η διεργαςία i πολλαπλαςιάηει τθ γραμμι του A που ζχει με το x(t) που επίςθσ ζχει και υπολογίηει το i-οςτό ςτοιχείο του νζου x, δθλαδι το x i (t+1). Θα πρζπει να ςχθματίςει ολόκλθρο το x(t), προφανϊσ από τα ςτοιχεία που υπολόγιςαν οι άλλεσ διεργαςίεσ (πολλαπλή εκπομπή ή allgather) Αν απαιτθκεί αναςτροφή του Α (οι γραμμζσ να γίνουν ςτιλεσ και οι ςτιλεσ γραμμζσ), τότε θ διεργαςία i κα ζχει μόνο το ςτοιχείο A ii. Σο Α 0i το ζχει θ διεργαςία 0, το Α 1i το ζχει θ διεργαςία 1, το Α ki το ζχει θ διεργαςία k. Πρζπει να ςυλλζξει αυτά τα ςτοιχεία από όλεσ τισ άλλεσ διεργαςίεσ Σο ίδιο κάνουν, όμωσ, όλεσ, για τισ δικζσ τουσ ςτιλεσ (ολική ανταλλαγή ή alltoall) #18

Άλλεσ ςυλλογικζσ επικοινωνίεσ/υπολογιςμοί Λειτουργίεσ υποβίβαςθσ (reduction operations) Από ζνα μζγεκοσ μεγαλφτερθσ διάςταςθσ (π.χ. διάνυςμα) «υποβιβαηόμαςτε» ςε μζγεκοσ μικρότερθσ διάςταςθσ (π.χ. βακμωτό) global sum, product, εφρεςθ max, min κλπ Κλιςθσ φραγισ (barrier calls) Μερικι εμπομπι (multicast) Εκπομπι μόνο ςε μερικζσ διεργαςίεσ, όχι ςε όλεσ Είναι πιο «δφςκολθ» επικοινωνία από τθν ολικι εκπομπι (!) και άλλεσ... #19

Κλιςεισ Σθν ίδια κλιςθ κάνουν όλεσ οι διεργαςίεσ MPI_Bcast(buf, n, dtype, rootrank,mpi_comm_world); το rootrank δθλϊνει ποιοσ κάνει τθν εκπομπι MPI_Scatter(sbuf, sn, stype, rbuf, rn, rtype, rootrank, MPI_COMM_WORLD); Μόνο για τθν πθγι μετράνε τα 3 πρϊτα ορίςματα Σο sn είναι ο # ςτοιχείων που κα ςταλεί ςε κάκε διεργαςία (περιλαμβανομζνης και της πηγής) και πρζπει να είναι ίδιοσ με το rn. Άρα αν υπάρχουν Ν διεργαςίεσ, το sbuf πρζπει να ζχει Ν*sn ςτοιχεία. Κάκε διεργαςία παραλαμβάνει τα ςτοιχεία τθσ ςτο rbuf MPI_Gather(sbuf, sn, stype, rbuf, rn, rtype, targetrank, MPI_COMM_WORLD); Μόνο για τθ διεργαςία-αποδζκτθ μετράνε τα ορίςματα 4-6 Σο sn είναι ο # ςτοιχείων που κα ςταλεί θ κάκε διεργαςία (περιλαμβανομζνης και του αποδζκτη). MPI_Allgather(sbuf, sn, stype, rbuf, rn, rtype, MPI_COMM_WORLD); Κδια με MPI_Gather() μόνο που όλεσ οι διεργαςίεσ πρζπει να ζχουν receive buffer #20

Κλιςεισ, ςυνζχεια MPI_Alltoall(sbuf, sn, stype, rbuf, rn, rtype, MPI_COMM_WORLD); Παρόμοιεσ παράμετροι με με MPI_Allgather() MPI_Reduce(sbuf, rbuf, n, dtype, op, targetrank, MPI_COMM_WORLD); το op είναι MPI_MAX/MIN/SUM/PROD/LAND/BAND/LOR/BOR/LXOR/BXOR (αν και μπορεί κανείσ να ορίςει και δικά του) τζλοσ υπάρχουν και τα MPI_MINLOC και MPI_MAXLOC που μαηί με το min/max επιςτρζφουν το rank τθσ διεργαςίασ που το διακζτει Όλες οι διεργαςίεσ πρζπει να διακζτουν send & receive buffer (sbuf & rbuf) Η λειτουργία, αν το n είναι > 1, γίνεται ςε κάκε ςτοιχείο ξεχωριςτά MPI_Allreduce(sbuf, rbuf, n, dtype, op, MPI_COMM_WORLD); Κδια με MPI_Reduce() μόνο που όλεσ οι διεργαςίεσ παίρνουν το αποτζλεςμα και άλλεσ #21

Παράδειγμα: «κυριλζ» ( )υπολογιςμόσ του π #include <mpi.h> /* Μετάφραςη με mpicc */ main(int argc, char *argv[]) { float W, result = 0.0, temp; pi; int N, i, myid, nproc; MPI_status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myid); MPI_Comm_size(MPI_COMM_WORLD, &nproc); /* Αρχικοποίηςη διαμοίραςη */ if (myid == 0) { printf( Enter number of divisions: ); scanf( %d\n, &N); for (i = 1; i < nproc; i++) MPI_Bcast(&N, MPI_Send(&N, 1, MPI_INT, 1, MPI_INT, 0, MPI_COMM_WORLD); i, 0, MPI_COMM_WORLD); else /* Ο υπολογιςμόσ τησ κάθε διεργαςίασ */ W = MPI_Recv(&N, 1.0 / N; 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); for (i = myid; i < N; i += nproc) /* result Ο υπολογιςμόσ += 4*W / τησ (1 + κάθε (i+0.5)*(i+0.5)*w*w); διεργαςίασ */ W = 1.0 / N; for (i = myid; i < N; i += nproc) result += 4*W / (1 + (i+0.5)*(i+0.5)*w*w); /* Συλλογή αποτελεςμάτων */ MPI_Reduce(&result, if (myid == 0) { &pi, 1, MPI_FLOAT, for (i = 1; MPI_SUM, i < nproc; 0, MPI_COMM_WORLD); i++) { if (myid MPI_Recv(&temp, == 0) 1, MPI_FLOAT, i, 0, printf( pi = %f\n, MPI_COMM_WORLD, result); &status); result += temp; MPI_Finalize(); printf( pi = %f\n, result); else MPI_Send(&temp, 1, MPI_FLOAT, 0, 0, MPI_COMM_WORLD); MPI_Finalize(); #22

Παράδειγμα: πίνακασ επί διάνυςμα (ΙΙ) ςυλλογικά matrix_times_vector() { int i, j; int WORK = N / nprocs; /* Στοιχεία ανά διεργαςία */ float sum, v[ν], A[N][N], **B; if (myid == 0) initialize_elements(a, v, N); B = allocmatrix(work, N); mypart = allocvector(work); MPI_Scatter(Α, WORK*N, MPI_FLOAT, B, WORK*N, MPI_FLOAT, 0, MPI_COMM_WORLD); MPI_Bcast(v, N, MPI_FLOAT, 0, MPI_COMM_WORLD); for (i = 0; i < WORK; i++) { for (sum = 0.0, j = 0; j < Ν; j++) sum += B[i][j]*v[j]; mypart[i] = sum; MPI_Gather(mypart, WORK, MPI_FLOAT, res, WORK, MPI_FLOAT, 0, MPI_COMM_WORLD); if (myid == 0) show_result(res); #23

Τα ασφαλή

Προβλιματα; Δφο διεργαςίεσ ανταλλάςουν δεδομζνα: P0: MPI_Send(&a, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); MPI_Recv(&b, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status); P1: MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); MPI_Send(&b, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); Μία χαρά! Σο επόμενο; P0: MPI_Recv(&b, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status); MPI_Send(&a, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); P1: MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); MPI_Send(&b, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); deadlock! #25

Αςφάλεια Αυτό; P0: MPI_Send(&a, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); MPI_Recv(&b, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status); P1: MPI_Send(&b, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); Είναι εντάξει ΜΟΝΟ εφόςον υπάρχουν αρκετοί buffers (ςτθ μεριά του παραλιπτθ) να φυλάνε τα μθνφματα που ςτάλκθκαν (μζχρι να τθν οριςτικι παραλαβι τουσ) Αν δεν υπάρχει χϊροσ, τότε το MPI «μπλοκάρει» μζχρι να βρεκεί χϊροσ ςτον παραλιπτθ Αν οι buffers και των δφο διεργαςιϊν είναι «γεμάτοι», τότε DEADLOCK! Άρα θ ορκότθτα / αςφάλεια του κϊδικα εξαρτάται από το ποςό των διακζςιμων buffers ΜΗ ΑΦΑΛΕ ΠΡΟΓΡΑΜΜΑ Παρόμοια περίπτωςθ είναι και όταν Ν διεργαςίεσ ανταλλάςουν κυκλικά από ζνα δεδομζνο (θ i ςτζλνει ςτθν i+1 και λαμβάνει από τθν i-1). Ποιά είναι θ αςφαλζςτερθ υλοποίθςθ; Οι άρτιεσ διεργαςίεσ αρχικά λαμβάνουν και ςτθ ςυνζχεια ςτζλνουν Οι περιττζσ κάνουν το ανάποδο odd-even rule #26

υναρτιςεισ που παρζχουν αςφάλεια Όταν κάκε διεργαςία ςτζλνει & λαμβάνει, το MPI παρζχει μία ςυνάρτθςθ ϊςτε να μθν τίκεται κζμα αςφάλειασ: MPI_Sendrecv(sbuf, sn, sdtype, torank, stag, rbuf, rn, rdtype, fromrank, rtag, MPI_COMM_WORLD, status); Αυτι θ ςυνάρτθςθ μπορεί επίςθσ να παραλάβει και μθνφματα που ςτάλκθκαν με απλό MPI_Send(), ενϊ το μινυμα που ςτζλνεται από αυτιν μπορεί να παραλθφκεί και με απλό MPI_Recv() Αν κζλουμε ο buffer αποςτολισ & λιψθσ να είναι ο ίδιοσ, τότε: MPI_Sendrecv_replace(buf, n, dtype, torank, stag, fromrank, rtag, MPI_COMM_WORLD, status); #27

Τα προχωρημέμα

Communicators Αν κζλω να ορίςω γκρουπ διεργαςιϊν τότε δθμιουργϊ ζναν communicator και οι επικοινωνίεσ που γίνονται με αυτόν αφοροφν μόνο διεργαςίεσ του γκρουπ. O MPI_COMM_WORLD αφορά το γκρουπ ΟΛΩΝ των διεργαςιϊν που υπάρχουν. ε όλεσ τισ κλιςεισ που είδαμε, μπορεί κανείσ να αντικαταςτιςει το MPI_COMM_WORLD με όποιον άλλον δικόν του ζχει δθμιουργιςει τα send/receive με άλλον communicator απευκφνονται μόνο ςτισ διεργαςίεσ του αντίςτοιχου γκρουπ. ε κάκε γκρουπ/communicator, οι διεργαςίεσ ζχουν ακολουκιακό rank. Κάκε διεργαςία ανικει ςτο MPI_COMM_WORLD και πικανϊσ ςε πολλά άλλα communicators Αν μία διεργαςία ανικει ςε ζναν communicator comm, τότε δεν ςθμαίνει ότι τα myid1 και myid2 είναι οπωςδιποτε ίδια: MPI_Comm_rank(MPI_COMM_WORLD, &myid1); MPI_Comm_rank(comm, &myid2); #29

Άλλθ μία ανάγκθ Εκτόσ από τθν μεριά του χριςτθ, υπάρχει και άλλθ μία ανάγκθ για communicators: Σο MPI εγγυάται ότι τα μθνφματα φτάνουν ςτθν διεργαςία-παραλιπτθ, με τθ ςειρά που ςτάλκθκαν από τθ διεργαςία-αποςτολζα. Και οι δφο διεργαςίεσ χρθςιμοποιοφν μία βιβλιοκικθ θ οποία ςτζλνει/λαμβάνει τα δικά τθσ μθνφματα. Φανταςτείτε ότι ο αποςτολζσ κάνει μία κλιςθ ςε αυτιν μετά το send ενϊ ο παραλιπτθσ κάτι χρειάςτθκε από τθ βιβλιοκικθ πριν το receive. Σι κα γίνει; #30

βιβλιοκικεσ που δεν ελζγχονται από τον χριςτθ Δεν μπορείσ να βαςιςτείσ ςτα tags διότι δεν γνωρίηεισ τι tags χρθςιμοποιεί θ βιβλιοκικθ. Επίςθσ δεν μπορείσ να βαςιςτείσ ςτα ranks μιασ και οι διεργαςίεσ καλοφν ςυναρτιςεισ τθσ βιβλιοκικθσ (θ βιβλιοκικθ δεν είναι ξεχωριςτι διεργαςία είναι απλά ζνα ςφνολο ρουτινϊν) Λφςθ: communicators Οι βιβλιοκικεσ, για αυτοφσ τουσ λόγουσ, εςωτερικά δθμιουργοφν «ιδιωτικό» communicator και όλεσ οι αποςτολζσ/λιψεισ γίνονται μζςω αυτοφ Ζτςι δεν υπάρχει περίπτωςθ να «μπερδευτοφν» με τα μθνφματα των διεργαςιϊν του χριςτθ. #31

Φτιάχνοντασ communicators Νζοσ communicator φτιάχνεται (αυτόματα) όταν δθμιουργοφνται τοπολογίεσ (παρακάτω ) Ζνασ άλλοσ τρόποσ είναι να «χωρίςεισ» τισ διεργαςίεσ από ζναν υπάρχοντα communicator: MPI_Comm_split(oldcomm, int color, int key, &newcomm); Π.χ. MPI_Comm_split(MPI_COMM_WORLD, int color, int key, &newcomm); Είναι ςυλλογική διαδικαςία. Πρζπει ΟΛΕ οι διεργαςίεσ του oldcomm να τθν καλζςουν! Όςεσ διεργαςίεσ δϊςουν το ίδιο color κα είναι ςτον ίδιο νζο communicator Άρα φτιάχνονται τόςοι νζοι communicators όςα και τα διαφορετικά colors Σο rank κάκε διεργαςίασ ςτον νζο communicator που κα ανικει κακορίηεται από το key. ε ιςοπαλία, χρθςιμοποιείται θ κατάταξθ ςτον παλιό communicator #32

Σοπολογίεσ διεργαςιϊν Κανονικά οι διεργαςίεσ αρικμοφνται ακολουκιακά (γραμμικά) 0, 1, Ν-1. Πολλζσ φορζσ κζλουμε μία διαφορετικι αρίκμθςθ το MPI μποροφμε να ορίςουμε εικονικζσ «τοπολογίεσ» Η κάκε διεργαςία ζχει τθ δικι τθσ αρίκμθςθ (ετικζτα) ςτθν κάκε τοπολογία Σοπολογίεσ καρτεςιανοφ γινομζνου μόνο (πλζγματα και tori) Η νζα τοπολογία ΔΕΝ είναι πλζον αυτι του MPI_COMM_WORLD! Ορίηεται ζνασ νζοσ communicator για τθν τοπολογία αυτι Επίςθσ, μπορεί το MPI να τισ χρθςιμοποιιςει ϊςτε να κάνει καλφτερο mapping με τθν τοπολογία του δικτφου (ο χριςτθσ δεν ζχει ζλεγχο πάνω ςε αυτι τθν αντιςτοίχιςθ) #33

Δθμιουργία καρτεςιανϊν τοπολογιϊν Δθμιουργοφμε καρτεςιανζσ τοπολογίεσ (πλζγματα) με: MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods, int reorder, MPI_Comm *comm_cart) Οι διεργαςίεσ που ανικουν ςτον παλιό communicator δθμιουργοφν ζνα νζο communicator με τοπολογία πλζγματοσ ndims διαςτάςεων. Αν το periods[i] είναι 1, τότε θ διάςταςθ i κα είναι δακτφλιοσ (κφκλοσ) Αν το reorder είναι 0, οι διεργαςίεσ κα κρατιςουν το ίδιο (ακολουκιακό) rank που είχαν και ςτον παλιό communicator. Κάκε διεργαςία κα ζχει ωσ «ταυτότθτα» μία ndims-άδα, δθλαδι ζνα διάνυςμα ndims ςτοιχείων («ςυντεταγμζνεσ» ςε κάκε διάςταςθ). ζχοντασ φυςικά και το κλαςικό ακολουκιακό ranks τθσ #34

Σοπολογίεσ (0,0) (0,1) (0,2) (0,3) 0 1 2 3 (0,0) (0,1) (0,2) (0,3) 4 5 6 7 (1,0) (1,1) (1,2) (1,3) (2,0) (2,1) (2,2) (2,3) (1,0) (1,1) (1,2) (1,3) 8 9 10 11 (2,0) (2,1) (2,2) (2,3) (3,0) (3,1) (3,2) (3,3) (με μπλε τα ranks) ndims =2 dims[0]=4, dims[1]=4 periods[0]=1, periods[1]=1 ndims =2 dims[0]=3, dims[1]=4 periods[0]=0, periods[1]=0 #35

Χρθςιμοποιϊντασ καρτεςιανζσ τοπολογίεσ Μιασ και τα send/receive εξακολουκοφν να απαιτοφν ranks ωσ ορίςματα, το MPI παρζχει ρουτίνεσ μετατροπισ μεταξφ ranks και πολυδιάςτατων ςυντεταγμζνων: MPI_Cart_coords(MPI_Comm cartcomm, int rank, int ndims, int *coords) MPI_Cart_rank(MPI_Comm cartcomm, int *coords, int *rank) για «περιοδικζσ» διαςτάςεισ, αν θ ςυντεταγμζνθ είναι εκτόσ ορίων, υπολογίηεται modulo ςτο μζγεκοσ τθσ διάςταςθσ Από τισ πιο ςυνθκιςμζνεσ ενζργειεσ ςε καρτεςιανζσ τοπολογίεσ είναι θ κυκλικι μεταφορά δεδομζνων (shift). Κάκε διεργαςία μπορεί να υπολογίςει άμεςα τον προοριςμό και τθν πθγι που τθν αφοροφν με: MPI_Cart_shift(MPI_Comm cartcomm, int dir, int s_step, int *rank_source, int *rank_dest) Σο direction είναι θ διάςταςθ ςτθν οποία κα γίνει το shift (αρίκμθςθ από το 0). Σο s_step είναι το μζγεκοσ (# κζςεων) του shift (κετικό ι αρνθτικό). Τα αποτελζςματα μποροφν να χρηςιμοποιηθοφν άμεςα ςε MPI_Sendrecv(). #36

Εφαρμογή: ο αλγόριθμος του Cannon για πολλαπλασιασμό πιμάκωμ

Πολλαπλαςιαςμόσ Α*v Αρχικι τοποκζτθςθ ςτοιχείων (πλζγμα/torus) Α 00 V0 A 01 A 02 A 03 A 10 V1 A 11 A 12 A 13 A 20 V2 A 21 A 22 A 23 A 30 V3 A 31 A 32 A 33 #38

Τπολογιςμόσ 1 ου ςτοιχείου του A*v Α 00 V 0 A 01 A 02 A 03 Α 01 V 1 A 02 A 03 A 00 V 1 V 2 (α) (β) V 2 V 3 V 3 V 0 Α 02 V 2 A 03 A 00 A 01 Α 03 V 3 A 00 A 01 A 02 (γ) V 3 (δ) V 0 V 0 V 1 V 1 V 2 #39

Σι λείπει για να υπολογιςτεί το 2 ο ςτοιχείο; Να γίνει το αντίςτοιχο με τθν γραμμι 1 του Α Όμωσ πρζπει να ξεκινιςουμε από το A[1][1]*v[1], μιασ και το v[1] είναι αυτό που υπάρχει ςτθν γραμμι 1. Πϊσ; Απάντθςθ: *πριν* ξεκινιςει ο αλγόρικμοσ, κάνουμε τθ γραμμι 1 SHIFT (rotate) 1 κζςθ προσ τα αριςτερά. Από εκεί και φςτερα, ο υπολογιςμόσ του v[1] γίνεται ταυτόχρονα με αυτόν του v[0]! Γενικά: Φάςθ 1: προετοιμαςία Η γραμμι i ολιςκάνει i κζςεισ αριςτερά (ϊςτε το Α*i][i] να βρεκεί μαηί με το v[i]) Φάςθ 2: υπολογιςμόσ LOOP (N φορζσ): 1. ε κάκε επεξεργαςτι (i, 0) υπολογίηεται το γινόμενο του υπάρχοντοσ ςτοιχείου του πίνακα Α με το υπάρχον ςτοιχείο του διανφςματοσ v. 2. Ολίςκθςθ του διανφςματοσ v προσ τα πάνω 3. Ολίςκθςθ κάκε γραμμισ του Α προσ τα αριςτερά #40

A*v αρχικζσ τοποκετιςεισ & 1 ο βιμα Α 00 V 0 A 01 A 02 A 03 Α 01 V 1 A 02 A 03 A 00 Α 11 V 1 Α 12 Α 13 Α 10 Α 12 V 2 Α 13 Α 10 Α 11 Α 22 V 2 Α 23 Α 20 Α 21 Α 23 V 3 Α 20 Α 21 Α 22 Α 33 V 3 Α 30 Α 31 Α 32 Α 30 V 0 Α 31 Α 32 Α 33 #41

Γενίκευςθ ςε Α*Β (αλγόρικμοσ Cannon) Αρχικά, κάκε γραμμι i του πίνακα Α ολιςκαίνει κατά i κζςεισ αριςτερά και Α 00 Β00 A 01 Β11 A 02 B22 A 03 B33 κάκε ςτιλθ j του πίνακα Β ολιςκαίνει κατά j κζςεισ προσ τα πάνω Α 11 Β10 Α 12 Β21 Α 13 B32 Α 10 B03 τθ ςυνζχεια γίνονται n επαναλιψεισ, όπου ςε κάκε επανάλθψθ, κάκε επεξεργαςτισ πολλαπλαςιάηει τα δφο ςτοιχεία που διακζτει, ακροίηει και Α 22 Β20 Α 23 Β31 Α 20 B02 Α 21 B13 κάκε γραμμι (ςτιλθ) ολιςκαίνει προσ τα αριςτερά (πάνω). Α 33 Β30 Α 30 Β01 Α 31 B12 Α 32 B23 Σελικά ςτον επεξεργαςτι (i, j) κα βρεκεί το ςτοιχείο C ij του αποτελζςματοσ. #42

Τλοποίθςθ ςε MPI Σοπολογία πλζγματοσ 2D απαραίτθτθ για τον εφκολο χειριςμό Χρθςιμοποιεί blocks του πίνακα (όχι απλά ςτοιχεία). Δθλαδι θ κάκε διεργαςία ςε κάκε βιμα δεν πολλαπλαςιάηει ζνα ςτοιχείο του Α με ζνα ςτοιχείο του Β αλλά ζναν υποπίνακα του Α με ζναν υποπίνακα του Β (δεν αλλάηει ςε κάτι ο αλγόρικμοσ) τθν επόμενθ ςελίδα Σα a και b είναι οι υποπίνακεσ που διακζτει αρχικά κάκε διεργαςία #43

MatrixMatrixMultiply(int n, double *a, double *b, double *c, MPI_Comm comm) { int i, nlocal; int npes, dims[2], periods[2]; int myrank, my2drank, mycoords[2]; int uprank, downrank, leftrank, rightrank, coords[2]; int shiftsource, shiftdest; MPI_Status status; MPI_Comm comm_2d; /* Get the communicator related information */ MPI_Comm_size(comm, &npes); MPI_Comm_rank(comm, &myrank); /* Set up the Cartesian topology */ dims[0] = dims[1] = sqrt(npes); /* Set the periods for wraparound connections */ periods[0] = periods[1] = 1; /* Create the Cartesian topology, with rank reordering */ MPI_Cart_create(comm, 2, dims, periods, 1, &comm_2d); /* Get the rank and coordinates in he new topology */ MPI_Comm_rank(comm_2d, &my2drank); MPI_Cart_coords(comm_2d, my2drank, 2, mycoords); /* Compute ranks of the up and left shifts */ MPI_Cart_shift(comm_2d, 0, -1, &rightrank, &leftrank); MPI_Cart_shift(comm_2d, 1, -1, &downrank, &uprank); /* Determine the dimension of the local matrix block */ nlocal = n/dims[0]; /* Perform the initial matrix alignment B */ MPI_Cart_shift(comm_2d, 0, -mycoords[0], &shiftsource, &shiftdest); MPI_Sendrecv_replace(a, nlocal*nlocal, MPI_DOUBLE, shiftdest, 1, shiftsource, 1, comm_2d, &status); MPI_Cart_shift(comm_2d, 1, -mycoords[1], &shiftsource, &shiftdest); MPI_Sendrecv_replace(b, nlocal*nlocal, MPI_DOUBLE, shiftdest, 1, shiftsource, 1, comm_2d, &status); /* Get into the main computation loop */ for (i=0; i<dims[0]; i++) { MatrixMultiply(nlocal, a, b, c); /*c=c+a*b*/ /* Shift matrix a left by one */ MPI_Sendrecv_replace(a, nlocal*nlocal, MPI_DOUBLE, leftrank, 1, rightrank, 1, comm_2d, &status); /* Shift matrix b up by one */ MPI_Sendrecv_replace(b, nlocal*nlocal, MPI_DOUBLE, uprank, 1, downrank, 1, comm_2d, &status); /* Restore the original distribution of a and b */ MPI_Cart_shift(comm_2d, 0, +mycoords[0], &shiftsource, &shiftdest); MPI_Sendrecv_replace(a, nlocal*nlocal, MPI_DOUBLE, shiftdest, 1, shiftsource, 1, comm_2d, &status); MPI_Cart_shift(comm_2d, 1, +mycoords[1], &shiftsource, &shiftdest); MPI_Sendrecv_replace(b, nlocal*nlocal, MPI_DOUBLE, shiftdest, 1, shiftsource, 1, comm_2d, &status); MPI_Comm_free(&comm_2d); /* Free up communicator */ MatrixMultiply(int n, double *a, double *b, double *c) { /* matrix-matrix multiplication c = a*b */ int i, j, k; for (i=0; i<n; i++) for (j=0; j<n; j++) for (k=0; k<n; k++) c[i*n+j] += a[i*n+k]*b[k*n+j];

Μη εμποδιστικές (non-blocking) επικοιμωμίες

Λιψθ Μζχρι τϊρα υποκζςαμε ότι μια διεργαςία που κάνει MPI_Recv() «κολλάει» και περιμζνει μζχρι να ζρκει το μινυμα (blocking) τθν μθ εμποδιςτικι λιψθ: MPI_Irecv(buf, m, dtype, frank, tag, comm, &status, &req); Παραλαβι μόνο εάν ζχει ζρκει το μινυμα Αλλιϊσ άμεςη επιςτροφή Πρζπει να γνωρίηουμε αν παραλιφκθκε μινυμα ι όχι! MPI_Test(&req, &flag, &status); το flag επιςτρζφεται 0 (false) αν όχι, αλλιϊσ 1. Προφανϊσ ο ζλεγχοσ πρζπει να μπει ςε κάποιο loop μζχρι να παραλθφκεί το μινυμα. Για αναμονι (block) μζχρι να ζρκει το μινυμα: MPI_Wait(&req, &status); #46

Αποςτολι Τπάρχει και εδϊ θ ζννοια τθσ εμποδιςτικότθτασ αλλά όχι τόςο εμφανϊσ (δεν μιλάμε για ςυγχρονιςμζνεσ επικοινωνίεσ τφπου rendezvous όπου ο αποςτολζασ περιμζνει μζχρι ο παραλιπτθσ να κάνει receive) Η MPI_Send() επιςτρζφει μόλισ φφγει και το τελευταίο byte από τον κόμβο. Δθλαδι, περιμζνει μζχρι να ολοκλθρωκεί θ εξισ διαδικαςία: Η βιβλιοκικθ MPI παίρνει το μινυμα από τον χϊρο του χριςτθ (user space), το τοποκετεί πικανϊσ ςε δικοφσ τθσ buffers Σο λειτουργικό ςφςτθμα αντιγράφει από τον χϊρο τθσ βιβλιοκικθσ ςε buffers ςτον χϊρο του πυρινα (kernel space) Από τουσ buffers τθσ μνιμθσ του πυρινα μεταφζρεται ςτουσ buffers του υποςυςτιματοσ επικοινωνιϊν (π.χ. κάρτασ δικτφου) Από τουσ buffers τθσ κάρτασ «βγαίνουν» όλα τα bytes ςτο καλϊδιο και ταξιδεφουν προσ τον προοριςμό τθ μθ εμποδιςτικι αποςτολι: MPI_Isend(buf, n, dtype, trank, tag, comm, &req); Επιςτρζφει αμζςωσ Επομζνωσ, κάποια από τισ μεταφορζσ ςτουσ διάφορουσ buffers του τοπικοφ κόμβου ίςωσ να μθν ζχει ολοκλθρωκεί! Μία νζα MPI_Isend() «ςτο καπάκι» μπορεί να καταςτρζψει το προηγοφμενο μήνυμα που δεν ζχει προλάβει ακόμα να φφγει Πρζπει να ςιγουρευτοφμε ότι το προθγοφμενο μινυμα ζχει φφγει πριν ςτείλουμε το επόμενο: MPI_Test(&req, &flag, &status); MPI_Wait(&req, &status); #47

Γιατί μθ εμποδιςτικζσ επικοινωνίεσ; Κυρίωσ για βελτίωςθ επιδόςεων επικάλυψθ υπολογιςμϊν και επικοινωνιϊν εκκίνηςη όςο πιο νωρίς γίνεται ξεκίνα το send μόλισ ζχεισ τα δεδομζνα, ξεκίνα το receive μόλισ ζχεισ άδειο buffer και ολοκλήρωςη όςο πιο αργά γίνεται ολοκλιρωςθ του send μόλισ είναι να ξαναςτείλεισ κάτι, ολοκλιρωςθ του receive μόλισ είναι να χρθςιμοποιιςεισ τα δεδομζνα Δευτερευόντωσ λόγων μείωςθσ πικανότθτασ deadlock P0: MPI_Irecv(&b, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status, &req); MPI_Send(&a, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); P1: MPI_Recv(&a, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); MPI_Send(&b, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); Δεν ζχει deadlock! #48

Ο αλγόρικμοσ του Cannon με μθ εμποδιςτικζσ επικοινωνίεσ Θζλει διπλά πινακάκια a και b ϊςτε ςε άλλον buffer να παραλαμβάνει και από άλλον να ςτζλνει MatrixMatrixMultiply(int n, double *a, double *b, double *c, MPI_Comm comm) {... MPI_Request reqs[4]; double *a_buffers[2], *b_buffers[2]; /* Get the communicator related information */ /* Set up the Cartesian topology */ /* Set the periods for wraparound connections */ /* Create the Cartesian topology, with rank reordering */ /* Get the rank and coordinates in he new topology */ /* Compute ranks of the up and left shifts */ /* Determine the dimension of the local matrix block */ /* Perform the initial matrix alignment B */... /* Setup the a_buffers and b_buffers arrays */ a_buffers[0] = a; a_buffers[1] = malloc(nlocal*nlocal*sizeof(double)); b_buffers[0] = b; b_buffers[1] = malloc(nlocal*nlocal*sizeof(double)); /* Get into the main computation loop */ for (i=0; i<dims[0]; i++) { /* Shift up & left post early */ MPI_Isend(a_buffers[i%2], nlocal*nlocal, MPI_DOUBLE, leftrank, 1, comm_2d, &reqs[0]); MPI_Isend(b_buffers[i%2], nlocal*nlocal, MPI_DOUBLE, uprank, 1, comm_2d, &reqs[1]); MPI_Irecv(a_buffers[(i+1)%2], nlocal*nlocal, MPI_DOUBLE, rightrank, 1, comm_2d, &reqs[2]); MPI_Irecv(b_buffers[(i+1)%2], nlocal*nlocal, MPI_DOUBLE, downrank, 1, comm_2d, &reqs[3]); /* c = c + a*b * / MatrixMultiply(nlocal, a_buffers[i%2], b_buffers[i%2], c); /* Wait for completion before continuing */ for (j=0; j<4; j++) MPI_Wait(&reqs[j], &status); /* Restore the original distribution of a and b */... #49