-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmpi.c
More file actions
90 lines (73 loc) · 2.65 KB
/
mpi.c
File metadata and controls
90 lines (73 loc) · 2.65 KB
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
84
85
86
87
88
89
90
#include <stdio.h>
#include <stdlib.h>
#include <chrono>
#include <mpi.h>
#define N 1000
MPI_Status status;
double A[N][N], B[N][N],C[N][N];
int main(int argc, char* argv[])
{
srand((unsigned int)time(0));
// Initialization Matrix
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
A[i][j] = rand();
B[i][j] = rand();
}
}
int NUM_TOTAL, coreID, NUM_CORE, source, receiverID, itemPer, offset;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &coreID);
MPI_Comm_size(MPI_COMM_WORLD, &NUM_TOTAL);
NUM_CORE = NUM_TOTAL - 1;
if (coreID == 0) {
// Starting Time
auto start_time = std::chrono::high_resolution_clock::now();
itemPer = N / NUM_CORE;
offset = 0;
// Setting Message Passing
for (receiverID = 1; receiverID <= NUM_CORE; receiverID++)
{
MPI_Send(&offset, 1, MPI_INT, receiverID, 1, MPI_COMM_WORLD);
MPI_Send(&itemPer, 1, MPI_INT, receiverID, 1, MPI_COMM_WORLD);
MPI_Send(&A[offset][0], itemPer * N, MPI_DOUBLE, receiverID, 1, MPI_COMM_WORLD);
MPI_Send(&B, N * N, MPI_DOUBLE, receiverID, 1, MPI_COMM_WORLD);
offset = offset + itemPer;
}
for (int i = 1; i <= NUM_CORE; i++)
{
source = i;
MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&itemPer, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&C[offset][0], itemPer * N, MPI_DOUBLE, source, 2, MPI_COMM_WORLD, &status);
}
// Ending Time
auto end_time = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> duration = end_time - start_time;
printf("%f seconds\n", duration.count());
}
// Actual Workers
if (coreID > 0) {
source = 0;
MPI_Recv(&offset, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&itemPer, 1, MPI_INT, source, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&A, itemPer * N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&B, N * N, MPI_DOUBLE, source, 1, MPI_COMM_WORLD, &status);
// Matrix Multiplication
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
double total = 0;
for (int k = 0; k < N; k++)
total += A[i][k] + B[k][j];
C[i][j] = total;
}
MPI_Send(&offset, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
MPI_Send(&itemPer, 1, MPI_INT, 0, 2, MPI_COMM_WORLD);
MPI_Send(&C, itemPer * N, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}