xref: /petsc/src/mat/utils/matio.c (revision 3f1db9ec2fd39765c6c3a00831044586630c4cca)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matio.c,v 1.54 1998/12/03 04:02:25 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"             /*I  "mat.h"  I*/
11 #include "sys.h"
12 
13 static int MatLoadersSet = 0,(*MatLoaders[MAX_MATRIX_TYPES])(Viewer,MatType,Mat*) =
14            {0,0,0,0,0,0,0,0,0,0,0,0};
15 
16 #undef __FUNC__
17 #define __FUNC__ "MatLoadRegister"
18 /*@C
19     MatLoadRegister - Allows one to register a routine that reads matrices
20         from a binary file for a particular matrix type.
21 
22   Not Collective
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    Collective on Viewer
65 
66    Input Parameters:
67 +  viewer - binary file viewer, created with ViewerBinaryOpen()
68 -  outtype - type of matrix desired, for example MATSEQAIJ,
69              MATMPIROWBS, etc.  See types in petsc/include/mat.h.
70 
71    Output Parameters:
72 .  newmat - new matrix
73 
74    Basic Options Database Keys:
75    The following options will work if you first call MatGetTypeFromOptions()
76    and pass the resulting type to MatLoad().
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 ViewerBinaryOpen(). The options in the info
109    file will be ignored if you use the -matload_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: ViewerBinaryOpen(), MatView(), VecLoad(), MatLoadRegister(),
149           MatLoadRegisterAll(), MatGetTypeFromOptions()
150 
151  @*/
152 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat)
153 {
154   int         ierr,flg;
155   PetscTruth  set;
156   MatType     type;
157   ViewerType  vtype;
158   MPI_Comm    comm;
159 
160   PetscFunctionBegin;
161   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
162     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
163   }
164   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
165   *newmat  = 0;
166 
167   if (!MatLoadersSet) {
168     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
169   }
170 
171   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
172   if (PetscStrcmp(vtype,BINARY_VIEWER)){
173     SETERRQ(PETSC_ERR_ARG_WRONG,0,"Invalid viewer; open viewer with ViewerBinaryOpen()");
174   }
175 
176   PetscObjectGetComm((PetscObject)viewer,&comm);
177   ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr);
178   if (!set) type = outtype;
179 
180   ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr);
181 
182   PLogEventBegin(MAT_Load,viewer,0,0,0);
183 
184   if (!MatLoaders[outtype]) {
185     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
186   }
187 
188   ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr);
189 
190   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
191   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); }
192   PLogEventEnd(MAT_Load,viewer,0,0,0);
193   PetscFunctionReturn(0);
194 }
195 
196 #undef __FUNC__
197 #define __FUNC__ "MatLoadGetInfo_Private"
198 
199 /*
200     MatLoadGetInfo_Private - Loads the matrix options from the name.info file
201     if it exists.
202 */
203 int MatLoadGetInfo_Private(Viewer viewer)
204 {
205   FILE *file;
206   char string[128],*first,*second,*final;
207   int  len,ierr,flg;
208 
209   PetscFunctionBegin;
210   ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr);
211   if (flg) PetscFunctionReturn(0);
212 
213   ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr);
214   if (!file) PetscFunctionReturn(0);
215 
216   /* read rows of the file adding them to options database */
217   while (fgets(string,128,file)) {
218     /* Comments are indicated by #, ! or % in the first column */
219     if (string[0] == '#') continue;
220     if (string[0] == '!') continue;
221     if (string[0] == '%') continue;
222     first  = PetscStrtok(string," ");
223     second = PetscStrtok(0," ");
224     if (first && first[0] == '-') {
225 
226       /*
227          Check for -mat_complex or -mat_double
228       */
229 #if defined(USE_PETSC_COMPLEX)
230       if (!PetscStrncmp(first,"-mat_double",11)) {
231         SETERRQ(1,1,"Loading double number matrix with complex number code");
232       }
233 #else
234       if (!PetscStrncmp(first,"-mat_complex",12)) {
235         SETERRQ(1,1,"Loading complex number matrix with double number code");
236       }
237 #endif
238 
239       if (second) {final = second;} else {final = first;}
240       len = PetscStrlen(final);
241       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
242         len--; final[len] = 0;
243       }
244       ierr = OptionsSetValue(first,second); CHKERRQ(ierr);
245     }
246   }
247   PetscFunctionReturn(0);
248 
249 }
250