42 Int n, ncomponents, header [2] ;
50 if (Common->
myid == 0)
52 LUsymbolic = *LUsymbolicHandle ;
53 if (LUsymbolic !=
NULL)
62 *LUsymbolicHandle =
NULL ;
67 header [1] = ncomponents ;
68 MPI_Bcast (&header, 2,
MPI_Int,
TAG0, MPI_COMM_WORLD) ;
70 ncomponents = header [1] ;
74 PR0 ((Common->
file,
"proc "ID" root analyze fails\n", Common->
myid)) ;
78 PR1 ((Common->
file,
"proc "ID" in bcast symbolic: status "ID" header "ID" "ID"\n",
79 Common->
myid, cm->
status, header [0], header [1])) ;
81 if (Common->
myid != 0)
84 *LUsymbolicHandle = LUsymbolic ;
91 MPI_Allreduce (&ok, &all_ok, 1, MPI_INT, MPI_LAND, MPI_COMM_WORLD) ;
95 PR0 ((Common->
file,
"proc "ID
" all fail in analyze\n", Common->
myid)) ;
97 *LUsymbolicHandle =
NULL ;
111 Int *Cn = LUsymbolic->
Cn ;
112 Int *Cnz = LUsymbolic->
Cnz ;
120 for (cc = 0 ; cc < ncomponents ; cc++)
122 printf (
"component "ID
"\n", cc) ;
123 printf (
"Child "ID
"\n", Child [cc]) ;
124 printf (
"Clnz "ID
"\n", Clnz [cc]) ;
125 printf (
"Cn "ID
"\n", Cn [cc]) ;
126 printf (
"Cnz "ID
"\n", Cnz [cc]) ;
127 printf (
"Sched "ID
"\n", Sched [cc]) ;
128 printf (
"Cstart "ID
"\n", Cstart [cc]) ;
129 printf (
"Childp "ID
"\n", Childp [cc]) ;
131 printf (
"Cstart "ID
"\n", Cstart [ncomponents]) ;
132 printf (
"Childp "ID
"\n", Childp [ncomponents]) ;
158 Int *Cperm, *RpermInv, *Cparent, *Cmember, *ColCount, *Cstart, *Childp,
159 *Clnz, *Cn, *Cnz, *Parent, *Post, *First, *Level, *Child, *Ap, *Ai,
162 double one [2] = {1,1} ;
163 Int p, k,
n, ncomponents, ci, cj, i, j, clast, c, parent, nparent, nroots,
164 nproc, cp, nc0, nc1 ;
170 Int proc = 0, parent2, ncomp2, c2, cc, cmerge, nleaves,
171 Int *NewNode, *Cparent2, *Merged, *Leaves, *Nchildren ;
179 if (Common->
myid != 0)
182 return (LUsymbolic) ;
189 nproc = Common->
nproc ;
231 if (LUsymbolic ==
NULL)
234 PR0 ((Common->
file,
"oops, proc 0 ran out\n")) ;
242 Cperm = LUsymbolic->
Cperm ;
244 Cparent = LUsymbolic->
Cparent ;
273 PR0 ((Common->
file,
"oops, proc 0 ran out here2\n")) ;
313 ncomponents =
CHOLMOD (nested_dissection) (C,
NULL, 0, Cperm, Cparent,
322 for (k = 0 ; k < n ; k++)
324 c = Cmember [Cperm [k]] ;
341 PR0 ((Common->
file,
"oops, proc 0 ran out here3\n")) ;
377 PR0 ((Common->
file,
"oops, proc 0 ran out here4\n")) ;
417 for (c = 0 ; c < ncomponents ; c++)
421 for (k = 0 ; k < n ; k++)
423 c = Cmember [Cperm [k]] ;
425 Cwork [c] += cnt * cnt ;
429 for (c = 0 ; c < ncomponents ; c++)
431 PR1 ((Common->
file,
"Node "ID" work %g parent "ID"\n",
432 c, Cwork [c], Cparent [c])) ;
448 Nchildren = W + n + ncomponents + 1 ;
449 Leaves = W + n + 2 * (ncomponents+1) ;
451 for (c = 0 ; c <= ncomponents ; c++)
456 for (c = 0 ; c < ncomponents ; c++)
458 parent = Cparent [c] ;
461 parent = ncomponents ;
463 ASSERT (parent > c && parent <= ncomponents) ;
464 Nchildren [parent]++ ;
469 for (c = 0 ; c < ncomponents ; c++)
471 PR1 ((Common->
file,
"Node "ID" has "ID" children\n", c, Nchildren [c])) ;
472 if (Nchildren [c] == 0)
474 PR1 ((Common->
file,
"Leaf: "ID
"\n", c)) ;
475 Leaves [nleaves++] = c ;
485 while (nleaves > target_nleaves)
487 PR1 ((Common->
file,
"\n------------ nleaves: "ID"\n", nleaves)) ;
493 for (p = 0 ; p < nleaves ; p++)
495 PR2 ((Common->
file,
"Leaf "ID" work %g\n",
496 Leaves [p], Cwork [Leaves [p]])) ;
498 if (Leaves [p] == ncomponents-1)
509 if (work ==
EMPTY || Cwork [Leaves [p]] < work)
517 PR2 ((Common->
file,
"Lightest leaf is "ID" with work %g\n", c, Cwork [c]));
518 ASSERT (c < ncomponents-1) ;
519 ASSERT (Nchildren [c] == 0) ;
522 for (cmerge = c+1 ; cmerge < ncomponents ; cmerge++)
524 if (Merged [cmerge] ==
EMPTY)
531 parent = Cparent [c] ;
534 parent = ncomponents ;
538 PR1 ((Common->
file,
"merge "ID" into "ID", parent "ID"\n", c, cmerge, parent));
539 ASSERT (cmerge < ncomponents) ;
540 Cwork [cmerge] += Cwork [c] ;
542 Merged [c] = cmerge ;
543 Leaves [cp] = Leaves [--nleaves] ;
544 Nchildren [parent]-- ;
547 if (Nchildren [parent] == 0 && parent != ncomponents)
550 PR1 ((Common->
file,
"parent is new leaf: "ID
"\n", parent)) ;
551 Leaves [nleaves++] = parent ;
557 PR1 ((Common->
file,
"\n-------------------------- done merging leaves\n")) ;
560 for (c = 0 ; c < ncomponents-1 ; c++)
562 if (Merged [c] ==
EMPTY)
564 parent = Cparent [c] ;
565 if (parent ==
EMPTY) continue ;
566 if (Nchildren [parent] == 1)
568 PR1 ((Common->
file,
"\nparent "ID" of c "ID" has one child\n",
570 Cwork [parent] += Cwork [c] ;
572 Merged [c] = parent ;
573 for (cc = c+1 ; cc < parent ; cc++)
575 PR1 ((Common->
file,
"merge "ID
" into "ID
"\n", cc, parent)) ;
577 Merged [cc] = parent ;
586 for (c = 0 ; c < ncomponents ; c++)
589 PR1 ((Common->
file,
"\nFind ultimate node for "ID"\n", c)) ;
590 for (cc = c ; Merged [cc] !=
EMPTY ; cc = Merged [cc]) ;
591 for (c2 = c ; Merged [c2] !=
EMPTY ; c2 = Merged [c2])
593 PR1 ((Common->
file,
" merge "ID" into "ID"\n", c2, cc)) ;
601 for (c = 0 ; c < ncomponents ; c++)
603 if (Merged [c] ==
EMPTY)
605 PR1 ((Common->
file,
"Live node "ID" becomes node "ID"\n", c, ncomp2)) ;
606 NewNode [c] = ncomp2++ ;
609 for (c = 0 ; c < ncomponents ; c++)
611 if (Merged [c] !=
EMPTY)
613 NewNode [c] = NewNode [Merged [c]] ;
614 PR1 ((Common->
file,
"Dead node "ID" becomes part of node "ID"\n",
620 for (k = 0 ; k < n ; k++)
628 Cparent2 = Nchildren ;
629 for (c = 0 ; c < ncomponents ; c++)
631 if (Merged [c] ==
EMPTY)
634 parent = Cparent [c] ;
635 parent2 = (parent ==
EMPTY) ?
EMPTY : (NewNode [parent]) ;
636 Cparent2 [c2] = parent2 ;
642 for (c = 0 ; c < ncomponents ; c++)
647 ncomponents = ncomp2 ;
648 for (c = 0 ; c < ncomponents ; c++)
650 Cparent [c] = Cparent2 [c] ;
654 printf (
"Final components: "ID" leaves: "ID"\n", ncomponents, nleaves) ;
655 for (c = 0 ; c < ncomponents ; c++)
657 PR1 ((Common->
file,
"New node: "ID
" new parent "ID
"\n", c, Cparent [c])) ;
675 Child = LUsymbolic->
Child = LUsymbolic->
Mem_c ;
676 Clnz = LUsymbolic->
Clnz = LUsymbolic->
Mem_c + ncomponents ;
677 Cn = LUsymbolic->
Cn = LUsymbolic->
Mem_c + 2*ncomponents ;
678 Cnz = LUsymbolic->
Cnz = LUsymbolic->
Mem_c + 3*ncomponents ;
679 Sched = LUsymbolic->
Sched = LUsymbolic->
Mem_c + 4*ncomponents ;
682 Cstart = LUsymbolic->
Cstart = LUsymbolic->
Mem_c + 5*ncomponents ;
683 Childp = LUsymbolic->
Childp = LUsymbolic->
Mem_c + 6*ncomponents + 1 ;
686 LUsymbolic->
ncomp0 = nc0 ;
687 LUsymbolic->
ncomp1 = nc1 ;
704 for (k = 0 ; k < n ; k++)
706 c = Cmember [Cperm [k]] ;
715 Cstart [ncomponents] = n ;
721 for (c = 0 ; c < ncomponents ; c++)
724 for (k = Cstart [c] ; k < Cstart [c+1] ; k++)
747 for (c = 0 ; c < ncomponents ; c++)
752 for (c = 0 ; c < ncomponents ; c++)
754 parent = Cparent [c] ;
755 PR1 ((Common->
file,
"node "ID
": parent "ID
"\n", c, parent)) ;
762 ASSERT (parent > 0 && parent < ncomponents) ;
775 for (c = 0 ; c < ncomponents ; c++)
777 PR1 ((Common->
file,
"node "ID
": "ID
" children\n", c, Cn [c])) ;
783 for (c = 0 ; c < ncomponents ; c++)
788 PR1 ((Common->
file,
"k "ID
" ncomponents "ID
"\n", k, ncomponents)) ;
789 ASSERT (k == ncomponents - nroots) ;
790 Childp [ncomponents] = k ;
793 for (c = 0 ; c < ncomponents ; c++)
795 Cn [c] = Childp [c] ;
797 for (k = 0 ; k < ncomponents ; k++)
801 for (c = 0 ; c < ncomponents ; c++)
803 parent = Cparent [c] ;
806 Child [Cn [parent]++] = c ;
811 for (c = 0 ; c < ncomponents ; c++)
813 PR1 ((Common->
file,
"Node "ID
" children: ", c)) ;
814 for (cp = Childp [c] ; cp < Childp [c+1] ; cp++)
816 PR1 ((Common->
file,
""ID
" ", Child [cp])) ;
826 for (c = ncomponents - 1 ; c >= 0 ; c--)
828 parent = Cparent [c] ;
829 nparent = (parent ==
EMPTY) ? 0 : Cn [parent] ;
830 Cn [c] = (Cstart [c+1] - Cstart [c]) + nparent ;
831 PR1 ((Common->
file,
"node "ID
" Cn: "ID
"\n", c, Cn [c])) ;
838 for (c = 0 ; c < ncomponents ; c++)
844 for (j = 0 ; j < n ; j++)
847 for (p = Ap [j] ; p < Ap [j+1] ; p++)
853 PR3 ((Common->
file,
"A(1+"ID
",1+"ID
") = %g ; c(1+"ID
",1+"ID
") = "ID
" ;\n",
855 A->
x ? 0 : (((
double *) (A->
x)) [p]),
861 for (c = 0 ; c < ncomponents ; c++)
863 PR0 ((Common->
file,
"Cnz ["ID
"] = "ID
"\n", c, Cnz [c])) ;
871 Rperm = LUsymbolic->
Rperm ;
875 for (k = 0 ; k < n ; k++)
877 Rperm [k] = Cperm [k] ;
879 for (k = 0 ; k < n ; k++)
881 RpermInv [Rperm [k]] = k ;
891 Hi_id = W + ncomponents ;
893 for (c = 0 ; c < ncomponents ; c++)
900 Lo_id [ncomponents-1] = 0 ;
901 Hi_id [ncomponents-1] = nproc-1 ;
903 for (c = ncomponents - 1 ; c >= 0 ; c--)
905 Int nchild, child, child_left, child_right, c_nproc ;
908 Sched [c] = Lo_id [c] ;
911 nchild = Childp [c+1] - Childp [c] ;
918 else if (nchild == 1)
922 Lo_id [child] = Lo_id [c] ;
923 Hi_id [child] = Hi_id [c] ;
925 else if (nchild == 2)
928 child_left = Child [cp] ;
929 child_right = Child [cp+1] ;
931 c_nproc = Hi_id [c] - Lo_id [c] + 1 ;
934 Lo_id [child_left ] = Lo_id [c] ;
935 Hi_id [child_left ] = Lo_id [c] + c_nproc / 2 - 1 ;
936 Lo_id [child_right] = Lo_id [c] + c_nproc / 2 ;
937 Hi_id [child_right] = Hi_id [c] ;
941 Lo_id [child_left ] = Lo_id [c] ;
942 Hi_id [child_left ] = Lo_id [c] ;
943 Lo_id [child_right] = Lo_id [c] ;
944 Hi_id [child_right] = Lo_id [c] ;
957 for (c = 0 ; c < ncomponents ; c++)
959 Int nchild = Childp [c+1] - Childp [c] ;
962 PR1 ((Common->
file,
"\nSchedule child "ID
" to process "ID
"\n", c, proc));
963 for (cc = c ; cc !=
EMPTY && Sched [cc] ==
EMPTY ; cc = Cparent[cc])
965 PR1 ((Common->
file,
" node "ID
" to process "ID
"\n", cc, proc)) ;
969 proc = (proc + 1) % nproc ;
977 for (c = 0 ; c < ncomponents ; c++)
984 PR0 ((Common->
file,
"\nncomponents:: "ID
"\n", ncomponents)) ;
985 for (c = 0 ; c < ncomponents ; c++)
987 PR0 ((Common->
file,
" node "ID
" Sched "ID
" : Cparent "ID
" proc "ID
"\n",
988 c, Sched [c], Cparent [c],
989 (Cparent [c] ==
EMPTY) ?
EMPTY : Sched [Cparent [c]])) ;
994 for (c = 0 ; c < ncomponents ; c++)
996 printf (
" node "ID
" on "ID
" : Cparent "ID
" on "ID
"\n",
997 c, Sched [c], Cparent [c],
998 (Cparent [c] ==
EMPTY) ?
EMPTY : Sched [Cparent [c]]) ;
1007 PR1 ((Common->
file,
"analysis done\n")) ;
1009 return (LUsymbolic) ;
1032 cm = &(Common->
cm) ;
1078 if (ncomponents > 0)
1085 LUsymbolic->
Clnz = LUsymbolic->
Mem_c + ncomponents ;
1086 LUsymbolic->
Cn = LUsymbolic->
Mem_c + 2*ncomponents ;
1087 LUsymbolic->
Cnz = LUsymbolic->
Mem_c + 3*ncomponents ;
1088 LUsymbolic->
Sched = LUsymbolic->
Mem_c + 4*ncomponents ;
1091 LUsymbolic->
Cstart = LUsymbolic->
Mem_c + 5*ncomponents ;
1092 LUsymbolic->
Childp = LUsymbolic->
Mem_c + 6*ncomponents + 1 ;
1117 return (LUsymbolic) ;
1135 Int n, ncomponents ;
1137 if (LUsymbolicHandle ==
NULL)
1142 LUsymbolic = *LUsymbolicHandle ;
1143 if (LUsymbolic ==
NULL)
1149 cm = &(Common->
cm) ;
1166 CHOLMOD (free) (7*ncomponents + 2,
sizeof (
Int), LUsymbolic->
Mem_c, cm) ;
1175 *LUsymbolicHandle =
CHOLMOD (free) (
cholmod_sparse *CHOLMOD() add(cholmod_sparse *A, cholmod_sparse *B, double alpha[2], double beta[2], int values, int sorted, cholmod_common *Common)
int CHOLMOD() band_inplace(UF_long k1, UF_long k2, int mode, cholmod_sparse *A, cholmod_common *Common)
size_t CHOLMOD() add_size_t(size_t a, size_t b, int *ok)
int CHOLMOD() rowcolcounts(cholmod_sparse *A, Int *fset, size_t fsize, Int *Parent, Int *Post, Int *RowCount, Int *ColCount, Int *First, Int *Level, cholmod_common *Common)
cholmod_sparse *CHOLMOD() transpose(cholmod_sparse *A, int values, cholmod_common *Common)
#define RETURN_IF_NULL_COMMON(result)
struct cholmod_common_struct::cholmod_method_struct method[CHOLMOD_MAXMETHODS+1]
paraklete_symbolic * amesos_paraklete_alloc_symbolic(Int n, Int ncomponents, Int do_Rperm, paraklete_common *Common)
size_t CHOLMOD() mult_size_t(size_t a, size_t k, int *ok)
#define PARAKLETE_ERROR(status, message)
cholmod_sparse *CHOLMOD() ptranspose(cholmod_sparse *A, int values, Int *Perm, Int *fset, size_t fsize, cholmod_common *Common)
int CHOLMOD() free_sparse(cholmod_sparse **AHandle, cholmod_common *Common)
#define ASSERT(expression)
int CHOLMOD() etree(cholmod_sparse *A, Int *Parent, cholmod_common *Common)
int CHOLMOD() error(int status, char *file, int line, char *message, cholmod_common *Common)
paraklete_symbolic * amesos_paraklete_analyze(cholmod_sparse *A, paraklete_common *Common)
static Int paraklete_bcast_symbolic(paraklete_symbolic **LUsymbolicHandle, paraklete_common *Common)
int CHOLMOD() allocate_work(size_t nrow, size_t iworksize, size_t xworksize, cholmod_common *Common)
#define RETURN_IF_NULL(A, result)
struct paraklete_symbolic_struct paraklete_symbolic
void amesos_paraklete_free_symbolic(paraklete_symbolic **LUsymbolicHandle, paraklete_common *Common)