Untitled
unknown
plain_text
2 years ago
4.3 kB
7
Indexable
Never
#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <string.h> #include <math.h> #include <mpi.h> char* help = "\n\ ** Matrix_Mult_MPI.c ** \n\ Algoritm MPI de inmultire a doua matrice \n\ \n\ Se compileaza: \n\ mpicc Matrix_Mult_MPI.c -o Matrix_Mult_MPI \n\ \n\ Se lanseaza cu parametrii n, p max_rep (n divizibil cu p) \n\ Implicit n = 1024, p = 1, max_rep = 1 \n\ mpirun -np p Matrix_Mult_MPI n max_rep \n\ \n\ Executie in mai multe noduri specificate in fisierul hosts:\n\ mpirun -hostfile hosts -np p Matrix_Mult_MPI n \n\ \n\ Fisierul hosts contine numele nodurilor (hostname) si numarul de procesoare (slots): \n\ hpc slots=1 \n\ compute-0-1 slots=1 \n\ compute-0-2 slots=1 \n\ compute-0-3 slots=1 \n"; int main(int argc, char *argv[]) { int n = 1024; // Dim matrice int p = 1; // Nr procese MPI int max_rep = 1; // Numar de repetari executie int root = 0; int rank; // rangul procesului (q) int i, j, k, s, rep; struct timeval t1, t2; float tp; FILE * fp; char* fn = "Res_Matrix_Mult_MPI.txt"; // Citire parametri if (argc >= 2 && strcmp(argv[1],"-help") == 0) { printf("%s\n",help); return 0; } if (argc >= 2) n = atoi(argv[1]); if (argc >= 3) max_rep = atoi(argv[2]); // Testare parametri if (n < 2){ printf("Eroare: n < 2 \n"); exit(0); } if (max_rep < 1){ printf("Eroare: max_rep < 1 \n"); MPI_Finalize(); exit(0); } // MPI_Init (&argc,&argv); MPI_Comm_rank (MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &p); // Test n divizibil cu p if ( n % p != 0) { if (rank == root) printf("Eroare: n = %d nu este divizibil cu p = % d\n",n, p); MPI_Finalize(); exit(0); } s = n / p; // Alocarea matricelor float **a = (float**)malloc(sizeof(float*)*n); float *c = (float*)malloc(sizeof(float*)*n); float *ma = (float*)malloc(sizeof(float)*n*n); for (i = 0; i < n; i++){ a[i] = ma; ma += n; } // Initializare matrice a, b if (rank == root){ for (i = 0; i < n; i++) for (j = 0; j < n; j++) { a[i][j] = 1; } gettimeofday(&t1, NULL); } for (rep = 0; rep < max_rep; rep++){ // // Inmultire secventiala daca p = 1 // if (p == 1){ for (i = 0; i < n; i++) { c[i] = 0; for (j = 0; j < n; j++){ c[i] += a[i][j] ; } } } // // Inmultire paralela (p > 1) else { // Transmitere matrice a, b if (rank == root && root == 0) MPI_Scatter(a[0], s*n, MPI_FLOAT, MPI_IN_PLACE, s*n, MPI_FLOAT, root, MPI_COMM_WORLD); else MPI_Scatter(a[0], s*n, MPI_FLOAT, a[0], s*n, MPI_FLOAT, root, MPI_COMM_WORLD); // Inmultire submatrice de s linii in fiecare proces for (i = 0; i < s; i++) { c[i] = 0; for (j = 0; j < n; j++){ c[i] += a[i][j] ; } // Colectare rezultate if (rank == root && root == 0) MPI_Gather(MPI_IN_PLACE, s, MPI_FLOAT, c, s, MPI_FLOAT, root, MPI_COMM_WORLD); else MPI_Gather(c, s, MPI_FLOAT, c, s, MPI_FLOAT, root, MPI_COMM_WORLD); } // end else } // end rep // Scriere si afisare rezultate if (rank == root) { gettimeofday(&t2, NULL); tp = ((float)(t2.tv_sec - t1.tv_sec) + 0.000001*(t2.tv_usec - t1.tv_usec))/max_rep; fp = fopen(fn, "a"); if (p == 1) fprintf(fp, "\n%f ",tp); else fprintf(fp, "%f ",tp); fclose(fp); printf("%d rep, n = %d, p = %d, t = %f sec\n", max_rep, n, p, tp); if (n <= 16) { for (i = 0; i < n; i++) { printf("%4.0f ", c[i]); } } } MPI_Finalize(); return 0; } }