/*includes {{{*/ #include #include #include #include #include "mmio.h" /*}}}*/ /* global varibles and defines {{{*/ int nrepeat = 100; int option_print_matrices = 0; #define OPTION_NOPRINT_MATRICES 0 #define OPTION_PRINT_MATRICES 1 char transa = 'n'; /*}}}*/ /* method declarations {{{*/ int main(int argc, char* argv[]); void printmm_one(int m, double* Aval, int* AJ, int* AI); void printfilemm_one(char* file, int m, int n, double* Aval, int* AJ, int* AI); void printmm_zero(int m, double* Aval, int* AJ, int* AI); /*}}}*/ /** Multiply two sparse matrices which are stored in CSR format. MKL is used */ void mkl_cpu_spmv(const MKL_INT Am, const MKL_INT An, double* Aval, MKL_INT* AJ, MKL_INT* AI, double* xvec, double* yvec, double* time) { /*{{{*/ MKL_INT ierr; MKL_INT request = 1; // symbolic multiplication double alpha = 1.0; double beta = 0.0; char* matdescra = "G NF"; double time_st = dsecnd(); int i; for(i = 0; i < nrepeat; i++) { /** y := alpha*A*x + beta*y */ mkl_dcsrmv(&transa, &Am, &An, &alpha, matdescra, Aval, AJ, AI, (AI+1), xvec, &beta, yvec); } double time_end = dsecnd(); *time = (time_end - time_st)/nrepeat; } /*}}}*/ /** Read Matrix Market file into COO matrix */ void read_mm(char* strpath, int* pM, int* pN, int* prealnnz, int** pI, int** pJ, double** pval){ /*{{{*/ /* * taken from Matrix Market I/O library for ANSI C * * See http://math.nist.gov/MatrixMarket for details. * * */ int i, M, N, nz, *I, *J; double* val; int ret_code; MM_typecode matcode; FILE* f; if ((f = fopen(strpath, "r")) == NULL) {fprintf(stderr, "Input matrix file %s cannot be opened to read.", strpath);exit(1);} /* READ MATRIX */ if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); exit(1); } /* This is how one can screen matrix types if their application */ /* only supports a subset of the Matrix Market data types. */ if (mm_is_complex(matcode) && mm_is_matrix(matcode) && mm_is_sparse(matcode) ) { printf("Sorry, this application does not support "); printf("Market Market type: [%s]\n", mm_typecode_to_str(matcode));exit(1); } /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0) exit(1); /* reseve memory for matrices */ I = (int *) malloc((mm_is_symmetric(matcode) ? 2*nz : nz) * sizeof(int)); J = (int *) malloc((mm_is_symmetric(matcode) ? 2*nz : nz) * sizeof(int)); val = (double *) malloc((mm_is_symmetric(matcode) ? 2*nz : nz) * sizeof(double)); *pI = I; *pJ = J; *pval = val; /* NOTE: when reading in doubles, ANSI C requires the use of the "l" */ /* specifier as in "%lg", "%lf", "%le", otherwise errors will occur */ /* (ANSI C X3.159-1989, Sec. 4.9.6.2, p. 136 lines 13-15) */ int realnnz = 0; for (i=0; i 0) { mkl_set_num_threads(nthreads); } else { nthreads = mkl_get_max_threads(); } option_print_matrices = strcmp(argv[iarg], "PRINT_YES")==0?OPTION_PRINT_MATRICES:OPTION_NOPRINT_MATRICES; iarg++; assert(nrequired_args == iarg); /** read matrix market file for A matrix */ MKL_INT Am, An, Annz; MKL_INT *Ax, *Ay; double *Anz; read_mm(strpathA, &Am, &An, &Annz, &Ax, &Ay, &Anz); /** construct csr storage for A matrix */ MKL_INT* AJ = (MKL_INT*) mkl_malloc( Annz * sizeof( MKL_INT ), 64 ); MKL_INT* AI = (MKL_INT*) mkl_malloc( (Am+1) * sizeof( MKL_INT ), 64 ); double* Aval = (double*) mkl_malloc( Annz * sizeof( double ), 64 ); coo_to_csr(Am, Annz, Ax, Ay, Anz, AI, AJ, Aval); double* xvec = (double*) mkl_malloc( An * sizeof( double ), 64 ); double* yvec = (double*) mkl_malloc( Am * sizeof( double ), 64 ); int i; for(i=0;i