Subversion Repositories programming

Rev

Rev 326 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
327 ira 1
/* proj3_10.c - implements the APSP algorithm for a matrix of size 10x10
2
 *              as provided in the project description.
3
 *
4
 * Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)
5
 */
6
 
7
 
322 ira 8
#include <stdio.h>
9
#include <limits.h>
10
#include <mpi.h>
11
 
12
const int ROOT_NODE = 0;
325 ira 13
int numprocs;
14
int myid;
322 ira 15
 
16
/**
17
 * NOTE: Accessing "matrices" in this program is a little strange.
18
 * I decided to implement matrices using an array. To get to a[row][col],
19
 * you would use a[row*a_size+col]. Pretty simple actually.
20
 */
21
 
22
int* allocate (int rows, int cols)
23
{
24
    int *temp = NULL;
25
 
26
    if ((temp = (int*) malloc (rows * cols * sizeof(int))) == NULL)
27
        printf ("Could not allocate memory for array of size: %d x %d\n", rows, cols);
28
 
29
    return temp;
30
}
31
 
325 ira 32
void print_matrix (int *b, int n, const char *s)
33
{
34
    int i,j;
35
 
36
    if (n<=10) // n<=10
37
    {
38
        printf ("%s\n", s);
39
 
40
        for (i=0; i<n; i++)
41
        {
42
            for (j=0; j<n; j++)
43
                printf ("%d\t", b[i*n+j]);
44
 
45
            printf ("\n");
46
        }
47
        printf ("\n");
48
    }
49
    else if (n<=100) // 10<n<=100
50
    {
51
        printf ("%s\n", s);
52
 
53
        // First 2 rows
54
        for (i=0; i<2; i++)
55
        {
56
            for (j=0; j<n; j++)
57
                printf ("%d\t", b[i*n+j]);
58
 
59
            printf ("\n");
60
        }
61
        printf ("\n");
62
 
63
        // First 2 cols
64
        for (i=0; i<n; i++)
65
        {
66
            for (j=0; j<2; j++)
67
                printf ("%d\t", b[i*n+j]);
68
 
69
            printf ("\n");
70
        }
71
    }
72
}
73
 
74
void matrix_mult (int *b, int *c, int n)
75
{
76
    int i,j,k,ii,temp;
77
 
78
    /* Multiply our slice of the matrix, store it in c */
79
    for (ii=0; ii<n/numprocs; ii++)
80
    {
81
        i = ii + myid * n/numprocs; // i is the offset into b
82
 
83
        for (j=0; j<n; j++)
84
        {
85
            // MATRIX_MULT
86
            // c[i*n+j]=0;
87
 
88
            // SHORTEST PATH
89
            c[ii*n+j] = INT_MAX;
90
 
91
            for (k=0; k<n; k++)
92
            {
93
                // MATRIX MULT
94
                // c[i*n+j] += a[i*n+k] * b[k*n+j];
95
 
96
                // SHORTEST PATH
97
                if (b[i*n+k] == INT_MAX || b[k*n+j] == INT_MAX)
98
                    temp = INT_MAX;
99
                else
100
                    temp = b[i*n+k] + b[k*n+j];
101
 
102
                if (temp < c[ii*n+j])
103
                    c[ii*n+j] = temp;
104
            }
105
        }
106
    }
107
}
108
 
322 ira 109
int main (int argc, char *argv[])
110
{
327 ira 111
    const int n = 10;
325 ira 112
    int *b, *c;
113
    int i, j, k, temp, t;
114
    MPI_Status status;
322 ira 115
 
116
    /* Get all of the necessary info for each process */
117
    MPI_Init (&argc, &argv);
118
    MPI_Comm_rank (MPI_COMM_WORLD, &myid);
119
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
120
 
326 ira 121
    /* Do a quick sanity check for the correct number of processors */
122
    if (n % numprocs != 0)
123
    {
124
        if (myid == 0)
125
        {
126
            printf ("%d mod %d must be zero!\n", n, numprocs);
127
            printf ("You should probably change the -np parameter\n");
128
        }
129
 
130
        MPI_Finalize ();
131
        return 1;
132
    }
133
 
322 ira 134
    /* Allocate all of b for each process, since we'll need it */
135
    b = allocate (n, n);
136
 
137
    if (myid == ROOT_NODE)
138
    {
325 ira 139
        /* Allocate the full c, since we need to initialize it */
322 ira 140
        c = allocate (n, n);
141
 
142
        /* Initialize values */
143
        for (i=0; i<n; i++)
144
            for (j=0; j<n; j++)
324 ira 145
                b[i*n+j] = INT_MAX;
146
 
327 ira 147
        b[1] = 3;
148
        b[2] = 2;
149
        b[5] = 5;
150
        b[6] = 4;
151
        b[7] = 9;
152
        b[8] = 1;
153
        b[9] = 15;
323 ira 154
 
327 ira 155
        b[10] = 3;
156
        b[12] = 4;
157
        b[13] = 7;
158
        b[14] = 28;
159
        b[16] = 2;
160
        b[17] = 9;
161
        b[19] = 1;
324 ira 162
 
327 ira 163
        b[20] = 2;
164
        b[21] = 4;
165
        b[24] = 3;
166
        b[25] = 12;
167
        b[26] = 5;
168
        b[28] = 10;
169
        b[29] = 4;
324 ira 170
 
327 ira 171
        b[31] = 7;
172
        b[34] = 15;
173
        b[35] = 6;
174
        b[36] = 2;
175
        b[37] = 5;
324 ira 176
 
327 ira 177
        b[41] = 28;
178
        b[42] = 3;
179
        b[43] = 15;
180
        b[45] = 1;
181
        b[46] = 3;
182
        b[48] = 2;
183
        b[49] = 9;
184
 
185
        b[50] = 5;
186
        b[52] = 12;
187
        b[53] = 6;
188
        b[54] = 1;
189
        b[56] = 3;
190
        b[58] = 2;
191
        b[59] = 9;
192
 
193
        b[60] = 4;
194
        b[61] = 2;
195
        b[62] = 5;
196
        b[63] = 2;
197
        b[64] = 3;
198
        b[65] = 3;
199
        b[67] = 1;
200
        b[69] = 4;
201
 
202
        b[70] = 9;
203
        b[71] = 9;
204
        b[73] = 5;
205
        b[76] = 1;
206
        b[78] = 7;
207
        b[79] = 2;
208
 
209
        b[80] = 1;
210
        b[82] = 10;
211
        b[84] = 4;
212
        b[85] = 2;
213
        b[87] = 7;
214
        b[89] = 4;
215
 
216
        b[90] = 15;
217
        b[91] = 1;
218
        b[92] = 4;
219
        b[94] = 7;
220
        b[95] = 9;
221
        b[96] = 4;
222
        b[97] = 2;
223
        b[98] = 4;
224
 
225
        /* Force b[i][i] = 0 */
226
        for (i=0; i<n; i++)
227
            b[i*n+i] = 0; 
228
 
325 ira 229
        if (n<=100)
230
            print_matrix (b, n, "Input Matrix:");
231
        else
232
        {
233
            printf ("Beginning calculation for all shortest paths\n");
234
            printf ("for a graph with %d nodes\n", n);
235
        }
236
 
322 ira 237
    }
238
    else
239
    {
325 ira 240
        /* Allocate our slice of c, since that's all we need */
322 ira 241
        c = allocate (n/numprocs, n);
242
    }
243
 
325 ira 244
    /* Send all of b to each process, since they need all of it */
322 ira 245
    MPI_Bcast (b, n*n, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
246
 
325 ira 247
    /* Run our piece of the calculation.
248
     * Synchronize data with all other processes at the end of each step. */
249
    for (t=0; t<ceil(log(n-1)); t++)
322 ira 250
    {
325 ira 251
        matrix_mult (b, c, n);
252
        MPI_Allgather (c, n*n/numprocs, MPI_INT, b, n*n/numprocs, MPI_INT, MPI_COMM_WORLD);
322 ira 253
    }
254
 
325 ira 255
    /* Print out the result matrix. */
322 ira 256
    if (myid == ROOT_NODE)
257
    {
325 ira 258
        if (n<=100)
259
            print_matrix (b, n, "Result Matrix:");
260
        else
323 ira 261
        {
325 ira 262
            printf ("Finished calculation for all shortest paths\n");
263
            printf ("for a graph with %d nodes\n", n);
323 ira 264
        }
322 ira 265
    }
266
 
267
    /* Free all of the memory we allocated earlier */
268
    free (b);
269
    free (c);
270
 
271
    MPI_Finalize ();
272
    return 0;
273
}
274