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