source: CIVL/examples/mpi-pthread/mpi-pthreads-infinity-norm.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 6.8 KB
Line 
1#ifdef _CIVL
2#include <civlc.cvh>
3#endif
4
5/**********************************************************************
6 C-DAC Tech Workshop : hyPACK-2013
7 Oct 15-18,2013
8
9
10 Example 1.3 : mpi-Pthreads-infinity-norm.c
11
12 Objective : Write an MPI-Pthreads program to calculate Infinity
13 norm of a matrix using row wise Block-striped
14 partitioning.
15
16 Pthreads and MPI Library calls are used.
17
18 This Example demonstrates the use of:
19
20 pthread_create()
21 pthread_join()
22 pthread_mutex_lock()
23 pthread_mutex_unlock()
24
25 MPI_Init
26 MPI_Comm_rank
27 MPI_Comm_size
28 MPI_Barrier
29 MPI_Bcast
30 MPI_Allgather
31 MPI_Reduce
32 MPI_Finalize
33
34 Input : The input file holding the matrix.
35
36 Output : Infinity Norm of the given Matrix.
37
38 Created :MAY-2013
39
40 E-mail : hpcfte@cdac.in
41
42
43 ************************************************************************/
44
45#include <stdio.h>
46#include <stdlib.h>
47#include <mpi.h>
48#include <pthread.h>
49#include <math.h>
50
51#ifdef _CIVL
52$input int NUM_ROWS_BOUND;
53$input int NUM_COLS_BOUND;
54#endif
55
56int MyRank, currentRow, MyNoofRows, NoofCols, GlobalIndex = -1;
57int flag = 0, maxflag = 0, rowlimit;
58float **Matrix, *Vector, max;
59
60pthread_mutex_t mutex_Row = PTHREAD_MUTEX_INITIALIZER;
61pthread_mutex_t mutex_Flag = PTHREAD_MUTEX_INITIALIZER;
62pthread_mutex_t mutex_Max = PTHREAD_MUTEX_INITIALIZER;
63
64/* Routine executed by each thread */
65
66void * MyPartOfCalc(int Id)
67{
68
69 int myRow, col;
70 float sum;
71
72 if (flag == 0)
73 {
74 pthread_mutex_lock(&mutex_Flag);
75 rowlimit = currentRow + MyNoofRows;
76 flag++;
77 pthread_mutex_unlock(&mutex_Flag);
78 }
79
80 while (1)
81 {
82
83 /*
84 * Thread selects the row of Matrix on which it has to do the
85 * operation
86 */
87
88 pthread_mutex_lock(&mutex_Row);
89 {
90 #ifdef _CIVL
91 $assume(currentRow < rowlimit);
92 #endif
93 if (currentRow >= rowlimit)
94 {
95 pthread_mutex_unlock(&mutex_Row);
96 pthread_exit(0);
97 }
98 myRow = currentRow;
99 currentRow++;
100 }
101 pthread_mutex_unlock(&mutex_Row);
102
103 /*
104 * Perform the addition on the row selected and and store in
105 * max if it is the maximum value until now out of computed
106 * sums
107 */
108
109 printf(" Thread Id %d of process with Rank %d operated on Matrix Row %d\n", Id, MyRank, myRow);
110 sum = 0.0;
111
112 for (col = 0; col < NoofCols; col++)
113 sum += fabs(Matrix[myRow][col]);
114
115
116
117 pthread_mutex_lock(&mutex_Max);
118
119 if (maxflag == 0)
120 {
121 max = sum;
122 maxflag = 1;
123 }
124 else if (sum > max)
125 max = sum;
126
127 pthread_mutex_unlock(&mutex_Max);
128 }
129
130}
131
132
133//main(int argc, char **argv)
134int main(int argc, char **argv)
135{
136
137 int iproc, irow, icol, modval, divval, *Displacement;
138 int iprocb, *ArrayNoofRows, Numprocs, Root = 0, NoofRows, VectorSize;
139 float Result;
140
141 pthread_t *threads;
142 FILE *fp;
143
144
145 /* MPI Initialisation ... */
146
147 MPI_Init(&argc, &argv);
148 MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);
149 MPI_Comm_size(MPI_COMM_WORLD, &Numprocs);
150
151 /* Validity checking for minimum number of processors */
152 #ifdef _CIVL
153 $assume(Numprocs >= 2);
154 #endif
155 if (Numprocs < 2)
156 {
157 printf("Invalid Number of Processors ..... \n");
158 printf("Numprocs must be greater than 1 ......\n");
159 MPI_Finalize();
160 exit(0);
161 }
162
163 /* Read the Matrix from the file. */
164
165
166 fp = fopen("Norm_Data.dat", "r");
167 if (!fp)
168 {
169 printf("\nUnable to open the file Norm_Data.dat");
170 exit(0);
171 }
172
173 fscanf(fp, "%d", &NoofRows);
174 fscanf(fp, "%d", &NoofCols);
175
176 #ifdef _CIVL
177 $assume(NoofRows <= NUM_ROWS_BOUND);
178 $assume(NoofCols <= NUM_COLS_BOUND);
179 #endif
180
181 printf("\n Rows: %d Col:%d.", NoofRows, NoofCols);
182
183 MPI_Barrier(MPI_COMM_WORLD);
184
185 MPI_Bcast(&NoofRows, 1, MPI_INT, Root, MPI_COMM_WORLD);
186 MPI_Bcast(&NoofCols, 1, MPI_INT, Root, MPI_COMM_WORLD);
187
188 /* Validity checking for negative sizes of Matrix */
189 #ifdef _CIVL
190 $assume(NoofRows >= 1 && NoofCols >= 1);
191 #endif
192 if (NoofRows < 1 || NoofCols < 1)
193 {
194 printf("The number of rows or columns or size of Vector should be atleast one\n");
195 MPI_Finalize();
196 exit(-1);
197 }
198 /* Validity checking for minimum number of Rows of Matrix */
199 #ifdef _CIVL
200 $assume(NoofRows >= Numprocs);
201 #endif
202 if (NoofRows < Numprocs)
203 {
204 printf("The number of rows of Matrix should be greater than number of processors\n");
205 MPI_Finalize();
206 exit(-1);
207 }
208 /* Allocating and Populating the Matrix */
209
210 Matrix = (float **) malloc(NoofRows * sizeof(float *));
211 for (irow = 0; irow < NoofRows; irow++)
212 Matrix[irow] = (float *) malloc(NoofCols * sizeof(float));
213
214 for (irow = 0; irow < NoofRows; irow++)
215 for (icol = 0; icol < NoofCols; icol++)
216 fscanf(fp, "%f", &Matrix[irow][icol]);
217
218
219 /* Storing the number of Rows to be operated by each process in array */
220
221 modval = NoofRows % Numprocs;
222 divval = NoofRows / Numprocs;
223 MyNoofRows = (MyRank < modval ? divval + 1 : divval);
224
225 ArrayNoofRows = (int *) malloc(Numprocs * sizeof(int));
226 MPI_Allgather(&MyNoofRows, 1, MPI_INT, ArrayNoofRows, 1, MPI_INT, MPI_COMM_WORLD);
227
228 /* Storing the starting Row to be operated by each process in array */
229
230 Displacement = (int *) malloc(Numprocs * sizeof(int));
231 Displacement[0] = 0;
232 for (iproc = 1; iproc < Numprocs; iproc++)
233 Displacement[iproc] = Displacement[iproc - 1] + ArrayNoofRows[iproc - 1];
234
235 currentRow = Displacement[MyRank];
236
237 MPI_Barrier(MPI_COMM_WORLD);
238
239 /*
240 * Call threads equal to number of Rows to be processed by this
241 * process
242 */
243
244 threads = (pthread_t *) malloc(sizeof(pthread_t) * MyNoofRows);
245
246 for (irow = 0; irow < MyNoofRows; irow++)
247 pthread_create(&threads[irow], NULL, (void *(*) (void *)) MyPartOfCalc, (void *) irow);
248
249 MPI_Barrier(MPI_COMM_WORLD);
250 for (irow = 0; irow < MyNoofRows; irow++)
251 pthread_join(threads[irow], NULL);
252
253 MPI_Barrier(MPI_COMM_WORLD);
254
255 MPI_Reduce(&max, &Result, 1, MPI_FLOAT, MPI_MAX, Root, MPI_COMM_WORLD);
256
257
258 if (MyRank == Root)
259 {
260 printf("The matrix is :\n\n");
261 for (irow = 0; irow < NoofRows; irow++)
262 {
263 for (icol = 0; icol < NoofCols; icol++)
264 printf("%.1f ", Matrix[irow][icol]);
265 printf("\n");
266 }
267 printf("The infinity norm is %f \n", Result);
268 }
269 MPI_Finalize();
270
271}
Note: See TracBrowser for help on using the repository browser.