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