//------------------------------------------------------------------------------ // CHOLMOD/Tcov/t_memory: memory-failure testing in CHOLMOD //------------------------------------------------------------------------------ // CHOLMOD/Tcov Module. Copyright (C) 2005-2023, Timothy A. Davis. // All Rights Reserved. // SPDX-License-Identifier: GPL-2.0+ //------------------------------------------------------------------------------ // Extensive memory-failure testing for CHOLMOD. // // my_malloc2, my_calloc2, and my_realloc2 pretend to fail if my_tries goes to // zero, to test CHOLMOD's memory error handling. No failure occurs if // my_tries is negative. #include "cm.h" //------------------------------------------------------------------------------ // my_tries //------------------------------------------------------------------------------ int64_t my_tries = -1 ; // a global variable //------------------------------------------------------------------------------ // my_malloc2 //------------------------------------------------------------------------------ void *my_malloc2 (size_t size) { void *p ; if (my_tries == 0) { // pretend to fail return (NULL) ; } if (my_tries > 0) { my_tries-- ; } p = malloc (size) ; return (p) ; } //------------------------------------------------------------------------------ // my_calloc2 //------------------------------------------------------------------------------ void *my_calloc2 (size_t n, size_t size) { void *p ; if (my_tries == 0) { // pretend to fail return (NULL) ; } if (my_tries > 0) { my_tries-- ; } p = calloc (n, size) ; return (p) ; } //------------------------------------------------------------------------------ // my_realloc2 //------------------------------------------------------------------------------ void *my_realloc2 (void *p, size_t size) { void *p2 ; if (my_tries == 0) { // pretend to fail return (NULL) ; } if (my_tries > 0) { my_tries-- ; } p2 = realloc (p, size) ; return (p2) ; } //------------------------------------------------------------------------------ // my_free2 //------------------------------------------------------------------------------ void my_free2 (void *p) { free (p) ; } //------------------------------------------------------------------------------ // normal_memory_handler //------------------------------------------------------------------------------ void normal_memory_handler ( void ) { SuiteSparse_config_malloc_func_set (malloc) ; SuiteSparse_config_calloc_func_set (calloc) ; SuiteSparse_config_realloc_func_set (realloc) ; SuiteSparse_config_free_func_set (free) ; cm->error_handler = my_handler ; CHOLMOD(free_work) (cm) ; } //------------------------------------------------------------------------------ // test_memory_handler //------------------------------------------------------------------------------ void test_memory_handler ( void ) { SuiteSparse_config_malloc_func_set (my_malloc2) ; SuiteSparse_config_calloc_func_set (my_calloc2) ; SuiteSparse_config_realloc_func_set (my_realloc2) ; SuiteSparse_config_free_func_set (my_free2) ; cm->error_handler = NULL ; CHOLMOD(free_work) (cm) ; my_tries = 0 ; } //------------------------------------------------------------------------------ // memory tests //------------------------------------------------------------------------------ void memory_tests (cholmod_triplet *T) { double err ; cholmod_sparse *A ; Int trial ; size_t count, inuse ; const int psave = cm->print ; test_memory_handler ( ) ; inuse = cm->memory_inuse ; cm->nmethods = 8 ; cm->print = 0 ; cm->final_resymbol = TRUE ; cm->final_asis = FALSE ; cm->final_super = FALSE ; cm->final_ll = FALSE ; cm->final_pack = FALSE ; cm->final_monotonic = FALSE ; //-------------------------------------------------------------------------- // test raw factorizations //-------------------------------------------------------------------------- printf ("==================================== fac memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; my_srand (trial+1) ; // RAND reset err = raw_factor (A, FALSE) ; // RAND CHOLMOD(free_sparse) (&A, cm) ; OK (CHOLMOD(print_common) ("7:cm", cm)) ; CHOLMOD(free_work) (cm) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } CHOLMOD(free_work) (cm) ; printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; //-------------------------------------------------------------------------- // test raw factorizations (rowfac_mask) //-------------------------------------------------------------------------- printf ("==================================== fac memory test2\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; my_srand (trial+1) ; // RAND reset err = raw_factor2 (A, 0., 0) ; // RAND CHOLMOD(free_sparse) (&A, cm) ; OK (CHOLMOD(print_common) ("8:cm", cm)) ; CHOLMOD(free_work) (cm) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } CHOLMOD(free_work) (cm) ; printf ("memory test: fac error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; //-------------------------------------------------------------------------- // test augmented system solver //-------------------------------------------------------------------------- printf ("==================================== aug memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; err = aug (A) ; // no random number use CHOLMOD(free_sparse) (&A, cm) ; OK (CHOLMOD(print_common) ("9:cm", cm)) ; CHOLMOD(free_work) (cm) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } CHOLMOD(free_work) (cm) ; printf ("memory test: aug error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; //-------------------------------------------------------------------------- // test ops //-------------------------------------------------------------------------- printf ("==================================== test_ops memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; my_srand (trial+1) ; // RAND reset err = test_ops (A) ; // RAND CHOLMOD(free_sparse) (&A, cm) ; OK (CHOLMOD(print_common) ("10:cm", cm)) ; CHOLMOD(free_work) (cm) ; printf ("inuse "ID" "ID"\n", (Int) inuse, (Int) (cm->memory_inuse)) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } printf ("memory test: testops error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; //-------------------------------------------------------------------------- // test lpdemo //-------------------------------------------------------------------------- if (T == NULL || T->nrow != T->ncol) { printf ("==================================== lpdemo memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; my_srand (trial+1) ; // RAND reset err = lpdemo (T) ; // RAND OK (CHOLMOD(print_common) ("11:cm", cm)) ; CHOLMOD(free_work) (cm) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } CHOLMOD(free_work) (cm) ; printf ("memory test: lpdemo error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } //-------------------------------------------------------------------------- // test solver //-------------------------------------------------------------------------- printf ("==================================== solve memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { CHOLMOD(defaults) (cm) ; cm->useGPU = 0 ; cm->supernodal = CHOLMOD_SUPERNODAL ; cm->metis_memory = 2.0 ; cm->nmethods = 4 ; cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; my_srand (trial+1) ; // RAND reset err = solve (A) ; // RAND CHOLMOD(free_sparse) (&A, cm) ; OK (CHOLMOD(print_common) ("12:cm", cm)) ; CHOLMOD(free_work) (cm) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } CHOLMOD(free_work) (cm) ; printf ("memory test: solve error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; cm->supernodal = CHOLMOD_AUTO ; //-------------------------------------------------------------------------- // cat tests //-------------------------------------------------------------------------- CHOLMOD(defaults) (cm) ; cm->useGPU = 0 ; test_memory_handler ( ) ; printf ("==================================== cat_tests memory test\n") ; count = cm->malloc_count ; my_tries = -1 ; for (trial = 0 ; my_tries <= 0 ; trial++) { cm->print = 0 ; fflush (stdout) ; my_tries = trial ; A = CHOLMOD(triplet_to_sparse) (T, 0, cm) ; err = cat_tests (A, cm) ; CHOLMOD(free_sparse) (&A, cm) ; CHOLMOD(free_work) (cm) ; printf ("inuse "ID" "ID"\n", (Int) inuse, (Int) (cm->memory_inuse)) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; } printf ("memory test: cat_test error %.1g trials "ID"\n", err, trial) ; printf ("initial count: "ID" final count "ID"\n", (Int) count, (Int) cm->malloc_count) ; printf ("initial inuse: "ID" final inuse "ID"\n", (Int) inuse, (Int) cm->memory_inuse) ; OK (count == cm->malloc_count) ; OK (inuse == cm->memory_inuse) ; //-------------------------------------------------------------------------- // restore original memory handler //-------------------------------------------------------------------------- progress (1, '|') ; normal_memory_handler ( ) ; cm->print = psave ; printf ("All memory tests OK, no error\n") ; }