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); }
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); }