#include #include #pragma CIVL ACSL /* Filename : vss_example.cvl Author : Stephen F. Siegel Created : 2023-08-03 Modified : 2023-08-07 Verification of matrix-vector multiplication routine using Compressed Sparse Row representation for the matrix. Start with an arbitrary CSR matrix with N and M under specified bounds. Take an arbitrary vector v of length M. Call sparse matrix-vector multiplication routine to compute "actual" resulting vector. Convert the sparse matrix to a dense matrix and compute dense matrix-vector product to get "expected" result. Check the actual and expected agree. */ #include #include #include /* Compressed Sparse Row (CSR) sparse matrix representation. */ struct csr_matrix { double *val; // length NZ (number of non-0s) int *col_ind; // length NZ int *row_ptr; // length N+1. row_ptr[N]=NZ. int rows, cols; // number of rows (N), number of columns }; /* Multiplies matrix m and (dense) vector v, storing result in already allocated vector p. If m has dimensions NxM then v has length M and p has length N. */ /* Implementation of CSR matrix-vector multiplication from "LAProof: A Library of Formal Proofs of Accuracy and Correctness for Linear Algebra Programs" by Kellison, Appel, Tekriwal, and Bindel, IEEE 30th Symposium on Computer Arithmetic, 2023. That paper cites Barrett et al., "Templates for the Solution of Linear Systems: Building Blocks for Iterative Methods", SIAM, 1994, as the source of the algorithm. */ void csr_matrix_vector_multiply(struct csr_matrix *m, double *v, double *p) { int i, rows=m->rows; double *val = m->val; int *col_ind = m->col_ind; int *row_ptr = m->row_ptr; int next=row_ptr[0]; /*@ loop invariant next == row_ptr[i]; @ loop assigns p[0..rows-1], next; @ focus F | p[F]; @*/ for (i=0; i