xref: /petsc/src/mat/utils/matio.c (revision 832676f5f6fedcb357d670e365cdce9c00f7b7de)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matio.c,v 1.43 1997/07/02 22:26:14 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" /* 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,flg;
128   PetscTruth  set;
129   MatType     type;
130   ViewerType  vtype;
131   MPI_Comm    comm;
132 
133   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
134     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
135   }
136   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
137   *newmat  = 0;
138 
139   if (!MatLoadersSet) {
140     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
141   }
142 
143   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
144   if (vtype != BINARY_FILE_VIEWER)
145   SETERRQ(1,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()");
146 
147   PetscObjectGetComm((PetscObject)viewer,&comm);
148   ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr);
149   if (!set) type = outtype;
150 
151   ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr);
152 
153   PLogEventBegin(MAT_Load,viewer,0,0,0);
154 
155   if (!MatLoaders[outtype]) {
156     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
157   }
158 
159   ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr);
160 
161   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
162   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); }
163   PLogEventEnd(MAT_Load,viewer,0,0,0);
164   return 0;
165 }
166 
167 #undef __FUNC__
168 #define __FUNC__ "MatLoadGetInfo_Private" /* ADIC Ignore */
169 
170 /*
171     MatLoadGetInfo_Private - Loads the matrix options from the name.info file
172     if it exists.
173  */
174 int MatLoadGetInfo_Private(Viewer viewer)
175 {
176   FILE *file;
177   char string[128],*first,*second,*final;
178   int  len,ierr,flg;
179 
180   ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr);
181   if (flg) return 0;
182 
183   ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr);
184   if (!file) return 0;
185 
186   /* read rows of the file adding them to options database */
187   while (fgets(string,128,file)) {
188     /* Comments are indicated by #, ! or % in the first column */
189     if (string[0] == '#') continue;
190     if (string[0] == '!') continue;
191     if (string[0] == '%') continue;
192     first = PetscStrtok(string," ");
193     second = PetscStrtok(0," ");
194     if (first && first[0] == '-') {
195       if (second) {final = second;} else {final = first;}
196       len = PetscStrlen(final);
197       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
198         len--; final[len] = 0;
199       }
200       ierr = OptionsSetValue(first,second); CHKERRQ(ierr);
201     }
202   }
203   return 0;
204 
205 }
206