diff --git a/a.out b/a.out index 0098ea0..151c5ca 100755 Binary files a/a.out and b/a.out differ diff --git a/execMPI b/execMPI new file mode 100755 index 0000000..8b71865 Binary files /dev/null and b/execMPI differ diff --git a/mpi_cae.sh b/mpi_cae.sh new file mode 100755 index 0000000..97b471d --- /dev/null +++ b/mpi_cae.sh @@ -0,0 +1,4 @@ +mkdir -p ./dist/$(dirname ${1%".c"}) + +mpicc -w ./scripts/$1 -fopenmp -lm -o ./dist/${1%".c"} +mpirun -np $2 ./dist/${1%".c"} \ No newline at end of file diff --git a/readme.md b/readme.md index f16187f..86f0d15 100644 --- a/readme.md +++ b/readme.md @@ -86,3 +86,24 @@ l’exécution). #### Exercice 3 +1. Implémentation de la multiplication matricielle séquentielle [code](scripts/td2/exo3/produit_matrice_2d.c) + - Produit Matricielle parallèle + + +### TD 4 + +#### Exercice 1: inter-bloquage de communication + +1. Le programme risque un interblocage de communication car les deux noeuds attendent un message de l'autre dès le début de l'exécution. Car la fonction MPI_Recv est bloquante + +2. Le programme risque un interblocage également. Les deux machines Envoient un message en même temps en utilisant une procèdure bloquante synchrone et ils finissent par s'attendre mutuellement (interblocage) + +3. les solutions aux problèmes sont [Deadlock 1](scripts/td4/deadlock_1.c) [Deadlock 2](scripts/td4/deadlock_2.c) + +#### Exercice 2: + +1. Tout se passe comme prévu, le noeud rang 0 envoi 2 messages au noeuds 1 et 2, le noeud 1 ensuite envoi un message au noeud 2 et le noeud 2 attends 2 messages de n'importe quel source + +#### Exercice 3: + + diff --git a/scripts/td2/exo3/prod_mat_par_dynamic.png b/scripts/td2/exo3/prod_mat_par_dynamic.png new file mode 100644 index 0000000..241c02d Binary files /dev/null and b/scripts/td2/exo3/prod_mat_par_dynamic.png differ diff --git a/scripts/td2/exo3/prod_mat_par_static.png b/scripts/td2/exo3/prod_mat_par_static.png new file mode 100644 index 0000000..321b6a5 Binary files /dev/null and b/scripts/td2/exo3/prod_mat_par_static.png differ diff --git a/scripts/td2/exo3/produit_matrice_2d.c b/scripts/td2/exo3/produit_matrice_2d.c index 14422bc..90a9c1f 100644 --- a/scripts/td2/exo3/produit_matrice_2d.c +++ b/scripts/td2/exo3/produit_matrice_2d.c @@ -13,7 +13,7 @@ int main(int argc, char const *argv[]) { for (int j = 0; j < MAX; j++) { - a[i][j] = 1 + i + j/2; + a[i][j] = 1 + i ; b[i][j] = j + 1 ; c[i][j] = 0; } diff --git a/scripts/td2/exo3/produit_matrice_2d_par.c b/scripts/td2/exo3/produit_matrice_2d_par.c index b3cd67d..79003f3 100644 --- a/scripts/td2/exo3/produit_matrice_2d_par.c +++ b/scripts/td2/exo3/produit_matrice_2d_par.c @@ -4,39 +4,39 @@ #define MAX 10 +int a[MAX][MAX], b[MAX][MAX], c[MAX][MAX]; + int main(int argc, char const *argv[]) { - int a[MAX][MAX], b[MAX][MAX], c[MAX][MAX]; // initialisation for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { - a[i][j] = 1 + i + j/2; + a[i][j] = 1 + i ; b[i][j] = j + 1 ; c[i][j] = 0; } } - int i = 0; - #pragma omp parallel for shared(i) - for (i = 0; i < MAX; i++) - { - for (int j = 0; j < MAX; j++) + + #pragma omp parallel for schedule(dynamic) + for (int i = 0; i < MAX; i++) + { + for (int j = 0; j < MAX; j++) + { + for (int k = 0; k < MAX; k++) { - for (int k = 0; k < MAX; k++) - { - c[i][j]+=a[i][k]*b[k][j]; - } + c[i][j]+=a[i][k]*b[k][j]; } - } + } for (int i = 0; i < MAX; i++) { for (int j = 0; j < MAX; j++) { - printf("| %d "); + printf("|%d",c[i][j]); } printf("\n"); } diff --git a/scripts/td2/exo4/pi_for.c b/scripts/td2/exo4/pi_for.c new file mode 100644 index 0000000..caa0efa --- /dev/null +++ b/scripts/td2/exo4/pi_for.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +#define MAX 50 +#define NUMTHREAD 4 + +int main(int argc, char* argv[]){ + + float step, x, sum, pi; + int i, steps; + steps = 200.0; + + step = 1.0/(float)steps; + + float* resultArray = malloc(sizeof(float)*NUMTHREAD); + + // printf("\nwe have %d threads", omp_get_thread_num()); + // omp_set_num_threads(NUMTHREAD); + // int t_num = omp_get_thread_num(); + // int start = (steps/NUMTHREAD)*t_num; + // int end = (steps/NUMTHREAD) * (t_num + 1); + // printf("\nThread %d , starts: %d , ends: %d",t_num, start, end); + + #pragma omp parallel for + for (int i = 0; i < steps; i++) + { + x = (i + 0.5)* step; + sum += 4.0/(1.0+x*x); + } + + // printf("\nsum=%f",sum) + // printf("\nThread %d, sum: %f",t_num, sum); + + + pi = step * sum; + // print("pi= %f", math.pi) + printf("\npi= %.10f", pi); + + return 0; + +} \ No newline at end of file diff --git a/scripts/td2/exo4/pi_for_critical.c b/scripts/td2/exo4/pi_for_critical.c new file mode 100644 index 0000000..3a6aeb0 --- /dev/null +++ b/scripts/td2/exo4/pi_for_critical.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#define NUMTHREAD 4 + +int main(int argc, char* argv[]){ + + double step, x, sum, pi; + int i, steps; + steps = 1000.0; + + step = 1.0/(double)steps; + + #pragma omp parallel for private(x) + for (int i = 0; i < steps; i++) + { + x = (i + 0.5)* step; + #pragma omp critical + { + sum += 4.0/(1.0+x*x); + } + } + + + pi = step * sum; + printf("\npi= %.15f", pi); + + return 0; +} \ No newline at end of file diff --git a/scripts/td2/exo4/pi_for_iterations.c b/scripts/td2/exo4/pi_for_iterations.c new file mode 100644 index 0000000..8bff3fd --- /dev/null +++ b/scripts/td2/exo4/pi_for_iterations.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + + double step, x, sum, pi; + int i, steps; + steps = 1000.0; + + int p[4] = { 2, 4, 6, 8 }; + int n[5] = { 200, 400, 600, 800, 1000 }; + + for (int j = 0; j < 5; j++) + { + for (int k = 0; k < 5; k++) + { + pi = 0, sum = 0.0; + step = 1.0 / (double)n[k]; + omp_set_num_threads(p[j]); + + #pragma omp parallel for reduction(+:sum) + for (int i = 0; i < n[k]; i++) + { + x = (i + 0.5) * step; + sum += 4.0 / (1.0 + x * x); + } + + printf("\npi for num_threads %d and steps %d is %f",p[j], n[k], sum * step); + } + + } + + + + pi = step * sum; + printf("\npi= %.15f", pi); + + return 0; +} \ No newline at end of file diff --git a/scripts/td2/exo4/pi_for_reduction.c b/scripts/td2/exo4/pi_for_reduction.c new file mode 100644 index 0000000..7bbb1b3 --- /dev/null +++ b/scripts/td2/exo4/pi_for_reduction.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +#define NUMTHREAD 4 + +int main(int argc, char* argv[]){ + + double step, x, sum, pi; + int i, steps; + steps = 1000.0; + + step = 1.0/(double)steps; + + #pragma omp parallel for private(x) reduction(+:sum) + for (int i = 0; i < steps; i++) + { + x = (i + 0.5)* step; + sum += 4.0/(1.0+x*x); + } + + + pi = step * sum; + printf("\npi= %.15f", pi); + + return 0; +} \ No newline at end of file diff --git a/scripts/td2/exo4/pi_out.c b/scripts/td2/exo4/pi_out.c new file mode 100644 index 0000000..7686623 --- /dev/null +++ b/scripts/td2/exo4/pi_out.c @@ -0,0 +1,35 @@ +#include +#include +#include +#include + + +void main() +{ + float step,x,sum,pi; + int steps, tid; + steps=1000; + int num; + step = 1.0/(float)steps; + int numthread =4; + omp_set_num_threads(numthread); + #pragma omp parallel private(tid, num, x) + { + tid=omp_get_thread_num(); + num=omp_get_num_threads(); + + printf("threads num %d\n",numthread); + printf("threads %d\n",num); + printf("tid= %d\n",tid); + #pragma omp for reduction(+:sum) + for(int i= 0; i +#include + +int main(int argc, char const *argv[]) +{ + int numtasks, myRank, len, rc; + char hostname[MPI_MAX_PROCESSOR_NAME]; + MPI_Init(&argc, &argv); + + int sendbuf1, sendbuf2, count, recvbuf1, recvbuf2, tag; + + MPI_Comm comm = MPI_COMM_WORLD; + MPI_Status status; + + + MPI_Comm_rank(comm, &myRank); + if (myRank == 0) + { + MPI_Send(sendbuf1, count, MPI_INT, 2, tag, comm); + MPI_Send(sendbuf2, count, MPI_INT, 1, tag, comm); + } + else if (myRank == 1) + { + MPI_Recv(recvbuf1, count, MPI_INT, 0, tag, comm, &status); + MPI_Send(recvbuf1, count, MPI_INT, 2, tag, comm); + } + else if (myRank == 2) + { + MPI_Recv(recvbuf1, count, MPI_INT, MPI_ANY_SOURCE, tag, comm, &status); + MPI_Recv(recvbuf2, count, MPI_INT, MPI_ANY_SOURCE, tag, comm, &status); + } + + MPI_Finalize(); + + return 0; +} diff --git a/scripts/td4/exo3.c b/scripts/td4/exo3.c new file mode 100644 index 0000000..6b67e00 --- /dev/null +++ b/scripts/td4/exo3.c @@ -0,0 +1,59 @@ +#include +#include + +int main() +{ + MPI_Init(NULL, NULL); + + // Number of processes + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + // Number of current process + int process_id; + MPI_Comm_rank(MPI_COMM_WORLD, &process_id); + + // Processor name + char processor_name[MPI_MAX_PROCESSOR_NAME]; + int name_len; + MPI_Get_processor_name(processor_name, &name_len); + + // printf("Hello! - sent from process %d running on processor %s.\n\ + // Number of processes is %d.\n\ + // Length of proc name is %d.\n\ + // ***********************\n", + // process_id, processor_name, world_size, name_len); + + MPI_Status status; + + if (process_id == 0) + { + int data = 15; + + MPI_Ssend(&data, 1, MPI_INT, 1, 4, MPI_COMM_WORLD); + MPI_Recv(&data, 1, MPI_INT, world_size - 1, 4, MPI_COMM_WORLD, &status); + printf("\nReturn to Sender with value %d\n", data); + fflush(stdout); + } + else + { + int data; + MPI_Recv(&data, 1, MPI_INT, process_id - 1, 4, MPI_COMM_WORLD, &status); + if (process_id + 1 < world_size) + { + printf("\nI am %d Received value %d from %d and passing to %d", process_id, data, process_id - 1, process_id + 1); + fflush(stdout); + MPI_Ssend(&data, 1, MPI_INT, process_id + 1, 4, MPI_COMM_WORLD); + } + else + { + printf("\nI am %d The last and I am passing it back to 0", process_id); + fflush(stdout); + // int d = 5; + MPI_Ssend(&data, 1, MPI_INT, 0, 4, MPI_COMM_WORLD); + } + } + + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/scripts/td4/exo4/async.c b/scripts/td4/exo4/async.c new file mode 100644 index 0000000..5ef2ec2 --- /dev/null +++ b/scripts/td4/exo4/async.c @@ -0,0 +1,78 @@ +#include +#include + +int main() +{ + MPI_Init(NULL, NULL); + + // Number of processes + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + // Number of current process + int process_id; + MPI_Comm_rank(MPI_COMM_WORLD, &process_id); + + // Processor name + char processor_name[MPI_MAX_PROCESSOR_NAME]; + int name_len; + MPI_Get_processor_name(processor_name, &name_len); + + // printf("Hello! - sent from process %d running on processor %s.\n\ + // Number of processes is %d.\n\ + // Length of proc name is %d.\n\ + // ***********************\n", + // process_id, processor_name, world_size, name_len); + + MPI_Status status; + int n = 5; + + if (process_id == 0) + { + // create the data + float *data = malloc(sizeof(float) * n); + + MPI_Request requests[4]; + + // sending the data one by one + for (int i = 1; i < world_size; i++) + { + for (int j = 0; j < n; j++) + { + data[j] = (float) i + j * 0.1; + } + MPI_Isend(data, n, MPI_FLOAT, i, 4, MPI_COMM_WORLD, &requests[i]); + printf("\nI'm node 0 and I just sent %d data to %d", n, i); + fflush(stdout); + } + for (int i = 1; i < 4; i++) + { + MPI_Wait(&requests[i], MPI_STATUS_IGNORE); + } + + } + else + { + float *data = malloc(sizeof(float) * n); + MPI_Request request; + + MPI_Irecv(data, n, MPI_FLOAT, 0, 4, MPI_COMM_WORLD, &request); + + + MPI_Status status; + MPI_Wait(&request, &status); + + + printf("\n I'm process %d and I received %d of floats [", process_id, n); + for (int i = 0; i < n; i++) + { + printf(" %f,", data[i]); + } + printf("]\n"); + + fflush(stdout); + } + + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/scripts/td4/exo4/bcast.c b/scripts/td4/exo4/bcast.c new file mode 100644 index 0000000..4140383 --- /dev/null +++ b/scripts/td4/exo4/bcast.c @@ -0,0 +1,60 @@ +#include +#include + +int main() +{ + MPI_Init(NULL, NULL); + + // Number of processes + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + // Number of current process + int process_id; + MPI_Comm_rank(MPI_COMM_WORLD, &process_id); + + // Processor name + char processor_name[MPI_MAX_PROCESSOR_NAME]; + int name_len; + MPI_Get_processor_name(processor_name, &name_len); + + // printf("Hello! - sent from process %d running on processor %s.\n\ + // Number of processes is %d.\n\ + // Length of proc name is %d.\n\ + // ***********************\n", + // process_id, processor_name, world_size, name_len); + + MPI_Status status; + int n = 5; + + if (process_id == 0) + { + float* data = malloc(sizeof(float) * n); + + + for (int i = 0; i < n; i++) + { + data[i] =(float) i * 2.5; + } + MPI_Bcast(data, n, MPI_FLOAT, 0, MPI_COMM_WORLD); + printf("\nI'm node 0 and I just broadcasted %d data", n); + fflush(stdout); + } + else{ + float* data = malloc(sizeof(float) * n); + + MPI_Bcast(data, n, MPI_FLOAT, 0, MPI_COMM_WORLD); + + printf("\n I'm process %d and I received %d of floats [", process_id, n); + for (int i = 0; i < n; i++) + { + printf(" %f,",data[i]); + } + printf("]\n"); + + fflush(stdout); + } + + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/scripts/td4/exo4/bcast_time.png b/scripts/td4/exo4/bcast_time.png new file mode 100644 index 0000000..0d20a08 Binary files /dev/null and b/scripts/td4/exo4/bcast_time.png differ diff --git a/scripts/td4/exo4/naif.c b/scripts/td4/exo4/naif.c new file mode 100644 index 0000000..f3c0b5f --- /dev/null +++ b/scripts/td4/exo4/naif.c @@ -0,0 +1,66 @@ +#include +#include + +int main() +{ + MPI_Init(NULL, NULL); + + // Number of processes + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + // Number of current process + int process_id; + MPI_Comm_rank(MPI_COMM_WORLD, &process_id); + + // Processor name + char processor_name[MPI_MAX_PROCESSOR_NAME]; + int name_len; + MPI_Get_processor_name(processor_name, &name_len); + + // printf("Hello! - sent from process %d running on processor %s.\n\ + // Number of processes is %d.\n\ + // Length of proc name is %d.\n\ + // ***********************\n", + // process_id, processor_name, world_size, name_len); + + MPI_Status status; + int n = 5; + + if (process_id == 0) + { + // create the data + float *data = malloc(sizeof(float) * n); + + // printf("I'm here"); + // sending the data one by one + for (int i = 1; i < world_size; i++) + { + for (int j = 0; j < n; j++) + { + data[j] = (float) i + j * 0.1; + } + MPI_Ssend(data, n, MPI_FLOAT, i, 4, MPI_COMM_WORLD); + printf("\nI'm node 0 and I just sent %d data to %d", n, i); + fflush(stdout); + } + } + else + { + float *data = malloc(sizeof(float) * n); + + MPI_Recv(data, n, MPI_FLOAT, 0, 4, MPI_COMM_WORLD, &status); + + printf("\n I'm process %d and I received %d of floats [", process_id, n); + for (int i = 0; i < n; i++) + { + printf(" %f,", data[i]); + } + printf("]\n"); + + fflush(stdout); + } + + MPI_Finalize(); + return 0; +} \ No newline at end of file diff --git a/scripts/td4/exo4/time_async.png b/scripts/td4/exo4/time_async.png new file mode 100644 index 0000000..754bdae Binary files /dev/null and b/scripts/td4/exo4/time_async.png differ diff --git a/scripts/td4/exo4/time_naif.png b/scripts/td4/exo4/time_naif.png new file mode 100644 index 0000000..d059148 Binary files /dev/null and b/scripts/td4/exo4/time_naif.png differ diff --git a/scripts/td4/exo5.c b/scripts/td4/exo5.c new file mode 100644 index 0000000..e4e7472 --- /dev/null +++ b/scripts/td4/exo5.c @@ -0,0 +1,51 @@ +#include +#include +#include + + +int main(int argc, char const *argv[]) +{ + MPI_Init(NULL, NULL); + + int world_size, rank, name_len; + char processor_name[30]; + + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Get_processor_name(processor_name, &name_len); + + if(rank == 0){ + // if main process + int steps = 200; + + MPI_Bcast(&steps, 1, MPI_INT, 0, MPI_COMM_WORLD); + }else{ + // if other processes + int steps; + MPI_Bcast(&steps, 1, MPI_INT, 0, MPI_COMM_WORLD); + + int slice = steps / world_size; + int start = slice * rank; + int x, sum, step = 1.0/(float) steps; + + for (int i = start; i < start + slice; i++) + { + x = (i + 0.5)* step; + sum += 4.0/(1.0+x*x); + } + + } + + float* sums = malloc(sizeof(float)* (world_size-1)); + MPI_Gather(sums, world_size -1, MPI_FLOAT, sums, 4, MPI_FLOAT, 0, MPI_COMM_WORLD); + + if(rank == 0){ + for (int i = 0; i < world_size -1; i++) + { + printf("\n %f ,", sums[i]); + } + + } + + return 0; +} diff --git a/scripts/td4/exo6.c b/scripts/td4/exo6.c new file mode 100644 index 0000000..8c64bd9 --- /dev/null +++ b/scripts/td4/exo6.c @@ -0,0 +1,57 @@ +#include +#include +#include + + +int main(int argc, char const *argv[]) +{ + MPI_Init(NULL, NULL); + + int world_size, rank, name_len; + char processor_name[30]; + + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Get_processor_name(processor_name, &name_len); + + int B[10][5]; + int A[5][10]; + int line[10]; + + + if(rank == 0){ + // if main process + int steps = 200; + for (int i = 0; i < 5; i++) + { + for (int j = 0; j < 10; j++) + { + A[i][j] = i+j; + B[i][j] = A[i][j] - 2; + } + + } + + MPI_Bcast(&B, 10 * 5, MPI_INT, 0, MPI_COMM_WORLD); + + + }else{ + // if other processes + + MPI_Bcast(&B, 10 * 5, MPI_INT, 0, MPI_COMM_WORLD); + + printf("\n received B"); + + } + + MPI_Scatter(&A, 10 * 5, MPI_INT, &line, 10, MPI_INT, 0, MPI_COMM_WORLD); + + if(rank != 0){ + printf("\nProcessus %d a reçu %d donnée", rank, 10 * 5); + + } + + + MPI_Finalize(); + return 0; +}