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
| #include <stdio.h> #include <stdlib.h> #include <mpi.h>
#define M 1024 #define N 512 #define P 256
void initialize_matrices(int *a, int *b, int rows_a, int cols_a, int cols_b) { for (int i = 0; i < rows_a * cols_a; i++) { a[i] = rand() % 10000; } for (int i = 0; i < cols_a * cols_b; i++) { b[i] = rand() % 10000; } }
int main(int argc, char *argv[]) { int rank, size; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size);
int block_size = M / size; if (M % size != 0) { if (rank == 0) { printf("M must be divisible by size\n"); } MPI_Finalize(); return 1; }
int *a = (int *)malloc(M * N * sizeof(int)); int *b = (int *)malloc(N * P * sizeof(int)); int *c = (int *)malloc(M * P * sizeof(int)); int *local_a = (int *)malloc(block_size * N * sizeof(int)); int *local_c = (int *)malloc(block_size * P * sizeof(int));
if (rank == 0) { srand(time(NULL)); initialize_matrices(a, b, M, N, P); }
MPI_Bcast(b, N * P, MPI_INT, 0, MPI_COMM_WORLD); MPI_Scatter(a, block_size * N, MPI_INT, local_a, block_size * N, MPI_INT, 0, MPI_COMM_WORLD);
for (int i = 0; i < block_size * P; i++) { local_c[i] = 0; }
for (int i = 0; i < block_size; i++) { for (int j = 0; j < P; j++) { for (int k = 0; k < N; k++) { local_c[i * P + j] += local_a[i * N + k] * b[k * P + j]; } } }
MPI_Gather(local_c, block_size * P, MPI_INT, c, block_size * P, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0) {
free(a); free(b); free(c); }
free(local_a); free(local_c);
MPI_Finalize(); return 0; }
|