xref: /petsc/src/mat/utils/matio.c (revision 76be9ce4a233aaa47cda2bc7f5a27cd7faabecaa)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matio.c,v 1.48 1997/12/01 01:55:30 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"
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"
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   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    Input Parameters:
65 .  viewer - binary file viewer, created with ViewerFileOpenBinary()
66 .  outtype - type of matrix desired, for example MATSEQAIJ,
67    MATMPIROWBS, etc.  See types in petsc/include/mat.h.
68 
69    Output Parameters:
70 .  newmat - new matrix
71 
72    Basic Options Database Keys:
73    These options use MatCreateSeqXXX or MatCreateMPIXXX,
74    depending on the communicator, comm.
75 $    -mat_aij      : AIJ type
76 $    -mat_baij     : block AIJ type
77 $    -mat_dense    : dense type
78 $    -mat_bdiag    : block diagonal type
79 
80    More Options Database Keys:
81 $    -mat_seqaij   : AIJ type
82 $    -mat_mpiaij   : parallel AIJ type
83 $    -mat_seqbaij  : block AIJ type
84 $    -mat_mpibaij  : parallel block AIJ type
85 $    -mat_seqbdiag : block diagonal type
86 $    -mat_mpibdiag : parallel block diagonal type
87 $    -mat_mpirowbs : parallel rowbs type
88 $    -mat_seqdense : dense type
89 $    -mat_mpidense : parallel dense type
90 
91    More Options Database Keys:
92    Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify
93    block size
94 $    -matload_block_size <bs>
95 
96    Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats
97 $    -matload_bdiag_diags <s1,s2,s3,...>
98 
99    Notes:
100    In parallel, each processor can load a subset of rows (or the
101    entire matrix).  This routine is especially useful when a large
102    matrix is stored on disk and only part of it is desired on each
103    processor.  For example, a parallel solver may access only some of
104    the rows from each processor.  The algorithm used here reads
105    relatively small blocks of data rather than reading the entire
106    matrix and then subsetting it.
107 
108    Notes for advanced users:
109    Most users should not need to know the details of the binary storage
110    format, since MatLoad() and MatView() completely hide these details.
111    But for anyone who's interested, the standard binary matrix storage
112    format is
113 
114 $    int    MAT_COOKIE
115 $    int    number of rows
116 $    int    number of columns
117 $    int    total number of nonzeros
118 $    int    *number nonzeros in each row
119 $    int    *column indices of all nonzeros (starting index is zero)
120 $    Scalar *values of all nonzeros
121 
122    Note for Cray users, the int's stored in the binary file are 32 bit
123 integers; not 64 as they are represented in the memory, so if you
124 write your own routines to read/write these binary files from the Cray
125 you need to adjust the integer sizes that you read in, see
126 PetscReadBinary() and PetscWriteBinary() to see how this may be
127 done.
128 
129    In addition, PETSc automatically does the byte swapping for
130 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
131 linux, nt and the paragon; thus if you write your own binary
132 read/write routines you have to swap the bytes; see PetscReadBinary()
133 and PetscWriteBinary() to see how this may be done.
134 
135 .keywords: matrix, load, binary, input
136 
137 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad(), MatLoadRegister(),
138           MatLoadRegisterAll()
139  @*/
140 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat)
141 {
142   int         ierr,flg;
143   PetscTruth  set;
144   MatType     type;
145   ViewerType  vtype;
146   MPI_Comm    comm;
147 
148   PetscFunctionBegin;
149   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
150     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
151   }
152   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
153   *newmat  = 0;
154 
155   if (!MatLoadersSet) {
156     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
157   }
158 
159   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
160   if (vtype != BINARY_FILE_VIEWER)
161   SETERRQ(PETSC_ERR_ARG_WRONG,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()");
162 
163   PetscObjectGetComm((PetscObject)viewer,&comm);
164   ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr);
165   if (!set) type = outtype;
166 
167   ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr);
168 
169   PLogEventBegin(MAT_Load,viewer,0,0,0);
170 
171   if (!MatLoaders[outtype]) {
172     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
173   }
174 
175   ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr);
176 
177   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
178   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); }
179   PLogEventEnd(MAT_Load,viewer,0,0,0);
180   PetscFunctionReturn(0);
181 }
182 
183 #undef __FUNC__
184 #define __FUNC__ "MatLoadGetInfo_Private"
185 
186 /*
187     MatLoadGetInfo_Private - Loads the matrix options from the name.info file
188     if it exists.
189  */
190 int MatLoadGetInfo_Private(Viewer viewer)
191 {
192   FILE *file;
193   char string[128],*first,*second,*final;
194   int  len,ierr,flg;
195 
196   PetscFunctionBegin;
197   ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr);
198   if (flg) PetscFunctionReturn(0);
199 
200   ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr);
201   if (!file) PetscFunctionReturn(0);
202 
203   /* read rows of the file adding them to options database */
204   while (fgets(string,128,file)) {
205     /* Comments are indicated by #, ! or % in the first column */
206     if (string[0] == '#') continue;
207     if (string[0] == '!') continue;
208     if (string[0] == '%') continue;
209     first = PetscStrtok(string," ");
210     second = PetscStrtok(0," ");
211     if (first && first[0] == '-') {
212       if (second) {final = second;} else {final = first;}
213       len = PetscStrlen(final);
214       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
215         len--; final[len] = 0;
216       }
217       ierr = OptionsSetValue(first,second); CHKERRQ(ierr);
218     }
219   }
220   PetscFunctionReturn(0);
221 
222 }
223