1 #ifndef lint 2 static char vcid[] = "$Id: matio.c,v 1.30 1996/07/02 18:07:09 bsmith Exp curfman $"; 3 #endif 4 5 /* 6 This file contains simple binary read/write routines for matrices. 7 */ 8 9 #include "petsc.h" 10 #include "../matimpl.h" 11 #include "sys.h" 12 #include "pinclude/pviewer.h" 13 14 extern int MatLoad_MPIRowbs(Viewer,MatType,Mat*); 15 extern int MatLoad_SeqAIJ(Viewer,MatType,Mat*); 16 extern int MatLoad_MPIAIJ(Viewer,MatType,Mat*); 17 extern int MatLoad_SeqBDiag(Viewer,MatType,Mat*); 18 extern int MatLoad_MPIBDiag(Viewer,MatType,Mat*); 19 extern int MatLoad_SeqDense(Viewer,MatType,Mat*); 20 extern int MatLoad_MPIDense(Viewer,MatType,Mat*); 21 extern int MatLoad_SeqBAIJ(Viewer,MatType,Mat*); 22 extern int MatLoad_MPIBAIJ(Viewer,MatType,Mat*); 23 24 extern int MatLoadGetInfo_Private(Viewer); 25 26 /*@C 27 MatLoad - Loads a matrix that has been stored in binary format 28 with MatView(). The matrix format is determined from the options database. 29 Generates a parallel MPI matrix if the communicator has more than one 30 processor. The default matrix type is AIJ. 31 32 Input Parameters: 33 . viewer - binary file viewer, created with ViewerFileOpenBinary() 34 . outtype - type of matrix desired, for example MATSEQAIJ, 35 MATMPIROWBS, etc. See types in petsc/include/mat.h. 36 37 Output Parameters: 38 . newmat - new matrix 39 40 Basic Options Database Keys: 41 These options use MatCreateSeqXXX or MatCreateMPIXXX, 42 depending on the communicator, comm. 43 $ -mat_aij : AIJ type 44 $ -mat_baij : block AIJ type 45 $ -mat_dense : dense type 46 $ -mat_bdiag : block diagonal type 47 48 More Options Database Keys: 49 $ -mat_seqaij : AIJ type 50 $ -mat_mpiaij : parallel AIJ type 51 $ -mat_seqbaij : block AIJ type 52 $ -mat_mpibaij : parallel block AIJ type 53 $ -mat_seqbdiag : block diagonal type 54 $ -mat_mpibdiag : parallel block diagonal type 55 $ -mat_mpirowbs : parallel rowbs type 56 $ -mat_seqdense : dense type 57 $ -mat_mpidense : parallel dense type 58 59 More Options Database Keys: 60 Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify 61 block size 62 $ -matload_block_size <bs> 63 64 Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats 65 $ -matload_bdiag_diags <s1,s2,s3,...> 66 67 Notes: 68 In parallel, each processor can load a subset of rows (or the 69 entire matrix). This routine is especially useful when a large 70 matrix is stored on disk and only part of it is desired on each 71 processor. For example, a parallel solver may access only some of 72 the rows from each processor. The algorithm used here reads 73 relatively small blocks of data rather than reading the entire 74 matrix and then subsetting it. 75 76 Notes for advanced users: 77 Most users should not need to know the details of the binary storage 78 format, since MatLoad() and MatView() completely hide these details. 79 But for anyone who's interested, the standard binary matrix storage 80 format is 81 82 $ int MAT_COOKIE 83 $ int number of rows 84 $ int number of columns 85 $ int total number of nonzeros 86 $ int *number nonzeros in each row 87 $ int *column indices of all nonzeros (starting index is zero) 88 $ Scalar *values of all nonzeros 89 90 .keywords: matrix, load, binary, input 91 92 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad() 93 @*/ 94 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat) 95 { 96 int ierr,set; 97 MatType type; 98 ViewerType vtype; 99 MPI_Comm comm; 100 *newmat = 0; 101 102 PetscValidHeaderSpecific(viewer,VIEWER_COOKIE); 103 ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr); 104 if (vtype != BINARY_FILE_VIEWER) 105 SETERRQ(1,"MatLoad: Invalid viewer; open viewer with ViewerFileOpenBinary()"); 106 107 PetscObjectGetComm((PetscObject)viewer,&comm); 108 ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr); 109 if (!set) type = outtype; 110 111 ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr); 112 113 PLogEventBegin(MAT_Load,viewer,0,0,0); 114 115 if (type == MATSEQAIJ) { 116 ierr = MatLoad_SeqAIJ(viewer,type,newmat); CHKERRQ(ierr); 117 } 118 else if (type == MATMPIAIJ) { 119 ierr = MatLoad_MPIAIJ(viewer,type,newmat); CHKERRQ(ierr); 120 } 121 else if (type == MATSEQBDIAG) { 122 ierr = MatLoad_SeqBDiag(viewer,type,newmat); CHKERRQ(ierr); 123 } 124 else if (type == MATMPIBDIAG) { 125 ierr = MatLoad_MPIBDiag(viewer,type,newmat); CHKERRQ(ierr); 126 } 127 else if (type == MATSEQDENSE) { 128 ierr = MatLoad_SeqDense(viewer,type,newmat); CHKERRQ(ierr); 129 } 130 else if (type == MATMPIDENSE) { 131 ierr = MatLoad_MPIDense(viewer,type,newmat); CHKERRQ(ierr); 132 } 133 else if (type == MATMPIROWBS) { 134 #if defined(HAVE_BLOCKSOLVE) && !defined(__cplusplus) 135 ierr = MatLoad_MPIRowbs(viewer,type,newmat); CHKERRQ(ierr); 136 #else 137 SETERRQ(1,"MatLoad:MATMPIROWBS does not support complex numbers or c++"); 138 #endif 139 } 140 else if (type == MATSEQBAIJ) { 141 ierr = MatLoad_SeqBAIJ(viewer,type,newmat); CHKERRQ(ierr); 142 } 143 else if (type == MATMPIBAIJ) { 144 ierr = MatLoad_MPIBAIJ(viewer,type,newmat); CHKERRQ(ierr); 145 } 146 else { 147 SETERRQ(1,"MatLoad: cannot load with that matrix type yet"); 148 } 149 150 PLogEventEnd(MAT_Load,viewer,0,0,0); 151 return 0; 152 } 153 154 /* 155 MatLoadGetInfo_Private - Loads the matrix options from the name.info file 156 if it exists. 157 158 */ 159 int MatLoadGetInfo_Private(Viewer viewer) 160 { 161 FILE *file; 162 char string[128],*first,*second,*final; 163 int len,ierr,flg; 164 165 ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr); 166 if (flg) return 0; 167 168 ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr); 169 if (!file) return 0; 170 171 /* read rows of the file adding them to options database */ 172 while (fgets(string,128,file)) { 173 /* Comments are indicated by #, ! or % in the first column */ 174 if (string[0] == '#') continue; 175 if (string[0] == '!') continue; 176 if (string[0] == '%') continue; 177 first = PetscStrtok(string," "); 178 second = PetscStrtok(0," "); 179 if (first && first[0] == '-') { 180 if (second) {final = second;} else {final = first;} 181 len = PetscStrlen(final); 182 while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) { 183 len--; final[len] = 0; 184 } 185 ierr = OptionsSetValue(first,second); CHKERRQ(ierr); 186 } 187 } 188 return 0; 189 190 } 191