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