1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: matio.c,v 1.43 1997/07/02 22:26:14 bsmith 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 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,flg; 128 PetscTruth set; 129 MatType type; 130 ViewerType vtype; 131 MPI_Comm comm; 132 133 if (outtype > MAX_MATRIX_TYPES || outtype < 0) { 134 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type"); 135 } 136 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 137 *newmat = 0; 138 139 if (!MatLoadersSet) { 140 ierr = MatLoadRegisterAll(); CHKERRQ(ierr); 141 } 142 143 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 144 if (vtype != BINARY_FILE_VIEWER) 145 SETERRQ(1,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()"); 146 147 PetscObjectGetComm((PetscObject)viewer,&comm); 148 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 149 if (!set) type = outtype; 150 151 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 152 153 PLogEventBegin(MAT_Load,viewer,0,0,0); 154 155 if (!MatLoaders[outtype]) { 156 SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered"); 157 } 158 159 ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr); 160 161 ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 162 if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); } 163 PLogEventEnd(MAT_Load,viewer,0,0,0); 164 return 0; 165 } 166 167 #undef __FUNC__ 168 #define __FUNC__ "MatLoadGetInfo_Private" /* ADIC Ignore */ 169 170 /* 171 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 172 if it exists. 173 */ 174 int MatLoadGetInfo_Private(Viewer viewer) 175 { 176 FILE *file; 177 char string[128],*first,*second,*final; 178 int len,ierr,flg; 179 180 ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr); 181 if (flg) return 0; 182 183 ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr); 184 if (!file) return 0; 185 186 /* read rows of the file adding them to options database */ 187 while (fgets(string,128,file)) { 188 /* Comments are indicated by #, ! or % in the first column */ 189 if (string[0] == '#') continue; 190 if (string[0] == '!') continue; 191 if (string[0] == '%') continue; 192 first = PetscStrtok(string," "); 193 second = PetscStrtok(0," "); 194 if (first && first[0] == '-') { 195 if (second) {final = second;} else {final = first;} 196 len = PetscStrlen(final); 197 while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) { 198 len--; final[len] = 0; 199 } 200 ierr = OptionsSetValue(first,second); CHKERRQ(ierr); 201 } 202 } 203 return 0; 204 205 } 206