Amesos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
amesos_paraklete_solve.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === paraklete_solve ====================================================== */
3 /* ========================================================================== */
4 
6 
7 /* paraklete_solve (LU, LUsymbolic, B, Common) solves Ly=Pb, where P is
8  * the initial fill-reducing ordering (P=Cperm).
9  *
10  * The solution is left in LU->LUnode [c]->X, for each node c. Next, it solves
11  * UQ'x=y, where the solution is written into the input array B,
12  * and where Q is the final column ordering.
13  *
14  * This solve is performed using the original LUsymbolic object, not the one
15  * returned from paraklete_reanalyze.
16  *
17  * PARAKLETE version 0.3: parallel sparse LU factorization. Nov 13, 2007
18  * Copyright (C) 2007, Univ. of Florida. Author: Timothy A. Davis
19  * See License.txt for the Version 2.1 of the GNU Lesser General Public License
20  * http://www.cise.ufl.edu/research/sparse
21  */
22 
24 (
25  /* inputs, not modified */
27  paraklete_symbolic *LUsymbolic,
28  double *B,
29  paraklete_common *Common
30 )
31 {
32  cholmod_common *cm ;
33  double *Blocal, *X, *W, *X2 ;
34  Int *Cperm, *Rperm, *Cstart, *Q, *Sched, *Child, *Childp ;
35  Int i, n, ncomponents, k, c, k1, k2, nfound, myid, cp, nchild, child ;
36  MPI (MPI_Status ms) ;
37 
38  /* ---------------------------------------------------------------------- */
39  /* get inputs */
40  /* ---------------------------------------------------------------------- */
41 
42  cm = &(Common->cm) ;
43  n = LU->n ;
44  W = LU->W ; /* only non-NULL on the root process 0 */
45  myid = Common->myid ;
46 
47  ncomponents = LUsymbolic->ncomponents ;
48  Cperm = LUsymbolic->Cperm ;
49  Rperm = LUsymbolic->Rperm ;
50  Rperm = (Rperm == NULL) ? Cperm : Rperm ;
51  Cstart = LUsymbolic->Cstart ;
52  Sched = LUsymbolic->Sched ;
53 
54  /* ---------------------------------------------------------------------- */
55  /* W = Rperm*B, on process 0 only */
56  /* ---------------------------------------------------------------------- */
57 
58  if (myid == 0)
59  {
60  for (k = 0 ; k < n ; k++)
61  {
62  W [k] = B [Rperm [k]] ;
63  }
64  }
65 
66  /* ---------------------------------------------------------------------- */
67  /* distribute the permuted B to the nodes */
68  /* ---------------------------------------------------------------------- */
69 
70  for (c = 0 ; c < ncomponents ; c++)
71  {
72  k1 = Cstart [c] ;
73  k2 = Cstart [c+1] ;
74 
75  Blocal = LU->LUnode [c]->B ;
76 
77  /* send Blocal to node c */
78  MPI (LU->LUnode [c]->req = MPI_REQUEST_NULL) ;
79  if (myid == 0)
80  {
81  if (Sched [c] == myid)
82  {
83  for (i = 0 ; i < k2-k1 ; i++)
84  {
85  Blocal [i] = W [k1 + i] ;
86  }
87  }
88  else
89  {
90  MPI (MPI_Isend (W + k1, k2-k1, MPI_DOUBLE, Sched [c],
91  /* TAG: */ c, MPI_COMM_WORLD, &(LU->LUnode [c]->req))) ;
92  }
93  }
94  else
95  {
96  if (Sched [c] == myid)
97  {
98  MPI (MPI_Irecv (Blocal, k2-k1, MPI_DOUBLE, 0,
99  /* TAG: */ c, MPI_COMM_WORLD, &(LU->LUnode [c]->req))) ;
100  }
101  }
102  }
103 
104  /* ---------------------------------------------------------------------- */
105  /* forward solve: post a receive for X from each non-local child */
106  /* ---------------------------------------------------------------------- */
107 
108  Childp = LUsymbolic->Childp ; /* Child [Childp [c]..Childp[c+1]-1] */
109  Child = LUsymbolic->Child ; /* is list of children of node c */
110 
111  for (c = 0 ; c < ncomponents ; c++)
112  {
113  if (Sched [c] == myid)
114  {
115  nchild = Childp [c+1] - Childp [c] ;
116  for (cp = 0 ; cp < nchild ; cp++)
117  {
118  child = Child [Childp [c] + cp] ;
119  if (Sched [child] != myid)
120  {
121  MPI (MPI_Irecv (LU->LUnode [child]->X,
122  LU->LUnode [child]->PK_NN, MPI_DOUBLE, Sched [child],
123  TAG0, MPI_COMM_WORLD, &(LU->LUnode [c]->Req [cp]))) ;
124  }
125  else
126  {
127  MPI (LU->LUnode [c]->Req [cp] = MPI_REQUEST_NULL) ;
128  }
129  }
130  }
131  }
132 
133  /* ---------------------------------------------------------------------- */
134  /* forward solve: Ly=b */
135  /* ---------------------------------------------------------------------- */
136 
137  for (c = 0 ; c < ncomponents ; c++)
138  {
139  if (Sched [c] == myid)
140  {
141  amesos_paraklete_lsolve_node (c, LU, LUsymbolic, Common) ;
142  }
143  }
144 
145  MPI (MPI_Barrier (MPI_COMM_WORLD)) ;
146 
147  /* ---------------------------------------------------------------------- */
148  /* backsolve: Ux=y */
149  /* ---------------------------------------------------------------------- */
150 
151  for (c = ncomponents-1 ; c >= 0 ; c--)
152  {
153  if (Sched [c] == myid)
154  {
155  amesos_paraklete_usolve_node (c, LU, LUsymbolic, Common) ;
156  }
157  }
158 
159  MPI (MPI_Barrier (MPI_COMM_WORLD)) ;
160 
161  /* ---------------------------------------------------------------------- */
162  /* get the permuted solution from each node */
163  /* ---------------------------------------------------------------------- */
164 
165  Q = LU->Q ;
166  k = 0 ;
167  for (c = 0 ; c < ncomponents ; c++)
168  {
169  X = LU->LUnode [c]->X ;
170  nfound = LU->LUnode [c]->PK_NFOUND ;
171  if (myid == 0)
172  {
173  PR1 ((Common->file, "get soln, node c="ID", nfound "ID"\n", c, nfound));
174  /* get X from node c */
175  if (Sched [c] != myid)
176  {
177  PR1 ((Common->file, "recv node "ID" from "ID"\n", c, Sched [c])) ;
178  MPI (MPI_Recv (W, nfound, MPI_DOUBLE, Sched [c],
179  TAG0, MPI_COMM_WORLD, &ms)) ;
180  X2 = W ;
181  }
182  else
183  {
184  PR1 ((Common->file, "I own it already\n")) ;
185  X2 = X ;
186  }
187  PR1 ((Common->file, "got it from Sched [c] = "ID"\n", Sched [c])) ;
188  for (i = 0 ; i < nfound ; i++)
189  {
190  B [Q [k]] = X2 [i] ;
191  PR2 ((Common->file, "X ["ID"] is global B ["ID"] %g\n",
192  i, k, X2 [i])) ;
193  k++ ;
194  }
195  }
196  else
197  {
198  if (Sched [c] == myid)
199  {
200  PR1 ((Common->file,
201  "send soln, node c = "ID", myid "ID" nfound "ID"\n",
202  c, myid, nfound)) ;
203  MPI (MPI_Send (X, nfound, MPI_DOUBLE, 0, TAG0, MPI_COMM_WORLD));
204  }
205  }
206  }
207 
208  return (TRUE) ;
209 }
#define TAG0
#define Int
Int amesos_paraklete_lsolve_node(Int c, paraklete_numeric *LU, paraklete_symbolic *LUsymbolic, paraklete_common *Common)
#define PR2(params)
#define NULL
Int amesos_paraklete_usolve_node(Int c, paraklete_numeric *LU, paraklete_symbolic *LUsymbolic, paraklete_common *Common)
#define ID
#define PR1(params)
#define MPI(statement)
Int amesos_paraklete_solve(paraklete_numeric *LU, paraklete_symbolic *LUsymbolic, double *B, paraklete_common *Common)
int n
#define TRUE