1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: matio.c,v 1.51 1998/04/24 02:16: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" 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 Not Collective 25 26 Input Parameters: 27 + type - the type of matrix (defined in include/mat.h), for example, MATSEQAIJ. 28 - loader - the function that reads the matrix from the binary file. 29 30 .seealso: MatLoadRegisterAll() 31 32 @*/ 33 int MatLoadRegister(MatType type,int (*loader)(Viewer,MatType,Mat*)) 34 { 35 PetscFunctionBegin; 36 MatLoaders[type] = loader; 37 MatLoadersSet = 1; 38 PetscFunctionReturn(0); 39 } 40 41 extern int MatLoadGetInfo_Private(Viewer); 42 43 #undef __FUNC__ 44 #define __FUNC__ "MatLoadPrintHelp_Private" 45 static int MatLoadPrintHelp_Private(Mat A) 46 { 47 static int called = 0; 48 MPI_Comm comm = A->comm; 49 50 PetscFunctionBegin; 51 if (called) {PetscFunctionReturn(0);} else called = 1; 52 (*PetscHelpPrintf)(comm," Options for MatLoad:\n"); 53 (*PetscHelpPrintf)(comm," -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n"); 54 (*PetscHelpPrintf)(comm," -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n"); 55 PetscFunctionReturn(0); 56 } 57 58 #undef __FUNC__ 59 #define __FUNC__ "MatLoad" 60 /*@C 61 MatLoad - Loads a matrix that has been stored in binary format 62 with MatView(). The matrix format is determined from the options database. 63 Generates a parallel MPI matrix if the communicator has more than one 64 processor. The default matrix type is AIJ. 65 66 Collective on Viewer 67 68 Input Parameters: 69 + viewer - binary file viewer, created with ViewerFileOpenBinary() 70 - outtype - type of matrix desired, for example MATSEQAIJ, 71 MATMPIROWBS, etc. See types in petsc/include/mat.h. 72 73 Output Parameters: 74 . newmat - new matrix 75 76 Basic Options Database Keys: 77 These options use MatCreateSeqXXX or MatCreateMPIXXX, 78 depending on the communicator, comm. 79 + -mat_aij - AIJ type 80 . -mat_baij - block AIJ type 81 . -mat_dense - dense type 82 . -mat_bdiag - block diagonal type 83 . -mat_complex - indicates the matrix has complex entries 84 - -mat_double - indicates the matrix has double entries 85 86 More Options Database Keys: 87 + -mat_seqaij - AIJ type 88 . -mat_mpiaij - parallel AIJ type 89 . -mat_seqbaij - block AIJ type 90 . -mat_mpibaij - parallel block AIJ type 91 . -mat_seqbdiag - block diagonal type 92 . -mat_mpibdiag - parallel block diagonal type 93 . -mat_mpirowbs - parallel rowbs type 94 . -mat_seqdense - dense type 95 - -mat_mpidense - parallel dense type 96 97 More Options Database Keys: 98 Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify 99 block size 100 . -matload_block_size <bs> 101 102 Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats 103 . -matload_bdiag_diags <s1,s2,s3,...> 104 105 Notes: 106 MatLoad() automatically loads into the options database any options 107 given in the file filename.info where filename is the name of the file 108 that was passed to the ViewerFileOpenBinary(). The options in the info 109 file will be ignored if you use the -mat_ignore_info option. 110 111 In parallel, each processor can load a subset of rows (or the 112 entire matrix). This routine is especially useful when a large 113 matrix is stored on disk and only part of it is desired on each 114 processor. For example, a parallel solver may access only some of 115 the rows from each processor. The algorithm used here reads 116 relatively small blocks of data rather than reading the entire 117 matrix and then subsetting it. 118 119 Notes for advanced users: 120 Most users should not need to know the details of the binary storage 121 format, since MatLoad() and MatView() completely hide these details. 122 But for anyone who's interested, the standard binary matrix storage 123 format is 124 125 $ int MAT_COOKIE 126 $ int number of rows 127 $ int number of columns 128 $ int total number of nonzeros 129 $ int *number nonzeros in each row 130 $ int *column indices of all nonzeros (starting index is zero) 131 $ Scalar *values of all nonzeros 132 133 Note for Cray users, the int's stored in the binary file are 32 bit 134 integers; not 64 as they are represented in the memory, so if you 135 write your own routines to read/write these binary files from the Cray 136 you need to adjust the integer sizes that you read in, see 137 PetscReadBinary() and PetscWriteBinary() to see how this may be 138 done. 139 140 In addition, PETSc automatically does the byte swapping for 141 machines that store the bytes reversed, e.g. DEC alpha, freebsd, 142 linux, nt and the paragon; thus if you write your own binary 143 read/write routines you have to swap the bytes; see PetscReadBinary() 144 and PetscWriteBinary() to see how this may be done. 145 146 .keywords: matrix, load, binary, input 147 148 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad(), MatLoadRegister(), 149 MatLoadRegisterAll() 150 @*/ 151 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat) 152 { 153 int ierr,flg; 154 PetscTruth set; 155 MatType type; 156 ViewerType vtype; 157 MPI_Comm comm; 158 159 PetscFunctionBegin; 160 if (outtype > MAX_MATRIX_TYPES || outtype < 0) { 161 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type"); 162 } 163 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 164 *newmat = 0; 165 166 if (!MatLoadersSet) { 167 ierr = MatLoadRegisterAll(); CHKERRQ(ierr); 168 } 169 170 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 171 if (vtype != BINARY_FILE_VIEWER) 172 SETERRQ(PETSC_ERR_ARG_WRONG,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()"); 173 174 PetscObjectGetComm((PetscObject)viewer,&comm); 175 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 176 if (!set) type = outtype; 177 178 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 179 180 PLogEventBegin(MAT_Load,viewer,0,0,0); 181 182 if (!MatLoaders[outtype]) { 183 SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered"); 184 } 185 186 ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr); 187 188 ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 189 if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); } 190 PLogEventEnd(MAT_Load,viewer,0,0,0); 191 PetscFunctionReturn(0); 192 } 193 194 #undef __FUNC__ 195 #define __FUNC__ "MatLoadGetInfo_Private" 196 197 /* 198 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 199 if it exists. 200 */ 201 int MatLoadGetInfo_Private(Viewer viewer) 202 { 203 FILE *file; 204 char string[128],*first,*second,*final; 205 int len,ierr,flg; 206 207 PetscFunctionBegin; 208 ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr); 209 if (flg) PetscFunctionReturn(0); 210 211 ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr); 212 if (!file) PetscFunctionReturn(0); 213 214 /* read rows of the file adding them to options database */ 215 while (fgets(string,128,file)) { 216 /* Comments are indicated by #, ! or % in the first column */ 217 if (string[0] == '#') continue; 218 if (string[0] == '!') continue; 219 if (string[0] == '%') continue; 220 first = PetscStrtok(string," "); 221 second = PetscStrtok(0," "); 222 if (first && first[0] == '-') { 223 224 /* 225 Check for -mat_complex or -mat_double 226 */ 227 #if defined(USE_PETSC_COMPLEX) 228 if (!PetscStrncmp(first,"-mat_double",11)) { 229 SETERRQ(1,1,"Loading double number matrix with complex number code"); 230 } 231 #else 232 if (!PetscStrncmp(first,"-mat_complex",12)) { 233 SETERRQ(1,1,"Loading complex number matrix with double number code"); 234 } 235 #endif 236 237 if (second) {final = second;} else {final = first;} 238 len = PetscStrlen(final); 239 while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) { 240 len--; final[len] = 0; 241 } 242 ierr = OptionsSetValue(first,second); CHKERRQ(ierr); 243 } 244 } 245 PetscFunctionReturn(0); 246 247 } 248