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