Subversion Repositories programming

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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