/** compute validation rmse */ void validation_rmse3(float (*prediction_func)(const vertex_data & user, const vertex_data & movie, const vertex_data & time, float rating, double & prediction) ,graphchi_context & gcontext,int tokens_per_row = 4) { int ret_code; MM_typecode matcode; FILE *f; size_t nz; if ((f = fopen(validation.c_str(), "r")) == NULL) { std::cout<<std::endl; return; //missing validaiton data, nothing to compute } if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner. File: " << validation << std::endl; if (mm_is_complex(matcode) || !mm_is_sparse(matcode)) logstream(LOG_FATAL) << "Sorry, this application does not support complex values and requires a sparse matrix." << std::endl; /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &Me, &Ne, &nz)) !=0) { logstream(LOG_FATAL) << "Failed reading matrix size: error=" << ret_code << std::endl; } if ((M > 0 && N > 0) && (Me != M || Ne != N)) logstream(LOG_FATAL)<<"Input size of validation matrix must be identical to training matrix, namely " << M << "x" << N << std::endl; Le = nz; last_validation_rmse = dvalidation_rmse; dvalidation_rmse = 0; int I, J; double val, time = 1.0; for (size_t i=0; i<nz; i++) { int rc; rc = fscanf(f, "%d %d %lg %lg\n", &I, &J, &time, &val); if (rc != tokens_per_row) logstream(LOG_FATAL)<<"Error when reading input file on line: " << i << " . should have" << tokens_per_row << std::endl; if (val < minval || val > maxval) logstream(LOG_FATAL)<<"Value is out of range: " << val << " should be: " << minval << " to " << maxval << std::endl; if ((uint)time > K) logstream(LOG_FATAL)<<"Third column value time should be smaller than " << K << " while observed " << time << " in line : " << i << std::endl; I--; /* adjust from 1-based to 0-based */ J--; double prediction; (*prediction_func)(latent_factors_inmem[I], latent_factors_inmem[J+M], latent_factors_inmem[M+N+(uint)time], val, prediction); dvalidation_rmse += pow(prediction - val, 2); } fclose(f); assert(Le > 0); dvalidation_rmse = sqrt(dvalidation_rmse / (double)Le); std::cout<<" Validation RMSE: " << std::setw(10) << dvalidation_rmse << std::endl; if (halt_on_rmse_increase && dvalidation_rmse > last_validation_rmse && gcontext.iteration > 0){ logstream(LOG_WARNING)<<"Stopping engine because of validation RMSE increase" << std::endl; gcontext.set_last_iteration(gcontext.iteration); } }
/* READ_MTX - read symmetric sparse matrix in MatrixMarket format */ void read_MTX_SSS(char *fname, int *n, double **va, double **da, int **ja, int **ia) { int m, nz, ret_code, i; double *v_coo; int *i_coo, *j_coo; MM_typecode matcode; FILE *f; f = fopen(fname, "r"); assert(f != NULL); ret_code = mm_read_banner(f, &matcode); assert(ret_code == 0); assert(mm_is_real(matcode) && mm_is_matrix(matcode) && mm_is_sparse(matcode) && mm_is_symmetric(matcode)); ret_code = mm_read_mtx_crd_size(f, &m, n, &nz); assert(ret_code == 0); assert(m == *n); /* read COO format */ i_coo = (int *)malloc(nz * sizeof(int)); j_coo = (int *)malloc(nz * sizeof(int)); v_coo = (double *)malloc(nz * sizeof(double)); assert(i_coo && j_coo && v_coo); for (i = 0; i < nz; i ++) { fscanf(f, "%d %d %lg\n", &i_coo[i], &j_coo[i], &v_coo[i]); i_coo[i]--; /* adjust from 1-based to 0-based */ j_coo[i]--; } fclose(f); /* convert to SSS format */ convert_COO_SSS(*n, nz, i_coo, j_coo, v_coo, ia, ja, va, da); free(i_coo); free(j_coo); free(v_coo); }
void readmat(const char * filename,float **matrix,int *rows,int *cols,int *acc){ FILE *f; int M, N, nz,rt; int I,J,i; float temp; if(filename==NULL){ printf("ERROR! specify filename\n"); exit(1); } f=fopen(filename,"r"); mm_read_mtx_crd_size(f,&M,&N,&nz); *rows=M; *cols=N; *acc=nz; *matrix=(float*)malloc(sizeof(float)*M*N); for(i=0;i<M*N;i++){ //set all val of matrix to 0 (*matrix)[i]=0.0f; } printf("rows=%d,cols=%d\n",*rows,*cols); for (i=0; i<nz; i++){ rt=fscanf(f, "%d %d %f\n", &I, &J,&temp); I--; J--; (*matrix)[I*N+J]=temp; } printf("returned val=%d\n",rt); if(f!=stdin) fclose(f); printf("matrix reading done.first=%f,last=%f\n",(*matrix)[0],(*matrix)[M*N-1]); //verified }
void convert_2_vec(const char * filename, shotgun_data * prob ) { int ret_code; MM_typecode matcode; FILE *f; int M, N, nz; int i; if ((f = fopen(filename, "r")) == NULL) { printf("Could not file vector input file : %s.\n", filename); exit(1); } if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner in input file %s.\n", filename); 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){ printf("Could not process Matrix Market size in input file: %s.\n", filename); exit(1); } /* 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) */ prob->y.reserve(nz); int I,J; double val; for (i=0; i<nz; i++) { fscanf(f, "%d %d %lg\n", &I, &J, &val); I--; /* adjust from 1-based to 0-based */ J--; assert(J==0); prob->y.push_back(val); } if (f !=stdin) fclose(f); }
int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J, double **val, MM_typecode *matcode) { int ret_code; FILE *f; if (strcmp(fname, "stdin") == 0) f=stdin; else if ((f = fopen(fname, "r")) == NULL) return MM_COULD_NOT_READ_FILE; if ((ret_code = mm_read_banner(f, matcode)) != 0) return ret_code; if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) && mm_is_matrix(*matcode))) return MM_UNSUPPORTED_TYPE; if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0) return ret_code; //*I = (int *) malloc(*nz * sizeof(int)); //*J = (int *) malloc(*nz * sizeof(int)); //*val = NULL; *I = new int[*nz]; *J = new int[*nz]; *val = 0; if (mm_is_complex(*matcode)) { //*val = (double *) malloc(*nz * 2 * sizeof(double)); *val = new double[2*(*nz)]; ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } else if (mm_is_real(*matcode)) { //*val = (double *) malloc(*nz * sizeof(double)); *val = new double[*nz]; ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } else if (mm_is_pattern(*matcode)) { ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } if (f != stdin) fclose(f); return 0; }
void test_predictions3(float (*prediction_func)(const vertex_data & user, const vertex_data & movie, const vertex_data & time, float rating, double & prediction)) { int ret_code; MM_typecode matcode; FILE *f; uint Me, Ne; size_t nz; if ((f = fopen(test.c_str(), "r")) == NULL) { return; //missing validaiton data, nothing to compute } FILE * fout = fopen((test + ".predict").c_str(),"w"); if (fout == NULL) logstream(LOG_FATAL)<<"Failed to open test prediction file for writing"<<std::endl; if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner. File: " << test << std::endl; /* 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_sparse(matcode)) logstream(LOG_FATAL) << "Sorry, this application does not support complex values and requires a sparse matrix." << std::endl; /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &Me, &Ne, &nz)) !=0) { logstream(LOG_FATAL) << "Failed reading matrix size: error=" << ret_code << std::endl; } if ((M > 0 && N > 0 ) && (Me != M || Ne != N)) logstream(LOG_FATAL)<<"Input size of test matrix must be identical to training matrix, namely " << M << "x" << N << std::endl; mm_write_banner(fout, matcode); mm_write_mtx_crd_size(fout ,M,N,nz); for (uint i=0; i<nz; i++) { int I, J; double val; int time; int rc = fscanf(f, "%d %d %d %lg\n", &I, &J, &time, &val); if (rc != 4) logstream(LOG_FATAL)<<"Error when reading input file: " << i << std::endl; I--; /* adjust from 1-based to 0-based */ J--; double prediction; (*prediction_func)(latent_factors_inmem[I], latent_factors_inmem[J+M], latent_factors_inmem[time+M+N], 1, prediction); fprintf(fout, "%d %d %12.8lg\n", I+1, J+1, prediction); } fclose(f); fclose(fout); logstream(LOG_INFO)<<"Finished writing " << nz << " predictions to file: " << test << ".predict" << std::endl; }
/** Reads the dimensions of the matrix (n - number of rows, m - number of columns, nnzs - number of non-zeros) from the given Matrix Market file. If the given file contains an array rather than a COO matrix, nnzs will be set to n; */ void read_mm_matrix_size(FILE *f, int *n, int *m, int *nnzs, MM_typecode* mcode) { if (mm_read_banner(f, mcode) != 0) { printf("Could not process Matrix Market banner.\n"); exit(1); } if (mm_is_array(*mcode)) { mm_read_mtx_array_size(f, n, m); *nnzs = *n; } else { mm_read_mtx_crd_size(f, n, m, nnzs); } }
int mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J, double **val, MM_typecode *matcode) { int ret_code; ZOLTAN_FILE* f; if ((f = ZOLTAN_FILE_open(fname, "r", STANDARD)) == NULL) return MM_COULD_NOT_READ_FILE; if ((ret_code = mm_read_banner(f, matcode)) != 0) return ret_code; if (!(mm_is_valid(*matcode) && mm_is_sparse(*matcode) && mm_is_matrix(*matcode))) return MM_UNSUPPORTED_TYPE; if ((ret_code = mm_read_mtx_crd_size(f, M, N, nz)) != 0) return ret_code; *I = (int *) malloc(*nz * sizeof(int)); *J = (int *) malloc(*nz * sizeof(int)); *val = NULL; if (mm_is_complex(*matcode)) { *val = (double *) malloc(*nz * 2 * sizeof(double)); ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } else if (mm_is_real(*matcode)) { *val = (double *) malloc(*nz * sizeof(double)); ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } else if (mm_is_pattern(*matcode)) { ret_code = mm_read_mtx_crd_data(f, *M, *N, *nz, *I, *J, *val, *matcode); if (ret_code != 0) return ret_code; } ZOLTAN_FILE_close(f); return 0; }
/** load a matrix market file into a matrix */ void load_matrix_market_matrix(const std::string & filename, int offset, int D){ MM_typecode matcode; uint i,I,J; double val; uint rows, cols; size_t nnz; FILE * f = open_file(filename.c_str() ,"r"); int rc = mm_read_banner(f, &matcode); if (rc != 0) logstream(LOG_FATAL)<<"Failed to load matrix market banner in file: " << filename << std::endl; if (mm_is_sparse(matcode)){ int rc = mm_read_mtx_crd_size(f, &rows, &cols, &nnz); if (rc != 0) logstream(LOG_FATAL)<<"Failed to load matrix market banner in file: " << filename << std::endl; } else { //dense matrix rc = mm_read_mtx_array_size(f, &rows, &cols); if (rc != 0) logstream(LOG_FATAL)<<"Failed to load matrix market banner in file: " << filename << std::endl; nnz = rows * cols; } if (D != (int)cols) logstream(LOG_FATAL)<<"Wrong matrix size detected, command line argument should be --D=" << D << " instead of : " << cols << std::endl; for (i=0; i<nnz; i++){ if (mm_is_sparse(matcode)){ rc = fscanf(f, "%u %u %lg\n", &I, &J, &val); if (rc != 3) logstream(LOG_FATAL)<<"Error reading input line " << i << std::endl; I--; J--; assert(I >= 0 && I < rows); assert(J >= 0 && J < cols); //set_val(a, I, J, val); latent_factors_inmem[I+offset].set_val(J,val); } else { rc = fscanf(f, "%lg", &val); if (rc != 1) logstream(LOG_FATAL)<<"Error reading nnz " << i << std::endl; I = i / cols; J = i % cols; latent_factors_inmem[I+offset].set_val(J, val); } } logstream(LOG_INFO) << "Factors from file: loaded matrix of size " << rows << " x " << cols << " from file: " << filename << " total of " << nnz << " entries. "<< i << std::endl; fclose(f); }
int readBandedMatrix(char* filename, int& n, int& t, int& nz, long long*& AR, long long*& AC, double*& AV) { // 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)) { 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_general(type)) { fprintf(stderr, "Sorry, this application does not support Market Market type: [%s]\n", mm_typecode_to_str(type)); return 3; } // read the sizes and nnz of the matrix int m; if (mm_read_mtx_crd_size(fp, &n, &m, &nz)) { fprintf(stderr, "Could not read the size of the matrix.\n"); return 4; } printf("reading %s:\n\ta %d x %d banded matrix ", filename, n, m); // allocate the memory AR = new long long[nz]; AC = new long long[nz]; AV = new double[nz]; t = 0; for (int i = 0; i < nz; ++i) { fscanf(fp, "%d %d %lf\n", AR + i, AC + i, AV + i); --AR[i]; // 0-indexing --AC[i]; // 0-indexing t = std::max(t, (int)(AR[i] - AC[i])); } printf("with bandwidth (2m + 1) = %d...done\n", 2 * t + 1); // close the file fclose(fp); return 0; }
void read_matrix_market_banner_and_size(FILE * f, MM_typecode & matcode, uint & Me, uint & Ne, size_t & nz, const std::string & filename){ if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner. File: " << filename << std::endl; /* 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_sparse(matcode)) logstream(LOG_FATAL) << "Sorry, this application does not support complex values and requires a sparse matrix." << std::endl; /* find out size of sparse matrix .... */ if (mm_read_mtx_crd_size(f, &Me, &Ne, &nz) != 0) { logstream(LOG_FATAL) << "Failed reading matrix size: error" << std::endl; } }
bool loadMmProperties(int *rowsCount, int *columnsCount, int *nonZerosCount, bool *isStoredSparse, int* matrixStorage, int* matrixType, FILE *file) { MM_typecode matcode; // supports only valid matrices if ((mm_read_banner(file, &matcode) != 0) || (!mm_is_matrix(matcode)) || (!mm_is_valid(matcode))) return false; if ( mm_read_mtx_crd_size(file, rowsCount, columnsCount, nonZerosCount) != 0 ) return false; // is it stored sparse? if (mm_is_sparse(matcode)) *isStoredSparse = true; else *isStoredSparse = false; if (mm_is_integer(matcode)) *matrixStorage = MATRIX_STORAGE_INTEGER; else if (mm_is_real(matcode)) *matrixStorage = MATRIX_STORAGE_REAL; else if (mm_is_complex(matcode)) *matrixStorage = MATRIX_STORAGE_COMPLEX; else if (mm_is_pattern(matcode)) *matrixStorage = MATRIX_STORAGE_PATTERN; if (mm_is_general(matcode)) *matrixType = MATRIX_TYPE_GENERAL; else if (mm_is_symmetric(matcode)) *matrixType = MATRIX_TYPE_SYMMETRIC; else if (mm_is_skew(matcode)) *matrixType = MATRIX_TYPE_SKEW; else if (mm_is_hermitian(matcode)) *matrixType = MATRIX_TYPE_HERMITIAN; return true; }
int DenseMatrix_mm_read_strassen(DenseMatrix *m, char *file_name, int *nr_rows, int *nr_cols) { int res; MM_typecode matcode; FILE *file; file = fopen(file_name, "r"); CHECK_NULL_RETURN(file); res = mm_read_banner(file, &matcode); CHECK_ZERO_ERROR_RETURN(res, "Failed to read matrix code"); CHECK_ERROR_RETURN(!mm_is_matrix(matcode), "File is not a matrix", 1); if (mm_is_sparse(matcode)) { int nr_sparse_elements; res = mm_read_mtx_crd_size(file, nr_rows, nr_cols, &nr_sparse_elements); CHECK_ZERO_ERROR_RETURN(res, "Failed to read sparse mm dimensions"); int dim = pow2dim(*nr_rows, *nr_cols); // Initialzie matrix to zero to fill in with sparse elements res = DenseMatrix_init_zero(m, dim, dim); CHECK_ZERO_ERROR_RETURN(res, "Failed to allocate memory for mm matrix"); res = DenseMatrix_parse_mm_sparse(m, file, nr_sparse_elements); } else if (mm_is_dense(matcode)) { res = mm_read_mtx_array_size(file, nr_rows, nr_cols); CHECK_ZERO_ERROR_RETURN(res, "Failed to read dense mm dimensions"); int dim = pow2dim(*nr_rows, *nr_cols); res = DenseMatrix_init_zero(m, dim, dim); CHECK_ZERO_ERROR_RETURN(res, "Failed to allocate memory for mm matrix"); res = DenseMatrix_parse_mm_dense(m, file); } else { ERROR("mm matrix code is not supported. Only supports dense and sparse matrices"); } CHECK_ZERO_ERROR_RETURN(res, "Failed to parse mm file"); return 0; }
int get_mm_info(const char *file, int *m, int *n, int *nz) { FILE *fp; MM_typecode matcode; if ((fp = fopen(file, "r")) == NULL) { fprintf(stderr,"ERROR: Could not open file: %s\n",file); exit(1); } if (mm_read_banner(fp, &matcode) != 0) { fprintf(stderr,"ERROR: Could not process Matrix Market banner.\n"); exit(1); } if (!(mm_is_real(matcode) || mm_is_integer(matcode))) { fprintf(stderr,"ERROR: Market Market type: [%s] not supported\n", mm_typecode_to_str(matcode)); exit(1); } if (mm_is_sparse(matcode)) { if (mm_read_mtx_crd_size(fp, m, n, nz) !=0) { /* find out size of sparse matrix */ exit(1); } } else { if (mm_read_mtx_array_size(fp, m, n) !=0) { /* find out size of dense matrix */ exit(1); } *nz = -1; } fclose(fp); return 0; }
/* fread sparse */ static mm_sparse * mm_real_fread_sparse (FILE *fp, MM_typecode typecode) { int k, l; int m, n, nnz; int *j; mm_sparse *s; if (mm_read_mtx_crd_size (fp, &m, &n, &nnz) != 0) return NULL; s = mm_real_new (MM_REAL_SPARSE, MM_REAL_GENERAL, m, n, nnz); j = (int *) malloc (s->nnz * sizeof (int)); if (mm_read_mtx_crd_data (fp, s->m, s->n, s->nnz, s->i, j, s->data, typecode) != 0) { free (j); mm_real_free (s); return NULL; } l = 0; for (k = 0; k < nnz; k++) { s->i[k]--; // fortran -> c while (l < j[k]) s->p[l++] = k; } while (l <= n) s->p[l++] = k; if (mm_is_symmetric (typecode)) { mm_real_set_symmetric (s); for (k = 0; k < nnz; k++) { if (s->i[k] == j[k] - 1) continue; (s->i[k] < j[k] - 1) ? mm_real_set_upper (s) : mm_real_set_lower (s); break; } } free (j); return s; }
vec load_matrix_market_vector(const std::string & filename, bool optional_field, bool allow_zeros) { int ret_code; MM_typecode matcode; uint M, N; size_t i,nz; logstream(LOG_INFO) <<"Going to read matrix market vector from input file: " << filename << std::endl; FILE * f = open_file(filename.c_str(), "r", optional_field); //if optional file not found return if (f== NULL && optional_field){ return zeros(1); } if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner." << std::endl; /* 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) ) logstream(LOG_FATAL) << "sorry, this application does not support " << std::endl << "Market Market type: " << mm_typecode_to_str(matcode) << std::endl; /* find out size of sparse matrix .... */ if (mm_is_sparse(matcode)){ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0) logstream(LOG_FATAL) << "failed to read matrix market cardinality size " << std::endl; } else { if ((ret_code = mm_read_mtx_array_size(f, &M, &N))!= 0) logstream(LOG_FATAL) << "failed to read matrix market vector size " << std::endl; if (N > M){ //if this is a row vector, transpose int tmp = N; N = M; M = tmp; } nz = M*N; } vec ret = zeros(M); uint row,col; double val; for (i=0; i<nz; i++) { if (mm_is_sparse(matcode)){ int rc = fscanf(f, "%u %u %lg\n", &row, &col, &val); if (rc != 3){ logstream(LOG_FATAL) << "Failed reading input file: " << filename << "Problm at data row " << i << " (not including header and comment lines)" << std::endl; } row--; /* adjust from 1-based to 0-based */ col--; } else { int rc = fscanf(f, "%lg\n", &val); if (rc != 1){ logstream(LOG_FATAL) << "Failed reading input file: " << filename << "Problm at data row " << i << " (not including header and comment lines)" << std::endl; } row = i; col = 0; } //some users have gibrish in text file - better check both I and J are >=0 as well assert(row >=0 && row< M); assert(col == 0); if (val == 0 && !allow_zeros) logstream(LOG_FATAL)<<"Zero entries are not allowed in a sparse matrix market vector. Use --zero=true to avoid this error"<<std::endl; //set observation value ret[row] = val; } fclose(f); logstream(LOG_INFO)<<"Succesfully read a vector of size: " << M << " [ " << nz << "]" << std::endl; return ret; }
static void read_mtx_and_return_csr( int argc, char **argv, int *mm, int *nn, int **ia, int **ja, double **aa) { int ret_code; MM_typecode matcode; FILE *f; int m, n, nz; int i, *I, *J; double *val; if (argc < 2) { fprintf(stderr, "Usage: %s [martix-market-filename]\n", argv[0]); exit(1); } else { printf("\n===================================\n"); printf("mtx file = %s\n", argv[1]); if ((f = fopen(argv[1], "r")) == NULL) { printf("Could not open %s\n", argv[1]); exit(1); } } 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_pattern(matcode) || mm_is_dense(matcode) || mm_is_array(matcode) ) { printf("Sorry, this application does not support "); printf("Market Market type: [%s]\n", mm_typecode_to_str(matcode)); exit(1); } 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(nz * sizeof(int)); J = (int *) malloc(nz * sizeof(int)); val = (double *) malloc(nz * sizeof(double)); /* 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 (i=0; i<nz; i++) { fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]); I[i]--; /* adjust from 1-based to 0-based */ J[i]--; } if (f !=stdin) fclose(f); if (m != n) exit(1); *mm = m; *nn = n; *ia = (int*) malloc (sizeof(int) * (n+1)); *ja = (int*) malloc (sizeof(int) * nz); *aa = (double*) malloc (sizeof(double) * nz); coo2csr(n, nz, val, I, J, *aa, *ja, *ia); free (I); free (J); free (val); }
cs *read_matrix(const char *filename, MM_typecode &matcode) { LogInfo("Reading Matrix from " << std::string(filename) << "\n"); FILE *file = fopen(filename, "r"); if (!file) { LogError("Error: Cannot read file " << std::string(filename) << "\n"); return NULL; } LogInfo("Reading Matrix Market banner..."); if (mm_read_banner(file, &matcode) != 0) { LogError("Error: Could not process Matrix Market banner\n"); fclose(file); return NULL; } if (!mm_is_matrix(matcode) || !mm_is_sparse(matcode) || mm_is_complex(matcode)) { LogError( "Error: Unsupported matrix format - Must be real and sparse\n"); fclose(file); return NULL; } Int M, N, nz; if ((mm_read_mtx_crd_size(file, &M, &N, &nz)) != 0) { LogError("Error: Could not parse matrix dimension and size.\n"); fclose(file); return NULL; } if (M != N) { LogError("Error: Matrix must be square.\n"); fclose(file); return NULL; } LogInfo("Reading matrix data...\n"); Int *I = (Int *)SuiteSparse_malloc(static_cast<size_t>(nz), sizeof(Int)); Int *J = (Int *)SuiteSparse_malloc(static_cast<size_t>(nz), sizeof(Int)); double *val = (double *)SuiteSparse_malloc(static_cast<size_t>(nz), sizeof(double)); if (!I || !J || !val) { LogError("Error: Ran out of memory in Mongoose::read_matrix\n"); SuiteSparse_free(I); SuiteSparse_free(J); SuiteSparse_free(val); fclose(file); return NULL; } mm_read_mtx_crd_data(file, M, N, nz, I, J, val, matcode); fclose(file); // Close the file for (Int k = 0; k < nz; k++) { --I[k]; --J[k]; if (mm_is_pattern(matcode)) val[k] = 1; } cs *A = (cs *)SuiteSparse_malloc(1, sizeof(cs)); if (!A) { LogError("Error: Ran out of memory in Mongoose::read_matrix\n"); SuiteSparse_free(I); SuiteSparse_free(J); SuiteSparse_free(val); return NULL; } A->nzmax = nz; A->m = M; A->n = N; A->p = J; A->i = I; A->x = val; A->nz = nz; LogInfo("Compressing matrix from triplet to CSC format...\n"); cs *compressed_A = cs_compress(A); cs_spfree(A); if (!compressed_A) { LogError("Error: Ran out of memory in Mongoose::read_matrix\n"); return NULL; } return compressed_A; }
/* * 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); }
int main(int argc,char **args) { /*PETSc Mat Object */ Mat pMat; /* Input matrix market file and output PETSc binary file */ char inputFile[128],outputFile[128],buf[128]; /* number rows, columns, non zeros etc */ int i,j,m,n,nnz,ierr,col,row; /*We compute no of nozeros per row for PETSc Mat object pre-allocation*/ int *nnzPtr; /*Maximum nonzero in nay row */ int maxNNZperRow=0; /*Row number containing max non zero elements */ int maxRowNum = 0; /*Just no of comments that will be ignore during successive read of file */ int numComments=0; PetscScalar zero=0; /* This is variable of type double */ PetscScalar val; /*File handle for read and write*/ FILE* file; /*File handle for writing nonzero elements distribution per row */ FILE *fileRowDist; /*PETSc Viewer is used for writing PETSc Mat object in binary format */ PetscViewer view; /*Just record time required for conversion */ PetscLogDouble t1,t2,elapsed_time; /* MatrixMarket struct */ MM_typecode matcode; /*Initialise PETSc lib */ PetscInitialize(&argc,&args,(char *)0,PETSC_NULL); /* Just record time */ //ierr = PetscGetTime(&t1); CHKERRQ(ierr); /*Get name of matrix market file from command line options and Open file*/ ierr = PetscOptionsGetString(PETSC_NULL,"-fin",inputFile,127,PETSC_NULL); CHKERRQ(ierr); ierr = PetscFOpen(PETSC_COMM_SELF,inputFile,"r",&file); CHKERRQ(ierr); if (mm_read_banner(file, &matcode)) { PetscPrintf(PETSC_COMM_SELF, "Could not read Matrix Market banner.\n"); exit(1); } /********************* MM_typecode query fucntions ***************************/ /* #define mm_is_matrix(typecode) ((typecode)[0]=='M') */ /* #define mm_is_sparse(typecode) ((typecode)[1]=='C') */ /* #define mm_is_coordinate(typecode)((typecode)[1]=='C') */ /* #define mm_is_dense(typecode) ((typecode)[1]=='A') */ /* #define mm_is_array(typecode) ((typecode)[1]=='A') */ /* #define mm_is_complex(typecode) ((typecode)[2]=='C') */ /* #define mm_is_real(typecode) ((typecode)[2]=='R') */ /* #define mm_is_pattern(typecode) ((typecode)[2]=='P') */ /* #define mm_is_integer(typecode) ((typecode)[2]=='I') */ /* #define mm_is_symmetric(typecode)((typecode)[3]=='S') */ /* #define mm_is_general(typecode) ((typecode)[3]=='G') */ /* #define mm_is_skew(typecode) ((typecode)[3]=='K') */ /* #define mm_is_hermitian(typecode)((typecode)[3]=='H') */ /* int mm_is_valid(MM_typecode matcode); */ /* Do not convert pattern matrices */ if (mm_is_pattern(matcode)) { ierr = PetscPrintf(PETSC_COMM_SELF, "%s: Pattern matrix -- skipping.\n", inputFile); exit(0); } /* find out size of sparse matrix .... */ /*Reads size of sparse matrix from matrix market file */ int ret_code; if ((ret_code = mm_read_mtx_crd_size(file, &m, &n, &nnz)) !=0) exit(1); ierr = PetscPrintf(PETSC_COMM_SELF, "%s: ROWS = %d, COLUMNS = %d, NO OF NON-ZEROS = %d\n",inputFile,m,n,nnz); /* Only consider square matrices */ if (m != n) { ierr = PetscPrintf(PETSC_COMM_SELF, "%s: Nonsquare matrix -- skipping.\n", inputFile); exit(0); } ierr = MatCreate(PETSC_COMM_WORLD,&pMat);CHKERRQ(ierr); ierr = MatSetFromOptions(pMat);CHKERRQ(ierr); //ierr = MatSetOption(pMat, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE); CHKERRQ(ierr); if (mm_is_symmetric(matcode)) { ierr = MatSetOption(pMat,MAT_SYMMETRIC,PETSC_TRUE); CHKERRQ(ierr); ierr = MatSetOption(pMat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE); CHKERRQ(ierr); } ierr = MatSetSizes(pMat,PETSC_DECIDE,PETSC_DECIDE,m,n);CHKERRQ(ierr); ierr = MatSetUp(pMat);CHKERRQ(ierr); //printf("\n MAX NONZERO FOR ANY ROW ARE : %d & ROW NUM IS : %d", maxNNZperRow, maxRowNum ); /* Its important to pre-allocate memory by passing max non zero for any row in the matrix */ //ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,m,n,maxNNZperRow,PETSC_NULL,&pMat); /* OR we can also pass row distribution of nozero elements for every row */ /* ierr = MatCreateSeqAIJ(PETSC_COMM_WORLD,m,n,0,nnzPtr,&pMat);*/ /*Now Set matrix elements values form matrix market file */ for (i=0; i < m; i++){ for (j = 0; j < n; j++) { if (i != j) continue; ierr = MatSetValues(pMat,1,&i,1,&j,&zero,INSERT_VALUES); CHKERRQ(ierr); } } for (i=0; i<nnz; i++) { /*Read matrix element from matrix market file*/ fscanf(file,"%d %d %le\n",&row,&col,&val); /*In matrix market format, rows and columns starts from 1 */ row = row-1; col = col-1 ; /* For every non zero element,insert that value at row,col position */ ierr = MatSetValues(pMat,1,&row,1,&col,&val,INSERT_VALUES); CHKERRQ(ierr); } fclose(file); /*Matrix Read Complete */ ierr = PetscPrintf(PETSC_COMM_SELF,"%s MATRIX READ...DONE!\n", inputFile); /*Now assemeble the matrix */ ierr = MatAssemblyBegin(pMat,MAT_FINAL_ASSEMBLY); ierr = MatAssemblyEnd(pMat,MAT_FINAL_ASSEMBLY); /* Now open output file for writing into PETSc Binary FOrmat*/ ierr = PetscOptionsGetString(PETSC_NULL,"-fout",outputFile,127,PETSC_NULL);CHKERRQ(ierr); /*With the PETSc Viewer write output to File*/ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,outputFile,FILE_MODE_WRITE,&view);CHKERRQ(ierr); /*Matview will dump the Mat object to binary file */ ierr = MatView(pMat,view);CHKERRQ(ierr); //ierr = MatView(pMat,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"%s PETSC MATRIX STORED\n", outputFile); /* Destroy the data structure */ ierr = PetscViewerDestroy(&view);CHKERRQ(ierr); ierr = MatDestroy(&pMat);CHKERRQ(ierr); /*Just for statistics*/ /* ierr = PetscGetTime(&t2);CHKERRQ(ierr); elapsed_time = t2 - t1; ierr = PetscPrintf(PETSC_COMM_SELF,"ELAPSE TIME: %g\n",elapsed_time);CHKERRQ(ierr); */ ierr = PetscFinalize();CHKERRQ(ierr); return 0; }
int MatrixMarketFileToBlockMaps(const char* filename, const Epetra_Comm& comm, Epetra_BlockMap*& rowmap, Epetra_BlockMap*& colmap, Epetra_BlockMap*& rangemap, Epetra_BlockMap*& domainmap) { FILE* infile = fopen(filename, "r"); if (infile == NULL) { return(-1); } MM_typecode matcode; int err = mm_read_banner(infile, &matcode); if (err != 0) return(err); if (!mm_is_matrix(matcode) || !mm_is_coordinate(matcode) || !mm_is_real(matcode) || !mm_is_general(matcode)) { return(-1); } int numrows, numcols, nnz; err = mm_read_mtx_crd_size(infile, &numrows, &numcols, &nnz); if (err != 0) return(err); //for this case, we'll assume that the row-map is the same as //the range-map. //create row-map and range-map with linear distributions. rowmap = new Epetra_BlockMap(numrows, 1, 0, comm); rangemap = new Epetra_BlockMap(numrows, 1, 0, comm); int I, J; double val, imag; int num_map_cols = 0, insertPoint, foundOffset; int allocLen = numcols; int* map_cols = new int[allocLen]; //read through all matrix data and construct a list of the column- //indices that occur in rows that are local to this processor. for(int i=0; i<nnz; ++i) { err = mm_read_mtx_crd_entry(infile, &I, &J, &val, &imag, matcode); if (err == 0) { --I; --J; if (rowmap->MyGID(I)) { foundOffset = Epetra_Util_binary_search(J, map_cols, num_map_cols, insertPoint); if (foundOffset < 0) { Epetra_Util_insert(J, insertPoint, map_cols, num_map_cols, allocLen); } } } } //create colmap with the list of columns associated with rows that are //local to this processor. colmap = new Epetra_Map(-1, num_map_cols, map_cols, 0, comm); //create domainmap which has a linear distribution domainmap = new Epetra_BlockMap(numcols, 1, 0, comm); delete [] map_cols; return(0); }
magma_int_t magma_d_csr_mtx( magma_d_matrix *A, const char *filename, magma_queue_t queue ) { char buffer[ 1024 ]; magma_int_t info = 0; int csr_compressor = 0; // checks for zeros in original file magma_d_matrix B={Magma_CSR}; magma_index_t *coo_col = NULL; magma_index_t *coo_row = NULL; double *coo_val = NULL; double *new_val = NULL; magma_index_t* new_row = NULL; magma_index_t* new_col = NULL; magma_int_t symmetric = 0; std::vector< std::pair< magma_index_t, double > > rowval; FILE *fid = NULL; MM_typecode matcode; fid = fopen(filename, "r"); if (fid == NULL) { printf("%% Unable to open file %s\n", filename); info = MAGMA_ERR_NOT_FOUND; goto cleanup; } printf("%% Reading sparse matrix from file (%s):", filename); fflush(stdout); if (mm_read_banner(fid, &matcode) != 0) { printf("\n%% Could not process Matrix Market banner: %s.\n", matcode); info = MAGMA_ERR_NOT_SUPPORTED; goto cleanup; } if (!mm_is_valid(matcode)) { printf("\n%% Invalid Matrix Market file.\n"); info = MAGMA_ERR_NOT_SUPPORTED; goto cleanup; } if ( ! ( ( mm_is_real(matcode) || mm_is_integer(matcode) || mm_is_pattern(matcode) || mm_is_real(matcode) ) && mm_is_coordinate(matcode) && mm_is_sparse(matcode) ) ) { mm_snprintf_typecode( buffer, sizeof(buffer), matcode ); printf("\n%% Sorry, MAGMA-sparse does not support Market Market type: [%s]\n", buffer ); printf("%% Only real-valued or pattern coordinate matrices are supported.\n"); info = MAGMA_ERR_NOT_SUPPORTED; goto cleanup; } magma_index_t num_rows, num_cols, num_nonzeros; if (mm_read_mtx_crd_size(fid, &num_rows, &num_cols, &num_nonzeros) != 0) { info = MAGMA_ERR_UNKNOWN; goto cleanup; } A->storage_type = Magma_CSR; A->memory_location = Magma_CPU; A->num_rows = num_rows; A->num_cols = num_cols; A->nnz = num_nonzeros; A->fill_mode = MagmaFull; CHECK( magma_index_malloc_cpu( &coo_col, A->nnz ) ); CHECK( magma_index_malloc_cpu( &coo_row, A->nnz ) ); CHECK( magma_dmalloc_cpu( &coo_val, A->nnz ) ); if (mm_is_real(matcode) || mm_is_integer(matcode)) { for(magma_int_t i = 0; i < A->nnz; ++i) { magma_index_t ROW, COL; double VAL; // always read in a double and convert later if necessary fscanf(fid, " %d %d %lf \n", &ROW, &COL, &VAL); if ( VAL == 0 ) csr_compressor = 1; coo_row[i] = ROW - 1; coo_col[i] = COL - 1; coo_val[i] = MAGMA_D_MAKE( VAL, 0.); } } else if (mm_is_pattern(matcode) ) { for(magma_int_t i = 0; i < A->nnz; ++i) { magma_index_t ROW, COL; fscanf(fid, " %d %d \n", &ROW, &COL ); coo_row[i] = ROW - 1; coo_col[i] = COL - 1; coo_val[i] = MAGMA_D_MAKE( 1.0, 0.); } } else if (mm_is_real(matcode) ){ for(magma_int_t i = 0; i < A->nnz; ++i) { magma_index_t ROW, COL; double VAL, VALC; // always read in a double and convert later if necessary fscanf(fid, " %d %d %lf %lf\n", &ROW, &COL, &VAL, &VALC); coo_row[i] = ROW - 1; coo_col[i] = COL - 1; coo_val[i] = MAGMA_D_MAKE( VAL, VALC); } // printf(" ...successfully read real matrix... "); } else { printf("\n%% Unrecognized data type\n"); info = MAGMA_ERR_NOT_SUPPORTED; goto cleanup; } fclose(fid); fid = NULL; printf(" done. Converting to CSR:"); fflush(stdout); A->sym = Magma_GENERAL; if( mm_is_symmetric(matcode) ) { symmetric = 1; } if ( mm_is_symmetric(matcode) || mm_is_symmetric(matcode) ) { // duplicate off diagonal entries printf("\n%% Detected symmetric case."); A->sym = Magma_SYMMETRIC; magma_index_t off_diagonals = 0; for(magma_int_t i = 0; i < A->nnz; ++i) { if (coo_row[i] != coo_col[i]) ++off_diagonals; } magma_index_t true_nonzeros = 2*off_diagonals + (A->nnz - off_diagonals); //printf("%% total number of nonzeros: %d\n%%", int(A->nnz)); CHECK( magma_index_malloc_cpu( &new_row, true_nonzeros )); CHECK( magma_index_malloc_cpu( &new_col, true_nonzeros )); CHECK( magma_dmalloc_cpu( &new_val, true_nonzeros )); magma_index_t ptr = 0; for(magma_int_t i = 0; i < A->nnz; ++i) { if (coo_row[i] != coo_col[i]) { new_row[ptr] = coo_row[i]; new_col[ptr] = coo_col[i]; new_val[ptr] = coo_val[i]; ptr++; new_col[ptr] = coo_row[i]; new_row[ptr] = coo_col[i]; new_val[ptr] = (symmetric == 0) ? coo_val[i] : conj(coo_val[i]); ptr++; } else { new_row[ptr] = coo_row[i]; new_col[ptr] = coo_col[i]; new_val[ptr] = coo_val[i]; ptr++; } } magma_free_cpu(coo_row); magma_free_cpu(coo_col); magma_free_cpu(coo_val); coo_row = new_row; coo_col = new_col; coo_val = new_val; A->nnz = true_nonzeros; //printf("total number of nonzeros: %d\n", A->nnz); } // end symmetric case CHECK( magma_dmalloc_cpu( &A->val, A->nnz )); CHECK( magma_index_malloc_cpu( &A->col, A->nnz )); CHECK( magma_index_malloc_cpu( &A->row, A->num_rows+1 )); // original code from Nathan Bell and Michael Garland for (magma_index_t i = 0; i < num_rows; i++) (A->row)[i] = 0; for (magma_index_t i = 0; i < A->nnz; i++) (A->row)[coo_row[i]]++; // cumulative sum the nnz per row to get row[] magma_int_t cumsum; cumsum = 0; for(magma_int_t i = 0; i < num_rows; i++) { magma_index_t temp = (A->row)[i]; (A->row)[i] = cumsum; cumsum += temp; } (A->row)[num_rows] = A->nnz; // write Aj,Ax into Bj,Bx for(magma_int_t i = 0; i < A->nnz; i++) { magma_index_t row_ = coo_row[i]; magma_index_t dest = (A->row)[row_]; (A->col)[dest] = coo_col[i]; (A->val)[dest] = coo_val[i]; (A->row)[row_]++; } magma_free_cpu(coo_row); magma_free_cpu(coo_col); magma_free_cpu(coo_val); coo_row = NULL; coo_col = NULL; coo_val = NULL; int last; last = 0; for(int i = 0; i <= num_rows; i++) { int temp = (A->row)[i]; (A->row)[i] = last; last = temp; } (A->row)[A->num_rows] = A->nnz; // sort column indices within each row // copy into vector of pairs (column index, value), sort by column index, then copy back for (magma_index_t k=0; k < A->num_rows; ++k) { int kk = (A->row)[k]; int len = (A->row)[k+1] - (A->row)[k]; rowval.resize( len ); for( int i=0; i < len; ++i ) { rowval[i] = std::make_pair( (A->col)[kk+i], (A->val)[kk+i] ); } std::sort( rowval.begin(), rowval.end(), compare_first ); for( int i=0; i < len; ++i ) { (A->col)[kk+i] = rowval[i].first; (A->val)[kk+i] = rowval[i].second; } } if ( csr_compressor > 0) { // run the CSR compressor to remove zeros //printf("removing zeros: "); CHECK( magma_dmtransfer( *A, &B, Magma_CPU, Magma_CPU, queue )); CHECK( magma_d_csr_compressor( &(A->val), &(A->row), &(A->col), &B.val, &B.row, &B.col, &B.num_rows, queue )); B.nnz = B.row[num_rows]; //printf(" remaining nonzeros:%d ", B.nnz); magma_free_cpu( A->val ); magma_free_cpu( A->row ); magma_free_cpu( A->col ); CHECK( magma_dmtransfer( B, A, Magma_CPU, Magma_CPU, queue )); //printf("done.\n"); } A->true_nnz = A->nnz; printf(" done.\n"); cleanup: if ( fid != NULL ) { fclose( fid ); fid = NULL; } magma_dmfree( &B, queue ); magma_free_cpu(coo_row); magma_free_cpu(coo_col); magma_free_cpu(coo_val); return info; }
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)
//------------------------------------------------------------------------ int test_mm_read(std::string filename) { int ret_code; MM_typecode matcode; FILE *f; int M, N, nz; int i, *I, *J; double *val; int err=0; if ((f = fopen(filename.c_str(), "r")) == NULL) return -1; if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); return -2; } /* 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)); return -3; } /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0) return -4; /* reseve memory for matrices */ I = (int *) malloc(nz * sizeof(int)); J = (int *) malloc(nz * sizeof(int)); val = (double *) malloc(nz * sizeof(double)); /* 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 (i=0; i<nz; i++) { fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]); I[i]--; /* adjust from 1-based to 0-based */ J[i]--; } if (f !=stdin) fclose(f); /************************/ /* now write out matrix */ /************************/ fprintf(stdout, "Read full file contents: \n================================\n"); err += mm_write_banner(stdout, matcode); err += mm_write_mtx_crd_size(stdout, M, N, nz); for (i=0; i<nz; i++) { fprintf(stdout, "%d %d %lg\n", I[i]+1, J[i]+1, val[i]); } return err; }
int mm_read_unsymmetric_sparse(const char *fname, int *M_, int *N_, int *nz_, double **val_, int **I_, int **J_) { FILE *f; MM_typecode matcode; int M, N, nz; int i; double *val; int *I, *J; if ((f = fopen(fname, "r")) == NULL) return -1; if (mm_read_banner(f, &matcode) != 0) { printf("mm_read_unsymetric: Could not process Matrix Market banner "); printf(" in file [%s]\n", fname); return -1; } if ( !(mm_is_real(matcode) && mm_is_matrix(matcode) && mm_is_sparse(matcode))) { fprintf(stderr, "Sorry, this application does not support "); fprintf(stderr, "Market Market type: [%s]\n", mm_typecode_to_str(matcode)); return -1; } /* find out size of sparse matrix: M, N, nz .... */ if (mm_read_mtx_crd_size(f, &M, &N, &nz) !=0) { fprintf(stderr, "read_unsymmetric_sparse(): could not parse matrix size.\n"); return -1; } *M_ = M; *N_ = N; *nz_ = nz; /* reseve memory for matrices */ I = (int *) malloc(nz * sizeof(int)); J = (int *) malloc(nz * sizeof(int)); val = (double *) malloc(nz * sizeof(double)); *val_ = val; *I_ = I; *J_ = J; /* 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 (i=0; i<nz; i++) { fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]); I[i]--; /* adjust from 1-based to 0-based */ J[i]--; } fclose(f); return 0; }
int convert_matrixmarket(std::string base_filename, SharderPreprocessor<als_edge_type> * preprocessor = NULL) { // Note, code based on: http://math.nist.gov/MatrixMarket/mmio/c/example_read.c int ret_code; MM_typecode matcode; FILE *f; size_t nz; std::string suffix = ""; if (preprocessor != NULL) { suffix = preprocessor->getSuffix(); } /** * Create sharder object */ int nshards; if ((nshards = find_shards<als_edge_type>(base_filename+ suffix, get_option_string("nshards", "auto")))) { logstream(LOG_INFO) << "File " << base_filename << " was already preprocessed, won't do it again. " << std::endl; FILE * inf = fopen((base_filename + ".gm").c_str(), "r"); int rc = fscanf(inf,"%d\n%d\n%ld\n%lg\n%d\n",&M, &N, &L, &globalMean, &K); if (rc != 5) logstream(LOG_FATAL)<<"Failed to read global mean from file" << base_filename+ suffix << ".gm" << std::endl; fclose(inf); logstream(LOG_INFO) << "Opened matrix size: " <<M << " x " << N << " Global mean is: " << globalMean << " time bins: " << K << " Now creating shards." << std::endl; return nshards; } sharder<als_edge_type> sharderobj(base_filename + suffix); sharderobj.start_preprocessing(); if ((f = fopen(base_filename.c_str(), "r")) == NULL) { logstream(LOG_FATAL) << "Could not open file: " << base_filename << ", error: " << strerror(errno) << std::endl; } if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner. File: " << base_filename << std::endl; /* 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_sparse(matcode)) logstream(LOG_FATAL) << "Sorry, this application does not support complex values and requires a sparse matrix." << std::endl; /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0) { logstream(LOG_FATAL) << "Failed reading matrix size: error=" << ret_code << std::endl; } L=nz; logstream(LOG_INFO) << "Starting to read matrix-market input. Matrix dimensions: " << M << " x " << N << ", non-zeros: " << nz << std::endl; uint I, J; double val; if (!sharderobj.preprocessed_file_exists()) { for (size_t i=0; i<nz; i++) { int rc = fscanf(f, "%d %d %lg\n", &I, &J, &val); if (rc != 3) logstream(LOG_FATAL)<<"Error when reading input file: " << i << std::endl; I--; /* adjust from 1-based to 0-based */ J--; if (I >= M) logstream(LOG_FATAL)<<"Row index larger than the matrix row size " << I << " > " << M << " in line: " << i << std::endl; if (J >= N) logstream(LOG_FATAL)<<"Col index larger than the matrix col size " << J << " > " << N << " in line; " << i << std::endl; globalMean += val; sharderobj.preprocessing_add_edge(I, M + J, als_edge_type((float)val)); } uint toadd = 0; if (implicitratingtype == IMPLICIT_RATING_RANDOM) toadd = add_implicit_edges(implicitratingtype, sharderobj); globalMean += implicitratingvalue * toadd; L += toadd; sharderobj.end_preprocessing(); globalMean /= L; logstream(LOG_INFO) << "Global mean is: " << globalMean << " Now creating shards." << std::endl; if (preprocessor != NULL) { preprocessor->reprocess(sharderobj.preprocessed_name(), base_filename); } FILE * outf = fopen((base_filename + ".gm").c_str(), "w"); fprintf(outf, "%d\n%d\n%ld\n%lg\n%d\n", M, N, L, globalMean, K); fclose(outf); } else { logstream(LOG_INFO) << "Matrix already preprocessed, just run sharder." << std::endl; } fclose(f); logstream(LOG_INFO) << "Now creating shards." << std::endl; // Shard with a specified number of shards, or determine automatically if not defined nshards = sharderobj.execute_sharding(get_option_string("nshards", "auto")); logstream(LOG_INFO) << "Successfully finished sharding for " << base_filename + suffix << std::endl; logstream(LOG_INFO) << "Created " << nshards << " shards." << std::endl; return nshards; }
bool MatrixMarket::read_matrix(const char *file_name) { int ret_code; MM_typecode matcode; FILE *f; int i;//, *I(NULL); //, *J; // double *val; if ((f = fopen(file_name, "r")) == NULL) return false; if (mm_read_banner(f, &matcode) != 0) { printf("Could not process Matrix Market banner.\n"); return false; } /* 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)); return false; } /* find out size of sparse matrix .... */ int _num_rows, _num_cols, _num_nnzs; if ((ret_code = mm_read_mtx_crd_size(f, &_num_rows, &_num_cols, &_num_nnzs)) !=0) return false; bool is_vector = (_num_rows == _num_nnzs) && (_num_cols == 1); // convert to 64 bit m_num_rows = _num_rows; m_num_cols = _num_cols; m_num_nnzs = _num_nnzs; /* reseve memory for matrices */ // I = (int *) malloc(nz * sizeof(int)); // J = (int *) malloc(nz * sizeof(int)); // val = (double *) malloc(nz * sizeof(double)); m_rows.resize(m_num_nnzs); m_cols.resize(m_num_nnzs); m_coefs.resize(m_num_nnzs); /* 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) */ if (is_vector) { for (i=0; i<m_num_nnzs; i++) { fscanf(f, "%lg\n", &(m_coefs[i])); m_rows[i] = i; m_cols[i] = 0; } if (f !=stdin) fclose(f); return true; } std::vector<std::map<int32_t,double> > elements; elements.resize(m_num_rows); for (i=0; i<m_num_nnzs; i++) { fscanf(f, "%d %d %lg\n", &(m_rows[i]), &(m_cols[i]), &(m_coefs[i])); m_rows[i]--; /* adjust from 1-based to 0-based */ m_cols[i]--; elements[m_rows[i]][m_cols[i]] += m_coefs[i]; } // now sort by rows std::vector<int> m_rows2; std::vector<int32_t> m_cols2; std::vector<double> m_coefs2; m_rows2.resize(m_num_nnzs); m_cols2.resize(m_num_nnzs); m_coefs2.resize(m_num_nnzs); int index=0; for (int row=0; row<m_num_rows; row++) { assert((int)elements[row].size() > 0); // Make sure diagonal element is first if (elements[row].find(row) != elements[row].end()) { m_cols2[index] = row; m_rows2[index] = row; m_coefs2[index] = elements[row][row]; assert (m_coefs2[index] != 0.0); index++; } else assert(0); for (auto iter = elements[row].begin(); iter != elements[row].end(); iter++) { int col = iter->first; if (col != row) { double C = iter->second; assert(col < m_num_cols); m_rows2[index] = row; m_cols2[index] = col; m_coefs2[index] = C; index++; } } } if (f !=stdin) fclose(f); m_rows.swap(m_rows2); m_cols.swap(m_cols2); m_coefs.swap(m_coefs2); /* convert coo to csr row ptrs */ coo_to_csr_rows(m_rows, m_num_rows, m_row_ptrs); return true; // /************************/ // /* now write out matrix */ // /************************/ // mm_write_banner(stdout, matcode); // mm_write_mtx_crd_size(stdout, m_num_rows, m_num_cols, m_num_nnzs); // for (i=0; i<nz; i++) // fprintf(stdout, "%d %d %20.19g\n", I[i]+1, J[i]+1, val[i]); // free(I); }
int convert_matrixmarket4(std::string base_filename, bool add_time_edges = false, bool square = false) { // Note, code based on: http://math.nist.gov/MatrixMarket/mmio/c/example_read.c int ret_code; MM_typecode matcode; FILE *f; size_t nz; /** * Create sharder object */ int nshards; if ((nshards = find_shards<als_edge_type>(base_filename, get_option_string("nshards", "auto")))) { logstream(LOG_INFO) << "File " << base_filename << " was already preprocessed, won't do it again. " << std::endl; FILE * inf = fopen((base_filename + ".gm").c_str(), "r"); int rc = fscanf(inf,"%d\n%d\n%ld\n%lg\n%d\n",&M, &N, &L, &globalMean, &K); if (rc != 5) logstream(LOG_FATAL)<<"Failed to read global mean from file" << base_filename << ".gm" << std::endl; fclose(inf); if (K <= 0) logstream(LOG_FATAL)<<"Incorrect number of time bins K in .gm file " << base_filename << ".gm" << std::endl; logstream(LOG_INFO) << "Read matrix of size " << M << " x " << N << " Global mean is: " << globalMean << " time bins: " << K << " Now creating shards." << std::endl; return nshards; } sharder<als_edge_type> sharderobj(base_filename); sharderobj.start_preprocessing(); if ((f = fopen(base_filename.c_str(), "r")) == NULL) { logstream(LOG_FATAL) << "Could not open file: " << base_filename << ", error: " << strerror(errno) << std::endl; } if (mm_read_banner(f, &matcode) != 0) logstream(LOG_FATAL) << "Could not process Matrix Market banner. File: " << base_filename << std::endl; /* 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_sparse(matcode)) logstream(LOG_FATAL) << "Sorry, this application does not support complex values and requires a sparse matrix." << std::endl; /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0) { logstream(LOG_FATAL) << "Failed reading matrix size: error=" << ret_code << std::endl; } logstream(LOG_INFO) << "Starting to read matrix-market input. Matrix dimensions: " << M << " x " << N << ", non-zeros: " << nz << std::endl; uint I, J; double val, time; if (!sharderobj.preprocessed_file_exists()) { for (size_t i=0; i<nz; i++) { int rc = fscanf(f, "%d %d %lg %lg\n", &I, &J, &time, &val); if (rc != 4) logstream(LOG_FATAL)<<"Error when reading input file: " << i << std::endl; if (time < 0) logstream(LOG_FATAL)<<"Time (third columns) should be >= 0 " << std::endl; I--; /* adjust from 1-based to 0-based */ J--; if (I >= M) logstream(LOG_FATAL)<<"Row index larger than the matrix row size " << I << " > " << M << " in line: " << i << std::endl; if (J >= N) logstream(LOG_FATAL)<<"Col index larger than the matrix col size " << J << " > " << N << " in line; " << i << std::endl; K = std::max((int)time, (int)K); //avoid self edges if (square && I == J) continue; globalMean += val; L++; sharderobj.preprocessing_add_edge(I, (square? J : (M + J)), als_edge_type(val, time+M+N)); //in case of a tensor, add besides of the user-> movie edge also //time -> user and time-> movie edges if (add_time_edges){ sharderobj.preprocessing_add_edge((uint)time + M + N, I, als_edge_type(val, M+J)); sharderobj.preprocessing_add_edge((uint)time + M + N, M+J , als_edge_type(val, I)); } } uint toadd = 0; if (implicitratingtype == IMPLICIT_RATING_RANDOM) toadd = add_implicit_edges4(implicitratingtype, sharderobj); globalMean += implicitratingvalue * toadd; L += toadd; sharderobj.end_preprocessing(); globalMean /= L; logstream(LOG_INFO) << "Global mean is: " << globalMean << " time bins: " << K << " . Now creating shards." << std::endl; FILE * outf = fopen((base_filename + ".gm").c_str(), "w"); fprintf(outf, "%d\n%d\n%ld\n%lg\n%d\n", M, N, L, globalMean, K); fclose(outf); } else { logstream(LOG_INFO) << "Matrix already preprocessed, just run sharder." << std::endl; } fclose(f); logstream(LOG_INFO) << "Now creating shards." << std::endl; // Shard with a specified number of shards, or determine automatically if not defined nshards = sharderobj.execute_sharding(get_option_string("nshards", "auto")); return nshards; }
void HostMatrixCOO<ValueType>::ReadFileMTX(const std::string filename) { // Follow example_read.c (from Matrix Market web site) int ret_code; MM_typecode matcode; FILE *f; int M, N; int fnz, nnz; // file nnz, real nnz bool sym = false; LOG_INFO("ReadFileMTX: filename="<< filename << "; reading..."); if ((f = fopen(filename.c_str(), "r")) == NULL) { LOG_INFO("ReadFileMTX cannot open file " << filename); FATAL_ERROR(__FILE__, __LINE__); } if (mm_read_banner(f, &matcode) != 0) { LOG_INFO("ReadFileMTX could not process Matrix Market banner."); FATAL_ERROR(__FILE__, __LINE__); } /* 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) ) { LOG_INFO("ReadFileMTX does not support Market Market type:" << mm_typecode_to_str(matcode)); FATAL_ERROR(__FILE__, __LINE__); } /* find out size of sparse matrix .... */ if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &fnz)) !=0) { LOG_INFO("ReadFileMTX matrix size error"); FATAL_ERROR(__FILE__, __LINE__); } nnz = fnz ; /* reseve memory for matrices */ if(mm_is_symmetric(matcode)) { if (N != M) { LOG_INFO("ReadFileMTX non-squared symmetric matrices are not supported"); LOG_INFO("What is symmetric and non-squared matrix? e-mail me"); FATAL_ERROR(__FILE__, __LINE__); } nnz = 2*(nnz - N) + N; sym = true ; } this->AllocateCOO(nnz,M,N); int ii=0; int col, row; double val; int ret; for (int i=0; i<fnz; ++i) { ret = fscanf(f, "%d %d %lg\n", &row, &col, &val); if (!ret) FATAL_ERROR(__FILE__, __LINE__); row--; /* adjust from 1-based to 0-based */ col--; assert (ret == 3); // LOG_INFO(row << " " << col << " " << val); this->mat_.row[ii] = row; this->mat_.col[ii] = col; this->mat_.val[ii] = val; if (sym && (row!=col)) { ++ii; this->mat_.row[ii] = col; this->mat_.col[ii] = row; this->mat_.val[ii] = val; } ++ii; } LOG_INFO("ReadFileMTX: filename="<< filename << "; done"); fclose(f); }
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; }