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