-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
176 lines (126 loc) · 4.84 KB
/
main.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
///Mandlebrot OPENMPI
///Coded by MJ Wright 2014, 201176962
///Current implementation uses Master slave model
///Node 0 is master and allocates work to slaves
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/timeb.h>
#include "mpi.h"
#include "mandle.h"
static void DebugWait2(int rank, int size) {
char a;
MPI_Bcast(&a, 1, MPI_BYTE, 0, MPI_COMM_WORLD);
printf("%d: DEBUG reached,%i\n", rank,size);
}
int main(int argc,char* argv[])
{
//MPI
int id;//process id
int p;//num processes
MPI_Status status;
//Global vars
int globalNumberofpixels = XPICRES*YPICRES;
uint* mandleBuffer;
//even vs odd?
int lastProcessBlockSize;
//local vars
uint* localBuffer;
int localblocksize;
//Initialise OPENMPI
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&p);
//globaltimer
struct timeb gStart, gEnd;
float tt;
ftime(&gStart);//start global timer
//ssetup local timers
struct timeb tstart, tend, cStart, cEnd;
float diff;
//split up problem size and calculate share of work
int e = YPICRES/(p-1);
localblocksize = e;
//int f = d-(e*(p-1));
//printf("f:%lli",f);
//if(id!= (p-1)){//testing for uneven splits
// localblocksize = e;
//}else{
// localblocksize = e;
//}
//for calling the algorithm for each individual process
int yStart = localblocksize*(id-1);//where x starts for each process, p=0 = 0 till p=4=last position
int yEnd = yStart + localblocksize;//runs till here
int arrSize = localblocksize*XPICRES;
//start timers
ftime(&tstart);
MPI_Barrier(MPI_COMM_WORLD);//halt to ensure synchronizations
if (id == 0){ //0 node is master and allocates mem 1nce
mandleBuffer = (uint*)malloc(sizeof(uint)*globalNumberofpixels+1);//mandle buffer
if(mandleBuffer == NULL){//cleanup on alloc fail
printf("Failed to allocate memory for Mandlebuffer on process:%i\nExiting...\n",id);
fflush(stdout);
MPI_Finalize();
}
//now master process must recieve replies from nodes
MPI_Status status;
ftime(&cStart);//computation time!!
int g;
for(g = 1; g<=p-1; g++){//node 1->p-1
int bufsize;
MPI_Probe(MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status);//probe for incoming sizes of buffers
// DebugWait(id);
MPI_Get_count(&status, MPI_UNSIGNED, &bufsize);//get size
uint* recvBuf = (uint*)malloc(sizeof(uint) * bufsize);//aloc mem to buffer to recieve
MPI_Recv(recvBuf, bufsize, MPI_UNSIGNED, g, 0, MPI_COMM_WORLD,MPI_STATUS_IGNORE);//recieve buffer
//DebugWait(id, bufsize);
//place buffer in global buffer
int i;
for(i=0; i<=bufsize; i++){
mandleBuffer[i+(bufsize*(g-1))] = recvBuf[i];//place in array
}
free(recvBuf);
}
ftime(&cEnd);//computation end timer!!!
}//rest of nodes now do individual processing
else{
ftime(&cStart);//computation time!!
localBuffer = GenMandleSSEOMPCache(yStart, yEnd, 256*4, arrSize);
MPI_Send(localBuffer, arrSize, MPI_UNSIGNED, 0,0, MPI_COMM_WORLD);//send answer
//DebugWait(id, arrSize);
ftime(&cEnd);//computation end timer!!!
}
/*------------------------------------------------*///DebugWait(id);
ftime(&tend);
MPI_Barrier(MPI_COMM_WORLD);//wait until all is done
//cleanup
if(id==0){
printf("\n\n%i)---Mandle Picture Computation done---\n",id);
printf("%i)Escape time algorithm used with %i nodes used to compute\n",id,p-1);
printf("%i)Image size: %i by %i\n",id,XPICRES,YPICRES);
printf("%i)Runtime results below.\n\n",id);
}
MPI_Barrier(MPI_COMM_WORLD);//standardize output
//general time per process
//diff =((float) (1000.0 * (cEnd.time - cStart.time) + (cEnd.millitm - cStart.millitm)))/1000.0;
//printf("%i)Computation Time:%f\n",id,diff);
//diff =((float) (1000.0 * (tend.time - tstart.time) + (tend.millitm - tstart.millitm)))/1000.0;
//printf("%i)Total Time:%f\n\n",id,diff);
if(id==0){//FPS approx
ftime(&gEnd);
tt=((float) (1000.0 * (cEnd.time - cStart.time) + (cEnd.millitm - cStart.millitm)))/1000.0;
printf("\n\n[------------------------Total Running time:%f---------------------------]\n",tt);
tt = 1/tt;//rough FPS estimate as 1/tt = frequency of its occurance
printf("[------------------------Rough FPS estimate:%f---------------------------]\n\n",tt);
}
//cleanup & Save!
if(id==0){
MandleSavePPM(mandleBuffer);
printf("%i)Image saved to result.ppm\n\n",id);
free(mandleBuffer);
}
if(id!=0)
free(localBuffer);
MPI_Finalize();
return 0;
}