1 /* ========================================================================== */
2 /* === Tcov/memory ========================================================== */
3 /* ========================================================================== */
4 
5 /* -----------------------------------------------------------------------------
6  * CHOLMOD/Tcov Module.  Copyright (C) 2005-2006, Timothy A. Davis
7  * http://www.suitesparse.com
8  * -------------------------------------------------------------------------- */
9 
10 /* Extensive memory-failure testing for CHOLMOD.
11  *
12  * my_malloc2, my_calloc2, and my_realloc2 pretend to fail if my_tries goes to
13  * zero, to test CHOLMOD's memory error handling.   No failure occurs if
14  * my_tries is negative.
15  */
16 
17 #include "cm.h"
18 
19 
20 /* ========================================================================== */
21 /* === my_tries ============================================================= */
22 /* ========================================================================== */
23 
24 Int my_tries = -1 ; /* a global variable */
25 
26 
27 /* ========================================================================== */
28 /* === my_malloc2 =========================================================== */
29 /* ========================================================================== */
30 
my_malloc2(size_t size)31 void *my_malloc2 (size_t size)
32 {
33     void *p ;
34     if (my_tries == 0)
35     {
36 	/* pretend to fail */
37 	/* printf ("p 0 (pretend to fail)\n") ; */
38 	return (NULL) ;
39     }
40     if (my_tries > 0)
41     {
42 	my_tries-- ;
43     }
44     p = malloc (size) ;
45     /* printf ("p %p\n", p) ; */
46     return (p) ;
47 }
48 
49 
50 /* ========================================================================== */
51 /* === my_calloc2 =========================================================== */
52 /* ========================================================================== */
53 
my_calloc2(size_t n,size_t size)54 void *my_calloc2 (size_t n, size_t size)
55 {
56     void *p ;
57     if (my_tries == 0)
58     {
59 	/* pretend to fail */
60 	/* printf ("p 0 (pretend to fail)\n") ; */
61 	return (NULL) ;
62     }
63     if (my_tries > 0)
64     {
65 	my_tries-- ;
66     }
67     p = calloc (n, size) ;
68     /* printf ("p %p\n", p) ; */
69     return (p) ;
70 }
71 
72 
73 /* ========================================================================== */
74 /* === my_realloc2 ========================================================== */
75 /* ========================================================================== */
76 
my_realloc2(void * p,size_t size)77 void *my_realloc2 (void *p, size_t size)
78 {
79     void *p2 ;
80     if (my_tries == 0)
81     {
82 	/* pretend to fail */
83 	/* printf ("p2 0 (pretend to fail)\n") ; */
84 	return (NULL) ;
85     }
86     if (my_tries > 0)
87     {
88 	my_tries-- ;
89     }
90     p2 = realloc (p, size) ;
91     /* printf ("p2 %p\n", p2) ; */
92     return (p2) ;
93 }
94 
95 
96 /* ========================================================================== */
97 /* === my_free2 ============================================================= */
98 /* ========================================================================== */
99 
my_free2(void * p)100 void my_free2 (void *p)
101 {
102     free (p) ;
103 }
104 
105 
106 /* ========================================================================== */
107 /* === normal_memory_handler ================================================ */
108 /* ========================================================================== */
109 
normal_memory_handler(void)110 void normal_memory_handler ( void )
111 {
112 
113     SuiteSparse_config.malloc_func = malloc ;
114     SuiteSparse_config.calloc_func = calloc ;
115     SuiteSparse_config.realloc_func = realloc ;
116     SuiteSparse_config.free_func = free ;
117 
118     cm->error_handler = my_handler ;
119     CHOLMOD(free_work) (cm) ;
120 }
121 
122 
123 /* ========================================================================== */
124 /* === test_memory_handler ================================================== */
125 /* ========================================================================== */
126 
test_memory_handler(void)127 void test_memory_handler ( void )
128 {
129     SuiteSparse_config.malloc_func = my_malloc2 ;
130     SuiteSparse_config.calloc_func = my_calloc2 ;
131     SuiteSparse_config.realloc_func = my_realloc2 ;
132     SuiteSparse_config.free_func = my_free2 ;
133 
134     cm->error_handler = NULL ;
135     CHOLMOD(free_work) (cm) ;
136     my_tries = 0 ;
137 }
138 
139 
140 /* ========================================================================== */
141 /* === memory tests ========================================================= */
142 /* ========================================================================== */
143 
memory_tests(cholmod_triplet * T)144 void memory_tests (cholmod_triplet *T)
145 {
146     double err ;
147     cholmod_sparse *A ;
148     Int trial ;
149     size_t count, inuse ;
150 
151     test_memory_handler ( ) ;
152     inuse = cm->memory_inuse ;
153 
154     cm->nmethods = 8 ;
155     cm->print = 0 ;
156     cm->final_resymbol = TRUE ;
157 
158     cm->final_asis = FALSE ;
159     cm->final_super = FALSE ;
160     cm->final_ll = FALSE ;
161     cm->final_pack = FALSE ;
162     cm->final_monotonic = FALSE ;
163 
164     /* ---------------------------------------------------------------------- */
165     /* test raw factorizations */
166     /* ---------------------------------------------------------------------- */
167 
168     printf ("==================================== fac memory test\n") ;
169     count = cm->malloc_count ;
170     my_tries = -1 ;
171     for (trial = 0 ; my_tries <= 0 ; trial++)
172     {
173 	cm->print = 0 ;
174 	fflush (stdout) ;
175 	my_tries = trial ;
176 	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
177 	my_srand (trial+1) ;					/* RAND reset */
178 	err = raw_factor (A, FALSE) ;				/* RAND */
179 	CHOLMOD(free_sparse) (&A, cm) ;
180 	OK (CHOLMOD(print_common) ("cm", cm)) ;
181 	CHOLMOD(free_work) (cm) ;
182 	OK (count == cm->malloc_count) ;
183 	OK (inuse == cm->memory_inuse) ;
184     }
185     CHOLMOD(free_work) (cm) ;
186     printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ;
187     printf ("initial count: "ID" final count "ID"\n",
188 	    (Int) count, (Int) cm->malloc_count) ;
189     printf ("initial inuse: "ID" final inuse "ID"\n",
190 	    (Int) inuse, (Int) cm->memory_inuse) ;
191     OK (count == cm->malloc_count) ;
192     OK (inuse == cm->memory_inuse) ;
193 
194     /* ---------------------------------------------------------------------- */
195     /* test raw factorizations (rowfac_mask) */
196     /* ---------------------------------------------------------------------- */
197 
198     printf ("==================================== fac memory test2\n") ;
199     count = cm->malloc_count ;
200     my_tries = -1 ;
201     for (trial = 0 ; my_tries <= 0 ; trial++)
202     {
203 	cm->print = 0 ;
204 	fflush (stdout) ;
205 	my_tries = trial ;
206 	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
207 	my_srand (trial+1) ;					/* RAND reset */
208 	err = raw_factor2 (A, 0., 0) ;				/* RAND */
209 	CHOLMOD(free_sparse) (&A, cm) ;
210 	OK (CHOLMOD(print_common) ("cm", cm)) ;
211 	CHOLMOD(free_work) (cm) ;
212 	OK (count == cm->malloc_count) ;
213 	OK (inuse == cm->memory_inuse) ;
214     }
215     CHOLMOD(free_work) (cm) ;
216     printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ;
217     printf ("initial count: "ID" final count "ID"\n",
218 	    (Int) count, (Int) cm->malloc_count) ;
219     printf ("initial inuse: "ID" final inuse "ID"\n",
220 	    (Int) inuse, (Int) cm->memory_inuse) ;
221     OK (count == cm->malloc_count) ;
222     OK (inuse == cm->memory_inuse) ;
223 
224     /* ---------------------------------------------------------------------- */
225     /* test augmented system solver */
226     /* ---------------------------------------------------------------------- */
227 
228     printf ("==================================== aug memory test\n") ;
229     count = cm->malloc_count ;
230     my_tries = -1 ;
231     for (trial = 0 ; my_tries <= 0 ; trial++)
232     {
233 	cm->print = 0 ;
234 	fflush (stdout) ;
235 	my_tries = trial ;
236 	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
237 	err = aug (A) ;				/* no random number use */
238 	CHOLMOD(free_sparse) (&A, cm) ;
239 	OK (CHOLMOD(print_common) ("cm", cm)) ;
240 	CHOLMOD(free_work) (cm) ;
241 	OK (count == cm->malloc_count) ;
242 	OK (inuse == cm->memory_inuse) ;
243     }
244     CHOLMOD(free_work) (cm) ;
245     printf ("memory test: aug error %.1g trials "ID"\n", err, trial) ;
246     printf ("initial count: "ID" final count "ID"\n",
247 	    (Int) count, (Int) cm->malloc_count) ;
248     printf ("initial inuse: "ID" final inuse "ID"\n",
249 	    (Int) inuse, (Int) cm->memory_inuse) ;
250     OK (count == cm->malloc_count) ;
251     OK (inuse == cm->memory_inuse) ;
252 
253     /* ---------------------------------------------------------------------- */
254     /* test ops */
255     /* ---------------------------------------------------------------------- */
256 
257     printf ("==================================== test_ops memory test\n") ;
258     count = cm->malloc_count ;
259     my_tries = -1 ;
260     for (trial = 0 ; my_tries <= 0 ; trial++)
261     {
262 	cm->print = 0 ;
263 	fflush (stdout) ;
264 	my_tries = trial ;
265 	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
266 	my_srand (trial+1) ;					/* RAND reset */
267 	err = test_ops (A) ;					/* RAND */
268 	CHOLMOD(free_sparse) (&A, cm) ;
269 	OK (CHOLMOD(print_common) ("cm", cm)) ;
270 	CHOLMOD(free_work) (cm) ;
271 	printf ("inuse "ID" "ID"\n", (Int) inuse, (Int) (cm->memory_inuse)) ;
272 	OK (count == cm->malloc_count) ;
273 	OK (inuse == cm->memory_inuse) ;
274     }
275     printf ("memory test: testops error %.1g trials "ID"\n", err, trial) ;
276     printf ("initial count: "ID" final count "ID"\n",
277 	    (Int) count, (Int) cm->malloc_count) ;
278     printf ("initial inuse: "ID" final inuse "ID"\n",
279 	    (Int) inuse, (Int) cm->memory_inuse) ;
280     OK (count == cm->malloc_count) ;
281     OK (inuse == cm->memory_inuse) ;
282 
283     /* ---------------------------------------------------------------------- */
284     /* test lpdemo */
285     /* ---------------------------------------------------------------------- */
286 
287     if (T == NULL || T->nrow != T->ncol)
288     {
289 	printf ("==================================== lpdemo memory test\n") ;
290 	count = cm->malloc_count ;
291 	my_tries = -1 ;
292 	for (trial = 0 ; my_tries <= 0 ; trial++)
293 	{
294 	    cm->print = 0 ;
295 	    fflush (stdout) ;
296 	    my_tries = trial ;
297 	    my_srand (trial+1) ;				/* RAND reset */
298 	    err = lpdemo (T) ;					/* RAND */
299 	    OK (CHOLMOD(print_common) ("cm", cm)) ;
300 	    CHOLMOD(free_work) (cm) ;
301 	    OK (count == cm->malloc_count) ;
302 	    OK (inuse == cm->memory_inuse) ;
303 	}
304 	CHOLMOD(free_work) (cm) ;
305 	printf ("memory test: lpdemo error %.1g trials "ID"\n", err, trial) ;
306 	printf ("initial count: "ID" final count "ID"\n",
307 	    (Int) count, (Int) cm->malloc_count) ;
308 	printf ("initial inuse: "ID" final inuse "ID"\n",
309 	    (Int) inuse, (Int) cm->memory_inuse) ;
310 	OK (count == cm->malloc_count) ;
311 	OK (inuse == cm->memory_inuse) ;
312     }
313 
314     /* ---------------------------------------------------------------------- */
315     /* test solver */
316     /* ---------------------------------------------------------------------- */
317 
318     printf ("==================================== solve memory test\n") ;
319     count = cm->malloc_count ;
320     my_tries = -1 ;
321     for (trial = 0 ; my_tries <= 0 ; trial++)
322     {
323 	CHOLMOD(defaults) (cm) ; cm->useGPU = 0 ;
324 	cm->supernodal = CHOLMOD_SUPERNODAL ;
325 	cm->metis_memory = 2.0 ;
326 	cm->nmethods = 4 ;
327 	cm->print = 0 ;
328 	fflush (stdout) ;
329 	my_tries = trial ;
330 	A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ;
331 	my_srand (trial+1) ;					/* RAND reset */
332 	err = solve (A) ;					/* RAND */
333 	CHOLMOD(free_sparse) (&A, cm) ;
334 	OK (CHOLMOD(print_common) ("cm", cm)) ;
335 	CHOLMOD(free_work) (cm) ;
336 	OK (count == cm->malloc_count) ;
337 	OK (inuse == cm->memory_inuse) ;
338     }
339     CHOLMOD(free_work) (cm) ;
340     printf ("memory test: solve error %.1g trials "ID"\n", err, trial) ;
341     printf ("initial count: "ID" final count "ID"\n",
342 	    (Int) count, (Int) cm->malloc_count) ;
343     printf ("initial inuse: "ID" final inuse "ID"\n",
344 	    (Int) inuse, (Int) cm->memory_inuse) ;
345     OK (count == cm->malloc_count) ;
346     OK (inuse == cm->memory_inuse) ;
347     cm->supernodal = CHOLMOD_AUTO ;
348     progress (1, '|') ;
349 
350     /* ---------------------------------------------------------------------- */
351     /* restore original memory handler */
352     /* ---------------------------------------------------------------------- */
353 
354     normal_memory_handler ( ) ;
355     cm->print = 1 ;
356 
357     printf ("All memory tests OK, no error\n") ;
358 }
359