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