superlu_dist.c
Go to the documentation of this file.
1/*----------------------------------------------------------------
2 Interface to distributed SuperLU, written by JWB and heavily
3 revised by PM by adapting code in the SuperLU distribution. The
4 function
5 superlu_dist_distributed_matrix(...)
6 is based on the file
7 EXAMPLE/pddrive2.c
8 and the function
9 superlu_dist_global_matrix(...)
10 is based on the file
11 EXAMPLE/pddrive2_ABglobal.c
12
13 To update this driver code for use with later versions of
14 SuperLU_DIST look at any changes to the example drivers.
15
16 Adapted from code found in:
17 -- Distributed SuperLU routine (version 9.1.0) --
18 Lawrence Berkeley National Lab, Univ. of California Berkeley.
19 Nov 11, 2024
20 ----------------------------------------------------------------
21*/
22#include <math.h>
23#include <superlu_ddefs.h>
24#include <superlu_enum_consts.h>
25
26
27/* ================================================= */
28/* Struct for the lu factors */
29/* ================================================= */
30typedef struct
31{
32 gridinfo_t* grid;
33 SuperMatrix* A;
34 dScalePermstruct_t* ScalePermstruct;
35 dLUstruct_t* LUstruct;
36 dSOLVEstruct_t* SOLVEstruct;
37 superlu_dist_options_t* options;
38 int_t rowequ;
39 int_t colequ;
40 double anorm;
42
43
44/* ================================================= */
45/* Can't think of any other way to store the memory */
46/* stats... (PM) */
47/* ================================================= */
49{
50 // Storage for the memory stats
51 superlu_dist_mem_usage_t Memory_usage;
52
53 // Boolean
56
57/* ========================================================================= */
58/* Helper to record memory usage*/
59/* ========================================================================= */
61{
62 // If the LU decomposition has been stored
64 {
66 }
67 else
68 {
69 return 0.0;
70 }
71} // End of get_lu_factor_memory_usage_in_bytes
72
73/* ========================================================================= */
74/* Helper to record memory usage*/
75/* ========================================================================= */
77{
78 // If the LU decomposition has been stored
80 {
82 }
83 else
84 {
85 return 0.0;
86 }
87} // End of get_total_memory_usage_in_bytes
88
89/* ========================================================================= */
90/* Helper to record memory usage*/
91/* ========================================================================= */
92void get_memory_usage_in_bytes_dist(double* lu_factor_memory,
93 double* total_memory)
94{
95 (*lu_factor_memory) = symbolic_memory_statistics_storage.Memory_usage.for_lu;
97}
98
99//=============================================================================
100// helper method - just calls the superlu method dCompRow_to_CompCol to convert
101// the c-style vectors of a cr matrix to a cc matrix
102//=============================================================================
103void superlu_cr_to_cc(int nrow,
104 int ncol,
105 int nnz,
106 double* cr_values,
107 int* cr_index,
108 int* cr_start,
109 double** cc_values,
110 int** cc_index,
111 int** cc_start)
112{
113 dCompRow_to_CompCol(nrow,
114 ncol,
115 nnz,
116 cr_values,
117 cr_index,
118 cr_start,
119 cc_values,
120 cc_index,
121 cc_start);
122}
123
124/*----------------------------------------------------------------
125 Enumeration to select setup, solve, or clean up.
126 ----------------------------------------------------------------*/
127typedef enum
128{
132} opt_flag_t;
133
134/*----------------------------------------------------------------
135 Bridge to distributed SuperLU with distributed memory (version 2.0).
136 Requires input of system matrix in compressed row form.
137
138 Parameters:
139 op_flag = int specifies the operation:
140 1, performs LU decomposition for the first time
141 2, performs triangular solve
142 3, free all the storage in the end
143 - n = size of system (square matrix)
144 - nnz = # of nonzero entries
145 - values = 1D C array of nonzero entries
146 - row_index = 1D C array of row indices
147 - column_start = 1D C array of column start indices
148 - b = 1D C array representing the rhs vector, is overwritten
149 by solution.
150 - nprow = # of rows in process grid
151 - npcol = # of columns in process grid
152 - doc = 0/1 for doc/no doc
153 - data = pointer to structure to contain LU solver data.
154 If *opt_flag == 1, it is an output. Otherwise, it it an input.
155
156 Return value for *info:
157 = 0: successful exit
158 > 0: if *info = i, and i is
159 <= A->ncol: U(i,i) is exactly zero. The factorization has
160 been completed, but the factor U is exactly singular,
161 so the solution could not be computed.
162 > A->ncol: number of bytes allocated when memory allocation
163 failure occurred, plus A->ncol.
164 < 0: some other error
165 ----------------------------------------------------------------
166*/
168 int allow_permutations,
169 int n,
170 int nnz_local,
171 int nrow_local,
172 int first_row,
173 double* values,
174 int* col_index,
175 int* row_start,
176 double* b,
177 int nprow,
178 int npcol,
179 int doc,
180 void** data,
181 int* info,
182 MPI_Comm comm)
183{
184 /* Some SuperLU structures */
185 superlu_dist_options_t* options;
186 SuperLUStat_t stat;
187 SuperMatrix* A;
188 dScalePermstruct_t* ScalePermstruct;
189 dLUstruct_t* LUstruct;
190 dSOLVEstruct_t* SOLVEstruct;
191 gridinfo_t* grid;
192
193 /* Structure to hold SuperLU structures and data */
194 superlu_dist_data* superlu_data;
195
196 int_t* perm_r; /* row permutations from partial pivoting */
197 int_t* perm_c; /* column permutation vector */
198 int_t* etree; /* elimination tree */
199 int_t* rowptr = NULL;
200 int_t* colind; /* Local A in NR*/
201 int_t job, rowequ, colequ, iinfo, need_value, i, j, irow, icol;
202 int_t m_loc, fst_row, nnz, nnz_loc; /* dist_mem_use; */
203 int_t *colptr, *rowind;
204 Glu_persist_t* Glu_persist;
205 Glu_freeable_t* Glu_freeable = NULL;
206
207 float GA_mem_use = 0.0; /* memory usage by global A */
208 float dist_mem_use = 0.0; /* memory usage during distribution */
209 superlu_dist_mem_usage_t num_mem_usage, symb_mem_usage;
210 int64_t nnzLU;
211 int_t nsupers;
212
213 /* Other stuff needed by SuperLU */
214 double* berr = NULL;
215 double* a = NULL;
216 double *X, *b_col;
217 double* B = b;
218 double *C, *R, *C1, *R1, *x_col; /* *bcol, */
219 double amax, t, colcnd, rowcnd;
220 double anorm = 0.0;
221 char equed[1], norm[1];
222 int ldx; /* LDA for matrix X (local). */
223 // static superlu_dist_mem_usage_t symb_mem_usage;
224 fact_t Fact;
225 int_t Equil, factored, notran, permc_spec;
226
227 /* We're only doing single rhs problems
228 note: code will need modifying to deal with
229 multiple rhs (see function pdgssvx) */
230
231 /* Square matrix */
232 int m = n;
233
234 /* Set 'Leading dimension' of rhs vector */
235 int ldb = n;
236
237 /* Initialize the statistics variables. */
238 PStatInit(&stat);
239
240 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
241 SET UP GRID, FACTORS, ETC
242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
243 if (opt_flag == SETUP_PHASE)
244 {
245 /* Allocate data structure to store data between calls to this function */
246 superlu_data =
247 (superlu_dist_data*)SUPERLU_MALLOC(sizeof(superlu_dist_data));
248
249 /* Initialize the superlu process grid. */
250 grid = (gridinfo_t*)SUPERLU_MALLOC(sizeof(gridinfo_t));
251 superlu_gridinit(comm, nprow, npcol, grid);
252 superlu_data->grid = grid;
253
254 /* Bail out if I do not belong in the grid. */
255 int iam = grid->iam;
256 if (iam >= nprow * npcol) return;
257
258 /* Allocate memory for SuperLU_DIST structures */
259 options =
260 (superlu_dist_options_t*)SUPERLU_MALLOC(sizeof(superlu_dist_options_t));
261 A = (SuperMatrix*)SUPERLU_MALLOC(sizeof(SuperMatrix));
262 ScalePermstruct =
263 (dScalePermstruct_t*)SUPERLU_MALLOC(sizeof(dScalePermstruct_t));
264 LUstruct = (dLUstruct_t*)SUPERLU_MALLOC(sizeof(dLUstruct_t));
265 SOLVEstruct = (dSOLVEstruct_t*)SUPERLU_MALLOC(sizeof(dSOLVEstruct_t));
266
267 /* Create SuperMatrix from compressed row representation */
268 dCreate_CompRowLoc_Matrix_dist(A,
269 m,
270 n,
271 nnz_local,
272 nrow_local,
273 first_row,
274 values,
275 col_index,
276 row_start,
277 SLU_NR_loc,
278 SLU_D,
279 SLU_GE);
280
281 /* Set the default options */
282 set_default_options_dist(options);
283
284 /* Is the matrix transposed (NOTRANS or TRANS)? */
285 options->Trans = NOTRANS;
286
287 /* Row permutations (NATURAL [= do nothing], */
288 /* LargeDiag_MC64 [default], ...)? */
289 /* options->RowPerm=NATURAL; */
290 options->RowPerm = LargeDiag_MC64; /* hierher used to be LargeDiag */
291
292 /* note: LargeDiag_HWPM seems to be an opption too */
293 /* Column permutations (NATURAL [= do nothing], */
294 /* MMD_AT_PLUS_A [default],...) */
295 options->ColPerm = MMD_AT_PLUS_A;
296
297 /* Use natural ordering instead? */
298 if (allow_permutations == 0)
299 {
300 options->ColPerm = NATURAL;
301 options->RowPerm = NOROWPERM;
302 }
303
304 /* printf("\n\n\nSWITCHING OFF EQUILIBRATION\n\n\n"); */
305 /* options->Equil=NO; */
306
307 /* Iterative refinement (essential as far as I can tell).*/
308 /* Can be "NO" or "DOUBLE"*/
309 options->IterRefine = SLU_DOUBLE;
310
311 /* Specifies whether to replace the tiny diagonals by sqrt(eps)*||A|| during
312 * LU factorization. */
313 options->ReplaceTinyPivot = YES;
314
315 /* Print stats during solve? */
316 if (doc == 0)
317 {
318 options->PrintStat = YES;
319 }
320 else
321 {
322 options->PrintStat = NO;
323 }
324
325 /* Doc output on process 0 if required: */
326 if ((!iam) && (doc == 0))
327 {
328 printf("\nPerforming SuperLU_DIST setup\n");
329 printf("Process grid\t%d X %d\n", grid->nprow, grid->npcol);
330 print_options_dist(options);
331 }
332
333 /* Initialize ScalePermstruct and LUstruct. */
334 dScalePermstructInit(m, n, ScalePermstruct);
335 dLUstructInit(n, LUstruct);
336
337 /* Call the linear equation solver but only perform the LU factorisation. */
338 int nrhs = 0;
339 pdgssvx(options,
340 A,
341 ScalePermstruct,
342 b,
343 ldb,
344 nrhs,
345 grid,
346 LUstruct,
347 SOLVEstruct,
348 berr,
349 &stat,
350 info);
351
352 /* Indicate that A has now been factorised. */
353 options->Fact = FACTORED;
354
355 /* Print the statistics.
356
357 PM: A driver can hang if this is only executed when on the root processor
358 so make sure not to add "&& (!iam)" to the if condition!
359 */
360 if (doc == 0)
361 {
362 printf("\nStats after distributed setup....\n");
363 PStatPrint(options, &stat, grid);
364 }
365
366 /* ------------------------------------------------------------
367 Set up data structure.
368 ------------------------------------------------------------*/
369 superlu_data->A = A;
370 superlu_data->options = options;
371 superlu_data->ScalePermstruct = ScalePermstruct;
372 superlu_data->LUstruct = LUstruct;
373 superlu_data->SOLVEstruct = SOLVEstruct;
374 superlu_data->colequ = colequ;
375 superlu_data->rowequ = rowequ;
376 superlu_data->anorm = anorm;
377 *data = superlu_data;
378 } /* End of setup */
379
380
381 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
382 PERFORM A SOLVE_PHASE
383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
384 if (opt_flag == SOLVE_PHASE)
385 {
386 /* Get pointer to the grid */
387 superlu_data = (superlu_dist_data*)*data;
388 grid = superlu_data->grid;
389
390 /* Bail out if I do not belong in the grid. */
391 int iam = grid->iam;
392 if (iam >= nprow * npcol)
393 {
394 return;
395 }
396
397 if ((doc == 0) && (!iam))
398 {
399 printf("\nPerforming SuperLU_DIST solve\n");
400 }
401
402 /* ------------------------------------------------------------
403 Set other pointers to data structure.
404 ------------------------------------------------------------*/
405 A = superlu_data->A;
406 options = superlu_data->options;
407 ScalePermstruct = superlu_data->ScalePermstruct;
408 LUstruct = superlu_data->LUstruct;
409 SOLVEstruct = superlu_data->SOLVEstruct;
410 colequ = superlu_data->colequ;
411 rowequ = superlu_data->rowequ;
412 anorm = superlu_data->anorm;
413
414 /* Solving for a single RHS vector */
415 int nrhs = 1;
416
417 if (!(berr = doubleMalloc_dist(nrhs)))
418 {
419 ABORT("Malloc fails for berr[].");
420 }
421
422 /* Call the linear solver to perform the back sub. */
423 pdgssvx(options,
424 A,
425 ScalePermstruct,
426 b,
427 ldb,
428 nrhs,
429 grid,
430 LUstruct,
431 SOLVEstruct,
432 berr,
433 &stat,
434 info);
435
436 SUPERLU_FREE(berr);
437 } /* End of solve */
438
439 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
440 PERFORM CLEAN UP OF MEMORY
441 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
442 if (opt_flag == CLEAN_UP_PHASE)
443 {
444 /* Get pointer to the process grid */
445 superlu_data = (superlu_dist_data*)*data;
446 grid = superlu_data->grid;
447
448 /* Bail out if I do not belong in the grid. */
449 int iam = grid->iam;
450 if (iam >= nprow * npcol)
451 {
452 goto out;
453 }
454 if ((doc == 0) && (!iam))
455 {
456 printf("\nCleaning up memory allocated for SuperLU_DIST\n");
457 }
458
459 /* ------------------------------------------------------------
460 Set pointers to the data structure.
461 ------------------------------------------------------------*/
462 A = superlu_data->A;
463 options = superlu_data->options;
464 ScalePermstruct = superlu_data->ScalePermstruct;
465 LUstruct = superlu_data->LUstruct;
466 SOLVEstruct = superlu_data->SOLVEstruct;
467
468 /* -------------------------------
469 Set the other pointers required
470 -------------------------------*/
471 R = ScalePermstruct->R;
472 C = ScalePermstruct->C;
473
474 /* Local control paramaters */
475 Fact = options->Fact;
476 factored = (Fact == FACTORED);
477 Equil = (!factored && options->Equil == YES);
478
479 /* Deallocate R and/or C if it was not used. */
480 if (Equil && Fact != SamePattern_SameRowPerm)
481 {
482 switch (ScalePermstruct->DiagScale)
483 {
484 case NOEQUIL:
485 SUPERLU_FREE(R);
486 SUPERLU_FREE(C);
487 break;
488 case ROW:
489 SUPERLU_FREE(C);
490 break;
491 case COL:
492 SUPERLU_FREE(R);
493 break;
494 default:
495 break;
496 }
497 }
498
499 /* Free storage */
500 PStatFree(&stat);
501 // Destroy_CompRowLoc_Matrix_dist(&A);
502 dScalePermstructFree(ScalePermstruct);
503 dDestroy_LU(n, grid, LUstruct);
504 dLUstructFree(LUstruct);
505 dSolveFinalize(options, SOLVEstruct);
506
507 // Only destroy the store part of the matrix
508 Destroy_SuperMatrix_Store_dist(A);
509
510 /* Deallocate memory */
511 SUPERLU_FREE(A);
512 SUPERLU_FREE(ScalePermstruct);
513 SUPERLU_FREE(LUstruct);
514 SUPERLU_FREE(SOLVEstruct);
515 SUPERLU_FREE(options);
516
517 /* Release the superlu process grid. */
518 out:
519 superlu_gridexit(grid);
520
521 SUPERLU_FREE(grid);
522 SUPERLU_FREE(superlu_data);
523 }
524 return;
525}
526
527
528/*----------------------------------------------------------------
529 Bridge to distributed SuperLU with distributed memory (version 2.0).
530 Requires input of system matrix in compressed row form.
531
532 Parameters:
533 op_flag = int specifies the operation:
534 1, performs LU decomposition for the first time
535 2, performs triangular solve
536 3, free all the storage in the end
537 - n = size of system (square matrix)
538 - nnz = # of nonzero entries
539 - values = 1D C array of nonzero entries
540 - row_index = 1D C array of row indices
541 - column_start = 1D C array of column start indices
542 - b = 1D C array representing the rhs vector, is overwritten
543 by solution.
544 - nprow = # of rows in process grid
545 - npcol = # of columns in process grid
546 - doc = 0/1 for doc/no doc
547 - data = pointer to structure to contain LU solver data.
548 If *opt_flag == 1, it is an output. Otherwise, it it an input.
549
550 Return value of *info:
551 = 0: successful exit
552 > 0: if *info = i, and i is
553 <= A->ncol: U(i,i) is exactly zero. The factorization has
554 been completed, but the factor U is exactly singular,
555 so the solution could not be computed.
556 > A->ncol: number of bytes allocated when memory allocation
557 failure occurred, plus A->ncol.
558 < 0: some other error
559 ----------------------------------------------------------------
560*/
562 int allow_permutations,
563 int n_in,
564 int nnz_in,
565 double* values,
566 int* row_index,
567 int* col_start,
568 double* b,
569 int nprow,
570 int npcol,
571 int doc,
572 void** data,
573 int* info,
574 MPI_Comm comm)
575{
576 /* Some SuperLU structures */
577 superlu_dist_options_t* options;
578 SuperLUStat_t stat;
579 SuperMatrix* A;
580 dScalePermstruct_t* ScalePermstruct;
581 dLUstruct_t* LUstruct;
582 gridinfo_t* grid;
583
584 /* Structure to hold SuperLU structures and data */
585 superlu_dist_data* superlu_data;
586
587 int_t* perm_r; /* row permutations from partial pivoting */
588 int_t* perm_c; /* column permutation vector */
589 int_t* etree; /* elimination tree */
590 int_t job, rowequ, colequ, iinfo, i, j, irow; /* , need_value */
591 int_t m, n, nnz;
592 int_t *colptr, *rowind;
593 int_t Equil, factored, notran, permc_spec; /*, dist_mem_use; */
594 NCformat* Astore;
595 NCPformat* ACstore;
596 Glu_persist_t* Glu_persist;
597 Glu_freeable_t* Glu_freeable = NULL;
598
599 /* Other stuff needed by SuperLU */
600 double* berr = NULL;
601 double *a, *X, *b_col;
602 double* B = b;
603 double *C, *R, *C1, *R1, *b_work, *x_col; /* *bcol, */
604 double amax, t, colcnd, rowcnd;
605 double anorm = 0.0;
606 char equed[1], norm[1];
607 int ldx; /* LDA for matrix X (local). */
608 int iam;
609 // static superlu_dist_mem_usage_t num_mem_usage, symb_mem_usage;
610 fact_t Fact;
611
612 /* Square matrix */
613 n = n_in;
614 m = n_in;
615 nnz = nnz_in;
616
617 /* Set 'Leading dimension' of rhs vector */
618 int ldb = n;
619
620
621 /* Initialize the statistics variables. */
622 PStatInit(&stat);
623
624 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
625 SET UP GRID, FACTORS, ETC
626 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
627 if (opt_flag == SETUP_PHASE)
628 {
629 /* Allocate data structure to store data between calls to this function */
630 superlu_data =
631 (superlu_dist_data*)SUPERLU_MALLOC(sizeof(superlu_dist_data));
632
633 /* Initialize the superlu process grid. */
634 grid = (gridinfo_t*)SUPERLU_MALLOC(sizeof(gridinfo_t));
635 superlu_gridinit(comm, nprow, npcol, grid);
636 superlu_data->grid = grid;
637
638 /* Bail out if I do not belong in the grid. */
639 iam = grid->iam;
640 if (iam >= nprow * npcol)
641 {
642 return;
643 }
644
645 /* Allocate memory for SuperLU_DIST structures */
646 options =
647 (superlu_dist_options_t*)SUPERLU_MALLOC(sizeof(superlu_dist_options_t));
648 A = (SuperMatrix*)SUPERLU_MALLOC(sizeof(SuperMatrix));
649 ScalePermstruct =
650 (dScalePermstruct_t*)SUPERLU_MALLOC(sizeof(dScalePermstruct_t));
651 LUstruct = (dLUstruct_t*)SUPERLU_MALLOC(sizeof(dLUstruct_t));
652
653 /* Set the default options */
654 set_default_options_dist(options);
655
656 /* Is the matrix transposed (NOTRANS or TRANS)? */
657 options->Trans = NOTRANS;
658
659 /* Row permutations (NATURAL [= do nothing], */
660 /* LargeDiag_MC64 [default], ...)? */
661 /* options->RowPerm=NATURAL; */
662 options->RowPerm = LargeDiag_MC64;
663
664 /* Column permutations (NATURAL [= do nothing], */
665 /* MMD_AT_PLUS_A [default],...) */
666 options->ColPerm = MMD_AT_PLUS_A;
667
668 /* Use natural ordering instead? */
669 if (allow_permutations == 0)
670 {
671 options->ColPerm = NATURAL;
672 options->RowPerm = NOROWPERM;
673 }
674
675 /* Iterative refinement (essential as far as I can tell).*/
676 /* Can be "NO" or "DOUBLE"*/
677 options->IterRefine = SLU_DOUBLE;
678
679 /* Print stats during solve? */
680 if (doc == 0)
681 {
682 options->PrintStat = YES;
683 }
684 else
685 {
686 options->PrintStat = NO;
687 }
688
689 /* Doc output on process 0 if required: */
690 if ((!iam) && (doc == 0))
691 {
692 printf("\nPerforming SuperLU_DIST setup\n");
693 printf("Process grid\t%d X %d\n", grid->nprow, grid->npcol);
694 print_options_dist(options);
695 }
696
697 /* Create SuperMatrix from compressed column representation */
698 dCreate_CompCol_Matrix_dist(
699 A, m, n, nnz, values, row_index, col_start, SLU_NC, SLU_D, SLU_GE);
700
701 /* Initialize ScalePermstruct and LUstruct. */
702 dScalePermstructInit(m, n, ScalePermstruct);
703 dLUstructInit(n, LUstruct);
704
705 /* Call the linear equation solver. */
706 int nrhs = 0;
707 pdgssvx_ABglobal(options,
708 A,
709 ScalePermstruct,
710 b,
711 ldb,
712 nrhs,
713 grid,
714 LUstruct,
715 berr,
716 &stat,
717 info);
718
719 /* Indicate that A has now been factorised. */
720 options->Fact = FACTORED;
721
722 if (*info != 0)
723 {
724 printf("Trouble in pdgstrf. Info=%i\n", *info);
725 if (*info > 0)
726 {
727 printf(
728 "U(%i,%i) is exactly zero. The factorization has\n", *info, *info);
729 printf("been completed, but the factor U is exactly singular,\n");
730 printf("and division by zero will occur if it is used to solve a\n");
731 printf("system of equations.\n");
732 }
733 else
734 {
735 printf("The %i-th argument had an illegal value.\n", *info);
736 }
737 }
738
739 /* Print the statistics.
740
741 PM: A driver can hang if this is only executed when on the root processor
742 so make sure not to add "&& (!iam)" to the if condition!
743 */
744 if (doc == 0)
745 {
746 printf("\nStats after global setup....\n");
747 PStatPrint(options, &stat, grid);
748 }
749
750 /* ------------------------------------------------------------
751 Set up data structure.
752 ------------------------------------------------------------*/
753 superlu_data->A = A;
754 superlu_data->options = options;
755 superlu_data->ScalePermstruct = ScalePermstruct;
756 superlu_data->LUstruct = LUstruct;
757 superlu_data->colequ = colequ;
758 superlu_data->rowequ = rowequ;
759 superlu_data->anorm = anorm;
760 *data = superlu_data;
761 } /* End of setup */
762
763
764 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
765 PERFORM A SOLVE_PHASE
766 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
767 if (opt_flag == SOLVE_PHASE)
768 {
769 /* Get pointer to the grid */
770 superlu_data = (superlu_dist_data*)*data;
771 grid = superlu_data->grid;
772
773 /* Bail out if I do not belong in the grid. */
774 iam = grid->iam;
775 if (iam >= nprow * npcol)
776 {
777 return;
778 }
779
780 if ((doc == 0) && (!iam))
781 {
782 printf("\nPerforming SuperLU_DIST solve\n");
783 }
784
785 /* ------------------------------------------------------------
786 Set other pointers to data structure.
787 ------------------------------------------------------------*/
788 A = superlu_data->A;
789 options = superlu_data->options;
790 ScalePermstruct = superlu_data->ScalePermstruct;
791 LUstruct = superlu_data->LUstruct;
792 colequ = superlu_data->colequ;
793 rowequ = superlu_data->rowequ;
794 anorm = superlu_data->anorm;
795
796 /* Solving for a single RHS vector */
797 int nrhs = 1;
798
799 if (!(berr = doubleMalloc_dist(nrhs)))
800 {
801 ABORT("Malloc fails for berr[].");
802 }
803
804 /* Call the linear solver to perform the back sub. */
805 pdgssvx_ABglobal(options,
806 A,
807 ScalePermstruct,
808 b,
809 ldb,
810 nrhs,
811 grid,
812 LUstruct,
813 berr,
814 &stat,
815 info);
816
817 SUPERLU_FREE(berr);
818 } /* End of solve */
819
820 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
821 PERFORM CLEAN UP OF MEMORY
822 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
823 if (opt_flag == CLEAN_UP_PHASE)
824 {
825 /* Get pointer to the process grid */
826 superlu_data = (superlu_dist_data*)*data;
827 grid = superlu_data->grid;
828
829 /* Bail out if I do not belong in the grid. */
830 iam = grid->iam;
831 if (iam >= nprow * npcol)
832 {
833 goto out;
834 }
835 if ((doc == 0) && (!iam))
836 {
837 printf("\nCleaning up memory allocated for SuperLU_DIST\n");
838 }
839
840 /* ------------------------------------------------------------
841 Set pointers to the data structure.
842 ------------------------------------------------------------*/
843 A = superlu_data->A;
844 options = superlu_data->options;
845 ScalePermstruct = superlu_data->ScalePermstruct;
846 LUstruct = superlu_data->LUstruct;
847
848 /* -------------------------------
849 Set the other pointers required
850 -------------------------------*/
851 R = ScalePermstruct->R;
852 C = ScalePermstruct->C;
853
854 /* Local control paramaters */
855 Fact = options->Fact;
856 factored = (Fact == FACTORED);
857 Equil = (!factored && options->Equil == YES);
858
859 /* Deallocate storage. */
860 if (Equil && Fact != SamePattern_SameRowPerm)
861 {
862 switch (ScalePermstruct->DiagScale)
863 {
864 case NOEQUIL:
865 SUPERLU_FREE(R);
866 SUPERLU_FREE(C);
867 break;
868 case ROW:
869 SUPERLU_FREE(C);
870 break;
871 case COL:
872 SUPERLU_FREE(R);
873 break;
874 default:
875 break;
876 }
877 }
878
879 /* Free storage */
880 PStatFree(&stat);
881 // Destroy_CompCol_Matrix_dist(&A);
882 dDestroy_LU(n, grid, LUstruct);
883 dScalePermstructFree(ScalePermstruct);
884 dLUstructFree(LUstruct);
885
886 // Only destroy the store part of the matrix
887 Destroy_SuperMatrix_Store_dist(A);
888
889 /* Deallocate memory */
890 SUPERLU_FREE(A);
891 SUPERLU_FREE(ScalePermstruct);
892 SUPERLU_FREE(LUstruct);
893 SUPERLU_FREE(options);
894
895 /* Release the superlu process grid. */
896 out:
897 superlu_gridexit(grid);
898
899 SUPERLU_FREE(grid);
900 SUPERLU_FREE(superlu_data);
901 }
902 return;
903}
cstr elem_len * i
Definition cfortran.h:603
char t
Definition cfortran.h:568
superlu_dist_mem_usage_t Memory_usage
mem_usage_t Memory_usage
Definition superlu.c:39
int Memory_usage_has_been_recorded
Definition superlu.c:42
dSOLVEstruct_t * SOLVEstruct
dScalePermstruct_t * ScalePermstruct
superlu_dist_options_t * options
gridinfo_t * grid
dLUstruct_t * LUstruct
SuperMatrix * A
double get_total_memory_usage_in_bytes_dist()
struct MemoryStatisticsStorage symbolic_memory_statistics_storage
double get_lu_factor_memory_usage_in_bytes_dist()
void superlu_cr_to_cc(int nrow, int ncol, int nnz, double *cr_values, int *cr_index, int *cr_start, double **cc_values, int **cc_index, int **cc_start)
opt_flag_t
@ SOLVE_PHASE
@ CLEAN_UP_PHASE
@ SETUP_PHASE
void superlu_dist_global_matrix(opt_flag_t opt_flag, int allow_permutations, int n_in, int nnz_in, double *values, int *row_index, int *col_start, double *b, int nprow, int npcol, int doc, void **data, int *info, MPI_Comm comm)
void get_memory_usage_in_bytes_dist(double *lu_factor_memory, double *total_memory)
void superlu_dist_distributed_matrix(opt_flag_t opt_flag, int allow_permutations, int n, int nnz_local, int nrow_local, int first_row, double *values, int *col_index, int *row_start, double *b, int nprow, int npcol, int doc, void **data, int *info, MPI_Comm comm)