Subversion Repositories programming

Rev

Rev 323 | Rev 325 | Go to most recent revision | Details | Compare with Previous | 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;
6
 
7
/**
8
 * NOTE: Accessing "matrices" in this program is a little strange.
9
 * I decided to implement matrices using an array. To get to a[row][col],
10
 * you would use a[row*a_size+col]. Pretty simple actually.
11
 */
12
 
13
int* allocate (int rows, int cols)
14
{
15
    int *temp = NULL;
16
 
17
    if ((temp = (int*) malloc (rows * cols * sizeof(int))) == NULL)
18
        printf ("Could not allocate memory for array of size: %d x %d\n", rows, cols);
19
 
20
    return temp;
21
}
22
 
23
int main (int argc, char *argv[])
24
{
324 ira 25
    const int n = 4;
322 ira 26
    int myid, numprocs;
27
    int *a, *b, *c;
28
    int i, j, k;
29
    int temp;
30
 
31
    /* Get all of the necessary info for each process */
32
    MPI_Init (&argc, &argv);
33
    MPI_Comm_rank (MPI_COMM_WORLD, &myid);
34
    MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
35
 
36
    /* Allocate all of b for each process, since we'll need it */
37
    b = allocate (n, n);
38
 
39
    if (myid == ROOT_NODE)
40
    {
41
        /* Allocate the full a and c, since we need to initialize it */
42
        a = allocate (n, n);
43
        c = allocate (n, n);
44
 
45
        /* Initialize values */
323 ira 46
#if 0
322 ira 47
        for (i=0; i<n; i++)
48
            for (j=0; j<n; j++)
49
            {
50
                a[i*n+j] = i*n+j+1;
51
                b[i*n+j] = i*n+j+1;
52
            }
323 ira 53
#endif
54
 
324 ira 55
        for (i=0; i<n; i++)
56
            for (j=0; j<n; j++)
57
            {
58
                a[i*n+j] = INT_MAX;
59
                b[i*n+j] = INT_MAX;
60
            }
61
 
323 ira 62
        b[0] = 0;
324 ira 63
        b[1] = 2;
323 ira 64
        b[2] = INT_MAX;
324 ira 65
        b[3] = 10;
323 ira 66
 
324 ira 67
        b[4] = 2;
68
        b[5] = 0;
69
        b[6] = 2;
70
        b[7] = INT_MAX;
71
 
72
        b[8]  = INT_MAX;
73
        b[9]  = 2;
74
        b[10] = 0;
75
        b[11] = 3;
76
 
77
        b[12] = 10;
78
        b[13] = INT_MAX;
79
        b[14] = 3;
80
        b[15] = 0;
81
 
323 ira 82
        memcpy (a, b, n*n*sizeof(int));
322 ira 83
    }
84
    else
85
    {
86
        /* Allocate our slice of a and c, since that's all we need */
87
        a = allocate (n/numprocs, n);
88
        c = allocate (n/numprocs, n);
89
    }
90
 
91
    /* Send a slice of a to each process.
92
     * Send all of b to each process, since they need all of it */
93
    MPI_Scatter (a, n*n/numprocs, MPI_INT, a, n*n/numprocs, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
94
    MPI_Bcast (b, n*n, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
95
 
324 ira 96
    for (i=0; i<n/numprocs; i++)
97
        for (j=0; j<n; j++)
98
            c[i*n+j] = INT_MAX;
323 ira 99
 
322 ira 100
    /* Multiply our slice of the matrix, store it in c */
101
    for (i=0; i<n/numprocs; i++)
102
    {
103
        for (j=0; j<n; j++)
104
        {
105
            // MATRIX_MULT
323 ira 106
            // c[i*n+j]=0;
322 ira 107
 
108
            // SHORTEST PATH
323 ira 109
            //c[i*n+j] = INT_MAX;
322 ira 110
 
111
            for (k=0; k<n; k++)
112
            {
113
                // MATRIX MULT
323 ira 114
                // c[i*n+j] += a[i*n+k] * b[k*n+j];
322 ira 115
 
116
                // SHORTEST PATH
323 ira 117
                if (a[i*n+k] == INT_MAX || b[k*n+j] == INT_MAX)
118
                    temp = INT_MAX;
119
                else
120
                    temp = a[i*n+k] + b[k*n+j];
322 ira 121
 
324 ira 122
                //if (i*n+j == 3 || i*n+j == 12)
123
                //    printf ("i=%d, j=%d, k=%d, a[%d]=%d, b[%d]=%d, temp=%d\n", i,j,k, i*n+k,a[i*n+k], k*n+j,b[k*n+j], temp);
323 ira 124
 
125
                if (temp < c[i*n+j])
126
                    c[i*n+j] = temp; //a[i*n+k] + b[k*n+j];
322 ira 127
            }
128
        }
129
    }
130
 
131
    /* Recieve each slice from all processes, store the result in c */
132
    MPI_Gather (c, n*n/numprocs, MPI_INT, c, n*n/numprocs, MPI_INT, ROOT_NODE, MPI_COMM_WORLD);
133
 
134
    if (myid == ROOT_NODE)
135
    {
136
        for (i=0; i<n; i++)
323 ira 137
        {
322 ira 138
            for (j=0; j<n; j++)
323 ira 139
                printf ("%d\t", c[i*n+j]);
140
 
141
            printf ("\n");
142
        }
322 ira 143
    }
144
 
145
    /* Free all of the memory we allocated earlier */
146
    free (a);
147
    free (b);
148
    free (c);
149
 
150
    MPI_Finalize ();
151
    return 0;
152
}
153