1 /*  postponed.c  */
2 
3 #include "../FrontMtx.h"
4 
5 #define MYDEBUG 0
6 
7 /*--------------------------------------------------------------------*/
8 /*
9    ------------------------------------------------------------------
10    purpose -- to assemble any postponed data into frontJ
11 
12    frontJ  -- pointer to Chv objec that contains current front
13    chvlist -- pointer to a ChvList object that handles the
14               lists of postponed Chv objects
15    chvmanager -- pointer to a ChvManager object for the list
16                  of free Chv objects
17    pndelay -- pointer to address to contain the # of delayed rows
18               and columns that were assembled into the front
19 
20    return value -- pointer to Chv object that contains the new front
21 
22    created -- 98may04, cca
23    ------------------------------------------------------------------
24 */
25 Chv *
FrontMtx_assemblePostponedData(FrontMtx * frontmtx,Chv * frontJ,ChvList * chvlist,ChvManager * chvmanager,int * pndelay)26 FrontMtx_assemblePostponedData (
27    FrontMtx     *frontmtx,
28    Chv          *frontJ,
29    ChvList      *chvlist,
30    ChvManager   *chvmanager,
31    int          *pndelay
32 ) {
33 Chv   *child, *child2, *firstchild, *newfrontJ, *nextchild, *prev ;
34 int    nbytes, nDnew ;
35 
36 if ( (firstchild = ChvList_getList(chvlist, frontJ->id)) == NULL ) {
37 /*
38    -------------------------------------
39    quick return, no children to assemble
40    -------------------------------------
41 */
42    *pndelay = 0 ;
43    return(frontJ) ;
44 }
45 /*
46    -------------------------------------------------------
47    order the children in ascending order of their front id
48    this is done to ensure that the serial, multithreaded
49    and MPI codes all assemble the same frontal matrix.
50    -------------------------------------------------------
51 */
52 #if MYDEBUG > 0
53 fprintf(stdout, "\n postponed children of %d :", frontJ->id) ;
54 for ( child = firstchild ; child != NULL ; child = child->next ) {
55    fprintf(stdout, " %d", child->id) ;
56 }
57 fflush(stdout) ;
58 #endif
59 for ( child = firstchild, firstchild = NULL ;
60       child != NULL ;
61       child = nextchild ) {
62    nextchild = child->next ;
63    for ( child2 = firstchild, prev = NULL ;
64          child2 != NULL ;
65          child2 = child2->next ) {
66       if ( child2->id > child->id ) {
67          break ;
68       }
69       prev = child2 ;
70    }
71    if ( prev == NULL ) {
72       firstchild = child ;
73    } else {
74       prev->next = child ;
75    }
76    child->next = child2 ;
77 }
78 #if MYDEBUG > 0
79 fprintf(stdout, "\n front %d, postponed children reordered :",
80         frontJ->id) ;
81 for ( child = firstchild ; child != NULL ; child = child->next ) {
82    fprintf(stdout, " %d", child->id) ;
83 }
84 fflush(stdout) ;
85 #endif
86 /*
87    --------------------------
88    compute the new dimensions
89    --------------------------
90 */
91 nDnew = frontJ->nD ;
92 for ( child = firstchild ; child != NULL ; child = child->next ) {
93    nDnew += child->nD ;
94 }
95 /*
96    ------------------------
97    get a new chevron object
98    ------------------------
99 */
100 nbytes = Chv_nbytesNeeded(nDnew, frontJ->nL, frontJ->nU,
101                           frontJ->type, frontJ->symflag) ;
102 newfrontJ = ChvManager_newObjectOfSizeNbytes(chvmanager, nbytes) ;
103 Chv_init(newfrontJ, frontJ->id, nDnew, frontJ->nL, frontJ->nU,
104          frontJ->type, frontJ->symflag) ;
105 /*
106    ----------------------------------------------------------
107    pivoting has been enabled, assemble any postponed chevrons
108    ----------------------------------------------------------
109 */
110 *pndelay = Chv_assemblePostponedData(newfrontJ, frontJ, firstchild) ;
111 /*
112    --------------------------------------------------
113    now put the postponed chevrons onto the free list.
114    --------------------------------------------------
115 */
116 ChvManager_releaseListOfObjects(chvmanager, firstchild) ;
117 /*
118    -------------------------------------
119    set the delay to zero if a root front
120    -------------------------------------
121 */
122 if ( frontJ->nU == 0 ) {
123    *pndelay = 0 ;
124 }
125 return(newfrontJ) ; }
126 
127 /*--------------------------------------------------------------------*/
128 /*
129    ---------------------------------------------------------
130    purpose -- extract and store the postponed data
131 
132    frontJ  -- pointer to present front object
133    npost   -- # of postponed rows and columns in frontJ
134    K       -- parent of J
135    chvlist -- pointer to a ChvList object that handles the
136               lists of postponed Chv objects
137               a singly linked list to assemble
138    chvmanager -- pointer to a ChvManager object for the list
139                  of free Chv objects
140 
141    created -- 98may04, cca
142    ---------------------------------------------------------
143 */
144 void
FrontMtx_storePostponedData(FrontMtx * frontmtx,Chv * frontJ,int npost,int K,ChvList * chvlist,ChvManager * chvmanager)145 FrontMtx_storePostponedData (
146    FrontMtx     *frontmtx,
147    Chv          *frontJ,
148    int          npost,
149    int          K,
150    ChvList      *chvlist,
151    ChvManager   *chvmanager
152 ) {
153 Chv   *chv ;
154 int    nbytes, nD, nent, nind, nL, nU ;
155 
156 if ( npost <= 0 && chvlist != NULL ) {
157    if ( K == -1 ) {
158       ChvList_addObjectToList(chvlist, NULL, frontmtx->nfront) ;
159    } else {
160       ChvList_addObjectToList(chvlist, NULL, K) ;
161    }
162    return ;
163 }
164 /*
165    --------------------------------------
166    find the number of indices and entries
167    necessary to store the delayed data
168    --------------------------------------
169 */
170 Chv_dimensions(frontJ, &nD, &nL, &nU) ;
171 #if MYDEBUG > 0
172 fprintf(stdout, "\n\n front %d: npost = %d, nD = %d, nL = %d, nU = %d",
173         frontJ->id, npost, nD, nL, nU) ;
174 fflush(stdout) ;
175 #endif
176 if ( CHV_IS_SYMMETRIC(frontJ) || CHV_IS_HERMITIAN(frontJ) ) {
177    nind = npost + nU ;
178    nent = (npost*(npost+1))/2 + npost*nU ;
179 } else if ( CHV_IS_NONSYMMETRIC(frontJ) ) {
180    nind = 2*(npost + nU) ;
181    nent = npost*(npost + 2*nU) ;
182 }
183 /*
184    ------------------------------------
185    get a Chv object from the free list
186    ------------------------------------
187 */
188 nbytes = Chv_nbytesNeeded(npost, nL, nU, frontJ->type, frontJ->symflag);
189 chv = ChvManager_newObjectOfSizeNbytes(chvmanager, nbytes) ;
190 Chv_init(chv, frontJ->id, npost, nL, nU, frontJ->type, frontJ->symflag);
191 /*
192    ----------------------
193    store the delayed data
194    ----------------------
195 */
196 Chv_copyTrailingPortion(chv, frontJ, nD - npost) ;
197 frontJ->nD -= npost ;
198 frontJ->nL += npost ;
199 frontJ->nU += npost ;
200 #if MYDEBUG > 0
201 fprintf(stdout, "\n\n postponed chevron %p", chv) ;
202 Chv_writeForHumanEye(chv, stdout) ;
203 fflush(stdout) ;
204 #endif
205 /*
206    ------------------------------
207    link the postponed Chv object
208    ------------------------------
209 */
210 if ( K == -1 ) {
211    ChvList_addObjectToList(chvlist, chv, frontmtx->nfront) ;
212 } else {
213    ChvList_addObjectToList(chvlist, chv, K) ;
214 }
215 return ; }
216 
217 /*--------------------------------------------------------------------*/
218