-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlab3.c
More file actions
134 lines (124 loc) · 4.25 KB
/
lab3.c
File metadata and controls
134 lines (124 loc) · 4.25 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
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
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <math.h>
//#define VECSIZE 65536
#define VECSIZE 1
//#define ITERATIONS 10000
#define ITERATIONS 10000
typedef struct nodeElement {
double val;
int rank;
} NodeElement;
// Broadcast vector to all nodes
void broadcast(int numdim, int rank, NodeElement * vector, int vectorSize, MPI_Datatype datatype) {
MPI_Status status;
int notparticipating = pow(2,numdim-1)-1;
int bitmask = pow(2,numdim-1);
int curdim = 0;
for(curdim = 0; curdim < numdim; curdim++) {
if ((rank & notparticipating) == 0) {
if ((rank & bitmask) == 0) {
int msg_dest = rank ^ bitmask;
MPI_Send(vector, vectorSize, datatype, msg_dest, 0, MPI_COMM_WORLD);
}
else {
int msg_src = rank ^ bitmask;
MPI_Recv(vector, vectorSize, datatype, msg_src, 0, MPI_COMM_WORLD, &status);
}
}
notparticipating >>= 1;
bitmask >>=1;
}
}
// Reduce values to one node
void maxReduce(int numdim, int rank, NodeElement * vector, int vectorSize, MPI_Datatype datatype)
{
MPI_Status status;
int notparticipating = 0;
int curdim = 0;
int bitmask = 1;
// allocate a new array to hold received values
NodeElement * newValues = malloc(vectorSize * sizeof(NodeElement));
for(curdim = 0; curdim < numdim; curdim++) {
if ((rank & notparticipating) == 0) {
if ((rank & bitmask) != 0) {
int msg_dest = rank ^ bitmask;
MPI_Send(vector, vectorSize, datatype, msg_dest, 0, MPI_COMM_WORLD);
}
else {
int msg_src = rank ^ bitmask;
MPI_Recv(newValues, vectorSize, datatype, msg_src, 0, MPI_COMM_WORLD, &status);
int i;
for (i = 0; i < vectorSize; i++) {
if ((*(newValues + i)).val > (*(vector + i)).val) {
*(vector + i) = *(newValues + i);
}
}
}
}
notparticipating = notparticipating ^ bitmask;
bitmask <<=1;
}
}
double When() {
struct timeval tp;
gettimeofday(&tp, NULL);
return ((double) tp.tv_sec + (double) tp.tv_usec * 1e-6);
}
main(int argc, char *argv[]) {
int iproc, nproc,i, iter;
char host[255], message[55];
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &nproc);
MPI_Comm_rank(MPI_COMM_WORLD, &iproc);
gethostname(host,253);
// printf("I am proc %d of %d running on %s\n", iproc, nproc,host);
// each process has an array of VECSIZE double: ain[VECSIZE]
double ain[VECSIZE], aout[VECSIZE];
int ind[VECSIZE];
NodeElement in[VECSIZE], out[VECSIZE];
int myrank, root = 0;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
// Start time here
srand(myrank+5);
double start = When();
for(iter = 0; iter < ITERATIONS; iter++) {
for(i = 0; i < VECSIZE; i++) {
ain[i] = rand();
//printf("init proc %d [%d]=%f\n",myrank,i,ain[i]);
}
for (i=0; i<VECSIZE; ++i) {
in[i].val = ain[i];
in[i].rank = myrank;
}
maxReduce((int)log2(nproc), myrank, in, VECSIZE, MPI_DOUBLE_INT);
//printf("starting max reduce.\n");
memcpy(out, in, sizeof(NodeElement) * VECSIZE);
// MPI_Reduce( in, out, VECSIZE, MPI_DOUBLE_INT, MPI_MAXLOC, root, MPI_COMM_WORLD);
// At this point, the answer resides on process root
if (myrank == root) {
/* read ranks out
*/
for (i=0; i<VECSIZE; ++i) {
//printf("root out[%d] = %f from %d\n",i,out[i].val,out[i].rank);
aout[i] = out[i].val;
ind[i] = out[i].rank;
}
}
// Now broadcast this max vector to everyone else.
//printf("Starting broadcast.");
broadcast((int) log2(nproc), myrank, in, VECSIZE, MPI_DOUBLE_INT);
memcpy(out, in, sizeof(NodeElement) * VECSIZE);
// MPI_Bcast(out, VECSIZE, MPI_DOUBLE_INT, root, MPI_COMM_WORLD);
for(i = 0; i < VECSIZE; i++) {
//printf("final proc %d [%d]=%f from %d\n",myrank,i,out[i].val,out[i].rank);
}
}
MPI_Finalize();
double end = When();
if(myrank == root) {
printf("Time %f\n",end-start);
}
}