Blender V2.61 - r43446

smemory.c

Go to the documentation of this file.
00001 
00005 /*
00006  * -- SuperLU routine (version 3.0) --
00007  * Univ. of California Berkeley, Xerox Palo Alto Research Center,
00008  * and Lawrence Berkeley National Lab.
00009  * October 15, 2003
00010  *
00011  */
00012 #include "ssp_defs.h"
00013 
00014 #include "superlu_sys_types.h" // needed for intptr_t
00015 
00016 /* Constants */
00017 #define NO_MEMTYPE  4      /* 0: lusup;
00018                   1: ucol;
00019                   2: lsub;
00020                   3: usub */
00021 #define GluIntArray(n)   (5 * (n) + 5)
00022 
00023 /* Internal prototypes */
00024 void  *sexpand (int *, MemType,int, int, GlobalLU_t *);
00025 int   sLUWorkInit (int, int, int, int **, float **, LU_space_t);
00026 void  copy_mem_float (int, void *, void *);
00027 void  sStackCompress (GlobalLU_t *);
00028 void  sSetupSpace (void *, int, LU_space_t *);
00029 void  *suser_malloc (int, int);
00030 void  suser_free (int, int);
00031 
00032 /* External prototypes (in memory.c - prec-indep) */
00033 extern void    copy_mem_int    (int, void *, void *);
00034 extern void    user_bcopy      (char *, char *, int);
00035 
00036 /* Headers for 4 types of dynamatically managed memory */
00037 typedef struct e_node {
00038     int size;      /* length of the memory that has been used */
00039     void *mem;     /* pointer to the new malloc'd store */
00040 } ExpHeader;
00041 
00042 typedef struct {
00043     int  size;
00044     int  used;
00045     int  top1;  /* grow upward, relative to &array[0] */
00046     int  top2;  /* grow downward */
00047     void *array;
00048 } LU_stack_t;
00049 
00050 /* Variables local to this file */
00051 static ExpHeader *expanders = 0; /* Array of pointers to 4 types of memory */
00052 static LU_stack_t stack;
00053 static int no_expand;
00054 
00055 /* Macros to manipulate stack */
00056 #define StackFull(x)         ( x + stack.used >= stack.size )
00057 #define NotDoubleAlign(addr) ( (intptr_t)addr & 7 )
00058 #define DoubleAlign(addr)    ( ((intptr_t)addr + 7) & ~7L )
00059 #define TempSpace(m, w)      ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \
00060                   (w + 1) * m * sizeof(float) )
00061 #define Reduce(alpha)        ((alpha + 1) / 2)  /* i.e. (alpha-1)/2 + 1 */
00062 
00063 
00064 
00065 
00066 /*
00067  * Setup the memory model to be used for factorization.
00068  *    lwork = 0: use system malloc;
00069  *    lwork > 0: use user-supplied work[] space.
00070  */
00071 void sSetupSpace(void *work, int lwork, LU_space_t *MemModel)
00072 {
00073     if ( lwork == 0 ) {
00074     *MemModel = SYSTEM; /* malloc/free */
00075     } else if ( lwork > 0 ) {
00076     *MemModel = USER;   /* user provided space */
00077     stack.used = 0;
00078     stack.top1 = 0;
00079     stack.top2 = (lwork/4)*4; /* must be word addressable */
00080     stack.size = stack.top2;
00081     stack.array = (void *) work;
00082     }
00083 }
00084 
00085 
00086 
00087 void *suser_malloc(int bytes, int which_end)
00088 {
00089     void *buf;
00090     
00091     if ( StackFull(bytes) ) return (NULL);
00092 
00093     if ( which_end == HEAD ) {
00094     buf = (char*) stack.array + stack.top1;
00095     stack.top1 += bytes;
00096     } else {
00097     stack.top2 -= bytes;
00098     buf = (char*) stack.array + stack.top2;
00099     }
00100     
00101     stack.used += bytes;
00102     return buf;
00103 }
00104 
00105 
00106 void suser_free(int bytes, int which_end)
00107 {
00108     if ( which_end == HEAD ) {
00109     stack.top1 -= bytes;
00110     } else {
00111     stack.top2 += bytes;
00112     }
00113     stack.used -= bytes;
00114 }
00115 
00116 
00117 
00118 /*
00119  * mem_usage consists of the following fields:
00120  *    - for_lu (float)
00121  *      The amount of space used in bytes for the L\U data structures.
00122  *    - total_needed (float)
00123  *      The amount of space needed in bytes to perform factorization.
00124  *    - expansions (int)
00125  *      Number of memory expansions during the LU factorization.
00126  */
00127 int sQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage)
00128 {
00129     SCformat *Lstore;
00130     NCformat *Ustore;
00131     register int n, iword, dword, panel_size = sp_ienv(1);
00132 
00133     Lstore = L->Store;
00134     Ustore = U->Store;
00135     n = L->ncol;
00136     iword = sizeof(int);
00137     dword = sizeof(float);
00138 
00139     /* For LU factors */
00140     mem_usage->for_lu = (float)( (4*n + 3) * iword + Lstore->nzval_colptr[n] *
00141                  dword + Lstore->rowind_colptr[n] * iword );
00142     mem_usage->for_lu += (float)( (n + 1) * iword +
00143                  Ustore->colptr[n] * (dword + iword) );
00144 
00145     /* Working storage to support factorization */
00146     mem_usage->total_needed = mem_usage->for_lu +
00147     (float)( (2 * panel_size + 4 + NO_MARKER) * n * iword +
00148         (panel_size + 1) * n * dword );
00149 
00150     mem_usage->expansions = --no_expand;
00151 
00152     return 0;
00153 } /* sQuerySpace */
00154 
00155 /*
00156  * Allocate storage for the data structures common to all factor routines.
00157  * For those unpredictable size, make a guess as FILL * nnz(A).
00158  * Return value:
00159  *     If lwork = -1, return the estimated amount of space required, plus n;
00160  *     otherwise, return the amount of space actually allocated when
00161  *     memory allocation failure occurred.
00162  */
00163 int
00164 sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
00165       int panel_size, SuperMatrix *L, SuperMatrix *U, GlobalLU_t *Glu,
00166       int **iwork, float **dwork)
00167 {
00168     int      info, iword, dword;
00169     SCformat *Lstore;
00170     NCformat *Ustore;
00171     int      *xsup, *supno;
00172     int      *lsub, *xlsub;
00173     float   *lusup;
00174     int      *xlusup;
00175     float   *ucol;
00176     int      *usub, *xusub;
00177     int      nzlmax, nzumax, nzlumax;
00178     int      FILL = sp_ienv(6);
00179     
00180     Glu->n    = n;
00181     no_expand = 0;
00182     iword     = sizeof(int);
00183     dword     = sizeof(float);
00184 
00185     if ( !expanders )   
00186         expanders = (ExpHeader*)SUPERLU_MALLOC(NO_MEMTYPE * sizeof(ExpHeader));
00187     if ( !expanders ) ABORT("SUPERLU_MALLOC fails for expanders");
00188     
00189     if ( fact != SamePattern_SameRowPerm ) {
00190     /* Guess for L\U factors */
00191     nzumax = nzlumax = FILL * annz;
00192     nzlmax = SUPERLU_MAX(1, FILL/4.) * annz;
00193 
00194     if ( lwork == -1 ) {
00195         return ( GluIntArray(n) * iword + TempSpace(m, panel_size)
00196             + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n );
00197         } else {
00198         sSetupSpace(work, lwork, &Glu->MemModel);
00199     }
00200     
00201 #ifdef DEBUG           
00202     printf("sLUMemInit() called: annz %d, MemModel %d\n", 
00203         annz, Glu->MemModel);
00204 #endif  
00205     
00206     /* Integer pointers for L\U factors */
00207     if ( Glu->MemModel == SYSTEM ) {
00208         xsup   = intMalloc(n+1);
00209         supno  = intMalloc(n+1);
00210         xlsub  = intMalloc(n+1);
00211         xlusup = intMalloc(n+1);
00212         xusub  = intMalloc(n+1);
00213     } else {
00214         xsup   = (int *)suser_malloc((n+1) * iword, HEAD);
00215         supno  = (int *)suser_malloc((n+1) * iword, HEAD);
00216         xlsub  = (int *)suser_malloc((n+1) * iword, HEAD);
00217         xlusup = (int *)suser_malloc((n+1) * iword, HEAD);
00218         xusub  = (int *)suser_malloc((n+1) * iword, HEAD);
00219     }
00220 
00221     lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
00222     ucol  = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu );
00223     lsub  = (int *)    sexpand( &nzlmax, LSUB, 0, 0, Glu );
00224     usub  = (int *)    sexpand( &nzumax, USUB, 0, 1, Glu );
00225 
00226     while ( !lusup || !ucol || !lsub || !usub ) {
00227         if ( Glu->MemModel == SYSTEM ) {
00228         SUPERLU_FREE(lusup); 
00229         SUPERLU_FREE(ucol); 
00230         SUPERLU_FREE(lsub); 
00231         SUPERLU_FREE(usub);
00232         } else {
00233         suser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, HEAD);
00234         }
00235         nzlumax /= 2;
00236         nzumax /= 2;
00237         nzlmax /= 2;
00238         if ( nzlumax < annz ) {
00239         printf("Not enough memory to perform factorization.\n");
00240         return (smemory_usage(nzlmax, nzumax, nzlumax, n) + n);
00241         }
00242         lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
00243         ucol  = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu );
00244         lsub  = (int *)    sexpand( &nzlmax, LSUB, 0, 0, Glu );
00245         usub  = (int *)    sexpand( &nzumax, USUB, 0, 1, Glu );
00246     }
00247     
00248     } else {
00249     /* fact == SamePattern_SameRowPerm */
00250     Lstore   = L->Store;
00251     Ustore   = U->Store;
00252     xsup     = Lstore->sup_to_col;
00253     supno    = Lstore->col_to_sup;
00254     xlsub    = Lstore->rowind_colptr;
00255     xlusup   = Lstore->nzval_colptr;
00256     xusub    = Ustore->colptr;
00257     nzlmax   = Glu->nzlmax;    /* max from previous factorization */
00258     nzumax   = Glu->nzumax;
00259     nzlumax  = Glu->nzlumax;
00260     
00261     if ( lwork == -1 ) {
00262         return ( GluIntArray(n) * iword + TempSpace(m, panel_size)
00263             + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n );
00264         } else if ( lwork == 0 ) {
00265         Glu->MemModel = SYSTEM;
00266     } else {
00267         Glu->MemModel = USER;
00268         stack.top2 = (lwork/4)*4; /* must be word-addressable */
00269         stack.size = stack.top2;
00270     }
00271     
00272     lsub  = expanders[LSUB].mem  = Lstore->rowind;
00273     lusup = expanders[LUSUP].mem = Lstore->nzval;
00274     usub  = expanders[USUB].mem  = Ustore->rowind;
00275     ucol  = expanders[UCOL].mem  = Ustore->nzval;;
00276     expanders[LSUB].size         = nzlmax;
00277     expanders[LUSUP].size        = nzlumax;
00278     expanders[USUB].size         = nzumax;
00279     expanders[UCOL].size         = nzumax;  
00280     }
00281 
00282     Glu->xsup    = xsup;
00283     Glu->supno   = supno;
00284     Glu->lsub    = lsub;
00285     Glu->xlsub   = xlsub;
00286     Glu->lusup   = lusup;
00287     Glu->xlusup  = xlusup;
00288     Glu->ucol    = ucol;
00289     Glu->usub    = usub;
00290     Glu->xusub   = xusub;
00291     Glu->nzlmax  = nzlmax;
00292     Glu->nzumax  = nzumax;
00293     Glu->nzlumax = nzlumax;
00294     
00295     info = sLUWorkInit(m, n, panel_size, iwork, dwork, Glu->MemModel);
00296     if ( info )
00297     return ( info + smemory_usage(nzlmax, nzumax, nzlumax, n) + n);
00298     
00299     ++no_expand;
00300     return 0;
00301     
00302 } /* sLUMemInit */
00303 
00304 /* Allocate known working storage. Returns 0 if success, otherwise
00305    returns the number of bytes allocated so far when failure occurred. */
00306 int
00307 sLUWorkInit(int m, int n, int panel_size, int **iworkptr, 
00308             float **dworkptr, LU_space_t MemModel)
00309 {
00310     int    isize, dsize, extra;
00311     float *old_ptr;
00312     int    maxsuper = sp_ienv(3),
00313            rowblk   = sp_ienv(4);
00314 
00315     isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int);
00316     dsize = (m * panel_size +
00317          NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(float);
00318     
00319     if ( MemModel == SYSTEM ) 
00320     *iworkptr = (int *) intCalloc(isize/sizeof(int));
00321     else
00322     *iworkptr = (int *) suser_malloc(isize, TAIL);
00323     if ( ! *iworkptr ) {
00324     fprintf(stderr, "sLUWorkInit: malloc fails for local iworkptr[]\n");
00325     return (isize + n);
00326     }
00327 
00328     if ( MemModel == SYSTEM )
00329     *dworkptr = (float *) SUPERLU_MALLOC(dsize);
00330     else {
00331     *dworkptr = (float *) suser_malloc(dsize, TAIL);
00332     if ( NotDoubleAlign(*dworkptr) ) {
00333         old_ptr = *dworkptr;
00334         *dworkptr = (float*) DoubleAlign(*dworkptr);
00335         *dworkptr = (float*) ((double*)*dworkptr - 1);
00336         extra = (char*)old_ptr - (char*)*dworkptr;
00337 #ifdef DEBUG        
00338         printf("sLUWorkInit: not aligned, extra %d\n", extra);
00339 #endif      
00340         stack.top2 -= extra;
00341         stack.used += extra;
00342     }
00343     }
00344     if ( ! *dworkptr ) {
00345     fprintf(stderr, "malloc fails for local dworkptr[].");
00346     return (isize + dsize + n);
00347     }
00348     
00349     return 0;
00350 }
00351 
00352 
00353 /*
00354  * Set up pointers for real working arrays.
00355  */
00356 void
00357 sSetRWork(int m, int panel_size, float *dworkptr,
00358      float **dense, float **tempv)
00359 {
00360     float zero = 0.0;
00361 
00362     int maxsuper = sp_ienv(3),
00363         rowblk   = sp_ienv(4);
00364     *dense = dworkptr;
00365     *tempv = *dense + panel_size*m;
00366     sfill (*dense, m * panel_size, zero);
00367     sfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero);     
00368 }
00369     
00370 /*
00371  * Free the working storage used by factor routines.
00372  */
00373 void sLUWorkFree(int *iwork, float *dwork, GlobalLU_t *Glu)
00374 {
00375     if ( Glu->MemModel == SYSTEM ) {
00376     SUPERLU_FREE (iwork);
00377     SUPERLU_FREE (dwork);
00378     } else {
00379     stack.used -= (stack.size - stack.top2);
00380     stack.top2 = stack.size;
00381 /*  sStackCompress(Glu);  */
00382     }
00383     
00384     SUPERLU_FREE (expanders);   
00385     expanders = 0;
00386 }
00387 
00388 /* Expand the data structures for L and U during the factorization.
00389  * Return value:   0 - successful return
00390  *               > 0 - number of bytes allocated when run out of space
00391  */
00392 int
00393 sLUMemXpand(int jcol,
00394        int next,          /* number of elements currently in the factors */
00395        MemType mem_type,  /* which type of memory to expand  */
00396        int *maxlen,       /* modified - maximum length of a data structure */
00397        GlobalLU_t *Glu    /* modified - global LU data structures */
00398        )
00399 {
00400     void   *new_mem;
00401     
00402 #ifdef DEBUG    
00403     printf("sLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n",
00404        jcol, next, *maxlen, mem_type);
00405 #endif    
00406 
00407     if (mem_type == USUB) 
00408         new_mem = sexpand(maxlen, mem_type, next, 1, Glu);
00409     else
00410     new_mem = sexpand(maxlen, mem_type, next, 0, Glu);
00411     
00412     if ( !new_mem ) {
00413     int    nzlmax  = Glu->nzlmax;
00414     int    nzumax  = Glu->nzumax;
00415     int    nzlumax = Glu->nzlumax;
00416         fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol);
00417         return (smemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n);
00418     }
00419 
00420     switch ( mem_type ) {
00421       case LUSUP:
00422     Glu->lusup   = (float *) new_mem;
00423     Glu->nzlumax = *maxlen;
00424     break;
00425       case UCOL:
00426     Glu->ucol   = (float *) new_mem;
00427     Glu->nzumax = *maxlen;
00428     break;
00429       case LSUB:
00430     Glu->lsub   = (int *) new_mem;
00431     Glu->nzlmax = *maxlen;
00432     break;
00433       case USUB:
00434     Glu->usub   = (int *) new_mem;
00435     Glu->nzumax = *maxlen;
00436     break;
00437     }
00438     
00439     return 0;
00440     
00441 }
00442 
00443 
00444 
00445 void
00446 copy_mem_float(int howmany, void *old, void *new)
00447 {
00448     register int i;
00449     float *dold = old;
00450     float *dnew = new;
00451     for (i = 0; i < howmany; i++) dnew[i] = dold[i];
00452 }
00453 
00454 /*
00455  * Expand the existing storage to accommodate more fill-ins.
00456  */
00457 void
00458 *sexpand (
00459      int *prev_len,   /* length used from previous call */
00460      MemType type,    /* which part of the memory to expand */
00461      int len_to_copy, /* size of the memory to be copied to new store */
00462      int keep_prev,   /* = 1: use prev_len;
00463                  = 0: compute new_len to expand */
00464      GlobalLU_t *Glu  /* modified - global LU data structures */
00465     )
00466 {
00467     float    EXPAND = 1.5;
00468     float    alpha;
00469     void     *new_mem, *old_mem;
00470     int      new_len, tries, lword, extra, bytes_to_copy;
00471 
00472     alpha = EXPAND;
00473 
00474     if ( no_expand == 0 || keep_prev ) /* First time allocate requested */
00475         new_len = *prev_len;
00476     else {
00477     new_len = alpha * *prev_len;
00478     }
00479     
00480     if ( type == LSUB || type == USUB ) lword = sizeof(int);
00481     else lword = sizeof(float);
00482 
00483     if ( Glu->MemModel == SYSTEM ) {
00484     new_mem = (void *) SUPERLU_MALLOC(new_len * lword);
00485 /*  new_mem = (void *) calloc(new_len, lword); */
00486     if ( no_expand != 0 ) {
00487         tries = 0;
00488         if ( keep_prev ) {
00489         if ( !new_mem ) return (NULL);
00490         } else {
00491         while ( !new_mem ) {
00492             if ( ++tries > 10 ) return (NULL);
00493             alpha = Reduce(alpha);
00494             new_len = alpha * *prev_len;
00495             new_mem = (void *) SUPERLU_MALLOC(new_len * lword); 
00496 /*          new_mem = (void *) calloc(new_len, lword); */
00497         }
00498         }
00499         if ( type == LSUB || type == USUB ) {
00500         copy_mem_int(len_to_copy, expanders[type].mem, new_mem);
00501         } else {
00502         copy_mem_float(len_to_copy, expanders[type].mem, new_mem);
00503         }
00504         SUPERLU_FREE (expanders[type].mem);
00505     }
00506     expanders[type].mem = (void *) new_mem;
00507     
00508     } else { /* MemModel == USER */
00509     if ( no_expand == 0 ) {
00510         new_mem = suser_malloc(new_len * lword, HEAD);
00511         if ( NotDoubleAlign(new_mem) &&
00512         (type == LUSUP || type == UCOL) ) {
00513         old_mem = new_mem;
00514         new_mem = (void *)DoubleAlign(new_mem);
00515         extra = (char*)new_mem - (char*)old_mem;
00516 #ifdef DEBUG        
00517         printf("expand(): not aligned, extra %d\n", extra);
00518 #endif      
00519         stack.top1 += extra;
00520         stack.used += extra;
00521         }
00522         expanders[type].mem = (void *) new_mem;
00523     }
00524     else {
00525         tries = 0;
00526         extra = (new_len - *prev_len) * lword;
00527         if ( keep_prev ) {
00528         if ( StackFull(extra) ) return (NULL);
00529         } else {
00530         while ( StackFull(extra) ) {
00531             if ( ++tries > 10 ) return (NULL);
00532             alpha = Reduce(alpha);
00533             new_len = alpha * *prev_len;
00534             extra = (new_len - *prev_len) * lword;      
00535         }
00536         }
00537 
00538         if ( type != USUB ) {
00539         new_mem = (void*)((char*)expanders[type + 1].mem + extra);
00540         bytes_to_copy = (char*)stack.array + stack.top1
00541             - (char*)expanders[type + 1].mem;
00542         user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy);
00543 
00544         if ( type < USUB ) {
00545             Glu->usub = expanders[USUB].mem =
00546             (void*)((char*)expanders[USUB].mem + extra);
00547         }
00548         if ( type < LSUB ) {
00549             Glu->lsub = expanders[LSUB].mem =
00550             (void*)((char*)expanders[LSUB].mem + extra);
00551         }
00552         if ( type < UCOL ) {
00553             Glu->ucol = expanders[UCOL].mem =
00554             (void*)((char*)expanders[UCOL].mem + extra);
00555         }
00556         stack.top1 += extra;
00557         stack.used += extra;
00558         if ( type == UCOL ) {
00559             stack.top1 += extra;   /* Add same amount for USUB */
00560             stack.used += extra;
00561         }
00562         
00563         } /* if ... */
00564 
00565     } /* else ... */
00566     }
00567 
00568     expanders[type].size = new_len;
00569     *prev_len = new_len;
00570     if ( no_expand ) ++no_expand;
00571     
00572     return (void *) expanders[type].mem;
00573     
00574 } /* sexpand */
00575 
00576 
00577 /*
00578  * Compress the work[] array to remove fragmentation.
00579  */
00580 void
00581 sStackCompress(GlobalLU_t *Glu)
00582 {
00583     register int iword, dword, ndim;
00584     char    *last, *fragment;
00585     int      *ifrom, *ito;
00586     float   *dfrom, *dto;
00587     int      *xlsub, *lsub, *xusub, *usub, *xlusup;
00588     float   *ucol, *lusup;
00589     
00590     iword = sizeof(int);
00591     dword = sizeof(float);
00592     ndim = Glu->n;
00593 
00594     xlsub  = Glu->xlsub;
00595     lsub   = Glu->lsub;
00596     xusub  = Glu->xusub;
00597     usub   = Glu->usub;
00598     xlusup = Glu->xlusup;
00599     ucol   = Glu->ucol;
00600     lusup  = Glu->lusup;
00601     
00602     dfrom = ucol;
00603     dto = (float *)((char*)lusup + xlusup[ndim] * dword);
00604     copy_mem_float(xusub[ndim], dfrom, dto);
00605     ucol = dto;
00606 
00607     ifrom = lsub;
00608     ito = (int *) ((char*)ucol + xusub[ndim] * iword);
00609     copy_mem_int(xlsub[ndim], ifrom, ito);
00610     lsub = ito;
00611     
00612     ifrom = usub;
00613     ito = (int *) ((char*)lsub + xlsub[ndim] * iword);
00614     copy_mem_int(xusub[ndim], ifrom, ito);
00615     usub = ito;
00616     
00617     last = (char*)usub + xusub[ndim] * iword;
00618     fragment = (char*) (((char*)stack.array + stack.top1) - last);
00619     stack.used -= (intptr_t) fragment;
00620     stack.top1 -= (intptr_t) fragment;
00621 
00622     Glu->ucol = ucol;
00623     Glu->lsub = lsub;
00624     Glu->usub = usub;
00625     
00626 #ifdef DEBUG
00627     printf("sStackCompress: fragment %d\n", (int)*fragment);
00628     /* for (last = 0; last < ndim; ++last)
00629     print_lu_col("After compress:", last, 0);*/
00630 #endif    
00631     
00632 }
00633 
00634 /*
00635  * Allocate storage for original matrix A
00636  */
00637 void
00638 sallocateA(int n, int nnz, float **a, int **asub, int **xa)
00639 {
00640     *a    = (float *) floatMalloc(nnz);
00641     *asub = (int *) intMalloc(nnz);
00642     *xa   = (int *) intMalloc(n+1);
00643 }
00644 
00645 
00646 float *floatMalloc(int n)
00647 {
00648     float *buf;
00649     buf = (float *) SUPERLU_MALLOC(n * sizeof(float)); 
00650     if ( !buf ) {
00651     ABORT("SUPERLU_MALLOC failed for buf in floatMalloc()\n");
00652     }
00653     return (buf);
00654 }
00655 
00656 float *floatCalloc(int n)
00657 {
00658     float *buf;
00659     register int i;
00660     float zero = 0.0;
00661     buf = (float *) SUPERLU_MALLOC(n * sizeof(float));
00662     if ( !buf ) {
00663     ABORT("SUPERLU_MALLOC failed for buf in floatCalloc()\n");
00664     }
00665     for (i = 0; i < n; ++i) buf[i] = zero;
00666     return (buf);
00667 }
00668 
00669 
00670 int smemory_usage(const int nzlmax, const int nzumax, 
00671           const int nzlumax, const int n)
00672 {
00673     register int iword, dword;
00674 
00675     iword   = sizeof(int);
00676     dword   = sizeof(float);
00677     
00678     return (10 * n * iword +
00679         nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword);
00680 
00681 }