Professional Documents
Culture Documents
Tomasz Olas
MPI
...
CPU CPU CPU CPU
Sieć komunikacyjna
Historia
Podstawy programowania
Struktura programu
#include <mpi.h>
Inicjalizacja obliczeń
MPI_Init(&argc, &argv);
MPI_Finalize();
MPI_Init i MPI_Finalize
Kompilacja i uruchamianie
#include <iostream>
#include <mpi.h>
return 0;
}
Komunikatory
comm - komunikator,
rank - po wykonaniu funkcji pod ta˛ zmienna˛ zostanie
zapisany identyfikator procesu, który ja˛ wywołał.
Identyfikator bieżacego
˛ procesu jest liczba˛ z przedziału od
0 do p − 1, gdzie p oznacza liczbe˛ procesów w
komunikatorze.
#include <iostream>
#include <mpi.h>
using namespace std;
Komunikat
Wysłanie komunikatu
Odebranie komunikatu
int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
int src, int tag, MPI_Comm comm,
MPI_Status *status)
#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank == 0)
{ > mpic++ -O3 -o pp pp.cpp
int a = 10;
MPI_Send(&a, 1, MPI_INT, 1, 102, MPI_COMM_WORLD); > mpirun -np 2 ./pp
} Proces 1 odebral liczbe: 10
if (rank == 1)
{
int b;
MPI_Recv(&b, 1, MPI_INT, 0, 102, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
cout << "Proces 1 odebral liczbe: " << b << endl;
}
MPI_Finalize();
return 0;
}
Komunikacja grupowa
Broadcast
P0 P1 P2 P3
buffer buffer buffer buffer
0 1 2 3
P0 P1 P2 P3
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
Przykład - Broadcast
#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
> mpirun -np 4 ./bcast
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank); PRZED: rank 0 - ok
PRZED: rank 1 - __
char napis[] = "__"; PRZED: rank 2 - __
if (rank == 0) PRZED: rank 3 - __
{ PO: rank 0 - ok
napis[0] = ’o’; PO: rank 2 - ok
napis[1] = ’k’;
} PO: rank 3 - ok
PO: rank 1 - ok
cout << "PRZED: rank " << rank << " - " << napis << endl;
MPI_Bcast(napis, 3, MPI_CHAR, 0, MPI_COMM_WORLD);
cout << "PO: rank " << rank << " - " << napis << endl;
MPI_Finalize();
return 0;
}
Scatter
int MPI_Scatter(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)
P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf
0 1 2 3
P0 P1 P2 P3
0 1 2 3
Przykład - Scatter
#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank); > mpirun -np 3 ./scatter
int source[] = {0,1,2,3,4,5}; rank 0 - 0 1
int dest[2]; rank 1 - 2 3
MPI_Scatter(source, 2, MPI_INT, rank 2 - 4 5
dest, 2, MPI_INT,
0, MPI_COMM_WORLD);
cout << "rank " << rank << " - "
<< dest[0] << " " << dest[1] << endl;
MPI_Finalize();
return 0;
}
Gather
int MPI_Gather(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
int root, MPI_Comm comm)
P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf
0 1 2 3
P0 P1 P2 P3
0 1 2 3
Przykład - Gather
#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
int source = rank; > mpirun -np 4 ./gather
int dest[4]; 0 1 2 3
MPI_Gather(&source, 1, MPI_INT,
dest, 1, MPI_INT,
3, MPI_COMM_WORLD);
if (rank == 3)
cout << dest[0] << " " << dest[1] << " "
<< dest[2] << " " << dest[3] << endl;
MPI_Finalize();
return 0;
}
Allgather
int MPI_Allgather(
void* sendbuf, int sendcount, MPI_Datatype sendtype,
void* recvbuf, int recvcount, MPI_Datatype recvtype,
MPI_Comm comm)
P0 P1 P2 P3
sendbuf sendbuf sendbuf sendbuf
0 1 2 3
P0 P1 P2 P3
0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3
Reduce
0P P 1 P
2 P
3
sendbuf sendbuf sendbuf sendbuf
0 1 2 3
+ MPI_SUM
P0 P1 P2 P3
6
Przykład - Reduce
#include <iostream>
#include <mpi.h>
using namespace std;
int main (int argc, char *argv[])
{
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
> mpirun -np 4 ./reduce
int source = rank; Suma: 6
int sum;
MPI_Reduce(&source, &sum, 1, MPI_INT,
MPI_SUM, 2, MPI_COMM_WORLD);
if (rank == 2)
cout << "Suma: " << sum << endl;
MPI_Finalize();
return 0;
}
Allreduce
int MPI_Allreduce(void* sendbuf, void* recbuf, int count,
MPI_Datatype type, int op, MPI_Comm comm)
P0 P 1 P2 P3
sendbuf sendbuf sendbuf sendbuf
0 1 2 3
+ MPI_SUM
P0 P1 P2 P3
6 6 6 6