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