source: CIVL/examples/mpi-pthread/mpi-pthreads-marix-vector.c@ e35f210

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

added assumptions to bound variables.

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

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