1 /* ========================================================================== */
2 /* === UMFPACK_load_numeric ================================================= */
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 Numeric object from a file created by
12     umfpack_*_save_numeric.
13 */
14 
15 #include "umf_internal.h"
16 #include "umf_valid_numeric.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_numeric ((void **) &Numeric) ; \
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_numeric ((void **) &Numeric) ; \
32 	fclose (f) ; \
33 	return (UMFPACK_ERROR_file_IO) ; \
34     } \
35     if (ferror (f)) \
36     { \
37 	UMFPACK_free_numeric ((void **) &Numeric) ; \
38 	fclose (f) ; \
39 	return (UMFPACK_ERROR_file_IO) ; \
40     } \
41 }
42 
43 /* ========================================================================== */
44 /* === UMFPACK_load_numeric ================================================= */
45 /* ========================================================================== */
46 
UMFPACK_load_numeric(void ** NumericHandle,char * user_filename)47 GLOBAL Int UMFPACK_load_numeric
48 (
49     void **NumericHandle,
50     char *user_filename
51 )
52 {
53     NumericType *Numeric ;
54     char *filename ;
55     FILE *f ;
56 
57     *NumericHandle = (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 = "numeric.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 Numeric header from the file, in binary */
79     /* ---------------------------------------------------------------------- */
80 
81     Numeric = (NumericType *) UMF_malloc (1, sizeof (NumericType)) ;
82     if (Numeric == (NumericType *) NULL)
83     {
84 	fclose (f) ;
85 	return (UMFPACK_ERROR_out_of_memory) ;
86     }
87     if (fread (Numeric, sizeof (NumericType), 1, f) != 1)
88     {
89 	(void) UMF_free ((void *) Numeric) ;
90 	fclose (f) ;
91 	return (UMFPACK_ERROR_file_IO) ;
92     }
93     if (ferror (f))
94     {
95 	(void) UMF_free ((void *) Numeric) ;
96 	fclose (f) ;
97 	return (UMFPACK_ERROR_file_IO) ;
98     }
99 
100     if (Numeric->valid != NUMERIC_VALID || Numeric->n_row <= 0 ||
101 	Numeric->n_col <= 0 || Numeric->npiv < 0 || Numeric->ulen < 0 ||
102 	Numeric->size <= 0)
103     {
104 	/* Numeric does not point to a NumericType object */
105 	(void) UMF_free ((void *) Numeric) ;
106 	fclose (f) ;
107 	return (UMFPACK_ERROR_invalid_Numeric_object) ;
108     }
109 
110     Numeric->D        = (Entry *) NULL ;
111     Numeric->Rperm    = (Int *) NULL ;
112     Numeric->Cperm    = (Int *) NULL ;
113     Numeric->Lpos     = (Int *) NULL ;
114     Numeric->Lilen    = (Int *) NULL ;
115     Numeric->Lip      = (Int *) NULL ;
116     Numeric->Upos     = (Int *) NULL ;
117     Numeric->Uilen    = (Int *) NULL ;
118     Numeric->Uip      = (Int *) NULL ;
119     Numeric->Rs       = (double *) NULL ;
120     Numeric->Memory   = (Unit *) NULL ;
121     Numeric->Upattern = (Int *) NULL ;
122 
123     /* umfpack_free_numeric can now be safely called if an error occurs */
124 
125     /* ---------------------------------------------------------------------- */
126     /* read the rest of the Numeric object */
127     /* ---------------------------------------------------------------------- */
128 
129     READ (Numeric->D,     Entry, MIN (Numeric->n_row, Numeric->n_col)+1) ;
130     READ (Numeric->Rperm, Int,   Numeric->n_row+1) ;
131     READ (Numeric->Cperm, Int,   Numeric->n_col+1) ;
132     READ (Numeric->Lpos,  Int,   Numeric->npiv+1) ;
133     READ (Numeric->Lilen, Int,   Numeric->npiv+1) ;
134     READ (Numeric->Lip,   Int,   Numeric->npiv+1) ;
135     READ (Numeric->Upos,  Int,   Numeric->npiv+1) ;
136     READ (Numeric->Uilen, Int,   Numeric->npiv+1) ;
137     READ (Numeric->Uip,   Int,   Numeric->npiv+1) ;
138     if (Numeric->scale != UMFPACK_SCALE_NONE)
139     {
140 	READ (Numeric->Rs, double, Numeric->n_row) ;
141     }
142     if (Numeric->ulen > 0)
143     {
144 	READ (Numeric->Upattern, Int, Numeric->ulen+1) ;
145     }
146     READ (Numeric->Memory, Unit, Numeric->size) ;
147 
148     /* close the file */
149     fclose (f) ;
150 
151     /* make sure the Numeric object is valid */
152     if (!UMF_valid_numeric (Numeric))
153     {
154 	UMFPACK_free_numeric ((void **) &Numeric) ;
155 	return (UMFPACK_ERROR_invalid_Numeric_object) ;
156     }
157 
158     *NumericHandle = (void *) Numeric ;
159     return (UMFPACK_OK) ;
160 }
161