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