-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmmult_mpi.c
148 lines (136 loc) · 4.6 KB
/
mmult_mpi.c
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/**
* Incomplete program to multiply a matrix times a matrix using both
* MPI to distribute the computation among nodes and OMP
* to distribute the computation among threads.
*/
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/times.h>
#define min(x, y) ((x) < (y) ? (x) : (y))
#include "mat.h"
int main(int argc, char *argv[])
{
int nrows, ncols;
double *aa; /* the A matrix */
double *bb; /* the B matrix */
double *b;
double *cc1; /* A x B computed using the omp-mpi code you write */
double *cc2; /* A x B computed using the conventional algorithm */
int numbersent = 0;
int send;
double recive;
int rowNumber; //for recive
double *buffer;
int myid, numprocs;
double starttime, endtime;
MPI_Status status;
/* insert other global variables here */
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
if (argc > 1)
{
nrows = atoi(argv[1]);
ncols = nrows;
if (myid == 0)
{
// Master Code goes here
aa = gen_matrix(nrows, ncols);
bb = gen_matrix(ncols, nrows);
cc1 = malloc(sizeof(double) * nrows * nrows);
starttime = MPI_Wtime();
//one row of a
buffer = malloc(sizeof(double) * nrows);
//whole b matix
MPI_Bcast(bb, nrows * ncols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
//send a row by row
for (int i = 0; i < min(numprocs-1, nrows); i++)
{
for (int j = 0; j < ncols; j++)
{
buffer[j] = aa[i * ncols + j];
}
MPI_Send(buffer, ncols, MPI_DOUBLE, i + 1, numbersent + 1, MPI_COMM_WORLD);
numbersent++;
}
//recive
free(buffer);
buffer = malloc(sizeof(double) * ncols);
for (int i = 0; i < nrows; i++)
{
MPI_Recv(buffer, ncols, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
send = status.MPI_SOURCE;
rowNumber = status.MPI_TAG;
//mpi calculate reslut put in cc1
for (int j = 0; j < ncols; j++)
{
cc1[(rowNumber - 1) * ncols + j] = buffer[j];
}
//from omp_mpi.c
if (numbersent < nrows)
{
for (int j = 0; j < ncols; j++)
{
buffer[j] = aa[numbersent * ncols + j];
}
MPI_Send(buffer, ncols, MPI_DOUBLE, send, numbersent + 1,
MPI_COMM_WORLD);
numbersent++;
}
else
{
MPI_Send(MPI_BOTTOM, 0, MPI_DOUBLE, send, 0, MPI_COMM_WORLD);
}
}
/* Insert your master code here to store the product into cc1 */
endtime = MPI_Wtime();
printf("%f\n", (endtime - starttime));
cc2 = malloc(sizeof(double) * nrows * nrows);
mmult(cc2, aa, nrows, ncols, bb, ncols, nrows);
compare_matrices(cc2, cc1, nrows, nrows);
}
else
{
// Slave Code goes here
b = malloc(sizeof(double) * ncols * nrows);
//recive bcast.
MPI_Bcast(b, nrows * ncols, MPI_DOUBLE, 0, MPI_COMM_WORLD);
//form omp_mpi.c
if (myid <= nrows)
{
while (1)
{
double a[ncols];
double answer[ncols];
// row of a matrix
MPI_Recv(&a, ncols, MPI_DOUBLE, 0,
MPI_ANY_TAG, MPI_COMM_WORLD, &status);
if (status.MPI_TAG == 0)
{
break;
}
rowNumber = status.MPI_TAG;
for (int i = 0; i < ncols; i++)
{
double sum = 0.0;
for (int j = 0; j < nrows; j++)
{
sum += a[j] * b[j * nrows + i];
}
answer[i] = sum;
}
MPI_Send(answer, ncols, MPI_DOUBLE, 0, rowNumber,MPI_COMM_WORLD);
}
}
}
}
else
{
fprintf(stderr, "Usage matrix_times_vector <size>\n");
}
MPI_Finalize();
return 0;
}