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