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