Skip to content
Snippets Groups Projects
Select Git revision
  • 68e35585adb8e5b39b4ee7f78d3bbf55146d733a
  • main default protected
2 results

main.py

Blame
  • 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;
    }