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