source: CIVL/examples/mpi-pthread/mpi-pthreads-marix-vector_fix.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 if(flag==0){
70 rowlimit = currentRow + MyNoofRows;
71 flag++;}
72 pthread_mutex_unlock(&mutex_Flag);
73 //}
74 while (1)
75 {
76
77 /*
78 * Thread selects the row of Matrix on which it has to do the
79 * operation
80 */
81
82 pthread_mutex_lock(&mutex_Row);
83 {
84 if (currentRow >= rowlimit)
85 {
86 pthread_mutex_unlock(&mutex_Row);
87 pthread_exit(0);
88 }
89 myRow = currentRow;
90 currentRow++;
91 GlobalIndex++;
92 myindex = GlobalIndex;
93 }
94 pthread_mutex_unlock(&mutex_Row);
95
96 /*
97 * Perform the multiplication on the row selected and store
98 * the addendum in MyResult array
99 */
100
101 printf(" Thread Id %d of process with Rank %d operated on Matrix Row %d\n", Id, MyRank, myRow);
102 MyResult[myindex] = 0.0;
103
104 for (icol = 0; icol < NoofCols; icol++)
105 MyResult[myindex] += Matrix[myRow][icol] * Vector[icol];
106 }
107
108}
109
110
111int main(int argc, char **argv)
112{
113
114 int iproc, irow, icol, modval, divval, *Displacement, iprocb, *ArrayNoofRows;
115 int Numprocs, Root = 0, NoofRows, VectorSize;
116 float *Results;
117
118 pthread_t *threads;
119
120
121 /* MPI Initialisation ... */
122
123 MPI_Init(&argc, &argv);
124 MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);
125 MPI_Comm_size(MPI_COMM_WORLD, &Numprocs);
126
127 /* Validity checking for minimum number of processors */
128
129 if (Numprocs < 2)
130 {
131 printf("Invalid Number of Processors ..... \n");
132 printf("Numprocs must be greater than 1 ......\n");
133 MPI_Finalize();
134 exit(0);
135 }
136 /* Read the sizes of Matrix and Vector */
137
138 if (MyRank == Root)
139 {
140 printf("Enter the number of rows and columns of Matrix\n");
141 scanf("%d %d", &NoofRows, &NoofCols);
142 printf("Enter the size of Vector\n");
143 scanf("%d", &VectorSize);
144 #ifdef _CIVL
145 $assume(NoofRows <= NUM_ROWS_BOUND);
146 $assume(NoofCols <= NUM_COLS_BOUND);
147 #endif
148 }
149 MPI_Barrier(MPI_COMM_WORLD);
150
151 MPI_Bcast(&NoofRows, 1, MPI_INT, Root, MPI_COMM_WORLD);
152 MPI_Bcast(&NoofCols, 1, MPI_INT, Root, MPI_COMM_WORLD);
153 MPI_Bcast(&VectorSize, 1, MPI_INT, Root, MPI_COMM_WORLD);
154
155 /* Validity checking for negative sizes of Matrix and Vector */
156
157 #ifdef _CIVL
158 $assume(NoofRows >= 1 && NoofCols >= 1 && VectorSize >= 1);
159 #endif
160 if (NoofRows < 1 || NoofCols < 1 || VectorSize < 1)
161 {
162 printf("The number of rows,columns or size of Vector should be atleast one\n");
163 MPI_Finalize();
164 exit(-1);
165 }
166 /* Validity checking for minimum number of Rows of Matrix */
167
168 #ifdef _CIVL
169 $assume(NoofRows >= Numprocs);
170 #endif
171 if (NoofRows < Numprocs)
172 {
173 printf("The number of rows of Matrix should be greater than number of processors\n");
174 MPI_Finalize();
175 exit(-1);
176 }
177 /* Validity checking for suitability of sizes for multiplication */
178 #ifdef _CIVL
179 $assume(NoofCols == VectorSize);
180 #endif
181 if (NoofCols != VectorSize)
182 {
183 printf("The number of columns of Matrix should be equal to size of Vector\n");
184 MPI_Finalize();
185 exit(-1);
186 }
187 /* Allocating and Populating the Matrices */
188
189 Matrix = (float **) malloc(NoofRows * sizeof(float *));
190 for (irow = 0; irow < NoofRows; irow++)
191 Matrix[irow] = (float *) malloc(NoofCols * sizeof(float));
192
193 //Vector = (float *) malloc(NoofRows * sizeof(float));
194 Vector = (float *) malloc(NoofCols * sizeof(float));
195
196 for (icol = 0; icol < NoofCols; icol++)
197 {
198 for (irow = 0; irow < NoofRows; irow++)
199 Matrix[irow][icol] = irow + icol;
200 Vector[icol] = icol;
201 }
202
203
204 /* Storing the number of Rows to be operated by each process in array */
205
206 modval = NoofRows % Numprocs;
207 divval = NoofRows / Numprocs;
208 MyNoofRows = (MyRank < modval ? divval + 1 : divval);
209
210 ArrayNoofRows = (int *) malloc(Numprocs * sizeof(int));
211 MPI_Allgather(&MyNoofRows, 1, MPI_INT, ArrayNoofRows, 1, MPI_INT, MPI_COMM_WORLD);
212
213 /* Storing the starting Row to be operated by each process in array */
214
215 Displacement = (int *) malloc(Numprocs * sizeof(int));
216 Displacement[0] = 0;
217
218
219 for (iproc = 1; iproc < Numprocs; iproc++)
220 Displacement[iproc] = Displacement[iproc - 1] + ArrayNoofRows[iproc - 1];
221
222 MyResult = (float *) malloc(MyNoofRows * sizeof(float));
223
224 currentRow = Displacement[MyRank];
225
226 MPI_Barrier(MPI_COMM_WORLD);
227
228 /*
229 * Call threads equal to number of Rows to be processed by this
230 * process
231 */
232
233 threads = (pthread_t *) malloc(sizeof(pthread_t) * MyNoofRows);
234
235 for (irow = 0; irow < MyNoofRows; irow++)
236 pthread_create(&threads[irow], NULL, (void *(*) (void *)) MyPartOfCalc, (void *) irow);
237
238 MPI_Barrier(MPI_COMM_WORLD);
239 for (irow = 0; irow < MyNoofRows; irow++)
240 pthread_join(threads[irow], NULL);
241
242 MPI_Barrier(MPI_COMM_WORLD);
243
244 /* Collection of results from each process using MPI_Gatherv */
245
246 Results = (float *) malloc(NoofRows * sizeof(float));
247
248
249 MPI_Gatherv(MyResult, MyNoofRows, MPI_FLOAT, Results, ArrayNoofRows, Displacement, MPI_FLOAT, Root, MPI_COMM_WORLD);
250
251 /* Printing of the Matrix , Vector and the Result Vector by Root */
252
253 if (MyRank == Root)
254 {
255 printf("\n\nMatrix is\n\n");
256 for (irow = 0; irow < NoofRows; irow++)
257 {
258 printf("Row %d : ", irow);
259 for (icol = 0; icol < NoofCols; icol++)
260 printf(" %f ", Matrix[irow][icol]);
261 printf("\n");
262 }
263 printf("\n");
264 printf("\n");
265
266 printf("Vector is\n\n");
267 for (icol = 0; icol < NoofCols; icol++)
268 printf("Row %d : %f \n", icol, Vector[icol]);
269
270 printf("\n");
271 printf("\n");
272
273 printf("\n\nResult Vector is \n\n");
274 for (irow = 0; irow < NoofRows; irow++)
275 printf("Row %d : %f \n", irow, Results[irow]);
276 }
277 printf("\n");
278 for (irow = 0; irow < NoofRows; irow++)
279 free(Matrix[irow]);
280 free(Matrix);
281 free(Vector);
282 free(ArrayNoofRows);
283 free(Displacement);
284 free(MyResult);
285 free(threads);
286 free(Results);
287 MPI_Finalize();
288 return 0;
289}
Note: See TracBrowser for help on using the repository browser.