/* postponed.c */
#include "../FrontMtx.h"
#define MYDEBUG 0
/*--------------------------------------------------------------------*/
/*
------------------------------------------------------------------
purpose -- to assemble any postponed data into frontJ
frontJ -- pointer to Chv objec that contains current front
chvlist -- pointer to a ChvList object that handles the
lists of postponed Chv objects
chvmanager -- pointer to a ChvManager object for the list
of free Chv objects
pndelay -- pointer to address to contain the # of delayed rows
and columns that were assembled into the front
return value -- pointer to Chv object that contains the new front
created -- 98may04, cca
------------------------------------------------------------------
*/
Chv *
FrontMtx_assemblePostponedData (
FrontMtx *frontmtx,
Chv *frontJ,
ChvList *chvlist,
ChvManager *chvmanager,
int *pndelay
) {
Chv *child, *child2, *firstchild, *newfrontJ, *nextchild, *prev ;
int nbytes, nDnew ;
if ( (firstchild = ChvList_getList(chvlist, frontJ->id)) == NULL ) {
/*
-------------------------------------
quick return, no children to assemble
-------------------------------------
*/
*pndelay = 0 ;
return(frontJ) ;
}
/*
-------------------------------------------------------
order the children in ascending order of their front id
this is done to ensure that the serial, multithreaded
and MPI codes all assemble the same frontal matrix.
-------------------------------------------------------
*/
#if MYDEBUG > 0
fprintf(stdout, "\n postponed children of %d :", frontJ->id) ;
for ( child = firstchild ; child != NULL ; child = child->next ) {
fprintf(stdout, " %d", child->id) ;
}
fflush(stdout) ;
#endif
for ( child = firstchild, firstchild = NULL ;
child != NULL ;
child = nextchild ) {
nextchild = child->next ;
for ( child2 = firstchild, prev = NULL ;
child2 != NULL ;
child2 = child2->next ) {
if ( child2->id > child->id ) {
break ;
}
prev = child2 ;
}
if ( prev == NULL ) {
firstchild = child ;
} else {
prev->next = child ;
}
child->next = child2 ;
}
#if MYDEBUG > 0
fprintf(stdout, "\n front %d, postponed children reordered :",
frontJ->id) ;
for ( child = firstchild ; child != NULL ; child = child->next ) {
fprintf(stdout, " %d", child->id) ;
}
fflush(stdout) ;
#endif
/*
--------------------------
compute the new dimensions
--------------------------
*/
nDnew = frontJ->nD ;
for ( child = firstchild ; child != NULL ; child = child->next ) {
nDnew += child->nD ;
}
/*
------------------------
get a new chevron object
------------------------
*/
nbytes = Chv_nbytesNeeded(nDnew, frontJ->nL, frontJ->nU,
frontJ->type, frontJ->symflag) ;
newfrontJ = ChvManager_newObjectOfSizeNbytes(chvmanager, nbytes) ;
Chv_init(newfrontJ, frontJ->id, nDnew, frontJ->nL, frontJ->nU,
frontJ->type, frontJ->symflag) ;
/*
----------------------------------------------------------
pivoting has been enabled, assemble any postponed chevrons
----------------------------------------------------------
*/
*pndelay = Chv_assemblePostponedData(newfrontJ, frontJ, firstchild) ;
/*
--------------------------------------------------
now put the postponed chevrons onto the free list.
--------------------------------------------------
*/
ChvManager_releaseListOfObjects(chvmanager, firstchild) ;
/*
-------------------------------------
set the delay to zero if a root front
-------------------------------------
*/
if ( frontJ->nU == 0 ) {
*pndelay = 0 ;
}
return(newfrontJ) ; }
/*--------------------------------------------------------------------*/
/*
---------------------------------------------------------
purpose -- extract and store the postponed data
frontJ -- pointer to present front object
npost -- # of postponed rows and columns in frontJ
K -- parent of J
chvlist -- pointer to a ChvList object that handles the
lists of postponed Chv objects
a singly linked list to assemble
chvmanager -- pointer to a ChvManager object for the list
of free Chv objects
created -- 98may04, cca
---------------------------------------------------------
*/
void
FrontMtx_storePostponedData (
FrontMtx *frontmtx,
Chv *frontJ,
int npost,
int K,
ChvList *chvlist,
ChvManager *chvmanager
) {
Chv *chv ;
int nbytes, nD, nent, nind, nL, nU ;
if ( npost <= 0 && chvlist != NULL ) {
if ( K == -1 ) {
ChvList_addObjectToList(chvlist, NULL, frontmtx->nfront) ;
} else {
ChvList_addObjectToList(chvlist, NULL, K) ;
}
return ;
}
/*
--------------------------------------
find the number of indices and entries
necessary to store the delayed data
--------------------------------------
*/
Chv_dimensions(frontJ, &nD, &nL, &nU) ;
#if MYDEBUG > 0
fprintf(stdout, "\n\n front %d: npost = %d, nD = %d, nL = %d, nU = %d",
frontJ->id, npost, nD, nL, nU) ;
fflush(stdout) ;
#endif
if ( CHV_IS_SYMMETRIC(frontJ) || CHV_IS_HERMITIAN(frontJ) ) {
nind = npost + nU ;
nent = (npost*(npost+1))/2 + npost*nU ;
} else if ( CHV_IS_NONSYMMETRIC(frontJ) ) {
nind = 2*(npost + nU) ;
nent = npost*(npost + 2*nU) ;
}
/*
------------------------------------
get a Chv object from the free list
------------------------------------
*/
nbytes = Chv_nbytesNeeded(npost, nL, nU, frontJ->type, frontJ->symflag);
chv = ChvManager_newObjectOfSizeNbytes(chvmanager, nbytes) ;
Chv_init(chv, frontJ->id, npost, nL, nU, frontJ->type, frontJ->symflag);
/*
----------------------
store the delayed data
----------------------
*/
Chv_copyTrailingPortion(chv, frontJ, nD - npost) ;
frontJ->nD -= npost ;
frontJ->nL += npost ;
frontJ->nU += npost ;
#if MYDEBUG > 0
fprintf(stdout, "\n\n postponed chevron %p", chv) ;
Chv_writeForHumanEye(chv, stdout) ;
fflush(stdout) ;
#endif
/*
------------------------------
link the postponed Chv object
------------------------------
*/
if ( K == -1 ) {
ChvList_addObjectToList(chvlist, chv, frontmtx->nfront) ;
} else {
ChvList_addObjectToList(chvlist, chv, K) ;
}
return ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1