xref: /petsc/src/mat/utils/matio.c (revision 6831982abb6453c2f3e25efecb5d0951d333371e)
1 #ifdef PETSC_RCS_HEADER
2 static char vcid[] = "$Id: matio.c,v 1.60 1999/10/01 21:21:43 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"             /*I  "mat.h"  I*/
11 #include "sys.h"
12 
13 static int MatLoadersSet = 0,(*MatLoaders[MAX_MATRIX_TYPES])(Viewer,MatType,Mat*) =
14            {0,0,0,0,0,0,0,0,0,0,0,0};
15 
16 #undef __FUNC__
17 #define __FUNC__ "MatLoadRegister"
18 /*@C
19     MatLoadRegister - Allows one to register a routine that reads matrices
20         from a binary file for a particular matrix type.
21 
22   Not Collective
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   Level: developer
29 
30 .seealso: MatLoadRegisterAll(), MatLoad()
31 
32 @*/
33 int MatLoadRegister(MatType type,int (*loader)(Viewer,MatType,Mat*))
34 {
35   PetscFunctionBegin;
36   MatLoaders[type] = loader;
37   MatLoadersSet    = 1;
38   PetscFunctionReturn(0);
39 }
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   int        ierr;
48 
49   PetscFunctionBegin;
50   if (called) {PetscFunctionReturn(0);} else called = 1;
51   ierr = (*PetscHelpPrintf)(comm," Options for MatLoad:\n");CHKERRQ(ierr);
52   ierr = (*PetscHelpPrintf)(comm,"  -matload_block_size <block_size> :Used for MATBAIJ, MATBDIAG\n");CHKERRQ(ierr);
53   ierr = (*PetscHelpPrintf)(comm,"  -matload_bdiag_diags <s1,s2,s3,...> : Used for MATBDIAG\n");CHKERRQ(ierr);
54   PetscFunctionReturn(0);
55 }
56 
57 #undef __FUNC__
58 #define __FUNC__ "MatLoad"
59 /*@C
60    MatLoad - Loads a matrix that has been stored in binary format
61    with MatView().  The matrix format is determined from the options database.
62    Generates a parallel MPI matrix if the communicator has more than one
63    processor.  The default matrix type is AIJ.
64 
65    Collective on Viewer
66 
67    Input Parameters:
68 +  viewer - binary file viewer, created with ViewerBinaryOpen()
69 -  outtype - type of matrix desired, for example MATSEQAIJ,
70              MATMPIROWBS, etc.  See types in petsc/include/mat.h.
71 
72    Output Parameters:
73 .  newmat - new matrix
74 
75    Basic Options Database Keys:
76    The following options will work if you first call MatGetTypeFromOptions()
77    and pass the resulting type to MatLoad().
78    These options use MatCreateSeqXXX or MatCreateMPIXXX,
79    depending on the communicator, comm.
80 +    -mat_aij      - AIJ type
81 .    -mat_baij     - block AIJ type
82 .    -mat_dense    - dense type
83 .    -mat_bdiag    - block diagonal type
84 .    -mat_complex  - indicates the matrix has complex entries
85 -    -mat_double   - indicates the matrix has double entries
86 
87    More Options Database Keys:
88 +    -mat_seqaij   - AIJ type
89 .    -mat_mpiaij   - parallel AIJ type
90 .    -mat_seqbaij  - block AIJ type
91 .    -mat_mpibaij  - parallel block AIJ type
92 .    -mat_seqbdiag - block diagonal type
93 .    -mat_mpibdiag - parallel block diagonal type
94 .    -mat_mpirowbs - parallel rowbs type
95 .    -mat_seqdense - dense type
96 -    -mat_mpidense - parallel dense type
97 
98    More Options Database Keys:
99    Used with block matrix formats (MATSEQBAIJ, MATMPIBDIAG, ...) to specify
100    block size
101 .    -matload_block_size <bs>
102 
103    Used to specify block diagonal numbers for MATSEQBDIAG and MATMPIBDIAG formats
104 .    -matload_bdiag_diags <s1,s2,s3,...>
105 
106    Level: beginner
107 
108    Notes:
109    MatLoad() automatically loads into the options database any options
110    given in the file filename.info where filename is the name of the file
111    that was passed to the ViewerBinaryOpen(). The options in the info
112    file will be ignored if you use the -matload_ignore_info option.
113 
114    In parallel, each processor can load a subset of rows (or the
115    entire matrix).  This routine is especially useful when a large
116    matrix is stored on disk and only part of it existsis desired on each
117    processor.  For example, a parallel solver may access only some of
118    the rows from each processor.  The algorithm used here reads
119    relatively small blocks of data rather than reading the entire
120    matrix and then subsetting it.
121 
122    Notes for advanced users:
123    Most users should not need to know the details of the binary storage
124    format, since MatLoad() and MatView() completely hide these details.
125    But for anyone who's interested, the standard binary matrix storage
126    format is
127 
128 $    int    MAT_COOKIE
129 $    int    number of rows
130 $    int    number of columns
131 $    int    total number of nonzeros
132 $    int    *number nonzeros in each row
133 $    int    *column indices of all nonzeros (starting index is zero)
134 $    Scalar *values of all nonzeros
135 
136    Note for Cray users, the int's stored in the binary file are 32 bit
137 integers; not 64 as they are represented in the memory, so if you
138 write your own routines to read/write these binary files from the Cray
139 you need to adjust the integer sizes that you read in, see
140 PetscReadBinary() and PetscWriteBinary() to see how this may be
141 done.
142 
143    In addition, PETSc automatically does the byte swapping for
144 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
145 linux, nt and the paragon; thus if you write your own binary
146 read/write routines you have to swap the bytes; see PetscReadBinary()
147 and PetscWriteBinary() to see how this may be done.
148 
149 .keywords: matrix, load, binary, input
150 
151 .seealso: ViewerBinaryOpen(), MatView(), VecLoad(), MatLoadRegister(),
152           MatLoadRegisterAll(), MatGetTypeFromOptions()
153 
154  @*/
155 int MatLoad(Viewer viewer,MatType outtype,Mat *newmat)
156 {
157   int         ierr,flg;
158   PetscTruth  set,isbinary;
159   MatType     type;
160   MPI_Comm    comm;
161 
162   PetscFunctionBegin;
163   if (outtype > MAX_MATRIX_TYPES || outtype < 0) {
164     SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,1,"Not a valid matrix type");
165   }
166   PetscValidHeaderSpecific(viewer,VIEWER_COOKIE);
167   *newmat  = 0;
168 
169   if (!MatLoadersSet) {
170     ierr = MatLoadRegisterAll();CHKERRQ(ierr);
171   }
172 
173   ierr = PetscTypeCompare((PetscObject)viewer,BINARY_VIEWER,&isbinary);CHKERRQ(ierr);
174   if (!isbinary) {
175     SETERRQ(PETSC_ERR_ARG_WRONG,0,"Invalid viewer; open viewer with ViewerBinaryOpen()");
176   }
177 
178   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
179   ierr = MatGetTypeFromOptions(comm,0,&type,&set);CHKERRQ(ierr);
180   if (!set) type = outtype;
181 
182   PLogEventBegin(MAT_Load,viewer,0,0,0);
183 
184   if (!MatLoaders[outtype]) {
185     SETERRQ(PETSC_ERR_ARG_WRONG,1,"Invalid matrix type, or matrix load not registered");
186   }
187 
188   ierr = (*MatLoaders[outtype])(viewer,type,newmat);CHKERRQ(ierr);
189 
190   ierr = OptionsHasName(PETSC_NULL,"-help", &flg);CHKERRQ(ierr);
191   if (flg) {ierr = MatLoadPrintHelp_Private(*newmat);CHKERRQ(ierr); }
192   PLogEventEnd(MAT_Load,viewer,0,0,0);
193   PetscFunctionReturn(0);
194 }
195 
196