xref: /petsc/src/mat/utils/matio.c (revision 93c39befdc2c545b92559b48e3c3f7c5a930faa6)
1 #ifndef lint
2 static char vcid[] = "$Id: matio.c,v 1.41 1997/06/10 04:05:53 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 "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" /* ADIC Ignore */
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   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   MatLoaders[type] = loader;
34   MatLoadersSet    = 1;
35   return 0;
36 }
37 
38 extern int MatLoadGetInfo_Private(Viewer);
39 
40 #undef __FUNC__
41 #define __FUNC__ "MatLoadPrintHelp_Private" /* ADIC Ignore */
42 static int MatLoadPrintHelp_Private(Mat A)
43 {
44   static int called = 0;
45   MPI_Comm   comm = A->comm;
46 
47   if (called) return 0; else called = 1;
48   PetscPrintf(comm," Options for MatLoad:\n");
49   PetscPrintf(comm,"  -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n");
50   PetscPrintf(comm,"  -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n");
51   return 0;
52 }
53 
54 #undef __FUNC__
55 #define __FUNC__ "MatLoad"
56 /*@C
57    MatLoad - Loads a matrix that has been stored in binary format
58    with MatView().  The matrix format is determined from the options database.
59    Generates a parallel MPI matrix if the communicator has more than one
60    processor.  The default matrix type is AIJ.
61 
62    Input Parameters:
63 .  viewer - binary file viewer, created with ViewerFileOpenBinary()
64 .  outtype - type of matrix desired, for example MATSEQAIJ,
65    MATMPIROWBS, etc.  See types in petsc/include/mat.h.
66 
67    Output Parameters:
68 .  newmat - new matrix
69 
70    Basic Options Database Keys:
71    These options use MatCreateSeqXXX or MatCreateMPIXXX,
72    depending on the communicator, comm.
73 $    -mat_aij      : AIJ type
74 $    -mat_baij     : block AIJ type
75 $    -mat_dense    : dense type
76 $    -mat_bdiag    : block diagonal type
77 
78    More Options Database Keys:
79 $    -mat_seqaij   : AIJ type
80 $    -mat_mpiaij   : parallel AIJ type
81 $    -mat_seqbaij  : block AIJ type
82 $    -mat_mpibaij  : parallel block AIJ type
83 $    -mat_seqbdiag : block diagonal type
84 $    -mat_mpibdiag : parallel block diagonal type
85 $    -mat_mpirowbs : parallel rowbs type
86 $    -mat_seqdense : dense type
87 $    -mat_mpidense : parallel dense type
88 
89    More Options Database Keys:
90    Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify
91    block size
92 $    -matload_block_size <bs>
93 
94    Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats
95 $    -matload_bdiag_diags <s1,s2,s3,...>
96 
97    Notes:
98    In parallel, each processor can load a subset of rows (or the
99    entire matrix).  This routine is especially useful when a large
100    matrix is stored on disk and only part of it is desired on each
101    processor.  For example, a parallel solver may access only some of
102    the rows from each processor.  The algorithm used here reads
103    relatively small blocks of data rather than reading the entire
104    matrix and then subsetting it.
105 
106    Notes for advanced users:
107    Most users should not need to know the details of the binary storage
108    format, since MatLoad() and MatView() completely hide these details.
109    But for anyone who's interested, the standard binary matrix storage
110    format is
111 
112 $    int    MAT_COOKIE
113 $    int    number of rows
114 $    int    number of columns
115 $    int    total number of nonzeros
116 $    int    *number nonzeros in each row
117 $    int    *column indices of all nonzeros (starting index is zero)
118 $    Scalar *values of all nonzeros
119 
120 .keywords: matrix, load, binary, input
121 
122 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad(), MatLoadRegister(),
123           MatLoadRegisterAll()
124  @*/
125 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat)
126 {
127   int         ierr,set,flg;
128   MatType     type;
129   ViewerType  vtype;
130   MPI_Comm    comm;
131 
132   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
133     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
134   }
135   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
136   *newmat  = 0;
137 
138   if (!MatLoadersSet) {
139     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
140   }
141 
142   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
143   if (vtype != BINARY_FILE_VIEWER)
144   SETERRQ(1,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()");
145 
146   PetscObjectGetComm((PetscObject)viewer,&comm);
147   ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr);
148   if (!set) type = outtype;
149 
150   ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr);
151 
152   PLogEventBegin(MAT_Load,viewer,0,0,0);
153 
154   if (!MatLoaders[outtype]) {
155     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
156   }
157 
158   ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr);
159 
160   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
161   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); }
162   PLogEventEnd(MAT_Load,viewer,0,0,0);
163   return 0;
164 }
165 
166 #undef __FUNC__
167 #define __FUNC__ "MatLoadGetInfo_Private" /* ADIC Ignore */
168 
169 /*
170     MatLoadGetInfo_Private - Loads the matrix options from the name.info file
171     if it exists.
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