/************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Tests for mem_info.c functions */ static char rcsid[] = "$Id: memtort.c,v 1.1.1.1 1999/04/14 14:16:17 borland Exp $"; #include #include #include "matrix2.h" #include "sparse2.h" #include "zmatrix2.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg) /* new types list */ extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS]; /* the number of a new list */ #define FOO_LIST 1 /* numbers of types */ #define TYPE_FOO_1 1 #define TYPE_FOO_2 2 typedef struct { int dim; int fix_dim; Real (*a)[10]; } FOO_1; typedef struct { int dim; int fix_dim; Real (*a)[2]; } FOO_2; FOO_1 *foo_1_get(dim) int dim; { FOO_1 *f; if ((f = (FOO_1 *)malloc(sizeof(FOO_1))) == NULL) error(E_MEM,"foo_1_get"); else if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_1,0,sizeof(FOO_1),FOO_LIST); mem_numvar_list(TYPE_FOO_1,1,FOO_LIST); } f->dim = dim; f->fix_dim = 10; if ((f->a = (Real (*)[10])malloc(dim*sizeof(Real [10]))) == NULL) error(E_MEM,"foo_1_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_FOO_1,0,dim*sizeof(Real [10]),FOO_LIST); return f; } FOO_2 *foo_2_get(dim) int dim; { FOO_2 *f; if ((f = (FOO_2 *)malloc(sizeof(FOO_2))) == NULL) error(E_MEM,"foo_2_get"); else if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_2,0,sizeof(FOO_2),FOO_LIST); mem_numvar_list(TYPE_FOO_2,1,FOO_LIST); } f->dim = dim; f->fix_dim = 2; if ((f->a = (Real (*)[2])malloc(dim*sizeof(Real [2]))) == NULL) error(E_MEM,"foo_2_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_FOO_2,0,dim*sizeof(Real [2]),FOO_LIST); return f; } int foo_1_free(f) FOO_1 *f; { if ( f != NULL) { if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_1,sizeof(FOO_1)+ f->dim*sizeof(Real [10]),0,FOO_LIST); mem_numvar_list(TYPE_FOO_1,-1,FOO_LIST); } free(f->a); free(f); } return 0; } int foo_2_free(f) FOO_2 *f; { if ( f != NULL) { if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_2,sizeof(FOO_2)+ f->dim*sizeof(Real [2]),0,FOO_LIST); mem_numvar_list(TYPE_FOO_2,-1,FOO_LIST); } free(f->a); free(f); } return 0; } char *foo_type_name[] = { "nothing", "FOO_1", "FOO_2" }; #define FOO_NUM_TYPES (sizeof(foo_type_name)/sizeof(*foo_type_name)) int (*foo_free_func[FOO_NUM_TYPES])() = { NULL, foo_1_free, foo_2_free }; static MEM_ARRAY foo_info_sum[FOO_NUM_TYPES]; /* px_rand -- generates sort-of random permutation */ PERM *px_rand(pi) PERM *pi; { int i, j, k; if ( ! pi ) error(E_NULL,"px_rand"); for ( i = 0; i < 3*pi->size; i++ ) { j = (rand() >> 8) % pi->size; k = (rand() >> 8) % pi->size; px_transp(pi,j,k); } return pi; } #ifdef SPARSE SPMAT *gen_non_symm(m,n) int m, n; { SPMAT *A; static PERM *px = PNULL; int i, j, k, k_max; Real s1; A = sp_get(m,n,8); px = px_resize(px,n); MEM_STAT_REG(px,TYPE_PERM); for ( i = 0; i < A->m; i++ ) { k_max = 1 + ((rand() >> 8) % 10); for ( k = 0; k < k_max; k++ ) { j = (rand() >> 8) % A->n; s1 = rand()/((double)MAX_RAND); sp_set_val(A,i,j,s1); } } /* to make it likely that A is nonsingular, use pivot... */ for ( i = 0; i < 2*A->n; i++ ) { j = (rand() >> 8) % A->n; k = (rand() >> 8) % A->n; px_transp(px,j,k); } for ( i = 0; i < A->n; i++ ) sp_set_val(A,i,px->pe[i],1.0); return A; } #endif void stat_test1(par) int par; { static MAT *AT = MNULL; static VEC *xt1 = VNULL, *yt1 = VNULL; static VEC *xt2 = VNULL, *yt2 = VNULL; static VEC *xt3 = VNULL, *yt3 = VNULL; static VEC *xt4 = VNULL, *yt4 = VNULL; AT = m_resize(AT,10,10); xt1 = v_resize(xt1,10); yt1 = v_resize(yt1,10); xt2 = v_resize(xt2,10); yt2 = v_resize(yt2,10); xt3 = v_resize(xt3,10); yt3 = v_resize(yt3,10); xt4 = v_resize(xt4,10); yt4 = v_resize(yt4,10); MEM_STAT_REG(AT,TYPE_MAT); #ifdef ANSI_C mem_stat_reg_vars(0,TYPE_VEC,&xt1,&xt2,&xt3,&xt4,&yt1, &yt2,&yt3,&yt4,NULL); #else #ifdef VARARGS mem_stat_reg_vars(0,TYPE_VEC,&xt1,&xt2,&xt3,&xt4,&yt1, &yt2,&yt3,&yt4,NULL); #else MEM_STAT_REG(xt1,TYPE_VEC); MEM_STAT_REG(yt1,TYPE_VEC); MEM_STAT_REG(xt2,TYPE_VEC); MEM_STAT_REG(yt2,TYPE_VEC); MEM_STAT_REG(xt3,TYPE_VEC); MEM_STAT_REG(yt3,TYPE_VEC); MEM_STAT_REG(xt4,TYPE_VEC); MEM_STAT_REG(yt4,TYPE_VEC); #endif #endif v_rand(xt1); m_rand(AT); mv_mlt(AT,xt1,yt1); } void stat_test2(par) int par; { static PERM *px = PNULL; static IVEC *ixt = IVNULL, *iyt = IVNULL; px = px_resize(px,10); ixt = iv_resize(ixt,10); iyt = iv_resize(iyt,10); MEM_STAT_REG(px,TYPE_PERM); MEM_STAT_REG(ixt,TYPE_IVEC); MEM_STAT_REG(iyt,TYPE_IVEC); px_rand(px); px_inv(px,px); } #ifdef SPARSE void stat_test3(par) int par; { static SPMAT *AT = (SPMAT *)NULL; static VEC *xt = VNULL, *yt = VNULL; static SPROW *r = (SPROW *) NULL; if (AT == (SPMAT *)NULL) AT = gen_non_symm(100,100); else AT = sp_resize(AT,100,100); xt = v_resize(xt,100); yt = v_resize(yt,100); if (r == NULL) r = sprow_get(100); MEM_STAT_REG(AT,TYPE_SPMAT); MEM_STAT_REG(xt,TYPE_VEC); MEM_STAT_REG(yt,TYPE_VEC); MEM_STAT_REG(r,TYPE_SPROW); v_rand(xt); sp_mv_mlt(AT,xt,yt); } #endif #ifdef COMPLEX void stat_test4(par) int par; { static ZMAT *AT = ZMNULL; static ZVEC *xt = ZVNULL, *yt = ZVNULL; AT = zm_resize(AT,10,10); xt = zv_resize(xt,10); yt = zv_resize(yt,10); MEM_STAT_REG(AT,TYPE_ZMAT); MEM_STAT_REG(xt,TYPE_ZVEC); MEM_STAT_REG(yt,TYPE_ZVEC); zv_rand(xt); zm_rand(AT); zmv_mlt(AT,xt,yt); } #endif void main(argc, argv) int argc; char *argv[]; { VEC *x = VNULL, *y = VNULL, *z = VNULL; PERM *pi1 = PNULL, *pi2 = PNULL, *pi3 = PNULL; MAT *A = MNULL, *B = MNULL, *C = MNULL; #ifdef SPARSE SPMAT *sA, *sB; SPROW *r; #endif IVEC *ix = IVNULL, *iy = IVNULL, *iz = IVNULL; int m,n,i,j,deg,k; Real s1,s2; #ifdef COMPLEX ZVEC *zx = ZVNULL, *zy = ZVNULL, *zz = ZVNULL; ZMAT *zA = ZMNULL, *zB = ZMNULL, *zC = ZMNULL; complex ONE; #endif /* variables for testing attaching new lists of types */ FOO_1 *foo_1; FOO_2 *foo_2; mem_info_on(TRUE); #if defined(ANSI_C) || defined(VARARGS) notice("vector initialize, copy & resize"); n = v_get_vars(15,&x,&y,&z,(VEC **)NULL); if (n != 3) { errmesg("v_get_vars"); printf(" n = %d (should be 3)\n",n); } v_rand(x); v_rand(y); z = v_copy(x,z); if ( v_norm2(v_sub(x,z,z)) >= MACHEPS ) errmesg("v_get_vars"); v_copy(x,y); n = v_resize_vars(10,&x,&y,&z,NULL); if ( n != 3 || v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC copy/resize"); n = v_resize_vars(20,&x,&y,&z,NULL); if ( n != 3 || v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC resize"); n = v_free_vars(&x,&y,&z,NULL); if (n != 3) errmesg("v_free_vars"); /* IVEC */ notice("int vector initialise, copy & resize"); n = iv_get_vars(15,&ix,&iy,&iz,NULL); if (n != 3) { errmesg("iv_get_vars"); printf(" n = %d (should be 3)\n",n); } for (i=0; i < ix->dim; i++) { ix->ive[i] = 2*i-1; iy->ive[i] = 3*i+2; } iz = iv_add(ix,iy,iz); for (i=0; i < ix->dim; i++) if ( iz->ive[i] != 5*i+1) errmesg("iv_get_vars"); n = iv_resize_vars(10,&ix,&iy,&iz,NULL); if ( n != 3) errmesg("IVEC copy/resize"); iv_add(ix,iy,iz); for (i=0; i < ix->dim; i++) if (iz->ive[i] != 5*i+1) errmesg("IVEC copy/resize"); n = iv_resize_vars(20,&ix,&iy,&iz,NULL); if ( n != 3 ) errmesg("IVEC resize"); iv_add(ix,iy,iz); for (i=0; i < 10; i++) if (iz->ive[i] != 5*i+1) errmesg("IVEC copy/resize"); n = iv_free_vars(&ix,&iy,&iz,NULL); if (n != 3) errmesg("iv_free_vars"); /* MAT */ notice("matrix initialise, copy & resize"); n = m_get_vars(10,10,&A,&B,&C,NULL); if (n != 3) { errmesg("m_get_vars"); printf(" n = %d (should be 3)\n",n); } m_rand(A); m_rand(B); C = m_copy(A,C); if ( m_norm_inf(m_sub(A,C,C)) >= MACHEPS ) errmesg("MAT copy"); m_copy(A,B); n = m_resize_vars(5,5,&A,&B,&C,NULL); if ( n != 3 || m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT copy/resize"); n = m_resize_vars(20,20,&A,&B,NULL); if ( m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT resize"); k = m_free_vars(&A,&B,&C,NULL); if ( k != 3 ) errmesg("MAT free"); /* PERM */ notice("permutation initialise, inverting & permuting vectors"); n = px_get_vars(15,&pi1,&pi2,&pi3,NULL); if (n != 3) { errmesg("px_get_vars"); printf(" n = %d (should be 3)\n",n); } v_get_vars(15,&x,&y,&z,NULL); px_rand(pi1); v_rand(x); px_vec(pi1,x,z); y = v_resize(y,x->dim); pxinv_vec(pi1,z,y); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); pi2 = px_inv(pi1,pi2); pi3 = px_mlt(pi1,pi2,pi3); for ( i = 0; i < pi3->size; i++ ) if ( pi3->pe[i] != i ) errmesg("PERM inverse/multiply"); px_resize_vars(20,&pi1,&pi2,&pi3,NULL); v_resize_vars(20,&x,&y,&z,NULL); px_rand(pi1); v_rand(x); px_vec(pi1,x,z); pxinv_vec(pi1,z,y); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); pi2 = px_inv(pi1,pi2); pi3 = px_mlt(pi1,pi2,pi3); for ( i = 0; i < pi3->size; i++ ) if ( pi3->pe[i] != i ) errmesg("PERM inverse/multiply"); n = px_free_vars(&pi1,&pi2,&pi3,NULL); if ( n != 3 ) errmesg("PERM px_free_vars"); #ifdef SPARSE /* set up two random sparse matrices */ m = 120; n = 100; deg = 5; notice("allocating sparse matrices"); k = sp_get_vars(m,n,deg,&sA,&sB,NULL); if (k != 2) { errmesg("sp_get_vars"); printf(" n = %d (should be 2)\n",k); } notice("setting and getting matrix entries"); for ( k = 0; k < m*deg; k++ ) { i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sA,i,j,rand()/((Real)MAX_RAND)); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sB,i,j,rand()/((Real)MAX_RAND)); } for ( k = 0; k < 10; k++ ) { s1 = rand()/((Real)MAX_RAND); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sA,i,j,s1); s2 = sp_get_val(sA,i,j); if ( fabs(s1 - s2) >= MACHEPS ) { printf(" s1 = %g, s2 = %g, |s1 - s2| = %g\n", s1,s2,fabs(s1-s2)); break; } } if ( k < 10 ) errmesg("sp_set_val()/sp_get_val()"); /* check column access paths */ notice("resizing and access paths"); k = sp_resize_vars(sA->m+10,sA->n+10,&sA,&sB,NULL); if (k != 2) { errmesg("sp_get_vars"); printf(" n = %d (should be 2)\n",k); } for ( k = 0 ; k < 20; k++ ) { i = sA->m - 1 - ((rand() >> 8) % 10); j = sA->n - 1 - ((rand() >> 8) % 10); s1 = rand()/((Real)MAX_RAND); sp_set_val(sA,i,j,s1); if ( fabs(s1 - sp_get_val(sA,i,j)) >= MACHEPS ) break; } if ( k < 20 ) errmesg("sp_resize()"); sp_col_access(sA); if ( ! chk_col_access(sA) ) { errmesg("sp_col_access()"); } sp_diag_access(sA); for ( i = 0; i < sA->m; i++ ) { r = &(sA->row[i]); if ( r->diag != sprow_idx(r,i) ) break; } if ( i < sA->m ) { errmesg("sp_diag_access()"); } k = sp_free_vars(&sA,&sB,NULL); if (k != 2) errmesg("sp_free_vars"); #endif /* SPARSE */ #ifdef COMPLEX /* complex stuff */ ONE = zmake(1.0,0.0); printf("# ONE = "); z_output(ONE); printf("# Check: MACHEPS = %g\n",MACHEPS); /* allocate, initialise, copy and resize operations */ /* ZVEC */ notice("vector initialise, copy & resize"); zv_get_vars(12,&zx,&zy,&zz,NULL); zv_rand(zx); zv_rand(zy); zz = zv_copy(zx,zz); if ( zv_norm2(zv_sub(zx,zz,zz)) >= MACHEPS ) errmesg("ZVEC copy"); zv_copy(zx,zy); zv_resize_vars(10,&zx,&zy,NULL); if ( zv_norm2(zv_sub(zx,zy,zz)) >= MACHEPS ) errmesg("ZVEC copy/resize"); zv_resize_vars(20,&zx,&zy,NULL); if ( zv_norm2(zv_sub(zx,zy,zz)) >= MACHEPS ) errmesg("VZEC resize"); zv_free_vars(&zx,&zy,&zz,NULL); /* ZMAT */ notice("matrix initialise, copy & resize"); zm_get_vars(8,5,&zA,&zB,&zC,NULL); zm_rand(zA); zm_rand(zB); zC = zm_copy(zA,zC); if ( zm_norm_inf(zm_sub(zA,zC,zC)) >= MACHEPS ) errmesg("ZMAT copy"); zm_copy(zA,zB); zm_resize_vars(3,5,&zA,&zB,&zC,NULL); if ( zm_norm_inf(zm_sub(zA,zB,zC)) >= MACHEPS ) errmesg("ZMAT copy/resize"); zm_resize_vars(20,20,&zA,&zB,&zC,NULL); if ( zm_norm_inf(zm_sub(zA,zB,zC)) >= MACHEPS ) errmesg("ZMAT resize"); zm_free_vars(&zA,&zB,&zC,NULL); #endif /* COMPLEX */ #endif /* if defined(ANSI_C) || defined(VARARGS) */ printf("# test of mem_info_bytes and mem_info_numvar\n"); printf(" TYPE VEC: %ld bytes allocated, %d variables allocated\n", mem_info_bytes(TYPE_VEC,0),mem_info_numvar(TYPE_VEC,0)); notice("static memory test"); mem_info_on(TRUE); mem_stat_mark(1); for (i=0; i < 100; i++) stat_test1(i); mem_stat_free(1); mem_stat_mark(1); for (i=0; i < 100; i++) { stat_test1(i); #ifdef COMPLEX stat_test4(i); #endif } mem_stat_mark(2); for (i=0; i < 100; i++) stat_test2(i); mem_stat_mark(3); #ifdef SPARSE for (i=0; i < 100; i++) stat_test3(i); #endif mem_info(); mem_dump_list(stdout,0); mem_stat_free(1); mem_stat_free(3); mem_stat_mark(4); for (i=0; i < 100; i++) { stat_test1(i); #ifdef COMPLEX stat_test4(i); #endif } mem_stat_dump(stdout,0); if (mem_stat_show_mark() != 4) { errmesg("not 4 in mem_stat_show_mark()"); } mem_stat_free(2); mem_stat_free(4); if (mem_stat_show_mark() != 0) { errmesg("not 0 in mem_stat_show_mark()"); } /* add new list of types */ mem_attach_list(FOO_LIST,FOO_NUM_TYPES,foo_type_name, foo_free_func,foo_info_sum); if (!mem_is_list_attached(FOO_LIST)) errmesg("list FOO_LIST is not attached"); mem_dump_list(stdout,FOO_LIST); foo_1 = foo_1_get(6); foo_2 = foo_2_get(3); for (i=0; i < foo_1->dim; i++) for (j=0; j < foo_1->fix_dim; j++) foo_1->a[i][j] = i+j; for (i=0; i < foo_2->dim; i++) for (j=0; j < foo_2->fix_dim; j++) foo_2->a[i][j] = i+j; printf(" foo_1->a[%d][%d] = %g\n",5,9,foo_1->a[5][9]); printf(" foo_2->a[%d][%d] = %g\n",2,1,foo_2->a[2][1]); mem_stat_mark(5); mem_stat_reg_list((void **)&foo_1,TYPE_FOO_1,FOO_LIST); mem_stat_reg_list((void **)&foo_2,TYPE_FOO_2,FOO_LIST); mem_stat_dump(stdout,FOO_LIST); mem_info_file(stdout,FOO_LIST); mem_stat_free_list(5,FOO_LIST); mem_stat_dump(stdout,FOO_LIST); if ( foo_1 != NULL ) errmesg(" foo_1 is not released"); if ( foo_2 != NULL ) errmesg(" foo_2 is not released"); mem_dump_list(stdout,FOO_LIST); mem_info_file(stdout,FOO_LIST); mem_free_vars(FOO_LIST); if ( mem_is_list_attached(FOO_LIST) ) errmesg("list FOO_LIST is not detached"); mem_info(); #if REAL == FLOAT printf("# SINGLE PRECISION was used\n"); #elif REAL == DOUBLE printf("# DOUBLE PRECISION was used\n"); #endif #define ANSI_OR_VAR #ifndef ANSI_C #ifndef VARARGS #undef ANSI_OR_VAR #endif #endif #ifdef ANSI_OR_VAR printf("# you should get: \n"); #if (REAL == FLOAT) printf("# type VEC: 276 bytes allocated, 3 variables allocated\n"); #elif (REAL == DOUBLE) printf("# type VEC: 516 bytes allocated, 3 variables allocated\n"); #endif printf("# and other types are zeros\n"); #endif /*#if defined(ANSI_C) || defined(VARAGS) */ printf("# Finished memory torture test\n"); return; }