~ubuntu-branches/ubuntu/raring/python-scipy/raring-proposed

« back to all changes in this revision

Viewing changes to Lib/sparse/SuperLU/SRC/zmemory.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-07 14:12:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070107141212-mm0ebkh5b37hcpzn
* Remove build dependency on python-numpy-dev.
* python-scipy: Depend on python-numpy instead of python-numpy-dev.
* Package builds on other archs than i386. Closes: #402783.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/*
3
 
 * -- SuperLU routine (version 3.0) --
4
 
 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
5
 
 * and Lawrence Berkeley National Lab.
6
 
 * October 15, 2003
7
 
 *
8
 
 */
9
 
#include "zsp_defs.h"
10
 
 
11
 
/* Constants */
12
 
#define NO_MEMTYPE  4      /* 0: lusup;
13
 
                              1: ucol;
14
 
                              2: lsub;
15
 
                              3: usub */
16
 
#define GluIntArray(n)   (5 * (n) + 5)
17
 
 
18
 
/* Internal prototypes */
19
 
void  *zexpand (int *, MemType,int, int, GlobalLU_t *);
20
 
int   zLUWorkInit (int, int, int, int **, doublecomplex **, LU_space_t);
21
 
void  copy_mem_doublecomplex (int, void *, void *);
22
 
void  zStackCompress (GlobalLU_t *);
23
 
void  zSetupSpace (void *, int, LU_space_t *);
24
 
void  *zuser_malloc (int, int);
25
 
void  zuser_free (int, int);
26
 
 
27
 
/* External prototypes (in memory.c - prec-indep) */
28
 
extern void    copy_mem_int    (int, void *, void *);
29
 
extern void    user_bcopy      (char *, char *, int);
30
 
 
31
 
/* Headers for 4 types of dynamatically managed memory */
32
 
typedef struct e_node {
33
 
    int size;      /* length of the memory that has been used */
34
 
    void *mem;     /* pointer to the new malloc'd store */
35
 
} ExpHeader;
36
 
 
37
 
typedef struct {
38
 
    int  size;
39
 
    int  used;
40
 
    int  top1;  /* grow upward, relative to &array[0] */
41
 
    int  top2;  /* grow downward */
42
 
    void *array;
43
 
} LU_stack_t;
44
 
 
45
 
/* Variables local to this file */
46
 
static ExpHeader *expanders = 0; /* Array of pointers to 4 types of memory */
47
 
static LU_stack_t stack;
48
 
static int no_expand;
49
 
 
50
 
/* Macros to manipulate stack */
51
 
#define StackFull(x)         ( x + stack.used >= stack.size )
52
 
#define NotDoubleAlign(addr) ( (long int)addr & 7 )
53
 
#define DoubleAlign(addr)    ( ((long int)addr + 7) & ~7L )
54
 
#define TempSpace(m, w)      ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \
55
 
                              (w + 1) * m * sizeof(doublecomplex) )
56
 
#define Reduce(alpha)        ((alpha + 1) / 2)  /* i.e. (alpha-1)/2 + 1 */
57
 
 
58
 
 
59
 
 
60
 
 
61
 
/*
62
 
 * Setup the memory model to be used for factorization.
63
 
 *    lwork = 0: use system malloc;
64
 
 *    lwork > 0: use user-supplied work[] space.
65
 
 */
66
 
void zSetupSpace(void *work, int lwork, LU_space_t *MemModel)
67
 
{
68
 
    if ( lwork == 0 ) {
69
 
        *MemModel = SYSTEM; /* malloc/free */
70
 
    } else if ( lwork > 0 ) {
71
 
        *MemModel = USER;   /* user provided space */
72
 
        stack.used = 0;
73
 
        stack.top1 = 0;
74
 
        stack.top2 = (lwork/4)*4; /* must be word addressable */
75
 
        stack.size = stack.top2;
76
 
        stack.array = (void *) work;
77
 
    }
78
 
}
79
 
 
80
 
 
81
 
 
82
 
void *zuser_malloc(int bytes, int which_end)
83
 
{
84
 
    void *buf;
85
 
    
86
 
    if ( StackFull(bytes) ) return (NULL);
87
 
 
88
 
    if ( which_end == HEAD ) {
89
 
        buf = (char*) stack.array + stack.top1;
90
 
        stack.top1 += bytes;
91
 
    } else {
92
 
        stack.top2 -= bytes;
93
 
        buf = (char*) stack.array + stack.top2;
94
 
    }
95
 
    
96
 
    stack.used += bytes;
97
 
    return buf;
98
 
}
99
 
 
100
 
 
101
 
void zuser_free(int bytes, int which_end)
102
 
{
103
 
    if ( which_end == HEAD ) {
104
 
        stack.top1 -= bytes;
105
 
    } else {
106
 
        stack.top2 += bytes;
107
 
    }
108
 
    stack.used -= bytes;
109
 
}
110
 
 
111
 
 
112
 
 
113
 
/*
114
 
 * mem_usage consists of the following fields:
115
 
 *    - for_lu (float)
116
 
 *      The amount of space used in bytes for the L\U data structures.
117
 
 *    - total_needed (float)
118
 
 *      The amount of space needed in bytes to perform factorization.
119
 
 *    - expansions (int)
120
 
 *      Number of memory expansions during the LU factorization.
121
 
 */
122
 
int zQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage)
123
 
{
124
 
    SCformat *Lstore;
125
 
    NCformat *Ustore;
126
 
    register int n, iword, dword, panel_size = sp_ienv(1);
127
 
 
128
 
    Lstore = L->Store;
129
 
    Ustore = U->Store;
130
 
    n = L->ncol;
131
 
    iword = sizeof(int);
132
 
    dword = sizeof(doublecomplex);
133
 
 
134
 
    /* For LU factors */
135
 
    mem_usage->for_lu = (float)( (4*n + 3) * iword + Lstore->nzval_colptr[n] *
136
 
                                 dword + Lstore->rowind_colptr[n] * iword );
137
 
    mem_usage->for_lu += (float)( (n + 1) * iword +
138
 
                                 Ustore->colptr[n] * (dword + iword) );
139
 
 
140
 
    /* Working storage to support factorization */
141
 
    mem_usage->total_needed = mem_usage->for_lu +
142
 
        (float)( (2 * panel_size + 4 + NO_MARKER) * n * iword +
143
 
                (panel_size + 1) * n * dword );
144
 
 
145
 
    mem_usage->expansions = --no_expand;
146
 
 
147
 
    return 0;
148
 
} /* zQuerySpace */
149
 
 
150
 
/*
151
 
 * Allocate storage for the data structures common to all factor routines.
152
 
 * For those unpredictable size, make a guess as FILL * nnz(A).
153
 
 * Return value:
154
 
 *     If lwork = -1, return the estimated amount of space required, plus n;
155
 
 *     otherwise, return the amount of space actually allocated when
156
 
 *     memory allocation failure occurred.
157
 
 */
158
 
int
159
 
zLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
160
 
          int panel_size, SuperMatrix *L, SuperMatrix *U, GlobalLU_t *Glu,
161
 
          int **iwork, doublecomplex **dwork)
162
 
{
163
 
    int      info, iword, dword;
164
 
    SCformat *Lstore;
165
 
    NCformat *Ustore;
166
 
    int      *xsup, *supno;
167
 
    int      *lsub, *xlsub;
168
 
    doublecomplex   *lusup;
169
 
    int      *xlusup;
170
 
    doublecomplex   *ucol;
171
 
    int      *usub, *xusub;
172
 
    int      nzlmax, nzumax, nzlumax;
173
 
    int      FILL = sp_ienv(6);
174
 
    
175
 
    Glu->n    = n;
176
 
    no_expand = 0;
177
 
    iword     = sizeof(int);
178
 
    dword     = sizeof(doublecomplex);
179
 
 
180
 
    if ( !expanders )   
181
 
        expanders = (ExpHeader*)SUPERLU_MALLOC(NO_MEMTYPE * sizeof(ExpHeader));
182
 
    if ( !expanders ) ABORT("SUPERLU_MALLOC fails for expanders");
183
 
    
184
 
    if ( fact != SamePattern_SameRowPerm ) {
185
 
        /* Guess for L\U factors */
186
 
        nzumax = nzlumax = FILL * annz;
187
 
        nzlmax = SUPERLU_MAX(1, FILL/4.) * annz;
188
 
 
189
 
        if ( lwork == -1 ) {
190
 
            return ( GluIntArray(n) * iword + TempSpace(m, panel_size)
191
 
                    + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n );
192
 
        } else {
193
 
            zSetupSpace(work, lwork, &Glu->MemModel);
194
 
        }
195
 
        
196
 
#ifdef DEBUG               
197
 
        printf("zLUMemInit() called: annz %d, MemModel %d\n", 
198
 
                annz, Glu->MemModel);
199
 
#endif  
200
 
        
201
 
        /* Integer pointers for L\U factors */
202
 
        if ( Glu->MemModel == SYSTEM ) {
203
 
            xsup   = intMalloc(n+1);
204
 
            supno  = intMalloc(n+1);
205
 
            xlsub  = intMalloc(n+1);
206
 
            xlusup = intMalloc(n+1);
207
 
            xusub  = intMalloc(n+1);
208
 
        } else {
209
 
            xsup   = (int *)zuser_malloc((n+1) * iword, HEAD);
210
 
            supno  = (int *)zuser_malloc((n+1) * iword, HEAD);
211
 
            xlsub  = (int *)zuser_malloc((n+1) * iword, HEAD);
212
 
            xlusup = (int *)zuser_malloc((n+1) * iword, HEAD);
213
 
            xusub  = (int *)zuser_malloc((n+1) * iword, HEAD);
214
 
        }
215
 
 
216
 
        lusup = (doublecomplex *) zexpand( &nzlumax, LUSUP, 0, 0, Glu );
217
 
        ucol  = (doublecomplex *) zexpand( &nzumax, UCOL, 0, 0, Glu );
218
 
        lsub  = (int *)    zexpand( &nzlmax, LSUB, 0, 0, Glu );
219
 
        usub  = (int *)    zexpand( &nzumax, USUB, 0, 1, Glu );
220
 
 
221
 
        while ( !lusup || !ucol || !lsub || !usub ) {
222
 
            if ( Glu->MemModel == SYSTEM ) {
223
 
                SUPERLU_FREE(lusup); 
224
 
                SUPERLU_FREE(ucol); 
225
 
                SUPERLU_FREE(lsub); 
226
 
                SUPERLU_FREE(usub);
227
 
            } else {
228
 
                zuser_free((nzlumax+nzumax)*dword+(nzlmax+nzumax)*iword, HEAD);
229
 
            }
230
 
            nzlumax /= 2;
231
 
            nzumax /= 2;
232
 
            nzlmax /= 2;
233
 
            if ( nzlumax < annz ) {
234
 
                printf("Not enough memory to perform factorization.\n");
235
 
                return (zmemory_usage(nzlmax, nzumax, nzlumax, n) + n);
236
 
            }
237
 
            lusup = (doublecomplex *) zexpand( &nzlumax, LUSUP, 0, 0, Glu );
238
 
            ucol  = (doublecomplex *) zexpand( &nzumax, UCOL, 0, 0, Glu );
239
 
            lsub  = (int *)    zexpand( &nzlmax, LSUB, 0, 0, Glu );
240
 
            usub  = (int *)    zexpand( &nzumax, USUB, 0, 1, Glu );
241
 
        }
242
 
        
243
 
    } else {
244
 
        /* fact == SamePattern_SameRowPerm */
245
 
        Lstore   = L->Store;
246
 
        Ustore   = U->Store;
247
 
        xsup     = Lstore->sup_to_col;
248
 
        supno    = Lstore->col_to_sup;
249
 
        xlsub    = Lstore->rowind_colptr;
250
 
        xlusup   = Lstore->nzval_colptr;
251
 
        xusub    = Ustore->colptr;
252
 
        nzlmax   = Glu->nzlmax;    /* max from previous factorization */
253
 
        nzumax   = Glu->nzumax;
254
 
        nzlumax  = Glu->nzlumax;
255
 
        
256
 
        if ( lwork == -1 ) {
257
 
            return ( GluIntArray(n) * iword + TempSpace(m, panel_size)
258
 
                    + (nzlmax+nzumax)*iword + (nzlumax+nzumax)*dword + n );
259
 
        } else if ( lwork == 0 ) {
260
 
            Glu->MemModel = SYSTEM;
261
 
        } else {
262
 
            Glu->MemModel = USER;
263
 
            stack.top2 = (lwork/4)*4; /* must be word-addressable */
264
 
            stack.size = stack.top2;
265
 
        }
266
 
        
267
 
        lsub  = expanders[LSUB].mem  = Lstore->rowind;
268
 
        lusup = expanders[LUSUP].mem = Lstore->nzval;
269
 
        usub  = expanders[USUB].mem  = Ustore->rowind;
270
 
        ucol  = expanders[UCOL].mem  = Ustore->nzval;;
271
 
        expanders[LSUB].size         = nzlmax;
272
 
        expanders[LUSUP].size        = nzlumax;
273
 
        expanders[USUB].size         = nzumax;
274
 
        expanders[UCOL].size         = nzumax;  
275
 
    }
276
 
 
277
 
    Glu->xsup    = xsup;
278
 
    Glu->supno   = supno;
279
 
    Glu->lsub    = lsub;
280
 
    Glu->xlsub   = xlsub;
281
 
    Glu->lusup   = lusup;
282
 
    Glu->xlusup  = xlusup;
283
 
    Glu->ucol    = ucol;
284
 
    Glu->usub    = usub;
285
 
    Glu->xusub   = xusub;
286
 
    Glu->nzlmax  = nzlmax;
287
 
    Glu->nzumax  = nzumax;
288
 
    Glu->nzlumax = nzlumax;
289
 
    
290
 
    info = zLUWorkInit(m, n, panel_size, iwork, dwork, Glu->MemModel);
291
 
    if ( info )
292
 
        return ( info + zmemory_usage(nzlmax, nzumax, nzlumax, n) + n);
293
 
    
294
 
    ++no_expand;
295
 
    return 0;
296
 
    
297
 
} /* zLUMemInit */
298
 
 
299
 
/* Allocate known working storage. Returns 0 if success, otherwise
300
 
   returns the number of bytes allocated so far when failure occurred. */
301
 
int
302
 
zLUWorkInit(int m, int n, int panel_size, int **iworkptr, 
303
 
            doublecomplex **dworkptr, LU_space_t MemModel)
304
 
{
305
 
    int    isize, dsize, extra;
306
 
    doublecomplex *old_ptr;
307
 
    int    maxsuper = sp_ienv(3),
308
 
           rowblk   = sp_ienv(4);
309
 
 
310
 
    isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int);
311
 
    dsize = (m * panel_size +
312
 
             NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(doublecomplex);
313
 
    
314
 
    if ( MemModel == SYSTEM ) 
315
 
        *iworkptr = (int *) intCalloc(isize/sizeof(int));
316
 
    else
317
 
        *iworkptr = (int *) zuser_malloc(isize, TAIL);
318
 
    if ( ! *iworkptr ) {
319
 
        fprintf(stderr, "zLUWorkInit: malloc fails for local iworkptr[]\n");
320
 
        return (isize + n);
321
 
    }
322
 
 
323
 
    if ( MemModel == SYSTEM )
324
 
        *dworkptr = (doublecomplex *) SUPERLU_MALLOC(dsize);
325
 
    else {
326
 
        *dworkptr = (doublecomplex *) zuser_malloc(dsize, TAIL);
327
 
        if ( NotDoubleAlign(*dworkptr) ) {
328
 
            old_ptr = *dworkptr;
329
 
            *dworkptr = (doublecomplex*) DoubleAlign(*dworkptr);
330
 
            *dworkptr = (doublecomplex*) ((double*)*dworkptr - 1);
331
 
            extra = (char*)old_ptr - (char*)*dworkptr;
332
 
#ifdef DEBUG        
333
 
            printf("zLUWorkInit: not aligned, extra %d\n", extra);
334
 
#endif      
335
 
            stack.top2 -= extra;
336
 
            stack.used += extra;
337
 
        }
338
 
    }
339
 
    if ( ! *dworkptr ) {
340
 
        fprintf(stderr, "malloc fails for local dworkptr[].");
341
 
        return (isize + dsize + n);
342
 
    }
343
 
        
344
 
    return 0;
345
 
}
346
 
 
347
 
 
348
 
/*
349
 
 * Set up pointers for real working arrays.
350
 
 */
351
 
void
352
 
zSetRWork(int m, int panel_size, doublecomplex *dworkptr,
353
 
         doublecomplex **dense, doublecomplex **tempv)
354
 
{
355
 
    doublecomplex zero = {0.0, 0.0};
356
 
 
357
 
    int maxsuper = sp_ienv(3),
358
 
        rowblk   = sp_ienv(4);
359
 
    *dense = dworkptr;
360
 
    *tempv = *dense + panel_size*m;
361
 
    zfill (*dense, m * panel_size, zero);
362
 
    zfill (*tempv, NUM_TEMPV(m,panel_size,maxsuper,rowblk), zero);     
363
 
}
364
 
        
365
 
/*
366
 
 * Free the working storage used by factor routines.
367
 
 */
368
 
void zLUWorkFree(int *iwork, doublecomplex *dwork, GlobalLU_t *Glu)
369
 
{
370
 
    if ( Glu->MemModel == SYSTEM ) {
371
 
        SUPERLU_FREE (iwork);
372
 
        SUPERLU_FREE (dwork);
373
 
    } else {
374
 
        stack.used -= (stack.size - stack.top2);
375
 
        stack.top2 = stack.size;
376
 
/*      zStackCompress(Glu);  */
377
 
    }
378
 
    
379
 
    SUPERLU_FREE (expanders);   
380
 
    expanders = 0;
381
 
}
382
 
 
383
 
/* Expand the data structures for L and U during the factorization.
384
 
 * Return value:   0 - successful return
385
 
 *               > 0 - number of bytes allocated when run out of space
386
 
 */
387
 
int
388
 
zLUMemXpand(int jcol,
389
 
           int next,          /* number of elements currently in the factors */
390
 
           MemType mem_type,  /* which type of memory to expand  */
391
 
           int *maxlen,       /* modified - maximum length of a data structure */
392
 
           GlobalLU_t *Glu    /* modified - global LU data structures */
393
 
           )
394
 
{
395
 
    void   *new_mem;
396
 
    
397
 
#ifdef DEBUG    
398
 
    printf("zLUMemXpand(): jcol %d, next %d, maxlen %d, MemType %d\n",
399
 
           jcol, next, *maxlen, mem_type);
400
 
#endif    
401
 
 
402
 
    if (mem_type == USUB) 
403
 
        new_mem = zexpand(maxlen, mem_type, next, 1, Glu);
404
 
    else
405
 
        new_mem = zexpand(maxlen, mem_type, next, 0, Glu);
406
 
    
407
 
    if ( !new_mem ) {
408
 
        int    nzlmax  = Glu->nzlmax;
409
 
        int    nzumax  = Glu->nzumax;
410
 
        int    nzlumax = Glu->nzlumax;
411
 
        fprintf(stderr, "Can't expand MemType %d: jcol %d\n", mem_type, jcol);
412
 
        return (zmemory_usage(nzlmax, nzumax, nzlumax, Glu->n) + Glu->n);
413
 
    }
414
 
 
415
 
    switch ( mem_type ) {
416
 
      case LUSUP:
417
 
        Glu->lusup   = (doublecomplex *) new_mem;
418
 
        Glu->nzlumax = *maxlen;
419
 
        break;
420
 
      case UCOL:
421
 
        Glu->ucol   = (doublecomplex *) new_mem;
422
 
        Glu->nzumax = *maxlen;
423
 
        break;
424
 
      case LSUB:
425
 
        Glu->lsub   = (int *) new_mem;
426
 
        Glu->nzlmax = *maxlen;
427
 
        break;
428
 
      case USUB:
429
 
        Glu->usub   = (int *) new_mem;
430
 
        Glu->nzumax = *maxlen;
431
 
        break;
432
 
    }
433
 
    
434
 
    return 0;
435
 
    
436
 
}
437
 
 
438
 
 
439
 
 
440
 
void
441
 
copy_mem_doublecomplex(int howmany, void *old, void *new)
442
 
{
443
 
    register int i;
444
 
    doublecomplex *dold = old;
445
 
    doublecomplex *dnew = new;
446
 
    for (i = 0; i < howmany; i++) dnew[i] = dold[i];
447
 
}
448
 
 
449
 
/*
450
 
 * Expand the existing storage to accommodate more fill-ins.
451
 
 */
452
 
void
453
 
*zexpand (
454
 
         int *prev_len,   /* length used from previous call */
455
 
         MemType type,    /* which part of the memory to expand */
456
 
         int len_to_copy, /* size of the memory to be copied to new store */
457
 
         int keep_prev,   /* = 1: use prev_len;
458
 
                             = 0: compute new_len to expand */
459
 
         GlobalLU_t *Glu  /* modified - global LU data structures */
460
 
        )
461
 
{
462
 
    float    EXPAND = 1.5;
463
 
    float    alpha;
464
 
    void     *new_mem, *old_mem;
465
 
    int      new_len, tries, lword, extra, bytes_to_copy;
466
 
 
467
 
    alpha = EXPAND;
468
 
 
469
 
    if ( no_expand == 0 || keep_prev ) /* First time allocate requested */
470
 
        new_len = *prev_len;
471
 
    else {
472
 
        new_len = alpha * *prev_len;
473
 
    }
474
 
    
475
 
    if ( type == LSUB || type == USUB ) lword = sizeof(int);
476
 
    else lword = sizeof(doublecomplex);
477
 
 
478
 
    if ( Glu->MemModel == SYSTEM ) {
479
 
        new_mem = (void *) SUPERLU_MALLOC(new_len * lword);
480
 
/*      new_mem = (void *) calloc(new_len, lword); */
481
 
        if ( no_expand != 0 ) {
482
 
            tries = 0;
483
 
            if ( keep_prev ) {
484
 
                if ( !new_mem ) return (NULL);
485
 
            } else {
486
 
                while ( !new_mem ) {
487
 
                    if ( ++tries > 10 ) return (NULL);
488
 
                    alpha = Reduce(alpha);
489
 
                    new_len = alpha * *prev_len;
490
 
                    new_mem = (void *) SUPERLU_MALLOC(new_len * lword); 
491
 
/*                  new_mem = (void *) calloc(new_len, lword); */
492
 
                }
493
 
            }
494
 
            if ( type == LSUB || type == USUB ) {
495
 
                copy_mem_int(len_to_copy, expanders[type].mem, new_mem);
496
 
            } else {
497
 
                copy_mem_doublecomplex(len_to_copy, expanders[type].mem, new_mem);
498
 
            }
499
 
            SUPERLU_FREE (expanders[type].mem);
500
 
        }
501
 
        expanders[type].mem = (void *) new_mem;
502
 
        
503
 
    } else { /* MemModel == USER */
504
 
        if ( no_expand == 0 ) {
505
 
            new_mem = zuser_malloc(new_len * lword, HEAD);
506
 
            if ( NotDoubleAlign(new_mem) &&
507
 
                (type == LUSUP || type == UCOL) ) {
508
 
                old_mem = new_mem;
509
 
                new_mem = (void *)DoubleAlign(new_mem);
510
 
                extra = (char*)new_mem - (char*)old_mem;
511
 
#ifdef DEBUG            
512
 
                printf("expand(): not aligned, extra %d\n", extra);
513
 
#endif          
514
 
                stack.top1 += extra;
515
 
                stack.used += extra;
516
 
            }
517
 
            expanders[type].mem = (void *) new_mem;
518
 
        }
519
 
        else {
520
 
            tries = 0;
521
 
            extra = (new_len - *prev_len) * lword;
522
 
            if ( keep_prev ) {
523
 
                if ( StackFull(extra) ) return (NULL);
524
 
            } else {
525
 
                while ( StackFull(extra) ) {
526
 
                    if ( ++tries > 10 ) return (NULL);
527
 
                    alpha = Reduce(alpha);
528
 
                    new_len = alpha * *prev_len;
529
 
                    extra = (new_len - *prev_len) * lword;          
530
 
                }
531
 
            }
532
 
 
533
 
            if ( type != USUB ) {
534
 
                new_mem = (void*)((char*)expanders[type + 1].mem + extra);
535
 
                bytes_to_copy = (char*)stack.array + stack.top1
536
 
                    - (char*)expanders[type + 1].mem;
537
 
                user_bcopy(expanders[type+1].mem, new_mem, bytes_to_copy);
538
 
 
539
 
                if ( type < USUB ) {
540
 
                    Glu->usub = expanders[USUB].mem =
541
 
                        (void*)((char*)expanders[USUB].mem + extra);
542
 
                }
543
 
                if ( type < LSUB ) {
544
 
                    Glu->lsub = expanders[LSUB].mem =
545
 
                        (void*)((char*)expanders[LSUB].mem + extra);
546
 
                }
547
 
                if ( type < UCOL ) {
548
 
                    Glu->ucol = expanders[UCOL].mem =
549
 
                        (void*)((char*)expanders[UCOL].mem + extra);
550
 
                }
551
 
                stack.top1 += extra;
552
 
                stack.used += extra;
553
 
                if ( type == UCOL ) {
554
 
                    stack.top1 += extra;   /* Add same amount for USUB */
555
 
                    stack.used += extra;
556
 
                }
557
 
                
558
 
            } /* if ... */
559
 
 
560
 
        } /* else ... */
561
 
    }
562
 
 
563
 
    expanders[type].size = new_len;
564
 
    *prev_len = new_len;
565
 
    if ( no_expand ) ++no_expand;
566
 
    
567
 
    return (void *) expanders[type].mem;
568
 
    
569
 
} /* zexpand */
570
 
 
571
 
 
572
 
/*
573
 
 * Compress the work[] array to remove fragmentation.
574
 
 */
575
 
void
576
 
zStackCompress(GlobalLU_t *Glu)
577
 
{
578
 
    register int iword, dword, ndim;
579
 
    char    *last, *fragment;
580
 
    int      *ifrom, *ito;
581
 
    doublecomplex   *dfrom, *dto;
582
 
    int      *xlsub, *lsub, *xusub, *usub, *xlusup;
583
 
    doublecomplex   *ucol, *lusup;
584
 
    
585
 
    iword = sizeof(int);
586
 
    dword = sizeof(doublecomplex);
587
 
    ndim = Glu->n;
588
 
 
589
 
    xlsub  = Glu->xlsub;
590
 
    lsub   = Glu->lsub;
591
 
    xusub  = Glu->xusub;
592
 
    usub   = Glu->usub;
593
 
    xlusup = Glu->xlusup;
594
 
    ucol   = Glu->ucol;
595
 
    lusup  = Glu->lusup;
596
 
    
597
 
    dfrom = ucol;
598
 
    dto = (doublecomplex *)((char*)lusup + xlusup[ndim] * dword);
599
 
    copy_mem_doublecomplex(xusub[ndim], dfrom, dto);
600
 
    ucol = dto;
601
 
 
602
 
    ifrom = lsub;
603
 
    ito = (int *) ((char*)ucol + xusub[ndim] * iword);
604
 
    copy_mem_int(xlsub[ndim], ifrom, ito);
605
 
    lsub = ito;
606
 
    
607
 
    ifrom = usub;
608
 
    ito = (int *) ((char*)lsub + xlsub[ndim] * iword);
609
 
    copy_mem_int(xusub[ndim], ifrom, ito);
610
 
    usub = ito;
611
 
    
612
 
    last = (char*)usub + xusub[ndim] * iword;
613
 
    fragment = (char*) (((char*)stack.array + stack.top1) - last);
614
 
    stack.used -= (long int) fragment;
615
 
    stack.top1 -= (long int) fragment;
616
 
 
617
 
    Glu->ucol = ucol;
618
 
    Glu->lsub = lsub;
619
 
    Glu->usub = usub;
620
 
    
621
 
#ifdef DEBUG
622
 
    printf("zStackCompress: fragment %d\n", fragment);
623
 
    /* for (last = 0; last < ndim; ++last)
624
 
        print_lu_col("After compress:", last, 0);*/
625
 
#endif    
626
 
    
627
 
}
628
 
 
629
 
/*
630
 
 * Allocate storage for original matrix A
631
 
 */
632
 
void
633
 
zallocateA(int n, int nnz, doublecomplex **a, int **asub, int **xa)
634
 
{
635
 
    *a    = (doublecomplex *) doublecomplexMalloc(nnz);
636
 
    *asub = (int *) intMalloc(nnz);
637
 
    *xa   = (int *) intMalloc(n+1);
638
 
}
639
 
 
640
 
 
641
 
doublecomplex *doublecomplexMalloc(int n)
642
 
{
643
 
    doublecomplex *buf;
644
 
    buf = (doublecomplex *) SUPERLU_MALLOC(n * sizeof(doublecomplex)); 
645
 
    if ( !buf ) {
646
 
        ABORT("SUPERLU_MALLOC failed for buf in doublecomplexMalloc()\n");
647
 
    }
648
 
    return (buf);
649
 
}
650
 
 
651
 
doublecomplex *doublecomplexCalloc(int n)
652
 
{
653
 
    doublecomplex *buf;
654
 
    register int i;
655
 
    doublecomplex zero = {0.0, 0.0};
656
 
    buf = (doublecomplex *) SUPERLU_MALLOC(n * sizeof(doublecomplex));
657
 
    if ( !buf ) {
658
 
        ABORT("SUPERLU_MALLOC failed for buf in doublecomplexCalloc()\n");
659
 
    }
660
 
    for (i = 0; i < n; ++i) buf[i] = zero;
661
 
    return (buf);
662
 
}
663
 
 
664
 
 
665
 
int zmemory_usage(const int nzlmax, const int nzumax, 
666
 
                  const int nzlumax, const int n)
667
 
{
668
 
    register int iword, dword;
669
 
 
670
 
    iword   = sizeof(int);
671
 
    dword   = sizeof(doublecomplex);
672
 
    
673
 
    return (10 * n * iword +
674
 
            nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword);
675
 
 
676
 
}