source: CIVL/examples/mpi/matmat_mw/matmat_mw.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

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

  • Property mode set to 100644
File size: 3.5 KB
Line 
1/* matmat_mw.c : parallel multiplication of two matrices.
2 *
3 * To execute: mpicc matmat_mw.c ; mpiexec -n 4 ./a.out N L M
4 * Or replace "4" with however many procs you want to use.
5 * Arguments N L M should be replaced with any integer numbers which is
6 * no larger than the corresponding dimension decided in the "data" file.
7 * To verify: civl verify matmat_mw.c
8 */
9#include <stdlib.h>
10#include <stdio.h>
11#include <string.h>
12#include <mpi.h>
13
14#define comm MPI_COMM_WORLD
15#ifdef _CIVL
16#include <civlc.cvh>
17$input int _mpi_nprocs_lo = 2;
18$input int _mpi_nprocs_hi = 4;
19/* Dimensions of 2 matrices: a[N][L] * b[L][M] */
20$input int NB = 3; // upper bound of N
21$input int N;
22$assume(0 < N && N <= NB);
23$input int LB = 3; // upper bound of L
24$input int L;
25$assume(0 < L && L <= LB);
26$input int MB = 3; // upper bound of M
27$input int M;
28$assume(0 < M && M <= MB);
29$input double a[N][L]; // input data for matrix a
30$input double b[L][M]; // input data for matrix b
31double oracle[N][M]; // matrix stores results of a sequential run
32#else
33FILE * fp; // pointer to the data file which gives two matrices
34int N, L, M;
35#endif
36
37/* prints a matrix. In CIVL mode, it will compare the matrix with the
38 result of the sequential run.*/
39void printMatrix(int numRows, int numCols, double *m) {
40 int i, j;
41
42 for (i = 0; i < numRows; i++) {
43 for (j = 0; j < numCols; j++) {
44 printf("%f ", m[i*numCols + j]);
45#ifdef _CIVL
46 $assert(m[i*numCols + j] == oracle[i][j],
47 "The calculated value at position [%d][%d] is %f"
48 " but the expected one is %f",
49 i, j, m[i*numCols+j], oracle[i][j]);
50#endif
51 }
52 printf("\n");
53 }
54 printf("\n");
55}
56
57/* Computes a vetor with length L times a matrix with dimensions [L][M] */
58void vecmat(double vector[L], double matrix[L][M], double result[M]) {
59 int j, k;
60
61 for (j = 0; j < M; j++)
62 for (k = 0, result[j] = 0.0; k < L; k++)
63 result[j] += vector[k]*matrix[k][j];
64}
65
66int main(int argc, char *argv[]) {
67 int rank, nprocs, i, j;
68 MPI_Status status;
69
70#ifndef _CIVL
71 N = atoi(argv[1]);
72 L = atoi(argv[2]);
73 M = atoi(argv[3]);
74#endif
75 MPI_Init(&argc, &argv);
76 MPI_Comm_rank(comm, &rank);
77 MPI_Comm_size(comm, &nprocs);
78 if (rank == 0) {
79 double c[N][M], tmp[M];
80 int count;
81#ifndef _CIVL
82 double a[N][L], b[L][M];
83
84 fp = fopen("data", "r");
85 for (i = 0; i < N; i++)
86 for (j = 0; j < L; j++)
87 fscanf(fp,"%lf", &a[i][j]);
88 for (i = 0; i < L; i++)
89 for (j = 0; j < M; j++)
90 fscanf(fp,"%lf",&b[i][j]);
91#else
92 // sequential run
93 for(int i=0; i < N; i++) {
94 vecmat(a[i], b, &oracle[i][0]);
95 }
96
97#endif
98 MPI_Bcast(&b[0][0], L*M, MPI_DOUBLE, 0, comm);
99 for (count = 0; count < nprocs-1 && count < N; count++)
100 MPI_Send(&a[count][0], L, MPI_DOUBLE, count+1, count+1, comm);
101 for (i = 0; i < N; i++) {
102 MPI_Recv(tmp, M, MPI_DOUBLE, MPI_ANY_SOURCE, MPI_ANY_TAG, comm, &status);
103 for (j = 0; j < M; j++) c[status.MPI_TAG-1][j] = tmp[j];
104 if (count < N) {
105 MPI_Send(&a[count][0], L, MPI_DOUBLE, status.MPI_SOURCE, count+1, comm);
106 count++;
107 }
108 }
109 for (i = 1; i < nprocs; i++) MPI_Send(NULL, 0, MPI_INT, i, 0, comm);
110 printMatrix(N, M, &c[0][0]);
111#ifndef _CIVL
112 fclose(fp);
113#endif
114 } else {
115 double b[L][M], in[L], out[M];
116
117 MPI_Bcast(&b[0][0], L*M, MPI_DOUBLE, 0, comm);
118 while (1) {
119 MPI_Recv(in, L, MPI_DOUBLE, 0, MPI_ANY_TAG, comm, &status);
120 if (status.MPI_TAG == 0) break;
121 vecmat(in, b, out);
122 MPI_Send(out, M, MPI_DOUBLE, 0, status.MPI_TAG, comm);
123 }
124 }
125 MPI_Finalize();
126 return 0;
127}
128
Note: See TracBrowser for help on using the repository browser.