xref: /petsc/src/mat/utils/matio.c (revision 40eeca1449abe8fbf626bf991a580a70930a6a67)
1 #define PETSCMAT_DLL
2 
3 /*
4    This file contains simple binary read/write routines for matrices.
5  */
6 
7 #include "private/matimpl.h"             /*I  "petscmat.h"  I*/
8 #include "petscsys.h"
9 
10 #undef __FUNCT__
11 #define __FUNCT__ "MatLoad"
12 /*@C
13    MatLoad - Loads a matrix that has been stored in binary format
14    with MatView().  The matrix format is determined from the options database.
15    Generates a parallel MPI matrix if the communicator has more than one
16    processor.  The default matrix type is AIJ.
17 
18    Collective on PetscViewer
19 
20    Input Parameters:
21 +  viewer - binary file viewer, created with PetscViewerBinaryOpen()
22 -  outtype - type of matrix desired, for example MATSEQAIJ,
23               MATMPISBAIJ etc.  See types in petsc/include/petscmat.h.
24 
25    Output Parameters:
26 .  newmat - new matrix
27 
28    Basic Options Database Keys:
29 +    -matload_type seqaij   - AIJ type
30 .    -matload_type mpiaij   - parallel AIJ type
31 .    -matload_type seqbaij  - block AIJ type
32 .    -matload_type mpibaij  - parallel block AIJ type
33 .    -matload_type seqsbaij - block symmetric AIJ type
34 .    -matload_type mpisbaij - parallel block symmetric AIJ type
35 .    -matload_type seqdense - dense type
36 .    -matload_type mpidense - parallel dense type
37 -    -matload_symmetric - matrix in file is symmetric
38 
39    More Options Database Keys:
40    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
41    block size
42 .    -matload_block_size <bs>
43 
44    Level: beginner
45 
46    Notes:
47    MatLoad() automatically loads into the options database any options
48    given in the file filename.info where filename is the name of the file
49    that was passed to the PetscViewerBinaryOpen(). The options in the info
50    file will be ignored if you use the -viewer_binary_skip_info option.
51 
52    In parallel, each processor can load a subset of rows (or the
53    entire matrix).  This routine is especially useful when a large
54    matrix is stored on disk and only part of it existsis desired on each
55    processor.  For example, a parallel solver may access only some of
56    the rows from each processor.  The algorithm used here reads
57    relatively small blocks of data rather than reading the entire
58    matrix and then subsetting it.
59 
60    Notes for advanced users:
61    Most users should not need to know the details of the binary storage
62    format, since MatLoad() and MatView() completely hide these details.
63    But for anyone who's interested, the standard binary matrix storage
64    format is
65 
66 $    int    MAT_FILE_COOKIE
67 $    int    number of rows
68 $    int    number of columns
69 $    int    total number of nonzeros
70 $    int    *number nonzeros in each row
71 $    int    *column indices of all nonzeros (starting index is zero)
72 $    PetscScalar *values of all nonzeros
73 
74    PETSc automatically does the byte swapping for
75 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
76 linux, Windows and the paragon; thus if you write your own binary
77 read/write routines you have to swap the bytes; see PetscBinaryRead()
78 and PetscBinaryWrite() to see how this may be done.
79 
80 .keywords: matrix, load, binary, input
81 
82 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
83 
84  @*/
85 PetscErrorCode PETSCMAT_DLLEXPORT MatLoad(PetscViewer viewer, const MatType outtype,Mat *newmat)
86 {
87   Mat            factory;
88   PetscErrorCode ierr;
89   PetscTruth     isbinary,flg;
90   MPI_Comm       comm;
91   PetscErrorCode (*r)(PetscViewer, const MatType,Mat*);
92   char           mtype[256];
93   const char     *prefix;
94 
95   PetscFunctionBegin;
96   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,1);
97   PetscValidPointer(newmat,3);
98   *newmat = 0;
99 
100   ierr = PetscObjectGetOptionsPrefix((PetscObject)viewer,(const char **)&prefix);CHKERRQ(ierr);
101   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
102   if (!isbinary) {
103     SETERRQ(PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
104   }
105 
106   ierr = PetscOptionsGetString(prefix,"-mat_type",mtype,256,&flg);CHKERRQ(ierr);
107   if (flg) {
108     outtype = mtype;
109   }
110   ierr = PetscOptionsGetString(prefix,"-matload_type",mtype,256,&flg);CHKERRQ(ierr);
111   if (flg) {
112     outtype = mtype;
113   }
114   if (!outtype) outtype = MATAIJ;
115 
116   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
117   ierr = MatCreate(comm,&factory);CHKERRQ(ierr);
118   ierr = MatSetSizes(factory,0,0,0,0);CHKERRQ(ierr);
119   ierr = MatSetType(factory,outtype);CHKERRQ(ierr);
120   r = factory->ops->load;
121   ierr = MatDestroy(factory);
122   if (!r) SETERRQ1(PETSC_ERR_SUP,"MatLoad is not supported for type: %s",outtype);
123 
124   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
125   ierr = (*r)(viewer,outtype,newmat);CHKERRQ(ierr);
126   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
127 
128   flg  = PETSC_FALSE;
129   ierr = PetscOptionsGetTruth(prefix,"-matload_symmetric",&flg,PETSC_NULL);CHKERRQ(ierr);
130   if (flg) {
131     ierr = MatSetOption(*newmat,MAT_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr);
132     ierr = MatSetOption(*newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);CHKERRQ(ierr);
133   }
134   PetscFunctionReturn(0);
135 }
136 
137