source: /cluster/svnroot/bccd-ng/bw-institute/2016/day06/matmul/mpi.c @ 5712

Last change on this file since 5712 was 5712, checked in by skylar, 5 years ago

local product matrix should start at 0

  • Property svn:keywords set to Id
File size: 3.9 KB
Line 
1/*
2 * $Id: mpi.c 5712 2016-05-27 00:59:29Z skylar $
3 */
4
5#include "matmul.h"
6#include "mpi.h"
7
8#define FIRST_RANK 0
9
10int main(int argc,char **argv) {
11    int rank,size,c;
12    unsigned int start_row,stop_row,stride;
13    bool print;
14    struct matrix m1,m2,local_dst_m;
15
16    MPI_Init(&argc,&argv);
17    MPI_Comm_size(MPI_COMM_WORLD,&size);
18    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
19
20#ifdef DEBUG
21    fprintf(stderr,"Rank %d/%d - Hello World\n",rank,size);
22#endif
23
24    m1.rows = m1.cols = m2.rows = m2.cols = 0;
25
26    while((c = getopt(argc,argv, "x:y:a:b:p")) != -1) {
27        switch(c) {
28            case 'x':
29                m1.cols = atoi(optarg);
30                break;
31            case 'y':
32                m1.rows = atoi(optarg);
33                break;
34            case 'a':
35                m2.cols = atoi(optarg);
36                break;
37            case 'b':
38                m2.rows = atoi(optarg);
39                break;
40            case 'p':
41                print = true;
42                break;
43            case '?':
44                usage();
45                exit(EXIT_FAILURE);
46        }
47    }
48
49    if(m1.rows == 0 || m1.cols == 0 || m2.rows == 0 || m2.cols == 0) {
50        fprintf(stderr,"Supply row and column counts!\n");
51        usage();
52        exit(EXIT_FAILURE);
53    }
54
55    if(m1.cols != m2.rows) {
56        fprintf(stderr,"Invalid matrix dimensions!\n");
57        exit(EXIT_FAILURE);
58    }
59
60
61    m1.matrix       = safe_malloc_int(
62            m1.rows*m1.cols,
63            "Allocating first matrix"
64            );
65    m2.matrix       = safe_malloc_int(
66            m2.rows*m2.cols,
67            "Allocating second matrix"
68            );
69
70    if(rank == FIRST_RANK) {
71        // Each thread will get a separate random seed
72        unsigned int *random_seeds = init_random_seeds();
73        init_matrix(&m1,random_seeds);
74        init_matrix(&m2,random_seeds);
75
76        // Declare and allocate full destination matrix
77        // Will be populated via MPI_Gather
78        struct matrix dst_m;
79        dst_m.rows = m1.rows;
80        dst_m.cols = m2.cols;
81        dst_m.matrix    = safe_malloc_int(
82                dst_m.rows*dst_m.cols,
83                "Allocating destination matrix"
84                );
85
86        if(print) {
87            puts("Matrix 1\n");
88            print_matrix(&m1);
89            puts("");
90            puts("Matrix 2\n");
91            print_matrix(&m2);
92            puts("");
93        }
94    }
95
96    // Broadcast each element of the structs, to avoid the complexity
97    // of creating custom data types
98    MPI_Bcast(&m1.rows,1,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
99    MPI_Bcast(&m1.cols,1,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
100    MPI_Bcast(&m2.rows,1,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
101    MPI_Bcast(&m2.cols,1,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
102    MPI_Bcast(m1.matrix,m1.rows*m1.cols,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
103    MPI_Bcast(m2.matrix,m2.rows*m2.cols,MPI_INT,FIRST_RANK,MPI_COMM_WORLD);
104
105    // Calculate row offset in product matrix to start and stop calculation
106    stride                  = m1.rows/size;
107    start_row               = rank*stride;
108
109    // Assign an even number of rows to each rank, except for the last rank
110    // whiich gets the remainder
111    if(rank<(size-1)) {
112        stop_row = stride*(rank+1);
113    }
114    else {
115        stop_row = m1.rows;
116    }
117
118    // Only need to allocate enough for the local computation
119    local_dst_m.cols        = m2.cols;
120    local_dst_m.rows        = (stop_row-start_row),
121    local_dst_m.matrix      = safe_malloc_int(
122            local_dst_m.rows*local_dst_m.cols,
123            "Allocating local destination matrix"
124            );
125
126#ifdef DEBUG
127    fprintf(stderr,"Rank %d - Stride %u, start_row %u, stop_row %u\n",
128            rank,stride,start_row,stop_row);
129#endif
130    matmul(&m1,&m2,&local_dst_m,start_row,stop_row);
131
132#ifdef DEBUG
133    fprintf(stderr,"Rank %d local destination matrix:\n",rank);
134    print_matrix(&local_dst_m);
135#endif
136
137    MPI_Finalize();
138
139    free(m1.matrix);
140    free(m2.matrix);
141    free(local_dst_m.matrix);
142
143    exit(EXIT_SUCCESS);
144}
Note: See TracBrowser for help on using the repository browser.