| 1 | /* ************************************************************
|
|---|
| 2 | * matmat_spec.c : sequential multiplication of two matrices.
|
|---|
| 3 | *
|
|---|
| 4 | * To execute: cc matmat_mw.c ; ./a.out N L M
|
|---|
| 5 | *
|
|---|
| 6 | * Arguments N L M should be replaced with any integer numbers which
|
|---|
| 7 | * is no larger than the corresponding dimension decided in the "data"
|
|---|
| 8 | * file.
|
|---|
| 9 | *
|
|---|
| 10 | * To verify: civl verify matmat_spec.c
|
|---|
| 11 | *
|
|---|
| 12 | * From FEVS.
|
|---|
| 13 | * ************************************************************
|
|---|
| 14 | */
|
|---|
| 15 | #include <stdlib.h>
|
|---|
| 16 | #include <stdio.h>
|
|---|
| 17 | #include <string.h>
|
|---|
| 18 |
|
|---|
| 19 | #ifdef _CIVL
|
|---|
| 20 |
|
|---|
| 21 | #include <civlc.cvh>
|
|---|
| 22 |
|
|---|
| 23 | /* Dimensions of 2 matrices: a[N][L] * b[L][M] */
|
|---|
| 24 | $input int NB = 3; // upper bound of N
|
|---|
| 25 | $input int N;
|
|---|
| 26 | $assume(0 < N && N <= NB);
|
|---|
| 27 | $input int LB = 3; // upper bound of L
|
|---|
| 28 | $input int L;
|
|---|
| 29 | $assume(0 < L && L <= LB);
|
|---|
| 30 | $input int MB = 3; // upper bound of M
|
|---|
| 31 | $input int M;
|
|---|
| 32 | $assume(0 < M && M <= MB);
|
|---|
| 33 | $input double a[N][L]; // input data for matrix a
|
|---|
| 34 | $input double b[L][M]; // input data for matrix b
|
|---|
| 35 | $output double output[N][M];
|
|---|
| 36 |
|
|---|
| 37 | #else
|
|---|
| 38 |
|
|---|
| 39 | FILE * fp; // pointer to the data file which gives two matrices
|
|---|
| 40 | int N, L, M;
|
|---|
| 41 |
|
|---|
| 42 | #endif
|
|---|
| 43 |
|
|---|
| 44 | /* prints a matrix. In CIVL mode, it will compare the matrix with the
|
|---|
| 45 | result of the sequential run.*/
|
|---|
| 46 | void printMatrix(int numRows, int numCols, double *m) {
|
|---|
| 47 | int i, j;
|
|---|
| 48 |
|
|---|
| 49 | for (i = 0; i < numRows; i++) {
|
|---|
| 50 | for (j = 0; j < numCols; j++)
|
|---|
| 51 | printf("%f ", m[i*numCols + j]);
|
|---|
| 52 | printf("\n");
|
|---|
| 53 | }
|
|---|
| 54 | printf("\n");
|
|---|
| 55 | }
|
|---|
| 56 |
|
|---|
| 57 | /* Computes a vetor with length L times a matrix with dimensions [L][M] */
|
|---|
| 58 | void 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 |
|
|---|
| 66 | int main(int argc, char *argv[]) {
|
|---|
| 67 | int i, j;
|
|---|
| 68 |
|
|---|
| 69 | #ifndef _CIVL
|
|---|
| 70 | if(argc != 3) {
|
|---|
| 71 | printf("Please specify values for N, L, M.\n");
|
|---|
| 72 | exit(0);
|
|---|
| 73 | }
|
|---|
| 74 | N = atoi(argv[1]);
|
|---|
| 75 | L = atoi(argv[2]);
|
|---|
| 76 | M = atoi(argv[3]);
|
|---|
| 77 | #endif
|
|---|
| 78 |
|
|---|
| 79 | double c[N][M];
|
|---|
| 80 |
|
|---|
| 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 | fclose(fp);
|
|---|
| 92 | #endif
|
|---|
| 93 | for(int i=0; i < N; i++)
|
|---|
| 94 | vecmat(a[i], b, &c[i][0]);
|
|---|
| 95 | #ifdef _CIVL
|
|---|
| 96 | $elaborate(N*L*M);
|
|---|
| 97 | // copy to out put
|
|---|
| 98 | for(int i=0; i < N; i++)
|
|---|
| 99 | memcpy(&output[i][0], &c[i][0], M * sizeof(double));
|
|---|
| 100 | #endif
|
|---|
| 101 | printMatrix(N, M, &c[0][0]);
|
|---|
| 102 | return 0;
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|