Select Git revision
ArgumentParser.h
spmv.c 2.53 KiB
#include <stdio.h>
#include <stdlib.h>
extern double mysecond(void);
/*
* Example of sparse matrix-vector multiply, using CSR (compressed sparse
* row format). Because this code is in C, the index values in the ia and ja
* arrays are zero origin rather than one origin as they would be in Fortran.
*
* While this code does time the sparse matrix-vector product, as noted below,
* these timings are too simple to be used for serious analysis.
*/
int main(int argc, char *argv[])
{
int *ia, *ja;
double *a, *x, *y;
int row, i, j, idx, n, nnzMax, nnz, nrows;
double ts, t, rate;
n = 10;
if (argc > 1) n = atoi(argv[1]);
/* Warning: if n > sqrt(2^31), you may get integer overflow */
/* Allocate enough storage for the matix. We allocate more than
is needed in order to simplify the code */
nrows = n * n;
nnzMax = nrows * 5;
ia = (int*)malloc(nrows*sizeof(int));
ja = (int*)malloc(nnzMax*sizeof(int));
a = (double*)malloc(nnzMax*sizeof(double));
/* Allocate the source and result vectors */
x = (double*)malloc(nrows*sizeof(double));
y = (double*)malloc(nrows*sizeof(double));
/* Create a pentadiagonal matrix, representing very roughly a finite
difference approximation to the Laplacian on a square n x n mesh */
row = 0;
nnz = 0;
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
ia[row] = nnz;
if (i>0) { ja[nnz] = row - n; a[nnz] = -1.0; nnz++; }
if (j>0) { ja[nnz] = row - 1; a[nnz] = -1.0; nnz++; }
ja[nnz] = row; a[nnz] = 4.0; nnz++;
if (j<n-1) { ja[nnz] = row + 1; a[nnz] = -1.0; nnz++; }
if (i<n-1) { ja[nnz] = row + n; a[nnz] = -1.0; nnz++; }
row++;
}
}
ia[row] = nnz;
/* Create the source (x) vector */
for (i=0; i<nrows; i++) x[i] = 1.0;
/* Perform a matrix-vector multiply: y = A*x */
/* Warning: To use this for timing, you need to (a) handle cold start
(b) perform enough tests to make timing quantum relatively small */
ts = mysecond();
for (row=0; row<nrows; row++) {
double sum = 0.0;
for (idx=ia[row]; idx<ia[row+1]; idx++) {
sum += a[idx] * x[ja[idx]];
}
y[row] = sum;
}
t = mysecond() - ts;
/* Compute with the result to keep the compiler for marking the
code as dead */
for (row=0; row<nrows; row++) {
if (y[row] < 0) {
fprintf(stderr,"y[%d]=%f, fails consistency test\n", row, y[row]);
}
}
printf("Time for Sparse Ax, nrows=%d, nnz=%d, T = %f\n", nrows, nnz, t);
free(ia); free(ja); free(a); free(x); free(y);
return 0;
}