bool LoadMatrixMarketFile(const std::string& file_path, SparseMatrix<T>& A, unsigned int& height, unsigned int& width, unsigned int& nnz) { std::ifstream infile(file_path); if (!infile) return false; char mm_typecode[4]; // read the matrix market banner (header) if (0 != mm_read_banner(infile, mm_typecode)) return false; if (!mm_is_valid(mm_typecode)) return false; // this reader supports these matrix types: // // sparse, real/integer/pattern, general/symm/skew // if (!mm_is_sparse(mm_typecode)) { std::cerr << "Only sparse MatrixMarket files are supported." << std::endl; return false; } if (!mm_is_real(mm_typecode) && !mm_is_integer(mm_typecode) && !mm_is_pattern(mm_typecode)) { std::cerr << "Only real, integer, and pattern MatrixMarket formats are supported." << std::endl; return false; } if (!mm_is_general(mm_typecode) && !mm_is_symmetric(mm_typecode) && !mm_is_skew(mm_typecode)) { std::cerr << "Only general, symmetric, and skew-symmetric MatrixMarket formats are supported." << std::endl; return false; } // read the number of rows, cols, nonzeros if (0 != mm_read_mtx_crd_size(infile, height, width, nnz)) { std::cerr << "could not read matrix coordinate information" << std::endl; height = width = nnz = 0; return false; } // read the data according to the type bool is_real = mm_is_real(mm_typecode); bool is_int = mm_is_integer(mm_typecode); bool is_symmetric = mm_is_symmetric(mm_typecode); bool is_skew = mm_is_skew(mm_typecode); std::string line; unsigned int reserve_size = nnz; if (is_symmetric || is_skew) reserve_size *= 2; A.Clear(); A.Reserve(height, width, reserve_size); // load num random entries of A A.BeginLoad(); unsigned int row, col, count; if (is_real) { double val; for (count=0; count != nnz; ++count) { infile >> row; assert(row >= 1); infile >> col; assert(col >= 1); infile >> val; // convert to 0-based indexing row -= 1; col -= 1; A.Load(row, col, val); if (row != col) { if (is_symmetric) A.Load(col, row, val); else if (is_skew) A.Load(col, row, -val); } } } else if (is_int)
csr_matrix_t *csr_mm_load(char *filename) { int ret_code; MM_typecode matcode; FILE *f; int entry_count; int i, M, N, nz; matrix_entry_t *entries; matrix_entry_t *entry; int *row_start; int *col_index; double *val; csr_matrix_t *A; if ((f = fopen(filename, "r")) == NULL) exit(1); if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); exit(1); } if (!mm_is_sparse(matcode) || !mm_is_symmetric(matcode) || !mm_is_real(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); /* reserve memory for matrices */ row_start = (int *) malloc((M + 1) * sizeof(int)); col_index = (int *) malloc((2 * nz - M) * sizeof(int)); val = (double *) malloc((2 * nz - M) * sizeof(double)); entries = (matrix_entry_t *) malloc((2 * nz - M) * sizeof(matrix_entry_t)); /* 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) */ entry = entries; entry_count = 0; for (i = 0; i < nz; i++) { int row, col; double val; fscanf(f, "%d %d %lg\n", &row, &col, &val); --row; /* adjust to 0-based */ --col; assert(row >= 0 && col >= 0); assert(entry_count++ < 2 * nz - M); entry->i = row; entry->j = col; entry->val = val; ++entry; if (row != col) { /* Fill out the other half... */ assert(entry_count++ < 2 * nz - M); entry->i = col; entry->j = row; entry->val = val; ++entry; } } if (f != stdin) fclose(f); /**********************************/ /* now make CSR version of matrix */ /**********************************/ nz = 2 * nz - M; qsort(entries, nz, sizeof(matrix_entry_t), entry_comparison); entry = entries; row_start[0] = 0; for (i = 0; i < nz; ++i) { row_start[entry->i + 1] = i + 1; col_index[i] = entry->j; val[i] = entry->val; ++entry; } free(entries); A = (csr_matrix_t *) malloc(sizeof(csr_matrix_t)); A->m = M; A->n = N; A->nz = nz; A->row_start = row_start; A->col_idx = col_index; A->val = val; return A; }
int readSparseMatrix(char * filename, PetscInt & n, PetscInt & nz, PetscInt *& nnz, int *& i, int *& j, double *& v) { int in, m, inz; // try opening the files FILE *fp; if ((fp = fopen(filename, "r")) == NULL) { fprintf(stderr, "Error occurs while reading from file %s.\n", filename); return 1; } // try reading the banner MM_typecode type; if (mm_read_banner(fp, &type) != 0) { fprintf(stderr, "Could not process Matrix Market banner.\n"); return 2; } // check the type if (!mm_is_matrix(type) || !mm_is_coordinate(type) || !mm_is_real(type) || !mm_is_symmetric(type)) { fprintf(stderr, "Sorry, this application does not support Market Market type: [%s]\n", mm_typecode_to_str(type)); return 3; } // read the sizes of the vectors if (mm_read_mtx_crd_size(fp, &in, &m, &inz)) { fprintf(stderr, "Could not read the size of the matrix.\n"); return 4; } n = in; nz = inz; // check if it is a square matrix if (in != m) { fprintf(stderr, "Needs to be square.\n"); return 5; } // allocate the memory printf("reading %s:\n\ta %d x %d sparse matrix with %d nonzeros...", filename, m, in, inz); i = new int[nz]; j = new int[nz]; v = new double[nz]; nnz = new PetscInt[n](); for (int k = 0; k < inz; ++k) { fscanf(fp, "%u %u %lf\n", &j[k], &i[k], &v[k]); --i[k]; --j[k]; ++nnz[i[k]]; if (i[k] != j[k]) { ++nnz[j[k]]; } } printf("done\n"); // close the file fclose(fp); return 0; }
/* * Function: MatrixMarketRead * * Reads a matrix in matrix market format * * For more information about matrix market format see mmio.c/mmio.h * * Parameters: * dirname - Path to the directory containing matrix * Ncol - Number of columns * Nrow - Number of rows * Nnzero - Number of non zeros * col - Index of first element of each column in *row* and *val* * row - Row of eah element * val - Value of each element * Type - Type of the matrix * RhsType - Type of the right-hand-side. * */ void MatrixMarketRead(char const *filename, pastix_int_t *Ncol, pastix_int_t *Nrow, pastix_int_t *Nnzero, pastix_int_t **col, pastix_int_t **row, pastix_float_t **val, char **Type, char **RhsType) { FILE * file; pastix_int_t * tempcol; pastix_int_t iter,baseval; pastix_int_t * temprow; pastix_float_t * tempval; pastix_int_t total; pastix_int_t tmp; pastix_int_t pos; pastix_int_t limit; MM_typecode matcode; int tmpncol,tmpnrow,tmpnnzero; *Type = (char *) malloc(4*sizeof(char)); *RhsType = (char *) malloc(1*sizeof(char)); (*RhsType)[0] = '\0'; file = fopen (filename,"r"); if (file==NULL) { fprintf(stderr,"cannot load %s\n", filename); EXIT(MOD_SI,FILE_ERR); } if (mm_read_banner(file, &matcode) != 0) { fprintf(stderr,"Could not process Matrix Market banner.\n"); exit(1); } #ifdef TYPE_COMPLEX (*Type)[0] = 'C'; if (!mm_is_complex(matcode)) { fprintf(stderr, "\nWARNING : Matrix should be complex. Imaginary part will be 0.\n\n"); } #else /* TYPE_COMPLEX */ (*Type)[0] = 'R'; if (mm_is_complex(matcode)) { fprintf(stderr, "\nWARNING : Matrix should not be complex. Only real part will be taken.\n\n"); } #endif /* TYPE_COMPLEX */ (*Type)[1] = 'U'; if (mm_is_symmetric(matcode)) { (*Type)[1] = 'S'; } else { if (mm_is_hermitian(matcode)) { (*Type)[1] = 'H'; } } (*Type)[2] = 'A'; (*Type)[3] = '\0'; /* find out size of sparse matrix .... */ if (mm_read_mtx_crd_size(file, &tmpnrow, &tmpncol, &tmpnnzero) !=0) exit(1); *Ncol = tmpncol; *Nrow = tmpnrow; *Nnzero = tmpnnzero; /* Allocation memoire */ tempcol = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); temprow = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); tempval = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t)); if ((tempcol==NULL) || (temprow == NULL) || (tempval == NULL)) { fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero); EXIT(MOD_SI,OUTOFMEMORY_ERR); } /* Remplissage */ { long temp1,temp2; double re,im; im = 0.0; if (mm_is_complex(matcode)) { for (iter=0; iter<(*Nnzero); iter++) { if (4 != fscanf(file,"%ld %ld %lg %lg\n", &temp1, &temp2, &re, &im)) { fprintf(stderr, "ERROR: reading matrix (line %ld)\n", (long int)iter); exit(1); } temprow[iter]=(pastix_int_t)temp1; tempcol[iter]=(pastix_int_t)temp2; #ifdef TYPE_COMPLEX tempval[iter]=(pastix_float_t)(re+im*I); #else /* TYPE_COMPLEX */ tempval[iter]=(pastix_float_t)(re); #endif /* TYPE_COMPLEX */ } } else { for (iter=0; iter<(*Nnzero); iter++) { if (3 != fscanf(file,"%ld %ld %lg\n", &temp1, &temp2, &re)) { fprintf(stderr, "ERROR: reading matrix (line %ld)\n", (long int)iter); exit(1); } temprow[iter]=(pastix_int_t)temp1; tempcol[iter]=(pastix_int_t)temp2; #ifdef TYPE_COMPLEX tempval[iter]=(pastix_float_t)(re+im*I); #else /* TYPE_COMPLEX */ tempval[iter]=(pastix_float_t)(re); #endif /* TYPE_COMPLEX */ } } } (*col) = (pastix_int_t *) malloc((*Nrow+1)*sizeof(pastix_int_t)); memset(*col,0,(*Nrow+1)*sizeof(pastix_int_t)); (*row) = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); memset(*row,0,(*Nnzero)*sizeof(pastix_int_t)); (*val) = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t)); if (((*col)==NULL) || ((*row) == NULL) || ((*val) == NULL)) { fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero); EXIT(MOD_SI,OUTOFMEMORY_ERR); } /* Detection de la base */ baseval = 1; for(iter=0; iter<(*Nnzero); iter++) baseval = MIN(baseval, tempcol[iter]); if (baseval == 0) { for(iter=0; iter<(*Nnzero); iter++) { tempcol[iter]++; temprow[iter]++; } } for (iter = 0; iter < (*Nnzero); iter ++) { (*col)[tempcol[iter]-1]++; } baseval=1; /* Attention on base a 1 */ total = baseval; for (iter = 0; iter < (*Ncol)+1; iter ++) { tmp = (*col)[iter]; (*col)[iter]=total; total+=tmp; } for (iter = 0; iter < (*Nnzero); iter ++) { pos = (*col)[tempcol[iter]-1]-1; limit = (*col)[tempcol[iter]]-1; while((*row)[pos] != 0 && pos < limit) { pos++; } if (pos == limit) fprintf(stderr, "Erreur de lecture\n"); (*row)[pos] = temprow[iter]; (*val)[pos] = tempval[iter]; } memFree_null(tempval); memFree_null(temprow); memFree_null(tempcol); }
char *mm_typecode_to_str(MM_typecode matcode) { char buffer[MM_MAX_LINE_LENGTH]; const char *types[4]; char *mm_strdup(const char *); int error =0; /* check for MTX type */ if (mm_is_matrix(matcode)) types[0] = MM_MTX_STR; else { types[0] = NULL; error=1; } /* check for CRD or ARR matrix */ if (mm_is_sparse(matcode)) types[1] = MM_SPARSE_STR; else if (mm_is_dense(matcode)) types[1] = MM_DENSE_STR; else return NULL; /* check for element data type */ if (mm_is_real(matcode)) types[2] = MM_REAL_STR; else if (mm_is_complex(matcode)) types[2] = MM_COMPLEX_STR; else if (mm_is_pattern(matcode)) types[2] = MM_PATTERN_STR; else if (mm_is_integer(matcode)) types[2] = MM_INT_STR; else return NULL; /* check for symmetry type */ if (mm_is_general(matcode)) types[3] = MM_GENERAL_STR; else if (mm_is_symmetric(matcode)) types[3] = MM_SYMM_STR; else if (mm_is_hermitian(matcode)) types[3] = MM_HERM_STR; else if (mm_is_skew(matcode)) types[3] = MM_SKEW_STR; else return NULL; if( error == 1 ) sprintf(buffer,"Object to write is not a matrix; this is unsupported by the current mmio code."); else sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]); return mm_strdup(buffer); }
/* * Function: DistributedMatrixMarketRead * * Reads a matrix in distributed matrix market format * * For more information about matrix market format see mmio.c/mmio.h * * Parameters: * dirname - Path to the directory containing matrix * Ncol - Number of columns * Nrow - Number of rows * Nnzero - Number of non zeros * col - Index of first element of each column in *row* and *val* * row - Row of eah element * val - Value of each element * Type - Type of the matrix * RhsType - Type of the right-hand-side. * */ void DistributedMatrixMarketRead(char const *filename, pastix_int_t *Ncol, pastix_int_t *Nrow, pastix_int_t *Nnzero, pastix_int_t **col, pastix_int_t **row, pastix_float_t **val, pastix_int_t **l2g, char **Type, char **RhsType) { FILE * file; pastix_int_t * tempcol, *g2l, *templ2g; pastix_int_t iter, iter2, baseval, mincol, maxcol; pastix_int_t * temprow; pastix_float_t * tempval; pastix_int_t total; pastix_int_t tmp; pastix_int_t pos; pastix_int_t limit; MM_typecode matcode; int tmpncol,tmpnrow,tmpnnzero; int rank, size; int tmpint; pastix_int_t i, global_n_col; char line[BUFSIZ], my_filename_s[BUFSIZ]; char * my_filename; pastix_int_t column; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); file = fopen (filename,"r"); if (file==NULL) { fprintf(stderr,"cannot load %s\n", filename); EXIT(MOD_SI,FILE_ERR); } FGETS(line, BUFSIZ, file); sscanf(line, "%d", &tmpint); /* Read number of filename */ fprintf(stdout, "%d files\n", tmpint); if (size != tmpint) { /* pour l'instant rien. au choix : recreer un nouveau comm mpi, refusionner la csc et la redecouper */ if (rank == 0) fprintf(stderr, "Please rerun with %d processors\n", tmpint); exit(EXIT_FAILURE); } for (i = 0; i < rank+1; i++) { FGETS(line, BUFSIZ, file); sscanf(line, "%s", my_filename_s); } my_filename = (char*)malloc(sizeof(char)*(strlen(filename)+BUFSIZ)); strcpy(my_filename, filename); sprintf(my_filename,"%s/%s", dirname(my_filename), my_filename_s); fclose(file); *Type = (char *) malloc(4*sizeof(char)); *RhsType = (char *) malloc(1*sizeof(char)); (*RhsType)[0] = '\0'; file = fopen (my_filename,"r"); if (file==NULL) { fprintf(stderr,"cannot load %s\n", my_filename); EXIT(MOD_SI,FILE_ERR); } if (mm_read_banner(file, &matcode) != 0) { fprintf(stderr,"Could not process Matrix Market banner.\n"); exit(1); } #ifdef TYPE_COMPLEX (*Type)[0] = 'C'; if (!mm_is_complex(matcode)) { fprintf(stderr, "\nWARNING : Matrix should be complex. Imaginary part will be 0.\n\n"); } #else /* TYPE_COMPLEX */ (*Type)[0] = 'R'; if (mm_is_complex(matcode)) { fprintf(stderr, "\nWARNING : Matrix should not be complex. Only real part will be taken.\n\n"); } #endif /* TYPE_COMPLEX */ (*Type)[1] = 'U'; if (mm_is_symmetric(matcode)) { (*Type)[1] = 'S'; } else { if (mm_is_hermitian(matcode)) { (*Type)[1] = 'H'; } } (*Type)[2] = 'A'; (*Type)[3] = '\0'; /* find out size of sparse matrix .... */ if (mm_read_mtx_crd_size(file, &tmpnrow, &tmpncol, &tmpnnzero) !=0) exit(1); *Ncol = 0; *Nrow = 0; *Nnzero = tmpnnzero; /* Allocation memoire */ tempcol = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); templ2g = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); temprow = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); tempval = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t)); if ((tempcol==NULL) || (temprow == NULL) || (tempval == NULL)) { fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n",(long)*Nnzero); EXIT(MOD_SI,OUTOFMEMORY_ERR); } /* Remplissage */ { long temp1,temp2; double re,im; im = 0.0; if (mm_is_complex(matcode)) { for (iter=0; iter<(*Nnzero); iter++) { if (4 != fscanf(file,"%ld %ld %lg %lg\n", &temp1, &temp2, &re, &im)) { fprintf(stderr, "ERROR: reading matrix (line %ld)\n", (long int)iter); exit(1); } iter2 = 0; column = temp2; while ( iter2 < *Ncol && templ2g[iter2] < column) iter2++; if ( !(iter2 < *Ncol && (templ2g)[iter2] == column) ) { while ( iter2 < *Ncol ) { tmp = column; column = (templ2g)[iter2]; (templ2g)[iter2] = tmp; iter2++; } (templ2g)[iter2] = column; (*Ncol)++; } temprow[iter]=(pastix_int_t)temp1; tempcol[iter]=(pastix_int_t)temp2; #ifdef TYPE_COMPLEX tempval[iter]=(pastix_float_t)(re+im*I); #else /* TYPE_COMPLEX */ tempval[iter]=(pastix_float_t)(re); #endif /* TYPE_COMPLEX */ } } else { for (iter=0; iter<(*Nnzero); iter++) { if (3 != fscanf(file,"%ld %ld %lg\n", &temp1, &temp2, &re)) { fprintf(stderr, "ERROR: reading matrix (line %ld)\n", (long int)iter); exit(1); } iter2 = 0; column = temp2; while ( iter2 < *Ncol && (templ2g)[iter2] < column) iter2++; if ( iter2 == *Ncol || (templ2g)[iter2] != column ) { while ( iter2 < *Ncol ) { tmp = (templ2g)[iter2]; (templ2g)[iter2] = column; column = tmp; iter2++; } (templ2g)[iter2] = column; (*Ncol)++; } temprow[iter]=(pastix_int_t)temp1; tempcol[iter]=(pastix_int_t)temp2; #ifdef TYPE_COMPLEX tempval[iter]=(pastix_float_t)(re+im*I); #else /* TYPE_COMPLEX */ tempval[iter]=(pastix_float_t)(re); #endif /* TYPE_COMPLEX */ } } } *Nrow = *Ncol; (*l2g) = (pastix_int_t *) malloc((*Ncol)*sizeof(pastix_int_t)); memcpy(*l2g, templ2g, *Ncol*sizeof(pastix_int_t)); free(templ2g); (*col) = (pastix_int_t *) malloc((*Ncol+1)*sizeof(pastix_int_t)); memset(*col,0,(*Ncol+1)*sizeof(pastix_int_t)); (*row) = (pastix_int_t *) malloc((*Nnzero)*sizeof(pastix_int_t)); memset(*row,0,(*Nnzero)*sizeof(pastix_int_t)); (*val) = (pastix_float_t *) malloc((*Nnzero)*sizeof(pastix_float_t)); if (((*col)==NULL) || ((*row) == NULL) || ((*val) == NULL)) { fprintf(stderr, "MatrixMarketRead : Not enough memory (Nnzero %ld)\n", (long)*Nnzero); EXIT(MOD_SI,OUTOFMEMORY_ERR); } /* Detection de la base */ mincol = (*l2g)[0]; maxcol = (*l2g)[*Ncol-1]; if (sizeof(int) == sizeof(pastix_int_t)) { MPI_Allreduce(&mincol, &baseval, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&maxcol, &global_n_col, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); } else { MPI_Allreduce(&mincol, &baseval, 1, MPI_LONG, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&maxcol, &global_n_col, 1, MPI_LONG, MPI_MAX, MPI_COMM_WORLD); } *Nrow = global_n_col; if (baseval == 0) { for(iter=0; iter<(*Nnzero); iter++) { tempcol[iter]++; temprow[iter]++; } for (iter = 0; iter < *Ncol; iter++) { (*l2g)[iter]++; } } if (baseval > 1 || baseval < 0) { fprintf(stderr, "Baseval > 1 || baseval < 0\n"); exit(1); } baseval = 1; { /* Build loc2gloab */ int inserted_column = 0; int iter2; int column; for (iter = 0; iter < (*Nnzero); iter ++) { iter2 = 0; column = tempcol[iter]; while ( iter2 < inserted_column && (*l2g)[iter2] < column) iter2++; if (iter2 < inserted_column && (*l2g)[iter2] == column) continue; while ( iter2 < inserted_column ) { tmp = column; column = (*l2g)[iter2]; (*l2g)[iter2] = tmp; iter2++; } (*l2g)[iter2] = column; inserted_column++; if (inserted_column == *Ncol) break; } assert(inserted_column == *Ncol); } { /* Build loc2glob */ g2l = malloc(global_n_col*sizeof(pastix_int_t)); for (iter = 0; iter < global_n_col; iter++) g2l[iter] = -1; for (iter = 0; iter < (*Ncol); iter ++) g2l[(*l2g)[iter]-1] = iter+1; } for (iter = 0; iter < (*Nnzero); iter ++) { (*col)[g2l[tempcol[iter]-1]-1]++; } total = baseval; for (iter = 0; iter < (*Ncol)+1; iter ++) { tmp = (*col)[iter]; (*col)[iter]=total; total+=tmp; } for (iter = 0; iter < (*Nnzero); iter ++) { pos = (*col)[g2l[tempcol[iter]-1]-1]-1; limit = (*col)[g2l[tempcol[iter]-1]]-1; while((*row)[pos] != 0 && pos < limit) { pos++; } if (pos == limit) fprintf(stderr, "Erreur de lecture %ld %ld %ld\n", (long int)(*col)[g2l[tempcol[iter]-1]-1]-1, (long int)pos, (long int)limit); (*row)[pos] = temprow[iter]; (*val)[pos] = tempval[iter]; } memFree_null(tempval); memFree_null(temprow); memFree_null(tempcol); free(my_filename); }
char *mm_typecode_to_str ( MM_typecode matcode ) /******************************************************************************/ /* Purpose: MM_TYPECODE_TO_STR converts the internal typecode to an MM header string. Modified: 31 October 2008 */ { char buffer[MM_MAX_LINE_LENGTH]; char *types[4]; char *mm_strdup(const char *); //int error =0; /* check for MTX type */ if (mm_is_matrix(matcode)) types[0] = MM_MTX_STR; // else // error=1; /* check for CRD or ARR matrix */ if (mm_is_sparse(matcode)) types[1] = MM_SPARSE_STR; else if (mm_is_dense(matcode)) types[1] = MM_DENSE_STR; else return NULL; /* check for element data type */ if (mm_is_real(matcode)) types[2] = MM_REAL_STR; else if (mm_is_complex(matcode)) types[2] = MM_COMPLEX_STR; else if (mm_is_pattern(matcode)) types[2] = MM_PATTERN_STR; else if (mm_is_integer(matcode)) types[2] = MM_INT_STR; else return NULL; /* check for symmetry type */ if (mm_is_general(matcode)) types[3] = MM_GENERAL_STR; else if (mm_is_symmetric(matcode)) types[3] = MM_SYMM_STR; else if (mm_is_hermitian(matcode)) types[3] = MM_HERM_STR; else if (mm_is_skew(matcode)) types[3] = MM_SKEW_STR; else return NULL; sprintf(buffer,"%s %s %s %s", types[0], types[1], types[2], types[3]); return mm_strdup(buffer); }
int main(int argc, char ** argv) { // report precision of floating-point printf("---------------------------------------------------------------------------------------------\n"); char *precision; if (sizeof(VALUE_TYPE) == 4) { precision = (char *)"32-bit Single Precision"; } else if (sizeof(VALUE_TYPE) == 8) { precision = (char *)"64-bit Double Precision"; } else { printf("Wrong precision. Program exit!\n"); return 0; } printf("PRECISION = %s\n", precision); printf("Benchmark REPEAT = %i\n", BENCH_REPEAT); printf("---------------------------------------------------------------------------------------------\n"); int m, n, nnzA; int *csrRowPtrA; int *csrColIdxA; VALUE_TYPE *csrValA; //ex: ./spmv webbase-1M.mtx int argi = 1; char *filename; if(argc > argi) { filename = argv[argi]; argi++; } printf("-------------- %s --------------\n", filename); // read matrix from mtx file int ret_code; MM_typecode matcode; FILE *f; int nnzA_mtx_report; int isInteger = 0, isReal = 0, isPattern = 0, isSymmetric = 0; // load matrix if ((f = fopen(filename, "r")) == NULL) return -1; if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); return -2; } if ( mm_is_complex( matcode ) ) { printf("Sorry, data type 'COMPLEX' is not supported.\n"); return -3; } if ( mm_is_pattern( matcode ) ) { isPattern = 1; /*printf("type = Pattern\n");*/ } if ( mm_is_real ( matcode) ) { isReal = 1; /*printf("type = real\n");*/ } if ( mm_is_integer ( matcode ) ) { isInteger = 1; /*printf("type = integer\n");*/ } /* find out size of sparse matrix .... */ ret_code = mm_read_mtx_crd_size(f, &m, &n, &nnzA_mtx_report); if (ret_code != 0) return -4; if ( mm_is_symmetric( matcode ) || mm_is_hermitian( matcode ) ) { isSymmetric = 1; printf("input matrix is symmetric = true\n"); } else { printf("input matrix is symmetric = false\n"); } int *csrRowPtrA_counter = (int *)malloc((m+1) * sizeof(int)); memset(csrRowPtrA_counter, 0, (m+1) * sizeof(int)); int *csrRowIdxA_tmp = (int *)malloc(nnzA_mtx_report * sizeof(int)); int *csrColIdxA_tmp = (int *)malloc(nnzA_mtx_report * sizeof(int)); VALUE_TYPE *csrValA_tmp = (VALUE_TYPE *)malloc(nnzA_mtx_report * sizeof(VALUE_TYPE)); /* 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) */ for (int i = 0; i < nnzA_mtx_report; i++) { int idxi, idxj; double fval; int ival; int returnvalue; if (isReal) returnvalue = fscanf(f, "%d %d %lg\n", &idxi, &idxj, &fval); else if (isInteger) { returnvalue = fscanf(f, "%d %d %d\n", &idxi, &idxj, &ival); fval = ival; } else if (isPattern) { returnvalue = fscanf(f, "%d %d\n", &idxi, &idxj); fval = 1.0; } // adjust from 1-based to 0-based idxi--; idxj--; csrRowPtrA_counter[idxi]++; csrRowIdxA_tmp[i] = idxi; csrColIdxA_tmp[i] = idxj; csrValA_tmp[i] = fval; } if (f != stdin) fclose(f); if (isSymmetric) { for (int i = 0; i < nnzA_mtx_report; i++) { if (csrRowIdxA_tmp[i] != csrColIdxA_tmp[i]) csrRowPtrA_counter[csrColIdxA_tmp[i]]++; } } // exclusive scan for csrRowPtrA_counter int old_val, new_val; old_val = csrRowPtrA_counter[0]; csrRowPtrA_counter[0] = 0; for (int i = 1; i <= m; i++) { new_val = csrRowPtrA_counter[i]; csrRowPtrA_counter[i] = old_val + csrRowPtrA_counter[i-1]; old_val = new_val; } nnzA = csrRowPtrA_counter[m]; csrRowPtrA = (int *)malloc((m+1) * sizeof(int)); memcpy(csrRowPtrA, csrRowPtrA_counter, (m+1) * sizeof(int)); memset(csrRowPtrA_counter, 0, (m+1) * sizeof(int)); csrColIdxA = (int *)malloc(nnzA * sizeof(int)); csrValA = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE)); if (isSymmetric) { for (int i = 0; i < nnzA_mtx_report; i++) { if (csrRowIdxA_tmp[i] != csrColIdxA_tmp[i]) { int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]]; csrColIdxA[offset] = csrColIdxA_tmp[i]; csrValA[offset] = csrValA_tmp[i]; csrRowPtrA_counter[csrRowIdxA_tmp[i]]++; offset = csrRowPtrA[csrColIdxA_tmp[i]] + csrRowPtrA_counter[csrColIdxA_tmp[i]]; csrColIdxA[offset] = csrRowIdxA_tmp[i]; csrValA[offset] = csrValA_tmp[i]; csrRowPtrA_counter[csrColIdxA_tmp[i]]++; } else { int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]]; csrColIdxA[offset] = csrColIdxA_tmp[i]; csrValA[offset] = csrValA_tmp[i]; csrRowPtrA_counter[csrRowIdxA_tmp[i]]++; } } } else { for (int i = 0; i < nnzA_mtx_report; i++) { int offset = csrRowPtrA[csrRowIdxA_tmp[i]] + csrRowPtrA_counter[csrRowIdxA_tmp[i]]; csrColIdxA[offset] = csrColIdxA_tmp[i]; csrValA[offset] = csrValA_tmp[i]; csrRowPtrA_counter[csrRowIdxA_tmp[i]]++; } } // free tmp space free(csrColIdxA_tmp); free(csrValA_tmp); free(csrRowIdxA_tmp); free(csrRowPtrA_counter); /* // a small matrix free(csrColIdxA); free(csrValA); free(csrRowPtrA); m = n = 8; nnzA = 17; csrRowPtrA = (int *)malloc(sizeof(int) * (m+1)); csrColIdxA = (int *)malloc(sizeof(int) * nnzA); csrValA = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE)); csrRowPtrA[0] = 0; csrRowPtrA[1] = 1; csrRowPtrA[2] = 2; csrRowPtrA[3] = 4; csrRowPtrA[4] = 6; csrRowPtrA[5] = 10; csrRowPtrA[6] = 12; csrRowPtrA[7] = 15; csrRowPtrA[8] = nnzA; csrColIdxA[0] = 0; csrColIdxA[1] = 1; csrColIdxA[2] = 1; csrColIdxA[3] = 2; csrColIdxA[4] = 0; csrColIdxA[5] = 3; csrColIdxA[6] = 1; csrColIdxA[7] = 2; csrColIdxA[8] = 3; csrColIdxA[9] = 4; csrColIdxA[10] = 3; csrColIdxA[11] = 5; csrColIdxA[12] = 2; csrColIdxA[13] = 5; csrColIdxA[14] = 6; csrColIdxA[15] = 6; csrColIdxA[16] = 7; // a small matrix stop */ printf("input matrix A: ( %i, %i ) nnz = %i\n", m, n, nnzA); // extract L with the unit-lower triangular sparsity structure of A int nnzL = 0; int *csrRowPtrL_tmp = (int *)malloc((m+1) * sizeof(int)); int *csrColIdxL_tmp = (int *)malloc(nnzA * sizeof(int)); VALUE_TYPE *csrValL_tmp = (VALUE_TYPE *)malloc(nnzA * sizeof(VALUE_TYPE)); int nnz_pointer = 0; csrRowPtrL_tmp[0] = 0; for (int i = 0; i < m; i++) { for (int j = csrRowPtrA[i]; j < csrRowPtrA[i+1]; j++) { if (csrColIdxA[j] < i) { csrColIdxL_tmp[nnz_pointer] = csrColIdxA[j]; csrValL_tmp[nnz_pointer] = 1.0; //csrValA[j]; nnz_pointer++; } else { break; } } csrColIdxL_tmp[nnz_pointer] = i; csrValL_tmp[nnz_pointer] = 1.0; nnz_pointer++; csrRowPtrL_tmp[i+1] = nnz_pointer; } nnzL = csrRowPtrL_tmp[m]; printf("A's unit-lower triangular L: ( %i, %i ) nnz = %i\n", m, n, nnzL); csrColIdxL_tmp = (int *)realloc(csrColIdxL_tmp, sizeof(int) * nnzL); csrValL_tmp = (VALUE_TYPE *)realloc(csrValL_tmp, sizeof(VALUE_TYPE) * nnzL); // run serial syncfree SpTS as a reference printf("---------------------------------------------------------------------------------------------\n"); spts_syncfree_serialref(csrRowPtrL_tmp, csrColIdxL_tmp, csrValL_tmp, m, n, nnzL); // run cuda syncfree SpTS printf("---------------------------------------------------------------------------------------------\n"); spts_syncfree_opencl(csrRowPtrL_tmp, csrColIdxL_tmp, csrValL_tmp, m, n, nnzL); printf("---------------------------------------------------------------------------------------------\n"); // done! free(csrColIdxA); free(csrValA); free(csrRowPtrA); free(csrColIdxL_tmp); free(csrValL_tmp); free(csrRowPtrL_tmp); return 0; }
int main() { /* Host/device data structures */ cl_platform_id platform; cl_device_id device; cl_context context; cl_command_queue queue; cl_int err, i; /* Program/kernel data structures */ cl_program program; FILE *program_handle; char *program_buffer, *program_log; size_t program_size, log_size; cl_kernel kernel; size_t global_size, local_size; /* Data and buffers */ int num_rows, num_cols, num_values; int *rows, *cols; float *values, *b_vec; float result[2]; double value_double; cl_mem rows_buffer, cols_buffer, values_buffer, b_buffer, result_buffer; /* Read sparse file */ FILE *mm_handle; MM_typecode code; /* Read matrix file */ if ((mm_handle = fopen(MM_FILE, "r")) == NULL) { perror("Couldn't open the MatrixMarket file"); exit(1); } mm_read_banner(mm_handle, &code); mm_read_mtx_crd_size(mm_handle, &num_rows, &num_cols, &num_values); /* Check for symmetry and allocate memory */ if(mm_is_symmetric(code) || mm_is_skew(code) || mm_is_hermitian(code)) { num_values += num_values - num_rows; } rows = (int*) malloc(num_values * sizeof(int)); cols = (int*) malloc(num_values * sizeof(int)); values = (float*) malloc(num_values * sizeof(float)); b_vec = (float*) malloc(num_rows * sizeof(float)); /* Read matrix data and close file */ i=0; while(i<num_values) { fscanf(mm_handle, "%d %d %lg\n", &rows[i], &cols[i], &value_double); values[i] = (float)value_double; cols[i]--; rows[i]--; if((rows[i] != cols[i]) && (mm_is_symmetric(code) || mm_is_skew(code) || mm_is_hermitian(code))) { i++; rows[i] = cols[i-1]; cols[i] = rows[i-1]; values[i] = values[i-1]; } i++; } sort(num_values, rows, cols, values); fclose(mm_handle); /* Initialize the b vector */ srand(time(0)); for(i=0; i<num_rows; i++) { b_vec[i] = (float)(rand() - RAND_MAX/2); } /* Identify a platform */ err = clGetPlatformIDs(1, &platform, NULL); if(err < 0) { perror("Couldn't identify a platform"); exit(1); } /* Access a device */ err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL); if(err < 0) { perror("Couldn't access any devices"); exit(1); } /* Create a context */ context = clCreateContext(NULL, 1, &device, NULL, NULL, &err); if(err < 0) { perror("Couldn't create a context"); exit(1); } /* Read program file and place content into buffer */ program_handle = fopen(PROGRAM_FILE, "r"); if(program_handle == NULL) { perror("Couldn't find the program file"); exit(1); } fseek(program_handle, 0, SEEK_END); program_size = ftell(program_handle); rewind(program_handle); program_buffer = (char*)calloc(program_size+1, sizeof(char)); fread(program_buffer, sizeof(char), program_size, program_handle); fclose(program_handle); /* Create program from file */ program = clCreateProgramWithSource(context, 1, (const char**)&program_buffer, &program_size, &err); if(err < 0) { perror("Couldn't create the program"); exit(1); } free(program_buffer); /* Build program */ err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL); if(err < 0) { /* Find size of log and print to std output */ clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); program_log = (char*) calloc(log_size+1, sizeof(char)); clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size+1, program_log, NULL); printf("%s\n", program_log); free(program_log); exit(1); } /* Create a kernel */ kernel = clCreateKernel(program, KERNEL_FUNC, &err); if(err < 0) { printf("Couldn't create a kernel: %d", err); exit(1); }; /* Create buffers to hold the text characters and count */ rows_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, num_values*sizeof(int), rows, &err); if(err < 0) { perror("Couldn't create a buffer"); exit(1); }; cols_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, num_values*sizeof(int), cols, NULL); values_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, num_values*sizeof(float), values, NULL); b_buffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, num_values*sizeof(float), b_vec, NULL); result_buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, 2*sizeof(float), NULL, NULL); /* Create kernel argument */ err = clSetKernelArg(kernel, 0, sizeof(num_rows), &num_rows); err |= clSetKernelArg(kernel, 1, sizeof(num_values), &num_values); err |= clSetKernelArg(kernel, 2, num_rows * sizeof(float), NULL); err |= clSetKernelArg(kernel, 3, num_rows * sizeof(float), NULL); err |= clSetKernelArg(kernel, 4, num_rows * sizeof(float), NULL); err |= clSetKernelArg(kernel, 5, num_rows * sizeof(float), NULL); err |= clSetKernelArg(kernel, 6, sizeof(cl_mem), &rows_buffer); err |= clSetKernelArg(kernel, 7, sizeof(cl_mem), &cols_buffer); err |= clSetKernelArg(kernel, 8, sizeof(cl_mem), &values_buffer); err |= clSetKernelArg(kernel, 9, sizeof(cl_mem), &b_buffer); err |= clSetKernelArg(kernel, 10, sizeof(cl_mem), &result_buffer); if(err < 0) { printf("Couldn't set a kernel argument"); exit(1); }; /* Create a command queue */ queue = clCreateCommandQueue(context, device, 0, &err); if(err < 0) { perror("Couldn't create a command queue"); exit(1); }; /* Enqueue kernel */ global_size = num_rows; local_size = num_rows; err = clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_size, &local_size, 0, NULL, NULL); if(err < 0) { perror("Couldn't enqueue the kernel"); printf("Error: %d\n", err); exit(1); } /* Read the results */ err = clEnqueueReadBuffer(queue, result_buffer, CL_TRUE, 0, 2*sizeof(float), result, 0, NULL, NULL); if(err < 0) { perror("Couldn't read the buffer"); exit(1); } /* Print the result */ printf("After %d iterations, the residual length is %f.\n", (int)result[0], result[1]); /* Deallocate resources */ free(b_vec); free(rows); free(cols); free(values); clReleaseMemObject(b_buffer); clReleaseMemObject(rows_buffer); clReleaseMemObject(cols_buffer); clReleaseMemObject(values_buffer); clReleaseMemObject(result_buffer); clReleaseKernel(kernel); clReleaseCommandQueue(queue); clReleaseProgram(program); clReleaseContext(context); return 0; }
int main(int argc, char *argv[]) { FILE *input_file, *output_file, *time_file; if (argc < 4) { fprintf(stderr, "Invalid input parameters\n"); fprintf(stderr, "Usage: %s inputfile outputfile timefile \n", argv[0]); exit(1); } else { input_file = fopen(argv[1], "r"); output_file = fopen(argv[2], "w"); time_file = fopen(argv[3], "w"); if (!input_file || !output_file || !time_file) exit(1); } MM_typecode matcode; if (mm_read_banner(input_file, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); exit(1); } if (!mm_is_matrix(matcode) || !mm_is_real(matcode) || !mm_is_coordinate(matcode)) { printf("Sorry, this application does not support "); printf("Market Market type: [%s]\n", mm_typecode_to_str(matcode)); exit(1); } mtxMatrix inputMatrix, fullMatrix, LMatrix, UMatrix, UMatrixTranspose, MMatrix; ReadMatrix(inputMatrix, input_file); Timer timer; getRowIndex(&inputMatrix, inputMatrix.RowIndex); inputMatrix.RowIndex[inputMatrix.N] = inputMatrix.NZ; int diagNum = 0; for (int i = 0; i < inputMatrix.N; i++) { for (int j = inputMatrix.RowIndex[i]; j < inputMatrix.RowIndex[i + 1]; j++) { if (i == inputMatrix.Col[j]) diagNum++; } } if (mm_is_symmetric(matcode)) { InitializeMatrix(inputMatrix.N, 2 * inputMatrix.NZ - diagNum, fullMatrix); TriangleToFull(&inputMatrix, &fullMatrix); FreeMatrix(inputMatrix); } else { fullMatrix = inputMatrix; } int *diag = new int[fullMatrix.N]; for (int i = 0; i < fullMatrix.N; i++) { for (int j = fullMatrix.RowIndex[i]; j < fullMatrix.RowIndex[i + 1]; j++) { if (i == fullMatrix.Col[j]) diag[i] = j; } } // for (int i = 0; i < fullMatrix.N + 1; i++) { // printf("RowIndex[%i] = %i\n", i, fullMatrix.RowIndex[i]); // } // // // for (int i = 0; i < fullMatrix.N; i++) { // printf("input[%i]= %lf\n", i, fullMatrix.Value[inputMatrix.RowIndex[i]]); // } // // for (int i = 0; i < fullMatrix.N; i++) { // printf("diag[%i]= %d\n", i, diag[i]); // } timer.start(); ilu0(fullMatrix, fullMatrix.Value, diag); LUmatrixSeparation(fullMatrix, diag, LMatrix, UMatrix); Transpose(UMatrix, UMatrixTranspose); Multiplicate(LMatrix, UMatrixTranspose, MMatrix); timer.stop(); std::ofstream timeLog; timeLog.open(argv[3]); timeLog << timer.getElapsed(); WriteFullMatrix(MMatrix, output_file, matcode); FreeMatrix(fullMatrix); return 0; }
static PetscErrorCode loadmtx(const char* filename, Mat *M, PetscBool *pattern) { PetscErrorCode ierr; FILE *f; MM_typecode type; int m,n,nz,i,j,k; PetscInt low,high,lowj,highj,*d_nz,*o_nz; double re,im; PetscScalar s; long pos; PetscFunctionBegin; f = fopen(filename,"r"); if (!f) SETERRQ2(PETSC_COMM_SELF,1,"fopen '%s': %s",filename,strerror(errno)); /* first read to set matrix kind and size */ ierr = mm_read_banner(f,&type);CHKERRQ(ierr); if (!mm_is_valid(type) || !mm_is_sparse(type) || !(mm_is_real(type) || mm_is_complex(type) || mm_is_pattern(type) || mm_is_integer(type))) SETERRQ1(PETSC_COMM_SELF,1,"Matrix format '%s' not supported",mm_typecode_to_str(type)); #if !defined(PETSC_USE_COMPLEX) if (mm_is_complex(type)) SETERRQ(PETSC_COMM_SELF,1,"Complex matrix not supported in real configuration"); #endif if (pattern) *pattern = mm_is_pattern(type) ? PETSC_TRUE : PETSC_FALSE; ierr = mm_read_mtx_crd_size(f,&m,&n,&nz);CHKERRQ(ierr); pos = ftell(f); ierr = MatCreate(PETSC_COMM_WORLD,M);CHKERRQ(ierr); ierr = MatSetSizes(*M,PETSC_DECIDE,PETSC_DECIDE,(PetscInt)m,(PetscInt)n);CHKERRQ(ierr); ierr = MatSetFromOptions(*M);CHKERRQ(ierr); ierr = MatSetUp(*M);CHKERRQ(ierr); ierr = MatGetOwnershipRange(*M,&low,&high);CHKERRQ(ierr); ierr = MatGetOwnershipRangeColumn(*M,&lowj,&highj);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscInt)*(high-low),&d_nz);CHKERRQ(ierr); ierr = PetscMalloc(sizeof(PetscInt)*(high-low),&o_nz);CHKERRQ(ierr); for (i=0; i<high-low;i++) { d_nz[i] = (i+low>=lowj && i+low<highj) ? 1 : 0; o_nz[i] = (i+low>=lowj && i+low<highj) ? 0 : 1; } for (k=0;k<nz;k++) { ierr = mm_read_mtx_crd_entry(f,&i,&j,&re,&im,type);CHKERRQ(ierr); i--; j--; if (i!=j) { if (i>=low && i<high) { if (j>=lowj && j<highj) d_nz[i-low]++; else o_nz[i-low]++; } if (j>=low && j<high && !mm_is_general(type)) { if (i>=low && i<high) d_nz[j-low]++; else o_nz[j-low]++; } } } ierr = preallocation(*M,d_nz,o_nz);CHKERRQ(ierr); ierr = PetscFree(d_nz);CHKERRQ(ierr); ierr = PetscFree(o_nz);CHKERRQ(ierr); /* second read to load the values */ ierr = fseek(f, pos, SEEK_SET); if (ierr) SETERRQ1(PETSC_COMM_SELF,1,"fseek: %s",strerror(errno)); re = 1.0; im = 0.0; /* Set the diagonal to zero */ for (i=low; i<PetscMin(high,n); i++) { ierr = MatSetValue(*M,i,i,0.0,INSERT_VALUES);CHKERRQ(ierr); } for (k=0;k<nz;k++) { ierr = mm_read_mtx_crd_entry(f,&i,&j,&re,&im,type); i--; j--; if (i>=low && i<high) { s = re + IMAGINARY * im; ierr = MatSetValue(*M,i,j,s,INSERT_VALUES);CHKERRQ(ierr); } if (j>=low && j<high && i != j && !mm_is_general(type)) { if (mm_is_symmetric(type)) s = re + IMAGINARY * im; else if (mm_is_hermitian(type)) s = re - IMAGINARY * im; else if (mm_is_skew(type)) s = -re - IMAGINARY * im; else { SETERRQ1(PETSC_COMM_SELF,1,"Matrix format '%s' not supported",mm_typecode_to_str(type)); } ierr = MatSetValue(*M,j,i,s,INSERT_VALUES);CHKERRQ(ierr); } } ierr = MatAssemblyBegin(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); ierr = MatAssemblyEnd(*M,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); if (mm_is_symmetric(type)) { ierr = MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); } if ((mm_is_symmetric(type) && mm_is_real(type)) || mm_is_hermitian(type)) { ierr = MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);CHKERRQ(ierr); } ierr = fclose(f); if (ierr) SETERRQ1(PETSC_COMM_SELF,1,"fclose: %s",strerror(errno)); PetscFunctionReturn(0); }