1 /* ========================================================================== */
2 /* === UMFPACK_load_numeric ================================================= */
3 /* ========================================================================== */
4 
5 /* -------------------------------------------------------------------------- */
6 /* UMFPACK Copyright (c) Timothy A. Davis, CISE,                              */
7 /* Univ. of Florida.  All Rights Reserved.  See ../Doc/License for License.   */
8 /* web: http://www.cise.ufl.edu/research/sparse/umfpack                       */
9 /* -------------------------------------------------------------------------- */
10 
11 /*
12     User-callable.  Loads a Numeric object from a file created by
13     umfpack_*_save_numeric.
14 */
15 
16 #include "umf_internal.h"
17 #include "umf_valid_numeric.h"
18 #include "umf_malloc.h"
19 #include "umf_free.h"
20 
21 #define READ(object,type,n) \
22 { \
23     object = (type *) UMF_malloc (n, sizeof (type)) ; \
24     if (object == (type *) NULL) \
25     { \
26 	UMFPACK_free_numeric ((void **) &Numeric) ; \
27 	fclose (f) ; \
28 	return (UMFPACK_ERROR_out_of_memory) ; \
29     } \
30     if (fread (object, sizeof (type), n, f) != (size_t) n) \
31     { \
32 	UMFPACK_free_numeric ((void **) &Numeric) ; \
33 	fclose (f) ; \
34 	return (UMFPACK_ERROR_file_IO) ; \
35     } \
36     if (ferror (f)) \
37     { \
38 	UMFPACK_free_numeric ((void **) &Numeric) ; \
39 	fclose (f) ; \
40 	return (UMFPACK_ERROR_file_IO) ; \
41     } \
42 }
43 
44 /* ========================================================================== */
45 /* === UMFPACK_load_numeric ================================================= */
46 /* ========================================================================== */
47 
UMFPACK_load_numeric(void ** NumericHandle,char * user_filename)48 GLOBAL Int UMFPACK_load_numeric
49 (
50     void **NumericHandle,
51     char *user_filename
52 )
53 {
54     NumericType *Numeric ;
55     char *filename ;
56     FILE *f ;
57 
58     *NumericHandle = (void *) NULL ;
59 
60     /* ---------------------------------------------------------------------- */
61     /* get the filename, or use the default name if filename is NULL */
62     /* ---------------------------------------------------------------------- */
63 
64     if (user_filename == (char *) NULL)
65     {
66 	filename = "numeric.umf" ;
67     }
68     else
69     {
70 	filename = user_filename ;
71     }
72     f = fopen (filename, "rb") ;
73     if (!f)
74     {
75 	return (UMFPACK_ERROR_file_IO) ;
76     }
77 
78     /* ---------------------------------------------------------------------- */
79     /* read the Numeric header from the file, in binary */
80     /* ---------------------------------------------------------------------- */
81 
82     Numeric = (NumericType *) UMF_malloc (1, sizeof (NumericType)) ;
83     if (Numeric == (NumericType *) NULL)
84     {
85 	fclose (f) ;
86 	return (UMFPACK_ERROR_out_of_memory) ;
87     }
88     if (fread (Numeric, sizeof (NumericType), 1, f) != 1)
89     {
90 	(void) UMF_free ((void *) Numeric) ;
91 	fclose (f) ;
92 	return (UMFPACK_ERROR_file_IO) ;
93     }
94     if (ferror (f))
95     {
96 	(void) UMF_free ((void *) Numeric) ;
97 	fclose (f) ;
98 	return (UMFPACK_ERROR_file_IO) ;
99     }
100 
101     if (Numeric->valid != NUMERIC_VALID || Numeric->n_row <= 0 ||
102 	Numeric->n_col <= 0 || Numeric->npiv < 0 || Numeric->ulen < 0 ||
103 	Numeric->size <= 0)
104     {
105 	/* Numeric does not point to a NumericType object */
106 	(void) UMF_free ((void *) Numeric) ;
107 	fclose (f) ;
108 	return (UMFPACK_ERROR_invalid_Numeric_object) ;
109     }
110 
111     Numeric->D        = (Entry *) NULL ;
112     Numeric->Rperm    = (Int *) NULL ;
113     Numeric->Cperm    = (Int *) NULL ;
114     Numeric->Lpos     = (Int *) NULL ;
115     Numeric->Lilen    = (Int *) NULL ;
116     Numeric->Lip      = (Int *) NULL ;
117     Numeric->Upos     = (Int *) NULL ;
118     Numeric->Uilen    = (Int *) NULL ;
119     Numeric->Uip      = (Int *) NULL ;
120     Numeric->Rs       = (double *) NULL ;
121     Numeric->Memory   = (Unit *) NULL ;
122     Numeric->Upattern = (Int *) NULL ;
123 
124     /* umfpack_free_numeric can now be safely called if an error occurs */
125 
126     /* ---------------------------------------------------------------------- */
127     /* read the rest of the Numeric object */
128     /* ---------------------------------------------------------------------- */
129 
130     READ (Numeric->D,     Entry, MIN (Numeric->n_row, Numeric->n_col)+1) ;
131     READ (Numeric->Rperm, Int,   Numeric->n_row+1) ;
132     READ (Numeric->Cperm, Int,   Numeric->n_col+1) ;
133     READ (Numeric->Lpos,  Int,   Numeric->npiv+1) ;
134     READ (Numeric->Lilen, Int,   Numeric->npiv+1) ;
135     READ (Numeric->Lip,   Int,   Numeric->npiv+1) ;
136     READ (Numeric->Upos,  Int,   Numeric->npiv+1) ;
137     READ (Numeric->Uilen, Int,   Numeric->npiv+1) ;
138     READ (Numeric->Uip,   Int,   Numeric->npiv+1) ;
139     if (Numeric->scale != UMFPACK_SCALE_NONE)
140     {
141 	READ (Numeric->Rs, double, Numeric->n_row) ;
142     }
143     if (Numeric->ulen > 0)
144     {
145 	READ (Numeric->Upattern, Int, Numeric->ulen+1) ;
146     }
147     READ (Numeric->Memory, Unit, Numeric->size) ;
148 
149     /* close the file */
150     fclose (f) ;
151 
152     /* make sure the Numeric object is valid */
153     if (!UMF_valid_numeric (Numeric))
154     {
155 	UMFPACK_free_numeric ((void **) &Numeric) ;
156 	return (UMFPACK_ERROR_invalid_Numeric_object) ;
157     }
158 
159     *NumericHandle = (void *) Numeric ;
160     return (UMFPACK_OK) ;
161 }
162