xref: /petsc/src/mat/utils/matio.c (revision 7c4f633dc6bb6149cca88d301ead35a99e103cbb)
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              MATMPIROWBS, 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 mpirowbs - parallel rowbs type
36 .    -matload_type seqdense - dense type
37 .    -matload_type mpidense - parallel dense type
38 -    -matload_symmetric - matrix in file is symmetric
39 
40    More Options Database Keys:
41    Used with block matrix formats (MATSEQBAIJ,  ...) to specify
42    block size
43 .    -matload_block_size <bs>
44 
45    Level: beginner
46 
47    Notes:
48    MatLoad() automatically loads into the options database any options
49    given in the file filename.info where filename is the name of the file
50    that was passed to the PetscViewerBinaryOpen(). The options in the info
51    file will be ignored if you use the -viewer_binary_skip_info option.
52 
53    In parallel, each processor can load a subset of rows (or the
54    entire matrix).  This routine is especially useful when a large
55    matrix is stored on disk and only part of it existsis desired on each
56    processor.  For example, a parallel solver may access only some of
57    the rows from each processor.  The algorithm used here reads
58    relatively small blocks of data rather than reading the entire
59    matrix and then subsetting it.
60 
61    Notes for advanced users:
62    Most users should not need to know the details of the binary storage
63    format, since MatLoad() and MatView() completely hide these details.
64    But for anyone who's interested, the standard binary matrix storage
65    format is
66 
67 $    int    MAT_FILE_COOKIE
68 $    int    number of rows
69 $    int    number of columns
70 $    int    total number of nonzeros
71 $    int    *number nonzeros in each row
72 $    int    *column indices of all nonzeros (starting index is zero)
73 $    PetscScalar *values of all nonzeros
74 
75    PETSc automatically does the byte swapping for
76 machines that store the bytes reversed, e.g.  DEC alpha, freebsd,
77 linux, Windows and the paragon; thus if you write your own binary
78 read/write routines you have to swap the bytes; see PetscBinaryRead()
79 and PetscBinaryWrite() to see how this may be done.
80 
81 .keywords: matrix, load, binary, input
82 
83 .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
84 
85  @*/
86 PetscErrorCode PETSCMAT_DLLEXPORT MatLoad(PetscViewer viewer, const MatType outtype,Mat *newmat)
87 {
88   Mat            factory;
89   PetscErrorCode ierr;
90   PetscTruth     isbinary,flg;
91   MPI_Comm       comm;
92   PetscErrorCode (*r)(PetscViewer, const MatType,Mat*);
93   char           mtype[256];
94   const char     *prefix;
95 
96   PetscFunctionBegin;
97   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,1);
98   PetscValidPointer(newmat,3);
99   *newmat = 0;
100 
101   ierr = PetscObjectGetOptionsPrefix((PetscObject)viewer,(const char **)&prefix);CHKERRQ(ierr);
102   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);CHKERRQ(ierr);
103   if (!isbinary) {
104     SETERRQ(PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
105   }
106 
107   ierr = PetscOptionsGetString(prefix,"-mat_type",mtype,256,&flg);CHKERRQ(ierr);
108   if (flg) {
109     outtype = mtype;
110   }
111   ierr = PetscOptionsGetString(prefix,"-matload_type",mtype,256,&flg);CHKERRQ(ierr);
112   if (flg) {
113     outtype = mtype;
114   }
115   if (!outtype) outtype = MATAIJ;
116 
117   ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr);
118   ierr = MatCreate(comm,&factory);CHKERRQ(ierr);
119   ierr = MatSetSizes(factory,0,0,0,0);CHKERRQ(ierr);
120   ierr = MatSetType(factory,outtype);CHKERRQ(ierr);
121   r = factory->ops->load;
122   ierr = MatDestroy(factory);
123   if (!r) SETERRQ1(PETSC_ERR_SUP,"MatLoad is not supported for type: %s",outtype);
124 
125   ierr = PetscLogEventBegin(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
126   ierr = (*r)(viewer,outtype,newmat);CHKERRQ(ierr);
127   ierr = PetscLogEventEnd(MAT_Load,viewer,0,0,0);CHKERRQ(ierr);
128 
129   ierr = PetscOptionsHasName(prefix,"-matload_symmetric",&flg);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