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