コード例 #1
0
ファイル: EpetraExt_mmio.cpp プロジェクト: 00liujj/trilinos
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;
}
コード例 #2
0
ファイル: dr_mmio.c プロジェクト: 00liujj/trilinos
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;
}
コード例 #3
0
ファイル: mmreal.c プロジェクト: lizhangzhan/cdescent
/* 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;
}
コード例 #4
0
ファイル: mmread.cpp プロジェクト: davidebarbieri/spgpu
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;
}
コード例 #5
0
ファイル: io.cpp プロジェクト: ypzhang/playground
/*---------------------------------------------*
 *             READ COO Matrix Market          *
 *---------------------------------------------*/
int read_coo_MM(coo_t *coo, options_t *opts) {
    char *matfile = opts->fmatname;
    MM_typecode matcode;
    FILE *p = fopen(matfile,"r");
    if (p == NULL) {
        printf("Unable to open file %s\n", matfile);
        exit(1);
    }
    /*----------- READ MM banner */
    if (mm_read_banner(p, &matcode) != 0) {
        printf("Could not process Matrix Market banner.\n");
        exit(1);
    }
    if (!mm_is_valid(matcode)) {
        printf("Invalid Matrix Market file.\n");
        exit(1);
    }
    if (!(mm_is_real(matcode) && mm_is_coordinate(matcode)
            && mm_is_sparse(matcode))) {
        printf("Only sparse real-valued coordinate \
    matrices are supported\n");
        exit(1);
    }
コード例 #6
0
ファイル: magma_dmio.cpp プロジェクト: maxhutch/magma
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;
}
コード例 #7
0
ファイル: sparse_matrix_io.hpp プロジェクト: beckgom/smallk
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)
コード例 #8
0
ファイル: mm_io.cpp プロジェクト: Nikraaaazy/strads
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;
}
コード例 #9
0
ファイル: petscw.c プロジェクト: primme/primme
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);
}