1 #ifdef PETSC_RCS_HEADER 2 static char vcid[] = "$Id: matio.c,v 1.54 1998/12/03 04:02:25 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" /*I "mat.h" I*/ 11 #include "sys.h" 12 13 static int MatLoadersSet = 0,(*MatLoaders[MAX_MATRIX_TYPES])(Viewer,MatType,Mat*) = 14 {0,0,0,0,0,0,0,0,0,0,0,0}; 15 16 #undef __FUNC__ 17 #define __FUNC__ "MatLoadRegister" 18 /*@C 19 MatLoadRegister - Allows one to register a routine that reads matrices 20 from a binary file for a particular matrix type. 21 22 Not Collective 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 PetscFunctionBegin; 34 MatLoaders[type] = loader; 35 MatLoadersSet = 1; 36 PetscFunctionReturn(0); 37 } 38 39 extern int MatLoadGetInfo_Private(Viewer); 40 41 #undef __FUNC__ 42 #define __FUNC__ "MatLoadPrintHelp_Private" 43 static int MatLoadPrintHelp_Private(Mat A) 44 { 45 static int called = 0; 46 MPI_Comm comm = A->comm; 47 48 PetscFunctionBegin; 49 if (called) {PetscFunctionReturn(0);} else called = 1; 50 (*PetscHelpPrintf)(comm," Options for MatLoad:\n"); 51 (*PetscHelpPrintf)(comm," -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n"); 52 (*PetscHelpPrintf)(comm," -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n"); 53 PetscFunctionReturn(0); 54 } 55 56 #undef __FUNC__ 57 #define __FUNC__ "MatLoad" 58 /*@C 59 MatLoad - Loads a matrix that has been stored in binary format 60 with MatView(). The matrix format is determined from the options database. 61 Generates a parallel MPI matrix if the communicator has more than one 62 processor. The default matrix type is AIJ. 63 64 Collective on Viewer 65 66 Input Parameters: 67 + viewer - binary file viewer, created with ViewerBinaryOpen() 68 - outtype - type of matrix desired, for example MATSEQAIJ, 69 MATMPIROWBS, etc. See types in petsc/include/mat.h. 70 71 Output Parameters: 72 . newmat - new matrix 73 74 Basic Options Database Keys: 75 The following options will work if you first call MatGetTypeFromOptions() 76 and pass the resulting type to MatLoad(). 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 ViewerBinaryOpen(). The options in the info 109 file will be ignored if you use the -matload_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: ViewerBinaryOpen(), MatView(), VecLoad(), MatLoadRegister(), 149 MatLoadRegisterAll(), MatGetTypeFromOptions() 150 151 @*/ 152 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat) 153 { 154 int ierr,flg; 155 PetscTruth set; 156 MatType type; 157 ViewerType vtype; 158 MPI_Comm comm; 159 160 PetscFunctionBegin; 161 if (outtype > MAX_MATRIX_TYPES || outtype < 0) { 162 SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type"); 163 } 164 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 165 *newmat = 0; 166 167 if (!MatLoadersSet) { 168 ierr = MatLoadRegisterAll(); CHKERRQ(ierr); 169 } 170 171 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 172 if (PetscStrcmp(vtype,BINARY_VIEWER)){ 173 SETERRQ(PETSC_ERR_ARG_WRONG,0,"Invalid viewer; open viewer with ViewerBinaryOpen()"); 174 } 175 176 PetscObjectGetComm((PetscObject)viewer,&comm); 177 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 178 if (!set) type = outtype; 179 180 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 181 182 PLogEventBegin(MAT_Load,viewer,0,0,0); 183 184 if (!MatLoaders[outtype]) { 185 SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered"); 186 } 187 188 ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr); 189 190 ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr); 191 if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); } 192 PLogEventEnd(MAT_Load,viewer,0,0,0); 193 PetscFunctionReturn(0); 194 } 195 196 #undef __FUNC__ 197 #define __FUNC__ "MatLoadGetInfo_Private" 198 199 /* 200 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 201 if it exists. 202 */ 203 int MatLoadGetInfo_Private(Viewer viewer) 204 { 205 FILE *file; 206 char string[128],*first,*second,*final; 207 int len,ierr,flg; 208 209 PetscFunctionBegin; 210 ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr); 211 if (flg) PetscFunctionReturn(0); 212 213 ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr); 214 if (!file) PetscFunctionReturn(0); 215 216 /* read rows of the file adding them to options database */ 217 while (fgets(string,128,file)) { 218 /* Comments are indicated by #, ! or % in the first column */ 219 if (string[0] == '#') continue; 220 if (string[0] == '!') continue; 221 if (string[0] == '%') continue; 222 first = PetscStrtok(string," "); 223 second = PetscStrtok(0," "); 224 if (first && first[0] == '-') { 225 226 /* 227 Check for -mat_complex or -mat_double 228 */ 229 #if defined(USE_PETSC_COMPLEX) 230 if (!PetscStrncmp(first,"-mat_double",11)) { 231 SETERRQ(1,1,"Loading double number matrix with complex number code"); 232 } 233 #else 234 if (!PetscStrncmp(first,"-mat_complex",12)) { 235 SETERRQ(1,1,"Loading complex number matrix with double number code"); 236 } 237 #endif 238 239 if (second) {final = second;} else {final = first;} 240 len = PetscStrlen(final); 241 while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) { 242 len--; final[len] = 0; 243 } 244 ierr = OptionsSetValue(first,second); CHKERRQ(ierr); 245 } 246 } 247 PetscFunctionReturn(0); 248 249 } 250