1 #ifndef lint 2 static char vcid[] = "$Id: matio.c,v 1.33 1996/07/31 22:56:13 balay Exp bsmith $"; 3 #endif 4 5 /* 6 This file contains simple binary read/write routines for matrices. 7 */ 8 9 #include "petsc.h" 10 #include "src/mat/matimpl.h" 11 #include "sys.h" 12 #include "pinclude/pviewer.h" 13 14 extern int MatLoad_MPIRowbs(Viewer,MatType,Mat*); 15 extern int MatLoad_SeqAIJ(Viewer,MatType,Mat*); 16 extern int MatLoad_MPIAIJ(Viewer,MatType,Mat*); 17 extern int MatLoad_SeqBDiag(Viewer,MatType,Mat*); 18 extern int MatLoad_MPIBDiag(Viewer,MatType,Mat*); 19 extern int MatLoad_SeqDense(Viewer,MatType,Mat*); 20 extern int MatLoad_MPIDense(Viewer,MatType,Mat*); 21 extern int MatLoad_SeqBAIJ(Viewer,MatType,Mat*); 22 extern int MatLoad_MPIBAIJ(Viewer,MatType,Mat*); 23 24 extern int MatLoadGetInfo_Private(Viewer); 25 static int MatLoadPrintHelp_Private(Mat A) 26 { 27 static int called = 0; 28 MPI_Comm comm = A->comm; 29 30 if (called) return 0; else called = 1; 31 PetscPrintf(comm," Options for MatLoad:\n"); 32 PetscPrintf(comm," -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n"); 33 PetscPrintf(comm," -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n"); 34 return 0; 35 } 36 37 /*@C 38 MatLoad - Loads a matrix that has been stored in binary format 39 with MatView(). The matrix format is determined from the options database. 40 Generates a parallel MPI matrix if the communicator has more than one 41 processor. The default matrix type is AIJ. 42 43 Input Parameters: 44 . viewer - binary file viewer, created with ViewerFileOpenBinary() 45 . outtype - type of matrix desired, for example MATSEQAIJ, 46 MATMPIROWBS, etc. See types in petsc/include/mat.h. 47 48 Output Parameters: 49 . newmat - new matrix 50 51 Basic Options Database Keys: 52 These options use MatCreateSeqXXX or MatCreateMPIXXX, 53 depending on the communicator, comm. 54 $ -mat_aij : AIJ type 55 $ -mat_baij : block AIJ type 56 $ -mat_dense : dense type 57 $ -mat_bdiag : block diagonal type 58 59 More Options Database Keys: 60 $ -mat_seqaij : AIJ type 61 $ -mat_mpiaij : parallel AIJ type 62 $ -mat_seqbaij : block AIJ type 63 $ -mat_mpibaij : parallel block AIJ type 64 $ -mat_seqbdiag : block diagonal type 65 $ -mat_mpibdiag : parallel block diagonal type 66 $ -mat_mpirowbs : parallel rowbs type 67 $ -mat_seqdense : dense type 68 $ -mat_mpidense : parallel dense type 69 70 More Options Database Keys: 71 Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify 72 block size 73 $ -matload_block_size <bs> 74 75 Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats 76 $ -matload_bdiag_diags <s1,s2,s3,...> 77 78 Notes: 79 In parallel, each processor can load a subset of rows (or the 80 entire matrix). This routine is especially useful when a large 81 matrix is stored on disk and only part of it is desired on each 82 processor. For example, a parallel solver may access only some of 83 the rows from each processor. The algorithm used here reads 84 relatively small blocks of data rather than reading the entire 85 matrix and then subsetting it. 86 87 Notes for advanced users: 88 Most users should not need to know the details of the binary storage 89 format, since MatLoad() and MatView() completely hide these details. 90 But for anyone who's interested, the standard binary matrix storage 91 format is 92 93 $ int MAT_COOKIE 94 $ int number of rows 95 $ int number of columns 96 $ int total number of nonzeros 97 $ int *number nonzeros in each row 98 $ int *column indices of all nonzeros (starting index is zero) 99 $ Scalar *values of all nonzeros 100 101 .keywords: matrix, load, binary, input 102 103 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad() 104 @*/ 105 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat) 106 { 107 int ierr,set,flg; 108 MatType type; 109 ViewerType vtype; 110 MPI_Comm comm; 111 112 113 *newmat = 0; 114 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 115 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 116 if (vtype != BINARY_FILE_VIEWER) 117 SETERRQ(1,"MatLoad: Invalid viewer; open viewer with ViewerFileOpenBinary()"); 118 119 PetscObjectGetComm((PetscObject)viewer,&comm); 120 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 121 if (!set) type = outtype; 122 123 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 124 125 PLogEventBegin(MAT_Load,viewer,0,0,0); 126 127 if (type == MATSEQAIJ) { 128 ierr = MatLoad_SeqAIJ(viewer,type,newmat); CHKERRQ(ierr); 129 } 130 else if (type == MATMPIAIJ) { 131 ierr = MatLoad_MPIAIJ(viewer,type,newmat); CHKERRQ(ierr); 132 } 133 else if (type == MATSEQBDIAG) { 134 ierr = MatLoad_SeqBDiag(viewer,type,newmat); CHKERRQ(ierr); 135 } 136 else if (type == MATMPIBDIAG) { 137 ierr = MatLoad_MPIBDiag(viewer,type,newmat); CHKERRQ(ierr); 138 } 139 else if (type == MATSEQDENSE) { 140 ierr = MatLoad_SeqDense(viewer,type,newmat); CHKERRQ(ierr); 141 } 142 else if (type == MATMPIDENSE) { 143 ierr = MatLoad_MPIDense(viewer,type,newmat); CHKERRQ(ierr); 144 } 145 else if (type == MATMPIROWBS) { 146 #if defined(HAVE_BLOCKSOLVE) && !defined(PETSC_COMPLEX) 147 ierr = MatLoad_MPIRowbs(viewer,type,newmat); CHKERRQ(ierr); 148 #else 149 SETERRQ(1,"MatLoad:MATMPIROWBS does not support complex numbers"); 150 #endif 151 } 152 else if (type == MATSEQBAIJ) { 153 ierr = MatLoad_SeqBAIJ(viewer,type,newmat); CHKERRQ(ierr); 154 } 155 else if (type == MATMPIBAIJ) { 156 ierr = MatLoad_MPIBAIJ(viewer,type,newmat); CHKERRQ(ierr); 157 } 158 else { 159 SETERRQ(1,"MatLoad: cannot load with that matrix type yet"); 160 } 161 162 ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 163 if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); } 164 PLogEventEnd(MAT_Load,viewer,0,0,0); 165 return 0; 166 } 167 168 /* 169 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 170 if it exists. 171 172 */ 173 int MatLoadGetInfo_Private(Viewer viewer) 174 { 175 FILE *file; 176 char string[128],*first,*second,*final; 177 int len,ierr,flg; 178 179 ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr); 180 if (flg) return 0; 181 182 ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr); 183 if (!file) return 0; 184 185 /* read rows of the file adding them to options database */ 186 while (fgets(string,128,file)) { 187 /* Comments are indicated by #, ! or % in the first column */ 188 if (string[0] == '#') continue; 189 if (string[0] == '!') continue; 190 if (string[0] == '%') continue; 191 first = PetscStrtok(string," "); 192 second = PetscStrtok(0," "); 193 if (first && first[0] == '-') { 194 if (second) {final = second;} else {final = first;} 195 len = PetscStrlen(final); 196 while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) { 197 len--; final[len] = 0; 198 } 199 ierr = OptionsSetValue(first,second); CHKERRQ(ierr); 200 } 201 } 202 return 0; 203 204 } 205