/* ----------------------------------------------- purpose -- to write the object to a matlab file return value -- 1 -- normal return -1 -- mtx is NULL -2 -- mtx is NULL -3 -- fp is NULL created -- 98may02, cca ----------------------------------------------- */ int DenseMtx_writeForMatlab ( DenseMtx *mtx, char *mtxname, FILE *fp ) { double *entries ; int inc1, inc2, irow, jcol, ncol, nrow ; int *colind, *rowind ; /* --------------- check the input --------------- */ if ( mtx == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_writeForMatlab()" "\n mtx is NULL\n") ; return(-1) ; } if ( mtxname == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_writeForMatlab()" "\n mtxname is NULL\n") ; return(-2) ; } if ( fp == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_writeForMatlab()" "\n fp is NULL\n") ; return(-3) ; } DenseMtx_rowIndices(mtx, &nrow, &rowind) ; DenseMtx_columnIndices(mtx, &ncol, &colind) ; DenseMtx_dimensions(mtx, &nrow, &ncol) ; inc1 = DenseMtx_rowIncrement(mtx) ; inc2 = DenseMtx_columnIncrement(mtx) ; entries = DenseMtx_entries(mtx) ; if ( DENSEMTX_IS_REAL(mtx) ) { for ( jcol = 0 ; jcol < ncol ; jcol++ ) { for ( irow = 0 ; irow < nrow ; irow++ ) { fprintf(fp, "\n %s(%d,%d) = %24.16e ;", mtxname, rowind[irow]+1, colind[jcol]+1, entries[irow*inc1+jcol*inc2]) ; } } } else if ( DENSEMTX_IS_COMPLEX(mtx) ) { for ( jcol = 0 ; jcol < ncol ; jcol++ ) { for ( irow = 0 ; irow < nrow ; irow++ ) { fprintf(fp, "\n %s(%d,%d) = %24.16e + %24.16e*i ;", mtxname, rowind[irow]+1, colind[jcol]+1, entries[2*(irow*inc1+jcol*inc2)], entries[2*(irow*inc1+jcol*inc2)+1]) ; } } } return(1) ; }
/* ---------------------------------------------------- purpose -- to add a row of the matrix into a vector irow -- local row id vec -- double vector to supply the row entries created -- 98aug12, cca ---------------------------------------------------- */ void DenseMtx_addVectorIntoRow ( DenseMtx *mtx, int irow, double *vec ) { double *entries ; int inc1, inc2, jcol, jj, kk, nrow, ncol ; int *colind, *rowind ; /* --------------- check the input --------------- */ if ( mtx == NULL || irow < 0 || vec == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_addVectorIntoRow()" "\n bad input, mtx %p, irow %d, vec %p\n", mtx, irow, vec) ; spoolesFatal(); } DenseMtx_rowIndices(mtx, &nrow, &rowind) ; if ( irow >= nrow ) { fprintf(stderr, "\n fatal error in DenseMtx_addVectorIntoRow()" "\n irow = %d, nrow = %d\n", irow, nrow) ; spoolesFatal(); } DenseMtx_columnIndices(mtx, &ncol, &colind) ; inc1 = DenseMtx_rowIncrement(mtx) ; inc2 = DenseMtx_columnIncrement(mtx) ; entries = DenseMtx_entries(mtx) ; if ( DENSEMTX_IS_REAL(mtx) ) { for ( jcol = jj = 0, kk = irow*inc1 ; jcol < ncol ; jcol++, jj++, kk += inc2 ) { entries[kk] += vec[jj] ; } } else if ( DENSEMTX_IS_COMPLEX(mtx) ) { for ( jcol = jj = 0, kk = irow*inc1 ; jcol < ncol ; jcol++, jj++, kk += inc2 ) { entries[2*kk] += vec[2*jj] ; entries[2*kk+1] += vec[2*jj+1] ; } } return ; }
/* --------------------------------------------------------- sort the rows so the row ids are in ascending order sort the columns so the column ids are in ascending order created -- 98may02, cca --------------------------------------------------------- */ void DenseMtx_sort ( DenseMtx *mtx ) { A2 a2 ; int ii, ncol, nrow, sortColumns, sortRows ; int *colind, *rowind ; /* ---------------- check the output ---------------- */ if ( mtx == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_sort(%p)" "\n bad input\n", mtx) ; spoolesFatal(); } DenseMtx_rowIndices(mtx, &nrow, &rowind) ; DenseMtx_columnIndices(mtx, &ncol, &colind) ; if ( nrow <= 0 || ncol <= 0 ) { return ; } sortRows = sortColumns = 0 ; for ( ii = 1 ; ii < nrow ; ii++ ) { if ( rowind[ii-1] > rowind[ii] ) { sortRows = 1 ; break ; } } for ( ii = 1 ; ii < ncol ; ii++ ) { if ( colind[ii-1] > colind[ii] ) { sortColumns = 1 ; break ; } } if ( sortRows == 0 && sortColumns == 0 ) { return ; } A2_setDefaultFields(&a2) ; DenseMtx_setA2(mtx, &a2) ; if ( sortRows == 1 ) { A2_sortRowsUp(&a2, nrow, rowind) ; } if ( sortColumns == 1 ) { A2_sortColumnsUp(&a2, ncol, colind) ; } return ; }
/* ---------------------------------------- purpose -- to write the object to a file in human readable form return value -- 1 -- normal return -1 -- mtx is NULL -2 -- fp is NULL created -- 98may02, cca ---------------------------------------- */ int DenseMtx_writeForHumanEye ( DenseMtx *mtx, FILE *fp ) { A2 a2 ; int ierr, ncol, nrow ; int *colind, *rowind ; /* --------------- check the input --------------- */ if ( mtx == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_writeForHumanEye()" "\n mtx is NULL\n") ; return(-1) ; } if ( fp == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_writeForHumanEye()" "\n mtx is NULL\n") ; return(-2) ; } DenseMtx_writeStats(mtx, fp) ; DenseMtx_rowIndices(mtx, &nrow, &rowind) ; if ( nrow > 0 && rowind != NULL ) { fprintf(fp, "\n mtx's row indices at %p", rowind) ; IVfp80(fp, nrow, rowind, 80, &ierr) ; } DenseMtx_columnIndices(mtx, &ncol, &colind) ; if ( ncol > 0 && colind != NULL ) { fprintf(fp, "\n mtx's column indices at %p", colind) ; IVfp80(fp, ncol, colind, 80, &ierr) ; } if ( nrow > 0 && ncol > 0 ) { A2_setDefaultFields(&a2) ; DenseMtx_setA2(mtx, &a2) ; A2_writeForHumanEye(&a2, fp) ; } return(1) ; }
/* ----------------------------------- compute three checksums sums[0] = sum of row indices sums[1] = sum of columns indices sums[2] = sum of entry magnitudes created -- 98may16, cca ----------------------------------- */ void DenseMtx_checksums ( DenseMtx *mtx, double sums[] ) { double *entries ; int ii, ncol, nent, nrow ; int *colind, *rowind ; /* --------------- check the input --------------- */ if ( mtx == NULL || sums == NULL ) { fprintf(stderr, "\n fatal error in DenseMtx_checksums(%p,%p)" "\n bad input\n", mtx, sums) ; spoolesFatal(); } sums[0] = sums[1] = sums[2] = 0.0 ; DenseMtx_rowIndices(mtx, &nrow, &rowind) ; for ( ii = 0 ; ii < nrow ; ii++ ) { sums[0] += rowind[ii] ; } DenseMtx_columnIndices(mtx, &ncol, &colind) ; for ( ii = 0 ; ii < ncol ; ii++ ) { sums[1] += colind[ii] ; } entries = DenseMtx_entries(mtx) ; nent = nrow*ncol ; if ( DENSEMTX_IS_REAL(mtx) ) { for ( ii = 0 ; ii < nent ; ii++ ) { sums[2] += fabs(entries[ii]) ; } } else if ( DENSEMTX_IS_COMPLEX(mtx) ) { for ( ii = 0 ; ii < nent ; ii++ ) { sums[2] += Zabs(entries[2*ii], entries[2*ii+1]) ; } } return ; }
/* -------------------------------------------- purpose -- to solve the linear system MPI version if permuteflag is 1 then rhs is permuted into new ordering solution is permuted into old ordering return value --- 1 -- normal return -1 -- bridge is NULL -2 -- X is NULL -3 -- Y is NULL -4 -- frontmtx is NULL -5 -- mtxmanager is NULL -6 -- oldToNewIV not available -7 -- newToOldIV not available created -- 98sep18, cca -------------------------------------------- */ int BridgeMPI_solve ( BridgeMPI *bridge, int permuteflag, DenseMtx *X, DenseMtx *Y ) { DenseMtx *Xloc, *Yloc ; double cputotal, t0, t1, t2 ; double cpus[6] ; FILE *msgFile ; FrontMtx *frontmtx ; int firsttag, msglvl, myid, nmycol, nrhs, nrow ; int *mycolind, *rowind ; int stats[4] ; IV *mapIV, *ownersIV ; MPI_Comm comm ; SubMtxManager *mtxmanager ; /* --------------- check the input --------------- */ MARKTIME(t0) ; if ( bridge == NULL ) { fprintf(stderr, "\n error in BridgeMPI_solve" "\n bridge is NULL\n") ; return(-1) ; } if ( (frontmtx = bridge->frontmtx) == NULL ) { fprintf(stderr, "\n error in BridgeMPI_solve" "\n frontmtx is NULL\n") ; return(-4) ; } if ( (mtxmanager = bridge->mtxmanager) == NULL ) { fprintf(stderr, "\n error in BridgeMPI_solve" "\n mtxmanager is NULL\n") ; return(-5) ; } myid = bridge->myid ; comm = bridge->comm ; msglvl = bridge->msglvl ; msgFile = bridge->msgFile ; frontmtx = bridge->frontmtx ; ownersIV = bridge->ownersIV ; Xloc = bridge->Xloc ; Yloc = bridge->Yloc ; if ( myid != 0 ) { X = Y = NULL ; } else { if ( X == NULL ) { fprintf(stderr, "\n error in BridgeMPI_solve" "\n myid 0, X is NULL\n") ; return(-2) ; } if ( Y == NULL ) { fprintf(stderr, "\n error in BridgeMPI_solve" "\n myid 0, Y is NULL\n") ; return(-3) ; } } if ( msglvl > 2 ) { fprintf(msgFile, "\n\n inside BridgeMPI_solve()") ; fflush(msgFile) ; } if ( msglvl > 2 ) { fprintf(msgFile , "\n\n Xloc") ; DenseMtx_writeForHumanEye(Xloc, msgFile) ; fprintf(msgFile , "\n\n Yloc") ; DenseMtx_writeForHumanEye(Yloc, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ if ( myid == 0 ) { /* -------------------------- optionally permute the rhs -------------------------- */ if ( permuteflag == 1 ) { int rc ; IV *oldToNewIV ; MARKTIME(t1) ; rc = BridgeMPI_oldToNewIV(bridge, &oldToNewIV) ; if (rc != 1) { fprintf(stderr, "\n error in BridgeMPI_solve()" "\n rc = %d from BridgeMPI_oldToNewIV()\n", rc) ; return(-6) ; } DenseMtx_permuteRows(Y, oldToNewIV) ; MARKTIME(t2) ; bridge->cpus[15] += t2 - t1 ; if ( msglvl > 2 ) { fprintf(msgFile , "\n\n permuted Y") ; DenseMtx_writeForHumanEye(Y, msgFile) ; fflush(msgFile) ; } } } /*--------------------------------------------------------------------*/ /* ------------------------------------- distribute the right hand side matrix ------------------------------------- */ MARKTIME(t1) ; mapIV = bridge->rowmapIV ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n row map IV object") ; IV_writeForHumanEye(mapIV, msgFile) ; fflush(msgFile) ; } if ( myid == 0 ) { nrhs = Y->ncol ; } else { nrhs = 0 ; } MPI_Bcast((void *) &nrhs, 1, MPI_INT, 0, comm) ; firsttag = 0 ; IVfill(4, stats, 0) ; DenseMtx_MPI_splitFromGlobalByRows(Y, Yloc, mapIV, 0, stats, msglvl, msgFile, firsttag, comm) ; MARKTIME(t2) ; bridge->cpus[16] += t2 - t1 ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n local matrix Y after the split") ; DenseMtx_writeForHumanEye(Yloc, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* -------------------------------------- initialize the local solution X object -------------------------------------- */ MARKTIME(t1) ; IV_sizeAndEntries(bridge->ownedColumnsIV, &nmycol, &mycolind) ; DenseMtx_init(Xloc, bridge->type, -1, -1, nmycol, nrhs, 1, nmycol) ; if ( nmycol > 0 ) { DenseMtx_rowIndices(Xloc, &nrow, &rowind) ; IVcopy(nmycol, rowind, mycolind) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n local matrix X") ; DenseMtx_writeForHumanEye(Xloc, msgFile) ; fflush(msgFile) ; } } MARKTIME(t2) ; bridge->cpus[17] += t2 - t1 ; /*--------------------------------------------------------------------*/ /* ---------------- solve the system ---------------- */ MARKTIME(t1) ; DVzero(6, cpus) ; FrontMtx_MPI_solve(frontmtx, Xloc, Yloc, mtxmanager, bridge->solvemap, cpus, stats, msglvl, msgFile, firsttag, comm) ; MARKTIME(t2) ; bridge->cpus[18] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n CPU %8.3f : solve the system", t2 - t1) ; } cputotal = t2 - t1 ; if ( cputotal > 0.0 ) { fprintf(msgFile, "\n set up solves %8.3f %6.2f" "\n load rhs and store solution %8.3f %6.2f" "\n forward solve %8.3f %6.2f" "\n diagonal solve %8.3f %6.2f" "\n backward solve %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, cputotal) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n computed solution") ; DenseMtx_writeForHumanEye(Xloc, msgFile) ; fflush(stdout) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------- gather the solution on processor zero ------------------------------------- */ MARKTIME(t1) ; DenseMtx_MPI_mergeToGlobalByRows(X, Xloc, 0, stats, msglvl, msgFile, firsttag, comm) ; MARKTIME(t2) ; bridge->cpus[19] += t2 - t1 ; if ( myid == 0 ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n\n global matrix X in new ordering") ; DenseMtx_writeForHumanEye(X, msgFile) ; fflush(msgFile) ; } } /*--------------------------------------------------------------------*/ /* ------------------------------- optionally permute the solution ------------------------------- */ if ( myid == 0 ) { if ( permuteflag == 1 ) { int rc ; IV *newToOldIV ; rc = BridgeMPI_newToOldIV(bridge, &newToOldIV) ; if (rc != 1) { fprintf(stderr, "\n error in BridgeMPI_solve()" "\n rc = %d from BridgeMPI_newToOldIV()\n", rc) ; return(-7) ; } DenseMtx_permuteRows(X, newToOldIV) ; } MARKTIME(t2) ; bridge->cpus[20] += t2 - t1 ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n global matrix X in old ordering") ; DenseMtx_writeForHumanEye(X, msgFile) ; fflush(msgFile) ; } } MARKTIME(t2) ; bridge->cpus[21] += t2 - t0 ; return(1) ; }