int mm_is_valid ( MM_typecode matcode ) /******************************************************************************/ /* Purpose: MM_IS_VALID checks whether the MM header information is valid. Modified: 31 October 2008 Parameters: Input, MM_typecode MATCODE, the header information. Output, int MM_IS_VALID, is TRUE if the matrix code is valid. */ { if ( !mm_is_matrix ( matcode ) ) { return 0; } if ( mm_is_dense ( matcode ) && mm_is_pattern ( matcode ) ) { return 0; } if ( mm_is_real ( matcode ) && mm_is_hermitian ( matcode ) ) { return 0; } if ( mm_is_pattern ( matcode ) && ( mm_is_hermitian ( matcode ) || mm_is_skew ( matcode ) ) ) { return 0; } return 1; }
int mm_is_valid(MM_typecode matcode) { if (!mm_is_matrix(matcode)) return 0; if (mm_is_dense(matcode) && mm_is_pattern(matcode)) return 0; if (mm_is_real(matcode) && mm_is_hermitian(matcode)) return 0; if (mm_is_pattern(matcode) && (mm_is_hermitian(matcode) || mm_is_skew(matcode))) return 0; return 1; }
char *mm_typecode_to_str(MM_typecode matcode) { char buffer[MM_MAX_LINE_LENGTH]; char *types[4]; int error =0; int i; /* 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_sparserow(matcode)) types[1] = MM_SPARSEROW_STR; else if (mm_is_coordinate(matcode)) types[1] = MM_COORDINATE_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 strdup(buffer); }
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode) { int i; if (mm_is_complex(matcode)) { for (i=0; i<nz; i++) if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1]) != 4) return MM_PREMATURE_EOF; } else if (mm_is_real(matcode)) { for (i=0; i<nz; i++) { if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]) != 3) return MM_PREMATURE_EOF; } } else if (mm_is_pattern(matcode)) { for (i=0; i<nz; i++) if (fscanf(f, "%d %d", &I[i], &J[i]) != 2) return MM_PREMATURE_EOF; } else return MM_UNSUPPORTED_TYPE; return 0; }
int mm_read_mtx_crd_entry(FILE *f, int *I, int *J, double *real, double *imag, MM_typecode matcode) { if (mm_is_complex(matcode)) { if (fscanf(f, "%d %d %lg %lg", I, J, real, imag) != 4) return MM_PREMATURE_EOF; } else if (mm_is_real(matcode)) { if (fscanf(f, "%d %d %lg\n", I, J, real) != 3) return MM_PREMATURE_EOF; } else if (mm_is_pattern(matcode)) { if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF; } else return MM_UNSUPPORTED_TYPE; return 0; }
void MatrixMarketReader<FloatType>::MMGenerateCOOFromFile( FILE *infile, cl_bool read_explicit_zeroes ) { clsparseIdx_t unsym_actual_nnz = 0; FloatType val; clsparseIdx_t ir, ic; const int exp_zeroes = read_explicit_zeroes; //silence warnings from fscanf (-Wunused-result) clsparseIdx_t rv = 0; for ( clsparseIdx_t i = 0; i < nNZ; i++) { if( mm_is_real( Typecode ) ) { fscanf(infile, "%" SIZET "u", &ir); fscanf(infile, "%" SIZET "u", &ic); if (typeid(FloatType) == typeid(float)) rv = fscanf(infile, "%f\n", (float*)(&val)); else if( typeid( FloatType ) == typeid( double ) ) rv = fscanf( infile, "%lf\n", (double*)( &val ) ); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } else if( mm_is_integer( Typecode ) ) { fscanf(infile, "%" SIZET "u", &ir); fscanf(infile, "%" SIZET "u", &ic); if(typeid(FloatType) == typeid(float)) rv = fscanf(infile, "%f\n", (float*)( &val ) ); else if(typeid(FloatType) == typeid(double)) rv = fscanf(infile, "%lf\n", (double*)( &val ) ); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } else if( mm_is_pattern( Typecode ) ) { rv = fscanf(infile, "%" SIZET "u", &ir); rv = fscanf(infile, "%" SIZET "u", &ic); val = static_cast<FloatType>( MAX_RAND_VAL * ( rand( ) / ( RAND_MAX + 1.0 ) ) ); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } } nNZ = unsym_actual_nnz; }
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode) /******************************************************************************/ /* Purpose: MM_WRITE_MTX_CRD writes an MM coordinate file. Modified: 31 October 2008 */ { FILE *f; int i; if (strcmp(fname, "stdout") == 0) f = stdout; else if ((f = fopen(fname, "w")) == NULL) return MM_COULD_NOT_WRITE_FILE; /* print banner followed by typecode. */ fprintf(f, "%s ", MatrixMarketBanner); fprintf(f, "%s\n", mm_typecode_to_str(matcode)); /* print matrix sizes and nonzeros. */ fprintf(f, "%d %d %d\n", M, N, nz); /* print values. */ if (mm_is_pattern(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d\n", I[i], J[i]); else if (mm_is_real(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]); else if (mm_is_complex(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i], val[2*i+1]); else { if (f != stdout) fclose(f); return MM_UNSUPPORTED_TYPE; } if ( f !=stdout ) { fclose(f); } return 0; }
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 mm_typecode_to_str(MM_typecode matcode, char * buffer) { char type0[20]; char type1[20]; char type2[20]; char type3[20]; int error =0; /* check for MTX type */ if (mm_is_matrix(matcode)) strcpy(type0, MM_MTX_STR); else error=1; /* check for CRD or ARR matrix */ if (mm_is_sparse(matcode)) strcpy(type1, MM_SPARSE_STR); else if (mm_is_dense(matcode)) strcpy(type1, MM_DENSE_STR); else return; /* check for element data type */ if (mm_is_real(matcode)) strcpy(type2, MM_REAL_STR); else if (mm_is_complex(matcode)) strcpy(type2, MM_COMPLEX_STR); else if (mm_is_pattern(matcode)) strcpy(type2, MM_PATTERN_STR); else if (mm_is_integer(matcode)) strcpy(type2, MM_INT_STR); else return; /* check for symmetry type */ if (mm_is_general(matcode)) strcpy(type3, MM_GENERAL_STR); else if (mm_is_symmetric(matcode)) strcpy(type3, MM_SYMM_STR); else if (mm_is_hermitian(matcode)) strcpy(type3, MM_HERM_STR); else if (mm_is_skew(matcode)) strcpy(type3, MM_SKEW_STR); else return; sprintf(buffer,"%s %s %s %s", type0, type1, type2, type3); return; }
int mm_read_mtx_crd_data(FILE *f, int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode) /******************************************************************************/ /* Purpose: MM_READ_MTX_CRD_DATA reads the values in an MM coordinate file. Discussion: This function assumes the array storage has already been allocated. Modified: 31 October 2008 Parameters: Input, FILE *F, a pointer to the input file. */ { int i; if (mm_is_complex(matcode)) { for (i=0; i<nz; i++) if (fscanf(f, "%d %d %lg %lg", &I[i], &J[i], &val[2*i], &val[2*i+1]) != 4) return MM_PREMATURE_EOF; } else if (mm_is_real(matcode)) { for (i=0; i<nz; i++) { if (fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]) != 3) return MM_PREMATURE_EOF; } } else if (mm_is_pattern(matcode)) { for (i=0; i<nz; i++) if (fscanf(f, "%d %d", &I[i], &J[i]) != 2) return MM_PREMATURE_EOF; } else return MM_UNSUPPORTED_TYPE; return 0; }
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; }
void MatrixMarketReader<FloatType>::MMGenerateCOOFromFile( FILE *infile ) { int unsym_actual_nnz = 0; FloatType val; int ir, ic; const int exp_zeroes = 0; for( int i = 0; i < nNZ; i++ ) { if( mm_is_real( Typecode ) ) { if( typeid( FloatType ) == typeid( float ) ) fscanf( infile, "%d %d %f\n", &ir, &ic, &val ); else if( typeid( FloatType ) == typeid( double ) ) fscanf( infile, "%d %d %lf\n", &ir, &ic, &val ); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } else if( mm_is_integer( Typecode ) ) { if(typeid(FloatType) == typeid(float)) fscanf(infile, "%d %d %f\n", &ir, &ic, &val); else if(typeid(FloatType) == typeid(double)) fscanf(infile, "%d %d %lf\n", &ir, &ic, &val); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } else if( mm_is_pattern( Typecode ) ) { fscanf( infile, "%d %d", &ir, &ic ); val = static_cast<FloatType>( MAX_RAND_VAL * ( rand( ) / ( RAND_MAX + 1.0 ) ) ); if( exp_zeroes == 0 && val == 0 ) continue; else FillCoordData( Typecode, unsym_coords, unsym_actual_nnz, ir, ic, val ); } } nNZ = unsym_actual_nnz; }
int mm_write_mtx_crd(char fname[], int M, int N, int nz, int I[], int J[], double val[], MM_typecode matcode) { FILE *f; int i; char * tmp; if (strcmp(fname, "stdout") == 0) f = stdout; else if ((f = fopen(fname, "w")) == NULL) return MM_COULD_NOT_WRITE_FILE; /* print banner followed by typecode */ fprintf(f, "%s ", MatrixMarketBanner); tmp = mm_typecode_to_str(matcode); fprintf(f, "%s\n", tmp); if (tmp) { free(tmp); tmp = NULL; } /* print matrix sizes and nonzeros */ fprintf(f, "%d %d %d\n", M, N, nz); /* print values */ if (mm_is_pattern(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d\n", I[i], J[i]); else if (mm_is_real(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d %20.16g\n", I[i], J[i], val[i]); else if (mm_is_complex(matcode)) for (i=0; i<nz; i++) fprintf(f, "%d %d %20.16g %20.16g\n", I[i], J[i], val[2*i], val[2*i+1]); else { if (f != stdout) fclose(f); return MM_UNSUPPORTED_TYPE; } if (f !=stdout) fclose(f); return 0; }
/* mm_real supports real symmetric/general sparse/dense matrix */ static bool is_type_supported (const MM_typecode typecode) { // invalid type if (!mm_is_valid (typecode)) return false; // pattern is not supported if (mm_is_pattern (typecode)) return false; // integer and complex matrix are not supported if (mm_is_integer (typecode) || mm_is_complex (typecode)) return false; // skew and hermitian are not supported if (mm_is_skew (typecode) || mm_is_hermitian (typecode)) return false; return true; }
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 mm_read_mtx_crd_entry(FILE *f, int *I, int *J, double *real, double *imag, MM_typecode matcode) /******************************************************************************/ /* Purpose: MM_READ_MTX_CRD_ENTRY ??? Modified: 31 October 2008 Parameters: Input, FILE *F, a pointer to the input file. */ { if (mm_is_complex(matcode)) { if (fscanf(f, "%d %d %lg %lg", I, J, real, imag) != 4) return MM_PREMATURE_EOF; } else if (mm_is_real(matcode)) { if (fscanf(f, "%d %d %lg\n", I, J, real) != 3) return MM_PREMATURE_EOF; } else if (mm_is_pattern(matcode)) { if (fscanf(f, "%d %d", I, J) != 2) return MM_PREMATURE_EOF; } else return MM_UNSUPPORTED_TYPE; 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); }
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 mm_read_mtx_crd(char *fname, int *M, int *N, int *nz, int **I, int **J, double **val, MM_typecode *matcode) /******************************************************************************/ /* Purpose: MM_READ_MTX_CRD reads the values in an MM coordinate file. Discussion: This function allocates the storage for the arrays. Modified: 31 October 2008 Parameters: */ /* mm_read_mtx_crd() fills M, N, nz, array of values, and return type code, e.g. 'MCRS' if matrix is complex, values[] is of size 2*nz, (nz pairs of real/imaginary values) */ { 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; 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; } if (f != stdin) fclose(f); return 0; }
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; }
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); }
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; }
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; }
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); }
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 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; }