1 /* ========================================================================== */
2 /* === UMFPACK_load_symbolic ================================================ */
3 /* ========================================================================== */
4
5 /* -------------------------------------------------------------------------- */
6 /* Copyright (c) 2005-2012 by Timothy A. Davis, http://www.suitesparse.com. */
7 /* All Rights Reserved. See ../Doc/License.txt for License. */
8 /* -------------------------------------------------------------------------- */
9
10 /*
11 User-callable. Loads a Symbolic object from a file created by
12 umfpack_*_save_symbolic.
13 */
14
15 #include "umf_internal.h"
16 #include "umf_valid_symbolic.h"
17 #include "umf_malloc.h"
18 #include "umf_free.h"
19
20 #define READ(object,type,n) \
21 { \
22 object = (type *) UMF_malloc (n, sizeof (type)) ; \
23 if (object == (type *) NULL) \
24 { \
25 UMFPACK_free_symbolic ((void **) &Symbolic) ; \
26 fclose (f) ; \
27 return (UMFPACK_ERROR_out_of_memory) ; \
28 } \
29 if (fread (object, sizeof (type), n, f) != (size_t) n) \
30 { \
31 UMFPACK_free_symbolic ((void **) &Symbolic) ; \
32 fclose (f) ; \
33 return (UMFPACK_ERROR_file_IO) ; \
34 } \
35 if (ferror (f)) \
36 { \
37 UMFPACK_free_symbolic ((void **) &Symbolic) ; \
38 fclose (f) ; \
39 return (UMFPACK_ERROR_file_IO) ; \
40 } \
41 }
42
43 /* ========================================================================== */
44 /* === UMFPACK_load_symbolic ================================================ */
45 /* ========================================================================== */
46
UMFPACK_load_symbolic(void ** SymbolicHandle,char * user_filename)47 GLOBAL Int UMFPACK_load_symbolic
48 (
49 void **SymbolicHandle,
50 char *user_filename
51 )
52 {
53 SymbolicType *Symbolic ;
54 char *filename ;
55 FILE *f ;
56
57 *SymbolicHandle = (void *) NULL ;
58
59 /* ---------------------------------------------------------------------- */
60 /* get the filename, or use the default name if filename is NULL */
61 /* ---------------------------------------------------------------------- */
62
63 if (user_filename == (char *) NULL)
64 {
65 filename = "symbolic.umf" ;
66 }
67 else
68 {
69 filename = user_filename ;
70 }
71 f = fopen (filename, "rb") ;
72 if (!f)
73 {
74 return (UMFPACK_ERROR_file_IO) ;
75 }
76
77 /* ---------------------------------------------------------------------- */
78 /* read the Symbolic header from the file, in binary */
79 /* ---------------------------------------------------------------------- */
80
81 Symbolic = (SymbolicType *) UMF_malloc (1, sizeof (SymbolicType)) ;
82 if (Symbolic == (SymbolicType *) NULL)
83 {
84 fclose (f) ;
85 return (UMFPACK_ERROR_out_of_memory) ;
86 }
87 if (fread (Symbolic, sizeof (SymbolicType), 1, f) != 1)
88 {
89 (void) UMF_free ((void *) Symbolic) ;
90 fclose (f) ;
91 return (UMFPACK_ERROR_file_IO) ;
92 }
93 if (ferror (f))
94 {
95 (void) UMF_free ((void *) Symbolic) ;
96 fclose (f) ;
97 return (UMFPACK_ERROR_file_IO) ;
98 }
99
100 if (Symbolic->valid != SYMBOLIC_VALID || Symbolic->n_row <= 0 ||
101 Symbolic->n_col <= 0 || Symbolic->nfr < 0 || Symbolic->nchains < 0 ||
102 Symbolic->esize < 0)
103 {
104 /* Symbolic does not point to a Symbolic object */
105 (void) UMF_free ((void *) Symbolic) ;
106 fclose (f) ;
107 return (UMFPACK_ERROR_invalid_Symbolic_object) ;
108 }
109
110 Symbolic->Cperm_init = (Int *) NULL ;
111 Symbolic->Rperm_init = (Int *) NULL ;
112 Symbolic->Front_npivcol = (Int *) NULL ;
113 Symbolic->Front_parent = (Int *) NULL ;
114 Symbolic->Front_1strow = (Int *) NULL ;
115 Symbolic->Front_leftmostdesc = (Int *) NULL ;
116 Symbolic->Chain_start = (Int *) NULL ;
117 Symbolic->Chain_maxrows = (Int *) NULL ;
118 Symbolic->Chain_maxcols = (Int *) NULL ;
119 Symbolic->Cdeg = (Int *) NULL ;
120 Symbolic->Rdeg = (Int *) NULL ;
121 Symbolic->Esize = (Int *) NULL ;
122 Symbolic->Diagonal_map = (Int *) NULL ;
123
124 /* umfpack_free_symbolic can now be safely called if an error occurs */
125
126 /* ---------------------------------------------------------------------- */
127 /* read the rest of the Symbolic object */
128 /* ---------------------------------------------------------------------- */
129
130 READ (Symbolic->Cperm_init, Int, Symbolic->n_col+1) ;
131 READ (Symbolic->Rperm_init, Int, Symbolic->n_row+1) ;
132 READ (Symbolic->Front_npivcol, Int, Symbolic->nfr+1) ;
133 READ (Symbolic->Front_parent, Int, Symbolic->nfr+1) ;
134 READ (Symbolic->Front_1strow, Int, Symbolic->nfr+1) ;
135 READ (Symbolic->Front_leftmostdesc, Int, Symbolic->nfr+1) ;
136 READ (Symbolic->Chain_start, Int, Symbolic->nchains+1) ;
137 READ (Symbolic->Chain_maxrows, Int, Symbolic->nchains+1) ;
138 READ (Symbolic->Chain_maxcols, Int, Symbolic->nchains+1) ;
139 READ (Symbolic->Cdeg, Int, Symbolic->n_col+1) ;
140 READ (Symbolic->Rdeg, Int, Symbolic->n_row+1) ;
141 if (Symbolic->esize > 0)
142 {
143 /* only when dense rows are present */
144 READ (Symbolic->Esize, Int, Symbolic->esize) ;
145 }
146 if (Symbolic->prefer_diagonal)
147 {
148 /* only when diagonal pivoting is prefered */
149 READ (Symbolic->Diagonal_map, Int, Symbolic->n_col+1) ;
150 }
151
152 /* close the file */
153 fclose (f) ;
154
155 /* make sure the Symbolic object is valid */
156 if (!UMF_valid_symbolic (Symbolic))
157 {
158 UMFPACK_free_symbolic ((void **) &Symbolic) ;
159 return (UMFPACK_ERROR_invalid_Symbolic_object) ;
160 }
161
162 *SymbolicHandle = (void *) Symbolic ;
163 return (UMFPACK_OK) ;
164 }
165