xref: /petsc/src/mat/utils/matio.c (revision 83e2fdc756c13f964f3ed5aaff42e3626c5b72bc)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matio.c,v 1.44 1997/07/10 03:44:59 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    Note for Cray users, the int's stored in the binary file are 32 bit
121 integers; not 64 as they are represented in the memory, so if you
122 write your own routines to read/write these binary files from the Cray
123 you need to adjust the integer sizes that you read in, see
124 PetscReadBinary() and PetscWriteBinary() to see how this may be
125 done.
126 
127    In addition, PETSc automatically does the byte swapping for
128 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
129 linux, nt and the paragon; thus if you write your own binary
130 read/write routines you have to swap the bytes; see PetscReadBinary()
131 and PetscWriteBinary() to see how this may be done.
132 
133 .keywords: matrix, load, binary, input
134 
135 .seealso: ViewerFileOpenBinary(), MatView(), VecLoad(), MatLoadRegister(),
136           MatLoadRegisterAll()
137  @*/
138 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat)
139 {
140   int         ierr,flg;
141   PetscTruth  set;
142   MatType     type;
143   ViewerType  vtype;
144   MPI_Comm    comm;
145 
146   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
147     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
148   }
149   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
150   *newmat  = 0;
151 
152   if (!MatLoadersSet) {
153     ierr = MatLoadRegisterAll(); CHKERRQ(ierr);
154   }
155 
156   ierr = ViewerGetType(viewer,&vtype); CHKERRQ(ierr);
157   if (vtype != BINARY_FILE_VIEWER)
158   SETERRQ(1,0,"Invalid viewer; open viewer with ViewerFileOpenBinary()");
159 
160   PetscObjectGetComm((PetscObject)viewer,&comm);
161   ierr = MatGetTypeFromOptions(comm,0,&type,&set); CHKERRQ(ierr);
162   if (!set) type = outtype;
163 
164   ierr = MatLoadGetInfo_Private(viewer); CHKERRQ(ierr);
165 
166   PLogEventBegin(MAT_Load,viewer,0,0,0);
167 
168   if (!MatLoaders[outtype]) {
169     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
170   }
171 
172   ierr = (*MatLoaders[outtype])(viewer,type,newmat); CHKERRQ(ierr);
173 
174   ierr = OptionsHasName(PETSC_NULL,"-help", &flg); CHKERRQ(ierr);
175   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat); CHKERRQ(ierr); }
176   PLogEventEnd(MAT_Load,viewer,0,0,0);
177   return 0;
178 }
179 
180 #undef __FUNC__
181 #define __FUNC__ "MatLoadGetInfo_Private" /* ADIC Ignore */
182 
183 /*
184     MatLoadGetInfo_Private - Loads the matrix options from the name.info file
185     if it exists.
186  */
187 int MatLoadGetInfo_Private(Viewer viewer)
188 {
189   FILE *file;
190   char string[128],*first,*second,*final;
191   int  len,ierr,flg;
192 
193   ierr = OptionsHasName(PETSC_NULL,"-matload_ignore_info",&flg);CHKERRQ(ierr);
194   if (flg) return 0;
195 
196   ierr = ViewerBinaryGetInfoPointer(viewer,&file); CHKERRQ(ierr);
197   if (!file) return 0;
198 
199   /* read rows of the file adding them to options database */
200   while (fgets(string,128,file)) {
201     /* Comments are indicated by #, ! or % in the first column */
202     if (string[0] == '#') continue;
203     if (string[0] == '!') continue;
204     if (string[0] == '%') continue;
205     first = PetscStrtok(string," ");
206     second = PetscStrtok(0," ");
207     if (first && first[0] == '-') {
208       if (second) {final = second;} else {final = first;}
209       len = PetscStrlen(final);
210       while (len > 0 && (final[len-1] == ' ' || final[len-1] == '\n')) {
211         len--; final[len] = 0;
212       }
213       ierr = OptionsSetValue(first,second); CHKERRQ(ierr);
214     }
215   }
216   return 0;
217 
218 }
219