dynamic memory information

SYNOPSIS

#include "matrix.h"
void mem_info()
int  mem_info_on(int true_or_false)
int  mem_info_is_on(void)
void mem_info_file(FILE *fp, int list_num)
void mem_dump_list(FILE *fp, int list_num)
long mem_info_bytes (int type_num, int list_num)
int  mem_info_numvar(int type_num, int list_num)
int  mem_attach_list(int list_num, int ntypes, char *names[],
                     int (*frees[])(), MEM_ARRAY info_sum[])
int  mem_free_list(int list_num)
int  mem_is_list_attached(int list_num)
void mem_bytes(int type_num, int old_size, int new_size)
void mem_bytes_list(int type_num, int old_size, int new_size,
                    int list_num)
void mem_numvar(int type_num, int diff_numvar)
void mem_numvar_list(int type_num, int diff_numvar,
                     int list_num)

DESCRIPTION

These routines allow the user to obtain information about the amount of memory allocated for the Meschach data structures (VEC, BAND, MAT, PERM, IVEC, ITER, SPMAT, SPROW, ZVEC and ZMAT). The call mem_info_on(TRUE); sets a flag which directs the allocation and deallocation and resizing routines to store information about the memory that is (de)allocated and resized. The call mem_info_on(FALSE); turns the flag off. The routine mem_info_is_on() returns the status of the memory information flag. To get a general picture of the state of the memory allocated by Meschach data structures call mem_info_file(fp,list_num) which prints a summary of the amount of memory used for the different types of data structures to the file or stream fp. The list_num parameter indicates which list of types to use; use zero for the list of standard Meschach data types. The printout for mem_info_file(stdout,0), or the equivalent macro mem_info() looks like this for one real and one complex vector of dimension~10 allocated (with the full system installed on an RS/6000):

 MEMORY INFORMATION (standard types):
 type MAT           0 alloc. bytes     0 alloc. variables
 type BAND          0 alloc. bytes     0 alloc. variables
 type PERM          0 alloc. bytes     0 alloc. variables
 type VEC          92 alloc. bytes     1 alloc. variable 
 type IVEC          0 alloc. bytes     0 alloc. variables
 type ITER          0 alloc. bytes     0 alloc. variables
 type SPROW         0 alloc. bytes     0 alloc. variables
 type SPMAT         0 alloc. bytes     0 alloc. variables
 type ZVEC        204 alloc. bytes     1 alloc. variable 
 type ZMAT          0 alloc. bytes     0 alloc. variables
 total:           296 alloc. bytes     2 alloc. variables
(Note that this is for the system built with all of Meschach, including the sparse part: ITER, SPMAT; and the complex part: ZVEC, ZMAT. The mem_info_...() routines also work for partial installations of Meschach.) There is also the routine mem_dump_list() which provides a more complete printout, which is suitable for debugging purposes. To obtain information about the amount of memory allocated for objects of a particular type, use mem_info_bytes() (with list_num equal to zero for a standard Meschach structures). To find out the amount of memory allocated for ordinary vectors, use
printf("Bytes in VEC'S = 
       mem_info_bytes(TYPE_VEC,0));
The routine mem_info_numvar() returns the number of data structures that are allocated for each type. Use list_num equal to zero for standard Meschach structures. Each Meschach type has an associated type macro TYPE_... which is a small integer. The ``...'' is the ordinary name of the type, such as VEC, MAT etc. This is the complete list of TYPE_... macros:
TYPE_MAT       0   /* real dense matrix */
TYPE_BAND      1   /* real band matrix */
TYPE_PERM      2   /* permutation */
TYPE_VEC       3   /* real vector */
TYPE_IVEC      4   /* integer vector */
TYPE_ITER      5   /* iteration structure */
TYPE_SPROW     6   /* real sparse matrix row */
TYPE_SPMAT     7   /* real sparse matrix */
TYPE_ZVEC      8   /* complex vector */
TYPE_ZMAT      9   /* complex dense matrix */
This is how different types are distinguished within the mem_info_... system. Note that SPROW is an auxiliary type; when an SPROW (sparse row) is allocated as part of a SPMAT (sparse matrix), then the memory allocation is entered under SPMAT; only ``stand-alone'' SPROW's have their memory allocation entered under the typer SPROW. The routine mem_attach_list() can be used to add new lists of types to the Meschach system for both tracking memory usage, and also for registering static workspace arrays with MEM_STAT_REG(). The routine is passed a collection of arrays: names is an array of strings being the names of the different types, frees is an array of the .._free() routines which deallocate and destroy objects of the corresponding types, info_sum is an array in which the memory allocation information is stored. This array has the component type MEM_ARRAY which is defined as
typedef struct {
   long bytes;  /* # allocated bytes for each type */
   int  numvar; /* # allocated variables for each type */
} MEM_ARRAY;
This is defined in matrix.h. The parameter ntypes is the number of types, which should also be the common length of the arrays. The parameter list_num is the list number used to identify which list of types should be used. The routine mem_attach_list() returns the zero on successful completion, and $(-1)$ if there is an invalid parameter. An E_OVERWRITE error will be raised if the specified list_num has already been used. To track memory usage for any new types, the allocation, deallocation and resizing routines for these types you should use mem_bytes_list() and \newlinemem_numvar_list() to inform the mem_info_...() system of the change in the number of bytes allocated, and number of structures allocated, respectively, of an object of a particular type (as specified by the type_num and list_num parameters). In mem_bytes_list(), the parameter old_size should contain the old size in bytes, and new_size should contain the new size in bytes. In mem_numvar_list(), the parameter diff_numvar is the change in the number of allocated structures: $+1$ for allocating a new structure, and $-1$ for destroying a structure. The routines mem_bytes() and mem_numvar() are just macros that call \newlinemem_bytes_list() and mem_numvar() respectively, with list_num zero for the standard Meschach structures. The routine mem_attach_list() should be used once at the beginning of a program using these additional types. Here is an example of how this might be used to extend Meschach with three types for nodes, edges and graphs:
/* Example with three new types: NODE, EDGE and GRAPH */
#define MY_LIST 1
#define TYPE_NODE  0
#define TYPE_EDGE  1
#define TYPE_GRAPH 2
static char *my_names[] = {  "NODE", "EDGE", "GRAPH"  };
static int  (*my_frees[]) = { n_free, e_free, gr_free };
static MEM_ARRAY my_tnums[3];  /* initialised to zeros */

main(...)
{
      ......  /* declarations */
    mem_attach_list(MY_LIST,3,my_names,my_frees,my_tnums);
      ......  /* actual work  */
    mem_info_file(stdout,MY_LIST);  /* list memory used */
}
/* n_get -- get a node data structure;
            NODE has type number 0 */
NODE *n_get(...)
{
    NODE  *n;

    n = NEW(NODE);
    if ( n == NULL )
      error(E_MEM,"n_get"); /* can't allocate memory */
    mem_bytes_list(TYPE_NODE,0,sizeof(NODE),MY_LIST);
    mem_numvar_list(TYPE_NODE,1,MY_LIST);
      ......
}

/* n_free -- deallocate node data structure */
int   n_free(NODE *n)
{
    if ( n != NULL )
    {
        free(n);
        mem_res_elem_list(TYPE_NODE,sizeof(NODE),0,MY_LIST);
        mem_numvar_list(TYPE_NODE,-1,MY_LIST);
    }
    return 0;
}
For more information see chapter~8.

BUGS

Memory used by the underlying memory (de)allocation system (malloc(), calloc(), realloc(), sbrk() etc.) for headers are not included in the amounts of allocated memory. The numbers of vectors, matrices etc.\ currently allocated cannot be found by this system.

SEE ALSO: .._get(), .._free(), .._resize() routines; MEM_STAT_REG() and the \newlinemem_stat_...() routines.

SOURCE FILE: meminfo.c, meminfo.h