source: CIVL/examples/mpi-pthread/mpi-pthreads-marix-vector_fix.c@ 38a0561

1.23 2.0 main test-branch
Last change on this file since 38a0561 was bba6978, checked in by Manchun Zheng <zmanchun@…>, 11 years ago

fixed a bug in civl-omp.cvl

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

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