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