comparison main/sparse/SuperLU/SRC/dutil.c @ 0:6b33357c7561 octave-forge

Initial revision
author pkienzle
date Wed, 10 Oct 2001 19:54:49 +0000
parents
children 7dad48fc229c
comparison
equal deleted inserted replaced
-1:000000000000 0:6b33357c7561
1
2
3 /*
4 * -- SuperLU routine (version 2.0) --
5 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
6 * and Lawrence Berkeley National Lab.
7 * November 15, 1997
8 *
9 */
10 /*
11 Copyright (c) 1994 by Xerox Corporation. All rights reserved.
12
13 THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
14 EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
15
16 Permission is hereby granted to use or copy this program for any
17 purpose, provided the above notices are retained on all copies.
18 Permission to modify the code and to distribute modified code is
19 granted, provided the above notices are retained, and a notice that
20 the code was modified is included with the above copyright notice.
21 */
22
23 #include <math.h>
24 #include "dsp_defs.h"
25 #include "util.h"
26
27 void
28 dCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz,
29 double *nzval, int *rowind, int *colptr,
30 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
31 {
32 NCformat *Astore;
33
34 A->Stype = stype;
35 A->Dtype = dtype;
36 A->Mtype = mtype;
37 A->nrow = m;
38 A->ncol = n;
39 A->Store = (void *) SUPERLU_MALLOC( sizeof(NCformat) );
40 if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store");
41 Astore = A->Store;
42 Astore->nnz = nnz;
43 Astore->nzval = nzval;
44 Astore->rowind = rowind;
45 Astore->colptr = colptr;
46 }
47
48 void
49 dCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz,
50 double *nzval, int *colind, int *rowptr,
51 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
52 {
53 NRformat *Astore;
54
55 A->Stype = stype;
56 A->Dtype = dtype;
57 A->Mtype = mtype;
58 A->nrow = m;
59 A->ncol = n;
60 A->Store = (void *) SUPERLU_MALLOC( sizeof(NRformat) );
61 if ( !(A->Store) ) ABORT("SUPERLU_MALLOC fails for A->Store");
62 Astore = A->Store;
63 Astore->nnz = nnz;
64 Astore->nzval = nzval;
65 Astore->colind = colind;
66 Astore->rowptr = rowptr;
67 }
68
69 /* Copy matrix A into matrix B. */
70 void
71 dCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B)
72 {
73 NCformat *Astore, *Bstore;
74 int ncol, nnz, i;
75
76 B->Stype = A->Stype;
77 B->Dtype = A->Dtype;
78 B->Mtype = A->Mtype;
79 B->nrow = A->nrow;;
80 B->ncol = ncol = A->ncol;
81 Astore = (NCformat *) A->Store;
82 Bstore = (NCformat *) B->Store;
83 Bstore->nnz = nnz = Astore->nnz;
84 for (i = 0; i < nnz; ++i)
85 ((double *)Bstore->nzval)[i] = ((double *)Astore->nzval)[i];
86 for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i];
87 for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i];
88 }
89
90
91 void
92 dCreate_Dense_Matrix(SuperMatrix *X, int m, int n, double *x, int ldx,
93 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
94 {
95 DNformat *Xstore;
96
97 X->Stype = stype;
98 X->Dtype = dtype;
99 X->Mtype = mtype;
100 X->nrow = m;
101 X->ncol = n;
102 X->Store = (void *) SUPERLU_MALLOC( sizeof(DNformat) );
103 if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store");
104 Xstore = (DNformat *) X->Store;
105 Xstore->lda = ldx;
106 Xstore->nzval = (double *) x;
107 }
108
109 void
110 dCopy_Dense_Matrix(int M, int N, double *X, int ldx,
111 double *Y, int ldy)
112 {
113 /*
114 *
115 * Purpose
116 * =======
117 *
118 * Copies a two-dimensional matrix X to another matrix Y.
119 */
120 int i, j;
121
122 for (j = 0; j < N; ++j)
123 for (i = 0; i < M; ++i)
124 Y[i + j*ldy] = X[i + j*ldx];
125 }
126
127 void
128 dCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz,
129 double *nzval, int *nzval_colptr, int *rowind,
130 int *rowind_colptr, int *col_to_sup, int *sup_to_col,
131 Stype_t stype, Dtype_t dtype, Mtype_t mtype)
132 {
133 SCformat *Lstore;
134
135 L->Stype = stype;
136 L->Dtype = dtype;
137 L->Mtype = mtype;
138 L->nrow = m;
139 L->ncol = n;
140 L->Store = (void *) SUPERLU_MALLOC( sizeof(SCformat) );
141 if ( !(L->Store) ) ABORT("SUPERLU_MALLOC fails for L->Store");
142 Lstore = L->Store;
143 Lstore->nnz = nnz;
144 Lstore->nsuper = col_to_sup[n];
145 Lstore->nzval = nzval;
146 Lstore->nzval_colptr = nzval_colptr;
147 Lstore->rowind = rowind;
148 Lstore->rowind_colptr = rowind_colptr;
149 Lstore->col_to_sup = col_to_sup;
150 Lstore->sup_to_col = sup_to_col;
151
152 }
153
154
155 /*
156 * Convert a row compressed storage into a column compressed storage.
157 */
158 void
159 dCompRow_to_CompCol(int m, int n, int nnz,
160 double *a, int *colind, int *rowptr,
161 double **at, int **rowind, int **colptr)
162 {
163 register int i, j, col, relpos;
164 int *marker;
165
166 /* Allocate storage for another copy of the matrix. */
167 *at = (double *) doubleMalloc(nnz);
168 *rowind = (int *) intMalloc(nnz);
169 *colptr = (int *) intMalloc(n+1);
170 marker = (int *) intCalloc(n);
171
172 /* Get counts of each column of A, and set up column pointers */
173 for (i = 0; i < m; ++i)
174 for (j = rowptr[i]; j < rowptr[i+1]; ++j) ++marker[colind[j]];
175 (*colptr)[0] = 0;
176 for (j = 0; j < n; ++j) {
177 (*colptr)[j+1] = (*colptr)[j] + marker[j];
178 marker[j] = (*colptr)[j];
179 }
180
181 /* Transfer the matrix into the compressed column storage. */
182 for (i = 0; i < m; ++i) {
183 for (j = rowptr[i]; j < rowptr[i+1]; ++j) {
184 col = colind[j];
185 relpos = marker[col];
186 (*rowind)[relpos] = i;
187 (*at)[relpos] = a[j];
188 ++marker[col];
189 }
190 }
191
192 SUPERLU_FREE(marker);
193 }
194
195
196 void
197 dPrint_CompCol_Matrix(char *what, SuperMatrix *A)
198 {
199 NCformat *Astore;
200 register int i,n;
201 double *dp;
202
203 printf("\nCompCol matrix %s:\n", what);
204 printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
205 n = A->ncol;
206 Astore = (NCformat *) A->Store;
207 dp = (double *) Astore->nzval;
208 printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz);
209 printf("nzval: ");
210 for (i = 0; i < Astore->colptr[n]; ++i) printf("%f ", dp[i]);
211 printf("\nrowind: ");
212 for (i = 0; i < Astore->colptr[n]; ++i) printf("%d ", Astore->rowind[i]);
213 printf("\ncolptr: ");
214 for (i = 0; i <= n; ++i) printf("%d ", Astore->colptr[i]);
215 printf("\n");
216 fflush(stdout);
217 }
218
219 void
220 dPrint_SuperNode_Matrix(char *what, SuperMatrix *A)
221 {
222 SCformat *Astore;
223 register int i,n;
224 double *dp;
225
226 printf("\nSuperNode matrix %s:\n", what);
227 printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
228 n = A->ncol;
229 Astore = (SCformat *) A->Store;
230 dp = (double *) Astore->nzval;
231 printf("nrow %d, ncol %d, nnz %d, nsuper %d\n",
232 A->nrow,A->ncol,Astore->nnz,Astore->nsuper);
233 printf("nzval: ");
234 for (i = 0; i < Astore->nzval_colptr[n]; ++i) printf("%f ", dp[i]);
235 printf("\nnzval_colptr: ");
236 for (i = 0; i <= n; ++i) printf("%d ", Astore->nzval_colptr[i]);
237 printf("\nrowind: ");
238 for (i = 0; i < Astore->rowind_colptr[n]; ++i)
239 printf("%d ", Astore->rowind[i]);
240 printf("\nrowind_colptr: ");
241 for (i = 0; i <= n; ++i) printf("%d ", Astore->rowind_colptr[i]);
242 printf("\ncol_to_sup: ");
243 for (i = 0; i < n; ++i) printf("%d ", Astore->col_to_sup[i]);
244 printf("\nsup_to_col: ");
245 for (i = 0; i <= Astore->nsuper+1; ++i)
246 printf("%d ", Astore->sup_to_col[i]);
247 printf("\n");
248 fflush(stdout);
249 }
250
251 void
252 dPrint_Dense_Matrix(char *what, SuperMatrix *A)
253 {
254 DNformat *Astore;
255 register int i;
256 double *dp;
257
258 printf("\nDense matrix %s:\n", what);
259 printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
260 Astore = (DNformat *) A->Store;
261 dp = (double *) Astore->nzval;
262 printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,Astore->lda);
263 printf("\nnzval: ");
264 for (i = 0; i < A->nrow; ++i) printf("%f ", dp[i]);
265 printf("\n");
266 fflush(stdout);
267 }
268
269 /*
270 * Diagnostic print of column "jcol" in the U/L factor.
271 */
272 void
273 dprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu)
274 {
275 int i, k, fsupc;
276 int *xsup, *supno;
277 int *xlsub, *lsub;
278 double *lusup;
279 int *xlusup;
280 double *ucol;
281 int *usub, *xusub;
282
283 xsup = Glu->xsup;
284 supno = Glu->supno;
285 lsub = Glu->lsub;
286 xlsub = Glu->xlsub;
287 lusup = Glu->lusup;
288 xlusup = Glu->xlusup;
289 ucol = Glu->ucol;
290 usub = Glu->usub;
291 xusub = Glu->xusub;
292
293 printf("%s", msg);
294 printf("col %d: pivrow %d, supno %d, xprune %d\n",
295 jcol, pivrow, supno[jcol], xprune[jcol]);
296
297 printf("\tU-col:\n");
298 for (i = xusub[jcol]; i < xusub[jcol+1]; i++)
299 printf("\t%d%10.4f\n", usub[i], ucol[i]);
300 printf("\tL-col in rectangular snode:\n");
301 fsupc = xsup[supno[jcol]]; /* first col of the snode */
302 i = xlsub[fsupc];
303 k = xlusup[jcol];
304 while ( i < xlsub[fsupc+1] && k < xlusup[jcol+1] ) {
305 printf("\t%d\t%10.4f\n", lsub[i], lusup[k]);
306 i++; k++;
307 }
308 fflush(stdout);
309 }
310
311
312 /*
313 * Check whether tempv[] == 0. This should be true before and after
314 * calling any numeric routines, i.e., "panel_bmod" and "column_bmod".
315 */
316 void dcheck_tempv(int n, double *tempv)
317 {
318 int i;
319
320 for (i = 0; i < n; i++) {
321 if (tempv[i] != 0.0)
322 {
323 fprintf(stderr,"tempv[%d] = %f\n", i,tempv[i]);
324 ABORT("dcheck_tempv");
325 }
326 }
327 }
328
329
330 void
331 dGenXtrue(int n, int nrhs, double *x, int ldx)
332 {
333 int i, j;
334 for (j = 0; j < nrhs; ++j)
335 for (i = 0; i < n; ++i) {
336 x[i + j*ldx] = 1.0;/* + (double)(i+1.)/n;*/
337 }
338 }
339
340 /*
341 * Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's
342 */
343 void
344 dFillRHS(char *trans, int nrhs, double *x, int ldx,
345 SuperMatrix *A, SuperMatrix *B)
346 {
347 NCformat *Astore;
348 double *Aval;
349 DNformat *Bstore;
350 double *rhs;
351 double one = 1.0;
352 double zero = 0.0;
353 int ldc;
354
355 Astore = A->Store;
356 Aval = (double *) Astore->nzval;
357 Bstore = B->Store;
358 rhs = Bstore->nzval;
359 ldc = Bstore->lda;
360
361 sp_dgemm(trans, "N", A->nrow, nrhs, A->ncol, one, A,
362 x, ldx, zero, rhs, ldc);
363
364 }
365
366 /*
367 * Fills a double precision array with a given value.
368 */
369 void
370 dfill(double *a, int alen, double dval)
371 {
372 register int i;
373 for (i = 0; i < alen; i++) a[i] = dval;
374 }
375
376
377
378 /*
379 * Check the inf-norm of the error vector
380 */
381 void dinf_norm_error(int nrhs, SuperMatrix *X, double *xtrue)
382 {
383 DNformat *Xstore;
384 double err, xnorm;
385 double *Xmat, *soln_work;
386 int i, j;
387
388 Xstore = X->Store;
389 Xmat = Xstore->nzval;
390
391 for (j = 0; j < nrhs; j++) {
392 soln_work = &Xmat[j*Xstore->lda];
393 err = xnorm = 0.0;
394 for (i = 0; i < X->nrow; i++) {
395 err = MAX(err, fabs(soln_work[i] - xtrue[i]));
396 xnorm = MAX(xnorm, fabs(soln_work[i]));
397 }
398 err = err / xnorm;
399 printf("||X - Xtrue||/||X|| = %e\n", err);
400 }
401 }
402
403
404
405 /* Print performance of the code. */
406 void
407 dPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
408 double rpg, double rcond, double *ferr,
409 double *berr, char *equed)
410 {
411 SCformat *Lstore;
412 NCformat *Ustore;
413 extern SuperLUStat_t SuperLUStat;
414 double *utime;
415 flops_t *ops;
416
417 utime = SuperLUStat.utime;
418 ops = SuperLUStat.ops;
419
420 if ( utime[FACT] != 0. )
421 printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT],
422 ops[FACT]*1e-6/utime[FACT]);
423 printf("Identify relaxed snodes = %8.2f\n", utime[RELAX]);
424 if ( utime[SOLVE] != 0. )
425 printf("Solve flops = %.0f, Mflops = %8.2f\n", ops[SOLVE],
426 ops[SOLVE]*1e-6/utime[SOLVE]);
427
428 Lstore = (SCformat *) L->Store;
429 Ustore = (NCformat *) U->Store;
430 printf("\tNo of nonzeros in factor L = %d\n", Lstore->nnz);
431 printf("\tNo of nonzeros in factor U = %d\n", Ustore->nnz);
432 printf("\tNo of nonzeros in L+U = %d\n", Lstore->nnz + Ustore->nnz);
433
434 printf("L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
435 mem_usage->for_lu/1e6, mem_usage->total_needed/1e6,
436 mem_usage->expansions);
437
438 printf("\tFactor\tMflops\tSolve\tMflops\tEtree\tEquil\tRcond\tRefine\n");
439 printf("PERF:%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f%8.2f\n",
440 utime[FACT], ops[FACT]*1e-6/utime[FACT],
441 utime[SOLVE], ops[SOLVE]*1e-6/utime[SOLVE],
442 utime[ETREE], utime[EQUIL], utime[RCOND], utime[REFINE]);
443
444 printf("\tRpg\t\tRcond\t\tFerr\t\tBerr\t\tEquil?\n");
445 printf("NUM:\t%e\t%e\t%e\t%e\t%s\n",
446 rpg, rcond, ferr[0], berr[0], equed);
447
448 }
449
450
451
452
453 print_double_vec(char *what, int n, double *vec)
454 {
455 int i;
456 printf("%s: n %d\n", what, n);
457 for (i = 0; i < n; ++i) printf("%d\t%f\n", i, vec[i]);
458 return 0;
459 }
460