1 #ifndef lint 2 static char vcid[] = "$Id: matio.c,v 1.41 1997/06/10 04:05:53 bsmith Exp curfman $"; 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 15 static int MatLoadersSet = 0,(*MatLoaders[MAX_MATRIX_TYPES])(Viewer,MatType,Mat*) = 16 {0,0,0,0,0,0,0,0,0,0,0,0}; 17 18 #undef __FUNC__ 19 #define __FUNC__ "MatLoadRegister" /* ADIC Ignore */ 20 /*@C 21 MatLoadRegister - Allows one to register a routine that reads matrices 22 from a binary file for a particular matrix type. 23 24 Input Parameters: 25 . type - the type of matrix (defined in include/mat.h), for example, MATSEQAIJ. 26 . loader - the function that reads the matrix from the binary file. 27 28 .seealso: MatLoadRegisterAll() 29 30 @*/ 31 int MatLoadRegister(MatType type,int (*loader)(Viewer,MatType,Mat*)) 32 { 33 MatLoaders[type] = loader; 34 MatLoadersSet = 1; 35 return 0; 36 } 37 38 extern int MatLoadGetInfo_Private(Viewer); 39 40 #undef __FUNC__ 41 #define __FUNC__ "MatLoadPrintHelp_Private" /* ADIC Ignore */ 42 static int MatLoadPrintHelp_Private(Mat A) 43 { 44 static int called = 0; 45 MPI_Comm comm = A->comm; 46 47 if (called) return 0; else called = 1; 48 PetscPrintf(comm," Options for MatLoad:\n"); 49 PetscPrintf(comm," -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n"); 50 PetscPrintf(comm," -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n"); 51 return 0; 52 } 53 54 #undef __FUNC__ 55 #define __FUNC__ "MatLoad" 56 /*@C 57 MatLoad - Loads a matrix that has been stored in binary format 58 with MatView(). The matrix format is determined from the options database. 59 Generates a parallel MPI matrix if the communicator has more than one 60 processor. The default matrix type is AIJ. 61 62 Input Parameters: 63 . viewer - binary file viewer, created with ViewerFileOpenBinary() 64 . outtype - type of matrix desired, for example MATSEQAIJ, 65 MATMPIROWBS, etc. See types in petsc/include/mat.h. 66 67 Output Parameters: 68 . newmat - new matrix 69 70 Basic Options Database Keys: 71 These options use MatCreateSeqXXX or MatCreateMPIXXX, 72 depending on the communicator, comm. 73 $ -mat_aij : AIJ type 74 $ -mat_baij : block AIJ type 75 $ -mat_dense : dense type 76 $ -mat_bdiag : block diagonal type 77 78 More Options Database Keys: 79 $ -mat_seqaij : AIJ type 80 $ -mat_mpiaij : parallel AIJ type 81 $ -mat_seqbaij : block AIJ type 82 $ -mat_mpibaij : parallel block AIJ type 83 $ -mat_seqbdiag : block diagonal type 84 $ -mat_mpibdiag : parallel block diagonal type 85 $ -mat_mpirowbs : parallel rowbs type 86 $ -mat_seqdense : dense type 87 $ -mat_mpidense : parallel dense type 88 89 More Options Database Keys: 90 Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify 91 block size 92 $ -matload_block_size <bs> 93 94 Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats 95 $ -matload_bdiag_diags <s1,s2,s3,...> 96 97 Notes: 98 In parallel, each processor can load a subset of rows (or the 99 entire matrix). This routine is especially useful when a large 100 matrix is stored on disk and only part of it is desired on each 101 processor. For example, a parallel solver may access only some of 102 the rows from each processor. The algorithm used here reads 103 relatively small blocks of data rather than reading the entire 104 matrix and then subsetting it. 105 106 Notes for advanced users: 107 Most users should not need to know the details of the binary storage 108 format, since MatLoad() and MatView() completely hide these details. 109 But for anyone who's interested, the standard binary matrix storage 110 format is 111 112 $ int MAT_COOKIE 113 $ int number of rows 114 $ int number of columns 115 $ int total number of nonzeros 116 $ int *number nonzeros in each row 117 $ int *column indices of all nonzeros (starting index is zero) 118 $ Scalar *values of all nonzeros 119 120 .keywords: matrix, load, binary, input 121 122 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad(), MatLoadRegister(), 123 MatLoadRegisterAll() 124 @*/ 125 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat) 126 { 127 int ierr,set,flg; 128 MatType type; 129 ViewerType vtype; 130 MPI_Comm comm; 131 132 if (outtype > MAX_MATRIX_TYPES || outtype < 0) { 133 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type"); 134 } 135 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 136 *newmat = 0; 137 138 if (!MatLoadersSet) { 139 ierr = MatLoadRegisterAll(); CHKERRQ(ierr); 140 } 141 142 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 143 if (vtype != BINARY_FILE_VIEWER) 144 SETERRQ(1,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()"); 145 146 PetscObjectGetComm((PetscObject)viewer,&comm); 147 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 148 if (!set) type = outtype; 149 150 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 151 152 PLogEventBegin(MAT_Load,viewer,0,0,0); 153 154 if (!MatLoaders[outtype]) { 155 SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered"); 156 } 157 158 ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr); 159 160 ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 161 if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); } 162 PLogEventEnd(MAT_Load,viewer,0,0,0); 163 return 0; 164 } 165 166 #undef __FUNC__ 167 #define __FUNC__ "MatLoadGetInfo_Private" /* ADIC Ignore */ 168 169 /* 170 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 171 if it exists. 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