/* factor.c */
#include "../BridgeMPI.h"
/*--------------------------------------------------------------------*/
/*
--------------------------------------------------------------
purpose -- to permute (if necessary) the original matrix,
and to initialize, factor and postprocess the factor matrix
if permuteflag == 1 then
matrix is permuted into new ordering
endif
return value ---
1 -- normal return, factorization complete
0 -- factorization did not complete, see error flag
-1 -- bridge is NULL
-2 -- perror is NULL
created -- 98sep18, cca
--------------------------------------------------------------
*/
int
BridgeMPI_factor (
BridgeMPI *bridge,
InpMtx *mtxA,
int permuteflag,
int *perror
) {
Chv *rootchv ;
ChvManager *chvmanager ;
double cputotal, nfops, t0, t1, t2 ;
double cpus[20] ;
int firsttag, msglvl, myid, neqns, nproc, nzf ;
int stats[20] ;
InpMtx *Aloc ;
FILE *msgFile ;
FrontMtx *frontmtx ;
SubMtxManager *mtxmanager ;
/*--------------------------------------------------------------------*/
MARKTIME(t0) ;
/*
---------------
check the input
---------------
*/
if ( bridge == NULL ) {
fprintf(stderr, "\n error in BridgeMPI_factor()"
"\n bridge is NULL\n") ;
return(-1) ;
}
if ( perror == NULL ) {
fprintf(stderr, "\n error in BridgeMPI_factor()"
"\n perror is NULL\n") ;
return(-2) ;
}
msglvl = bridge->msglvl ;
msgFile = bridge->msgFile ;
neqns = bridge->neqns ;
myid = bridge->myid ;
nproc = bridge->nproc ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n all set in BridgeMPI_factor()") ;
fprintf(msgFile, "\n myid = %d", myid) ;
fprintf(msgFile, "\n permuteflag = %d", permuteflag) ;
fflush(msgFile) ;
}
/*--------------------------------------------------------------------*/
MARKTIME(t1) ;
if ( myid == 0 ) {
if ( permuteflag == 1 ) {
int *oldToNew = IV_entries(bridge->oldToNewIV) ;
/*
------------------------------------------------
permute the input matrix and convert to chevrons
------------------------------------------------
*/
InpMtx_permute(mtxA, oldToNew, oldToNew) ;
if ( bridge->symmetryflag == SPOOLES_SYMMETRIC
|| bridge->symmetryflag == SPOOLES_HERMITIAN ) {
InpMtx_mapToUpperTriangle(mtxA) ;
}
}
if ( ! INPMTX_IS_BY_CHEVRONS(mtxA) ) {
InpMtx_changeCoordType(mtxA, INPMTX_BY_CHEVRONS) ;
}
if ( ! INPMTX_IS_BY_VECTORS(mtxA) ) {
InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ;
}
MARKTIME(t2) ;
bridge->cpus[8] += t2 - t1 ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n CPU %8.3f : permute and format A", t2 - t1) ;
fflush(msgFile) ;
}
}
/*--------------------------------------------------------------------*/
/*
---------------------------------
distribute the front matrix.
processor 0 scatters the entries
to all the other processors.
--------------------------------
*/
MARKTIME(t1) ;
if ( myid != 0 ) {
mtxA = NULL ;
}
firsttag = 0 ;
IVzero(4, stats) ;
Aloc = bridge->Aloc = InpMtx_MPI_splitFromGlobal(mtxA, NULL,
bridge->vtxmapIV, 0, stats, msglvl,
msgFile, firsttag, bridge->comm) ;
if ( Aloc != NULL ) {
InpMtx_changeStorageMode(Aloc, INPMTX_BY_VECTORS) ;
}
MARKTIME(t2) ;
bridge->cpus[9] += t2 - t1 ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n CPU %8.3f : distribute A", t2 - t1) ;
fflush(msgFile) ;
}
if ( Aloc != NULL && msglvl > 1 ) {
fprintf(msgFile, "\n\n permuted and split InpMtx") ;
InpMtx_writeForHumanEye(Aloc, msgFile) ;
fflush(msgFile) ;
}
/*--------------------------------------------------------------------*/
/*
---------------------------
initialize the front matrix
---------------------------
*/
MARKTIME(t1) ;
if ( (mtxmanager = bridge->mtxmanager) == NULL ) {
mtxmanager = bridge->mtxmanager = SubMtxManager_new() ;
SubMtxManager_init(mtxmanager, NO_LOCK, 0) ;
}
if ( (frontmtx = bridge->frontmtx) == NULL ) {
frontmtx = bridge->frontmtx = FrontMtx_new() ;
} else {
FrontMtx_clearData(frontmtx) ;
}
FrontMtx_init(frontmtx, bridge->frontETree, bridge->symbfacIVL,
bridge->type, bridge->symmetryflag, bridge->sparsityflag,
bridge->pivotingflag, NO_LOCK, myid, bridge->ownersIV,
mtxmanager, bridge->msglvl, bridge->msgFile) ;
frontmtx->patchinfo = bridge->patchinfo ;
MARKTIME(t2) ;
bridge->cpus[10] += t2 - t1 ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n CPU %8.3f : initialize front matrix", t2 - t1) ;
fflush(msgFile) ;
}
if ( msglvl > 2 ) {
fprintf(msgFile, "\n\n bridge ownersIV") ;
IV_writeForHumanEye(bridge->ownersIV, msgFile) ;
fflush(msgFile) ;
}
/*--------------------------------------------------------------------*/
/*
-----------------
factor the matrix
-----------------
*/
nzf = ETree_nFactorEntries(bridge->frontETree, bridge->symmetryflag) ;
nfops = ETree_nFactorOps(bridge->frontETree,
bridge->type, bridge->symmetryflag) ;
if ( msglvl > 1 ) {
fprintf(msgFile,
"\n %d factor entries, %.0f factor ops, %8.3f ratio",
nzf, nfops, nfops/nzf) ;
fflush(msgFile) ;
}
IVzero(20, stats) ;
DVzero(20, cpus) ;
chvmanager = ChvManager_new() ;
ChvManager_init(chvmanager, NO_LOCK, 1) ;
MARKTIME(t1) ;
rootchv = FrontMtx_MPI_factorInpMtx(frontmtx, Aloc, bridge->tau,
bridge->droptol, chvmanager, bridge->ownersIV,
bridge->lookahead, perror, cpus, stats, bridge->msglvl,
bridge->msgFile, firsttag, bridge->comm) ;
MARKTIME(t2) ;
firsttag += 4*bridge->frontmtx->nfront ;
IVcopy(6, bridge->stats, stats) ;
bridge->cpus[11] += t2 - t1 ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n\n CPU %8.3f : factor matrix, %8.3f mflops",
t2 - t1, 1.e-6*nfops/(t2-t1)) ;
fprintf(msgFile,
"\n %8d pivots, %8d pivot tests, %8d delayed vertices"
"\n %d entries in D, %d entries in L, %d entries in U",
stats[0], stats[1], stats[2], stats[3], stats[4], stats[5]) ;
cputotal = cpus[8] ;
if ( cputotal > 0.0 ) {
fprintf(msgFile,
"\n initialize fronts %8.3f %6.2f"
"\n load original entries %8.3f %6.2f"
"\n update fronts %8.3f %6.2f"
"\n assemble postponed data %8.3f %6.2f"
"\n factor fronts %8.3f %6.2f"
"\n extract postponed data %8.3f %6.2f"
"\n store factor entries %8.3f %6.2f"
"\n miscellaneous %8.3f %6.2f"
"\n total time %8.3f",
cpus[0], 100.*cpus[0]/cputotal,
cpus[1], 100.*cpus[1]/cputotal,
cpus[2], 100.*cpus[2]/cputotal,
cpus[3], 100.*cpus[3]/cputotal,
cpus[4], 100.*cpus[4]/cputotal,
cpus[5], 100.*cpus[5]/cputotal,
cpus[6], 100.*cpus[6]/cputotal,
cpus[7], 100.*cpus[7]/cputotal, cputotal) ;
}
}
if ( msglvl > 2 ) {
fprintf(msgFile, "\n\n submatrix mananger after factorization") ;
SubMtxManager_writeForHumanEye(mtxmanager, msgFile) ;
fprintf(msgFile, "\n\n chevron mananger after factorization") ;
ChvManager_writeForHumanEye(chvmanager, msgFile) ;
fflush(msgFile) ;
}
if ( msglvl > 3 ) {
fprintf(msgFile, "\n\n front factor matrix") ;
FrontMtx_writeForHumanEye(frontmtx, msgFile) ;
fflush(msgFile) ;
}
ChvManager_free(chvmanager) ;
if ( *perror >= 0 ) {
return(0) ;
}
/*
-----------------------------
post-process the front matrix
-----------------------------
*/
MARKTIME(t1) ;
IVzero(4, stats) ;
FrontMtx_MPI_postProcess(frontmtx, bridge->ownersIV, stats,
msglvl, msgFile, firsttag, bridge->comm) ;
MARKTIME(t2) ;
bridge->cpus[12] += t2 - t1 ;
if ( msglvl > 1 ) {
fprintf(msgFile,
"\n\n CPU %8.3f : post-process the matrix", t2 - t1) ;
fflush(msgFile) ;
}
if ( msglvl > 2 ) {
fprintf(msgFile, "\n\n submatrix mananger after post-processing") ;
SubMtxManager_writeForHumanEye(frontmtx->manager, msgFile) ;
fflush(msgFile) ;
}
if ( msglvl > 3 ) {
fprintf(msgFile, "\n\n front factor matrix after post-processing") ;
FrontMtx_writeForHumanEye(frontmtx, msgFile) ;
fflush(msgFile) ;
}
/*--------------------------------------------------------------------*/
MARKTIME(t2) ;
bridge->cpus[13] += t2 - t0 ;
if ( msglvl > 1 ) {
fprintf(msgFile, "\n\n CPU %8.3f : total factor time", t2 - t0) ;
fflush(msgFile) ;
}
return(1) ; }
/*--------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1