Changes between Version 24 and Version 25 of Examples


Ignore:
Timestamp:
08/07/24 12:59:07 (21 months ago)
Author:
siegel
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Examples

    v24 v25  
    6363File `csr_driver.cvl`:
    6464{{{
    65 /* Filename : csr.cvl
     65/* Filename : csr_driver.cvl
    6666   Author   : Stephen F. Siegel
    67    Created  : 2023-09-03
    68    Modified : 2023-09-04
     67   Created  : 2023-08-03
     68   Modified : 2023-08-07
    6969
    7070   Verification of matrix-vector multiplication routine using
     
    8282#include "csr.h"
    8383
     84typedef struct $mat {
     85  int n, m; // num rows, columns;
     86  double data[][];
     87} $mat;
     88
     89void $mat_vec_mul($mat mat, double * v, double *p) {
     90  int n = mat.n, m = mat.m;
     91  for (int i=0; i<n; i++) {
     92    double s = 0.0;
     93    for (int j=0; j<m; j++) s += mat.data[i][j]*v[j];
     94    p[i] = s;
     95  }
     96}
     97
     98$mat $mat_csr(struct csr_matrix csr) {
     99  int n = csr.rows, m = csr.cols;
     100  $mat mat;
     101  mat.n = n;
     102  mat.m = m;
     103  mat.data = (double[n][m])$lambda(int i,j) 0.0;
     104  for (int i=0; i<n; i++) {
     105    int r = csr.row_ptr[i], rnxt = csr.row_ptr[i+1];
     106    for (int k=r; k<rnxt; k++)
     107      mat.data[i][csr.col_ind[k]] = csr.val[k];
     108  }
     109  return mat;
     110}
     111
    84112// N,M=number of rows,columns.  N_B,M_B=upper bounds on N,M
    85113$input int N_B = 3, M_B = 3, N, M;
     
    91119   of integers in [0,max].  Precondition: 0 <= len <= max+1 */
    92120void strict_inc(int * p, int len, int max) {
    93   $assert(0<=len && len <= max+1);
     121  //$assert(0<=len && len <= max+1);
    94122  for (int i=0; i<len; i++) {
    95123    int a = (i == 0 ? 0 : p[i-1]+1), b = max - len + i + 1;
     
    146174}
    147175
    148 /* Gets the (i,j)-th entry from the CSR matrix mat */
    149 double get_i_j(struct csr_matrix mat, int i, int j) {
    150   int r = mat.row_ptr[i], rnxt = mat.row_ptr[i+1], col;
    151   for (int k=r; k<rnxt; k++) {
    152     col = mat.col_ind[k];
    153     if (col == j) return mat.val[k];
    154     if (col > j) break;
    155   }
    156   return 0.0;
    157 }
    158 
    159 /* Makes a dense matrix from the given CSR matrix */
    160 double ** make_dense(struct csr_matrix mat) {
    161   int n = mat.rows, m = mat.cols;
    162   double ** dense = malloc(n*sizeof(double*));
    163   for (int i=0; i<n; i++) {
    164     dense[i] = malloc(m*sizeof(double));
    165     for (int j=0; j<m; j++)
    166       dense[i][j] = get_i_j(mat, i, j);
    167   }
    168   return dense;
    169 }
    170 
    171 void destroy_dense(double ** dense, int nrow) {
    172   for (int i=0; i<nrow; i++) free(dense[i]);
    173   free(dense);
    174 }
    175 
    176 void dense_matrix_vector_multiply(int nrow, int ncol, double ** dense,
    177                                   double * v, double *p) {
    178   for (int i=0; i<nrow; i++) {
    179     double s = 0.0;
    180     for (int j=0; j<ncol; j++) s += dense[i][j]*v[j];
    181     p[i] = s;
    182   }
    183 }
    184 
    185176int main(void) {
    186177  double v[M], actual[N], expected[N];
     
    188179  struct csr_matrix mat = make_csr(N, M);
    189180  csr_matrix_vector_multiply(&mat, v, actual);
    190   double ** dense = make_dense(mat);
    191   dense_matrix_vector_multiply(N, M, dense, v, expected);
     181  $mat dense = $mat_csr(mat);
     182  $mat_vec_mul(dense, v, expected);
    192183#ifdef VERBOSE
    193184  printf("\n");
     
    202193#endif
    203194  destroy_csr(mat);
    204   destroy_dense(dense, N);
    205195  $assert($equals(actual, expected));
    206196}
     
    339329}}}
    340330
    341 Times on a 2020 M1 !MacBook Pro: for matrices up to size 3x3: 10s.
    342 Up to 3x4: 40s.  Up to 4x3: 43s.  Up to 4x4: 38 minutes.
     331Times on a 2020 M1 !MacBook Pro: for matrices up to size 3x3: 6s.
     332Up to 3x4: 17s.  Up to 4x3: 17s.  Up to 4x4: 28 minutes.