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