Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_paraklete_usolve_node.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === paraklete_usolve_node ================================================ */
3 /* ========================================================================== */
4 
6 
7 /* Solve Ux=y with node c of the separator tree
8  *
9  * PARAKLETE version 0.3: parallel sparse LU factorization. Nov 13, 2007
10  * Copyright (C) 2007, Univ. of Florida. Author: Timothy A. Davis
11  * See License.txt for the Version 2.1 of the GNU Lesser General Public License
12  * http://www.cise.ufl.edu/research/sparse
13  */
14 
16 (
17  Int c,
19  paraklete_symbolic *LUsymbolic,
20  paraklete_common *Common
21 )
22 {
23  double xj ;
24  paraklete_node *LUnode ;
25  cholmod_common *cm ;
26  double *LUix, *Xchild, *Ux, *X ;
27  Int *Child, *Childp, *Lost, *Lostp, *Cstart, *Uip, *Ulen,
28  *Cn, *Qinv, *Ui, *Sched, *Cparent ;
29  Int cp, nchild, child, cn, k, j, p, i, nfound, k1, k2, ulen,
30  ci, nlost_in, cn_child, cn_nfound, myid, parent ;
31  MPI (MPI_Status ms) ;
32  MPI (MPI_Request req) ;
33 
34  /* ---------------------------------------------------------------------- */
35  /* get local workspace */
36  /* ---------------------------------------------------------------------- */
37 
38  cm = &(Common->cm) ;
39  PR0 ((Common->file, "\n\n########################### Usolve NODE "ID"\n", c));
40 
41  /* ---------------------------------------------------------------------- */
42  /* get the symbolic analysis of this node */
43  /* ---------------------------------------------------------------------- */
44 
45  myid = Common->myid ;
46  Childp = LUsymbolic->Childp ; /* Child [Childp [c]..Childp[c+1]-1] */
47  Child = LUsymbolic->Child ; /* is list of children of node c */
48  nchild = Childp [c+1] - Childp [c] ; /* # of children of node c */
49  Cn = LUsymbolic->Cn ; /* dimension of each node */
50  Cstart = LUsymbolic->Cstart ;
51  Sched = LUsymbolic->Sched ;
52  Cparent = LUsymbolic->Cparent ;
53 
54  /* ---------------------------------------------------------------------- */
55  /* get solution to Ly=Pb, and solution to Ux=y from parent */
56  /* ---------------------------------------------------------------------- */
57 
58  LUnode = LU->LUnode [c] ;
59  cn = LUnode->PK_NN ;
60  nfound = LUnode->PK_NFOUND ;
61  X = LUnode->X ;
62  parent = Cparent [c] ;
63 
64  PR1 ((Common->file, "Usolve node "ID" cn "ID" nfound "ID"\n", c, cn, nfound)) ;
65 
66  if (parent != EMPTY && Sched [parent] != myid)
67  {
68  PR1 ((Common->file, "Recving usolve from "ID", size "ID"\n", Sched [parent],
69  cn - nfound)) ;
70  MPI (MPI_Irecv (X + nfound, cn-nfound, MPI_DOUBLE, Sched [parent],
71  TAG0, MPI_COMM_WORLD, &req)) ;
72  MPI (MPI_Wait (&req, &ms)) ;
73  }
74 
75  /* ---------------------------------------------------------------------- */
76  /* solve Ux=y at this node */
77  /* ---------------------------------------------------------------------- */
78 
79  Uip = LUnode->up ;
80  Ulen = LUnode->ulen ;
81  LUix = LUnode->ix ;
82 
83  /* X1 = U2*X2 - X1 */
84  for (j = cn-1 ; j >= nfound ; j--)
85  {
86  xj = X [j] ;
87  GET_COLUMN (Uip, Ulen, LUix, j, Ui, Ux, ulen) ;
88  for (p = 0 ; p < ulen ; p++)
89  {
90  X [Ui [p]] -= Ux [p] * xj ;
91  }
92  }
93 
94  /* solve U*X1 */
95  for ( ; j >= 0 ; j--)
96  {
97  GET_COLUMN (Uip, Ulen, LUix, j, Ui, Ux, ulen) ;
98  xj = X [j] / Ux [ulen-1] ;
99  X [j] = xj ;
100  for (p = 0 ; p < ulen-1 ; p++)
101  {
102  X [Ui [p]] -= Ux [p] * xj ;
103  }
104  }
105 
106  /* ---------------------------------------------------------------------- */
107  /* get factors at this node */
108  /* ---------------------------------------------------------------------- */
109 
110  nlost_in = 0 ;
111  Lost = LUnode->Lost ;
112  Lostp = LUnode->Lostp ;
113  nlost_in = LUnode->nlost_in ;
114 
115  /* The matrix factorized at this node is cn-by-cn. */
116  cn = nlost_in + Cn [c] ;
117  k1 = Cstart [c] ;
118  k2 = Cstart [c+1] ;
119 
120  PR1 ((Common->file, "NODE "ID" nlost_in: "ID"\n", c, nlost_in)) ;
121 
122  Qinv = LUnode->Qinv ;
123 
124 #ifndef NDEBUG
125  {
126  Int npiv = LUnode->PK_NPIV ;
127  Int *Qlocal = LUnode->Qlocal ;
128  ASSERT (cn == LUnode->PK_NN) ;
129  ASSERT (npiv == nlost_in + (k2 - k1)) ;
130  for (k = 0 ; k < npiv ; k++)
131  {
132  i = Qlocal [k] ;
133  ASSERT (i >= 0 && i < npiv) ;
134  ASSERT (Qinv [i] == k) ;
135  }
136  DEBUG (CHOLMOD (print_perm) (Qlocal, npiv, npiv, "Qlocal at node c", cm));
137  DEBUG (CHOLMOD (print_perm) (Qinv, npiv, npiv, "Qinv at node c", cm)) ;
138  }
139 #endif
140 
141  /* ---------------------------------------------------------------------- */
142  /* send solutions to each child */
143  /* ---------------------------------------------------------------------- */
144 
145  for (cp = 0 ; cp < nchild ; cp++)
146  {
147  child = Child [Childp [c] + cp] ;
148  cn_child = LU->LUnode [child]->PK_NN ;
149  cn_nfound = LU->LUnode [child]->PK_NFOUND ;
150  Xchild = LU->LUnode [child]->X + cn_nfound ;
151 
152  PR1 ((Common->file, "child "ID" cn "ID" nfound "ID"\n",
153  child, cn_child, cn_nfound)) ;
154 
155  /* send the child its lost pivot cols */
156  for (i = 0 ; i < Lost [cp] ; i++)
157  {
158  ci = i + Lostp [cp] ; /* ci is now "original" local index */
159  k = Qinv [ci] ; /* kth local pivot col */
160  PR2 ((Common->file, "Xchild ["ID"] = %g from X ["ID"] (lost)\n",
161  i, Xchild [i], k)) ;
162  Xchild [i] = X [k] ;
163  }
164 
165  /* send the child the rest of the solution from c */
166  for ( ; i < Lost [cp] + (k2-k1) ; i++)
167  {
168  ci = i + (nlost_in - Lost [cp]) ;
169  k = Qinv [ci] ; /* kth local pivot col */
170  PR2 ((Common->file, "Xchild ["ID"] = %g from X ["ID"] (cand)\n",
171  i, Xchild [i], k)) ;
172  Xchild [i] = X [k] ;
173  }
174 
175  /* get the solutions of ancestors of c */
176  for ( ; i < cn_child - cn_nfound ; i++)
177  {
178  k = i + (nlost_in - Lost [cp]) ;
179  PR2 ((Common->file, "Xchild ["ID"] = %g from X ["ID"] (anc)\n",
180  i, Xchild [i], k)) ;
181  Xchild [i] = X [k] ;
182  }
183 
184  PR1 ((Common->file, "Usolve: Sending from "ID" to child "ID"\n", c, child));
185  if (Sched [child] != myid)
186  {
187  PR1 ((Common->file, "Sending to "ID", size "ID"\n", Sched [child],
188  cn_child - cn_nfound)) ;
189  MPI (MPI_Isend (Xchild, cn_child - cn_nfound, MPI_DOUBLE,
190  Sched [child], TAG0, MPI_COMM_WORLD, &req)) ;
191  /* this request can be freed, because the work of this node is now
192  done, and paraklete_usolve_node is followed by a barrier */
193  MPI (MPI_Request_free (&req)) ;
194  }
195  }
196 
197  return (TRUE) ;
198 }
#define TAG0
#define EMPTY
#define Int
#define PR0(params)
Int amesos_paraklete_usolve_node(Int c, paraklete_numeric *LU, paraklete_symbolic *LUsymbolic, paraklete_common *Common)
#define CHOLMOD(name)
#define PR2(params)
#define GET_COLUMN(Ap, Anz, Aix, j, Ai, Ax, len)
#define ASSERT(expression)
#define ID
#define PR1(params)
int CHOLMOD() print_perm(Int *Perm, size_t len, size_t n, char *name, cholmod_common *Common)
#define MPI(statement)
#define DEBUG(statement)
#define TRUE