/* -------------------------------------------------------------------- purpose -- produce a map from each row to the front that contains it created -- 98may04, cca -------------------------------------------------------------------- */ IV * FrontMtx_rowmapIV ( FrontMtx *frontmtx ) { int ii, J, nrowJ, neqns, nfront, nJ ; int *rowindJ, *rowmap ; IV *rowmapIV ; /* -------------------------------------- get the map from rows to owning fronts -------------------------------------- */ neqns = FrontMtx_neqns(frontmtx) ; nfront = FrontMtx_nfront(frontmtx) ; rowmapIV = IV_new() ; IV_init(rowmapIV, neqns, NULL) ; rowmap = IV_entries(rowmapIV) ; IVfill(neqns, rowmap, -1) ; for ( J = 0 ; J < nfront ; J++ ) { if ( (nJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) { FrontMtx_rowIndices(frontmtx, J, &nrowJ, &rowindJ) ; if ( nrowJ > 0 && rowindJ != NULL ) { for ( ii = 0 ; ii < nJ ; ii++ ) { rowmap[rowindJ[ii]] = J ; } } } } return(rowmapIV) ; }
/* ----------------------------------------- purpose -- produce a map from each column to the front that contains it created -- 98may04, cca ----------------------------------------- */ IV * FrontMtx_colmapIV ( FrontMtx *frontmtx ) { int ii, J, ncolJ, neqns, nfront, nJ ; int *colindJ, *colmap ; IV *colmapIV ; /* ----------------------------------------- get the map from columns to owning fronts ----------------------------------------- */ neqns = FrontMtx_neqns(frontmtx) ; nfront = FrontMtx_nfront(frontmtx) ; colmapIV = IV_new() ; IV_init(colmapIV, neqns, NULL) ; colmap = IV_entries(colmapIV) ; IVfill(neqns, colmap, -1) ; for ( J = 0 ; J < nfront ; J++ ) { if ( (nJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) { FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ; if ( ncolJ > 0 && colindJ != NULL ) { for ( ii = 0 ; ii < nJ ; ii++ ) { colmap[colindJ[ii]] = J ; } } } } return(colmapIV) ; }
/* ---------------------------------------------------- purpose -- worker method to factor the matrix created -- 98may29, cca ---------------------------------------------------- */ static void * FrontMtx_QR_workerFactor ( void *arg ) { char *status ; ChvList *updlist ; ChvManager *chvmanager ; double facops, t0, t1 ; double *cpus ; DV workDV ; FILE *msgFile ; FrontMtx *frontmtx ; Ideq *dequeue ; InpMtx *mtxA ; int J, K, myid, neqns, nfront, msglvl ; int *colmap, *firstnz, *nactiveChild, *owners, *par ; IVL *rowsIVL ; QR_factorData *data ; MARKTIME(t0) ; data = (QR_factorData *) arg ; mtxA = data->mtxA ; rowsIVL = data->rowsIVL ; firstnz = data->firstnz ; IV_sizeAndEntries(data->ownersIV, &nfront, &owners) ; frontmtx = data->frontmtx ; chvmanager = data->chvmanager ; updlist = data->updlist ; myid = data->myid ; cpus = data->cpus ; msglvl = data->msglvl ; msgFile = data->msgFile ; par = frontmtx->tree->par ; neqns = FrontMtx_neqns(frontmtx) ; /* -------------------------------------------------------- status[J] = 'F' --> J finished = 'W' --> J waiting to be finished create the Ideq object to handle the bottom-up traversal nactiveChild[K] = # of unfinished children of K, when zero, K can be placed on the dequeue -------------------------------------------------------- */ status = CVinit(nfront, 'F') ; dequeue = FrontMtx_setUpDequeue(frontmtx, owners, myid, status, NULL, 'W', 'F', msglvl, msgFile) ; FrontMtx_loadActiveLeaves(frontmtx, status, 'W', dequeue) ; nactiveChild = FrontMtx_nactiveChild(frontmtx, status, myid) ; colmap = IVinit(neqns, -1) ; DV_setDefaultFields(&workDV) ; facops = 0.0 ; if ( msglvl > 3 ) { fprintf(msgFile, "\n owners") ; IVfprintf(msgFile, nfront, owners) ; fprintf(msgFile, "\n Ideq") ; Ideq_writeForHumanEye(dequeue, msgFile) ; fflush(msgFile) ; } MARKTIME(t1) ; cpus[0] += t1 - t0 ; /* --------------------------- loop while a path is active --------------------------- */ while ( (J = Ideq_removeFromHead(dequeue)) != -1 ) { if ( msglvl > 1 ) { fprintf(msgFile, "\n\n ### checking out front %d, owner %d", J, owners[J]) ; } if ( owners[J] == myid ) { /* -------------------------------- front J is ready to be processed -------------------------------- */ FrontMtx_QR_factorVisit(frontmtx, J, mtxA, rowsIVL, firstnz, updlist, chvmanager, status, colmap, &workDV, cpus, &facops, msglvl, msgFile) ; if ( status[J] == 'F' ) { /* ------------------------------------------ front J is finished, put parent on dequeue if it exists or all children are finished ------------------------------------------ */ if ( (K = par[J]) != -1 && --nactiveChild[K] == 0 ) { Ideq_insertAtHead(dequeue, K) ; } } else { /* ----------------------------------------------- front J is not complete, put on tail of dequeue ----------------------------------------------- */ Ideq_insertAtTail(dequeue, J) ; } } else { /* ------------------------------------------- front J is not owned, put parent on dequeue if it exists and all children are finished ------------------------------------------- */ if ( (K = par[J]) != -1 && --nactiveChild[K] == 0 ) { Ideq_insertAtHead(dequeue, K) ; } } } data->facops = facops ; /* ------------------------ free the working storage ------------------------ */ CVfree(status) ; Ideq_free(dequeue) ; IVfree(nactiveChild) ; IVfree(colmap) ; DV_clearData(&workDV) ; MARKTIME(t1) ; cpus[6] = t1 - t0 ; cpus[5] = t1 - t0 - cpus[0] - cpus[1] - cpus[2] - cpus[3] - cpus[4] ; return(NULL) ; }
/* ---------------------------------------------------------------- purpose -- for each L_{bnd{J},J} matrix, remove from hash table, split into their L_{K,J} submatrices and insert into the hash table. created -- 98may04, cca ---------------------------------------------------------------- */ void FrontMtx_splitLowerMatrices ( FrontMtx *frontmtx, int msglvl, FILE *msgFile ) { SubMtx *mtxLJ, *mtxLJJ, *mtxLKJ ; SubMtxManager *manager ; double *entLJ, *entLKJ ; int count, first, ii, inc1, inc2, irow, jj, J, K, nbytes, ncolLJ, ncolLKJ, nentLJ, nentLKJ, neqns, nfront, nJ, nrowJ, nrowLJ, nrowLKJ, offset, v ; int *colindLJ, *colindLKJ, *rowmap, *indicesLJ, *indicesLKJ, *locmap, *rowindJ, *rowindLJ, *rowindLKJ, *sizesLJ, *sizesLKJ ; I2Ohash *lowerhash ; /* --------------- check the input --------------- */ if ( frontmtx == NULL || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in FrontMtx_splitLowerMatrices(%p,%d,%p)" "\n bad input\n", frontmtx, msglvl, msgFile) ; spoolesFatal(); } nfront = FrontMtx_nfront(frontmtx) ; neqns = FrontMtx_neqns(frontmtx) ; lowerhash = frontmtx->lowerhash ; manager = frontmtx->manager ; /* -------------------------------- construct the row and local maps -------------------------------- */ rowmap = IVinit(neqns, -1) ; locmap = IVinit(neqns, -1) ; for ( J = 0 ; J < nfront ; J++ ) { if ( (nJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) { FrontMtx_rowIndices(frontmtx, J, &nrowJ, &rowindJ) ; if ( nrowJ > 0 && rowindJ != NULL ) { for ( ii = 0 ; ii < nJ ; ii++ ) { v = rowindJ[ii] ; rowmap[v] = J ; locmap[v] = ii ; } } } } if ( msglvl > 2 ) { fprintf(msgFile, "\n\n rowmap[]") ; IVfprintf(msgFile, neqns, rowmap) ; fprintf(msgFile, "\n\n locmap[]") ; IVfprintf(msgFile, neqns, locmap) ; fflush(msgFile) ; } /* --------------------------------------------- move the L_{J,J} matrices into the hash table --------------------------------------------- */ for ( J = 0 ; J < nfront ; J++ ) { if ( (mtxLJJ = FrontMtx_lowerMtx(frontmtx, J, J)) != NULL ) { I2Ohash_insert(frontmtx->lowerhash, J, J, mtxLJJ) ; } } /* ------------------------------------------------------------ now split the L_{bnd{J},J} matrices into L_{K,J} matrices. note: columns of L_{bnd{J},J} are assumed to be in ascending order with respect to the column ordering of the matrix. ------------------------------------------------------------ */ for ( J = 0 ; J < nfront ; J++ ) { mtxLJ = FrontMtx_lowerMtx(frontmtx, nfront, J) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ### J = %d, mtxLJ = %p", J, mtxLJ) ; fflush(msgFile) ; } if ( mtxLJ != NULL ) { if ( msglvl > 2 ) { SubMtx_writeForHumanEye(mtxLJ, msgFile) ; fflush(msgFile) ; } SubMtx_columnIndices(mtxLJ, &ncolLJ, &colindLJ) ; SubMtx_rowIndices(mtxLJ, &nrowLJ, &rowindLJ) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n column indices for J") ; IVfprintf(msgFile, ncolLJ, colindLJ) ; fprintf(msgFile, "\n row indices for LJ") ; IVfprintf(msgFile, nrowLJ, rowindLJ) ; fflush(msgFile) ; } if ( (K = rowmap[rowindLJ[0]]) == rowmap[rowindLJ[nrowLJ-1]] ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n front %d supports only %d", J, K) ; fflush(msgFile) ; } /* ------------------------------------------------- L_{bnd{J},J} is one submatrix, bnd{J} \subseteq K set row and column indices and change column id ------------------------------------------------- */ IVramp(ncolLJ, colindLJ, 0, 1) ; for ( ii = 0 ; ii < nrowLJ ; ii++ ) { rowindLJ[ii] = locmap[rowindLJ[ii]] ; } /* mtxLJ->rowid = K ; */ SubMtx_setFields(mtxLJ, mtxLJ->type, mtxLJ->mode, K, J, mtxLJ->nrow, mtxLJ->ncol, mtxLJ->nent) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting L(%d,%d) ", K, J) ; SubMtx_writeForHumanEye(mtxLJ, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(lowerhash, K, J, (void *) mtxLJ) ; } else { /* ----------------------------------- split L_{bnd{J},J} into submatrices ----------------------------------- */ nJ = FrontMtx_frontSize(frontmtx, J) ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { SubMtx_denseInfo(mtxLJ, &nrowLJ, &ncolLJ, &inc1, &inc2, &entLJ) ; } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { SubMtx_sparseRowsInfo(mtxLJ, &nrowLJ, &nentLJ, &sizesLJ, &indicesLJ, &entLJ) ; offset = 0 ; count = sizesLJ[0] ; } first = 0 ; K = rowmap[rowindLJ[0]] ; for ( irow = 1 ; irow <= nrowLJ ; irow++ ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n irow = %d", irow) ; if ( irow < nrowLJ ) { fprintf(msgFile, ", rowmap[%d] = %d", rowindLJ[irow], rowmap[rowindLJ[irow]]); } fflush(msgFile) ; } if ( irow == nrowLJ || K != rowmap[rowindLJ[irow]] ) { nrowLKJ = irow - first ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { nentLKJ = nJ*nrowLKJ ; } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { if ( count == 0 ) { goto no_entries ; } nentLKJ = count ; } nbytes = SubMtx_nbytesNeeded(mtxLJ->type, mtxLJ->mode, nrowLKJ, nJ, nentLKJ) ; mtxLKJ = SubMtxManager_newObjectOfSizeNbytes(manager, nbytes) ; SubMtx_init(mtxLKJ, mtxLJ->type, mtxLJ->mode, K, J, nrowLKJ, nJ, nentLKJ) ; if ( SUBMTX_IS_DENSE_ROWS(mtxLJ) ) { SubMtx_denseInfo(mtxLKJ, &nrowLKJ, &ncolLKJ, &inc1, &inc2, &entLKJ) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentLKJ, entLKJ, entLJ + first*nJ) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentLKJ, entLKJ, entLJ + 2*first*nJ) ; } } else if ( SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { SubMtx_sparseRowsInfo(mtxLKJ, &nrowLKJ, &nentLKJ, &sizesLKJ, &indicesLKJ, &entLKJ) ; IVcopy(nrowLKJ, sizesLKJ, sizesLJ + first) ; IVcopy(nentLKJ, indicesLKJ, indicesLJ + offset) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentLKJ, entLKJ, entLJ + offset) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentLKJ, entLKJ, entLJ + 2*offset) ; } count = 0 ; offset += nentLKJ ; } /* ------------------------------------- initialize the row and column indices ------------------------------------- */ SubMtx_rowIndices(mtxLKJ, &nrowLKJ, &rowindLKJ) ; for ( ii = 0, jj = first ; ii < nrowLKJ ; ii++, jj++ ) { rowindLKJ[ii] = locmap[rowindLJ[jj]] ; } SubMtx_columnIndices(mtxLKJ, &ncolLKJ, &colindLKJ) ; IVramp(ncolLKJ, colindLKJ, 0, 1) ; /* ---------------------------------- insert L_{K,J} into the hash table ---------------------------------- */ if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting L(%d,%d) ", K, J) ; SubMtx_writeForHumanEye(mtxLKJ, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(lowerhash, K, J, (void *) mtxLKJ) ; /* ----------------------------------- we jump to here if there were no entries to be stored in the matrix. ----------------------------------- */ no_entries : /* ---------------------------------------------------- reset first and K to new first location and front id ---------------------------------------------------- */ first = irow ; if ( irow < nrowLJ ) { K = rowmap[rowindLJ[irow]] ; } } if ( irow < nrowLJ && SUBMTX_IS_SPARSE_ROWS(mtxLJ) ) { count += sizesLJ[irow] ; } } /* -------------------------------------------- give L_{bnd{J},J} back to the matrix manager -------------------------------------------- */ SubMtxManager_releaseObject(manager, mtxLJ) ; } } } /* ------------------------ free the working storage ------------------------ */ IVfree(rowmap) ; IVfree(locmap) ; return ; }
/* ---------------------------------------------------------------- purpose -- for each U_{J,bnd{J}} matrix, remove from hash table, split into their U_{J,K} submatrices and insert into the hash table. created -- 98may04, cca ---------------------------------------------------------------- */ void FrontMtx_splitUpperMatrices ( FrontMtx *frontmtx, int msglvl, FILE *msgFile ) { SubMtx *mtxUJ, *mtxUJJ, *mtxUJK ; SubMtxManager *manager ; double *entUJ, *entUJK ; int count, first, ii, inc1, inc2, jcol, jj, J, K, nbytes, ncolJ, ncolUJ, ncolUJK, nentUJ, nentUJK, neqns, nfront, nJ, nrowUJ, nrowUJK, offset, v ; int *colindJ, *colindUJ, *colindUJK, *colmap, *indicesUJ, *indicesUJK, *locmap, *rowindUJ, *rowindUJK, *sizesUJ, *sizesUJK ; I2Ohash *upperhash ; /* --------------- check the input --------------- */ if ( frontmtx == NULL || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in FrontMtx_splitUpperMatrices(%p,%d,%p)" "\n bad input\n", frontmtx, msglvl, msgFile) ; spoolesFatal(); } nfront = FrontMtx_nfront(frontmtx) ; neqns = FrontMtx_neqns(frontmtx) ; upperhash = frontmtx->upperhash ; manager = frontmtx->manager ; /* ----------------------------------- construct the column and local maps ----------------------------------- */ colmap = IVinit(neqns, -1) ; locmap = IVinit(neqns, -1) ; for ( J = 0 ; J < nfront ; J++ ) { if ( (nJ = FrontMtx_frontSize(frontmtx, J)) > 0 ) { FrontMtx_columnIndices(frontmtx, J, &ncolJ, &colindJ) ; if ( ncolJ > 0 && colindJ != NULL ) { for ( ii = 0 ; ii < nJ ; ii++ ) { v = colindJ[ii] ; colmap[v] = J ; locmap[v] = ii ; } } } } if ( msglvl > 2 ) { fprintf(msgFile, "\n\n colmap[]") ; IVfprintf(msgFile, neqns, colmap) ; fprintf(msgFile, "\n\n locmap[]") ; IVfprintf(msgFile, neqns, locmap) ; fflush(msgFile) ; } /* --------------------------------------------- move the U_{J,J} matrices into the hash table --------------------------------------------- */ for ( J = 0 ; J < nfront ; J++ ) { if ( (mtxUJJ = FrontMtx_upperMtx(frontmtx, J, J)) != NULL ) { I2Ohash_insert(frontmtx->upperhash, J, J, mtxUJJ) ; } } /* ------------------------------------------------------------ now split the U_{J,bnd{J}} matrices into U_{J,K} matrices. note: columns of U_{J,bnd{J}} are assumed to be in ascending order with respect to the column ordering of the matrix. ------------------------------------------------------------ */ for ( J = 0 ; J < nfront ; J++ ) { mtxUJ = FrontMtx_upperMtx(frontmtx, J, nfront) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ### J = %d, mtxUJ = %p", J, mtxUJ) ; fflush(msgFile) ; } if ( mtxUJ != NULL ) { if ( msglvl > 2 ) { SubMtx_writeForHumanEye(mtxUJ, msgFile) ; fflush(msgFile) ; } SubMtx_columnIndices(mtxUJ, &ncolUJ, &colindUJ) ; SubMtx_rowIndices(mtxUJ, &nrowUJ, &rowindUJ) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n column indices for J") ; IVfprintf(msgFile, ncolUJ, colindUJ) ; fprintf(msgFile, "\n row indices for UJ") ; IVfprintf(msgFile, nrowUJ, rowindUJ) ; fflush(msgFile) ; } if ( (K = colmap[colindUJ[0]]) == colmap[colindUJ[ncolUJ-1]] ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n front %d supports only %d", J, K) ; fflush(msgFile) ; } /* ------------------------------------------------- U_{J,bnd{J}} is one submatrix, bnd{J} \subseteq K set row and column indices and change column id ------------------------------------------------- */ IVramp(nrowUJ, rowindUJ, 0, 1) ; for ( ii = 0 ; ii < ncolUJ ; ii++ ) { colindUJ[ii] = locmap[colindUJ[ii]] ; } SubMtx_setFields(mtxUJ, mtxUJ->type, mtxUJ->mode, J, K, mtxUJ->nrow, mtxUJ->ncol, mtxUJ->nent) ; /* mtxUJ->colid = K ; */ if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting U(%d,%d) ", J, K) ; SubMtx_writeForHumanEye(mtxUJ, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(upperhash, J, K, (void *) mtxUJ) ; } else { /* ----------------------------------- split U_{J,bnd{J}} into submatrices ----------------------------------- */ nJ = FrontMtx_frontSize(frontmtx, J) ; if ( SUBMTX_IS_DENSE_COLUMNS(mtxUJ) ) { SubMtx_denseInfo(mtxUJ, &nrowUJ, &ncolUJ, &inc1, &inc2, &entUJ) ; } else if ( SUBMTX_IS_SPARSE_COLUMNS(mtxUJ) ) { SubMtx_sparseColumnsInfo(mtxUJ, &ncolUJ, &nentUJ, &sizesUJ, &indicesUJ, &entUJ) ; offset = 0 ; count = sizesUJ[0] ; } first = 0 ; K = colmap[colindUJ[0]] ; for ( jcol = 1 ; jcol <= ncolUJ ; jcol++ ) { if ( msglvl > 2 ) { fprintf(msgFile, "\n jcol = %d", jcol) ; if ( jcol < ncolUJ ) { fprintf(msgFile, ", colmap[%d] = %d", colindUJ[jcol], colmap[colindUJ[jcol]]); } fflush(msgFile) ; } if ( jcol == ncolUJ || K != colmap[colindUJ[jcol]] ) { ncolUJK = jcol - first ; if ( SUBMTX_IS_DENSE_COLUMNS(mtxUJ) ) { nentUJK = nJ*ncolUJK ; } else if ( SUBMTX_IS_SPARSE_COLUMNS(mtxUJ) ) { if ( count == 0 ) { goto no_entries ; } nentUJK = count ; } nbytes = SubMtx_nbytesNeeded(mtxUJ->type, mtxUJ->mode, nJ, ncolUJK, nentUJK) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n ncolUJK %d, nentUJK %d, nbytes %d", ncolUJK, nentUJK, nbytes) ; fflush(msgFile) ; } mtxUJK = SubMtxManager_newObjectOfSizeNbytes(manager, nbytes) ; SubMtx_init(mtxUJK, mtxUJ->type, mtxUJ->mode, J, K, nJ, ncolUJK, nentUJK) ; if ( SUBMTX_IS_DENSE_COLUMNS(mtxUJ) ) { SubMtx_denseInfo(mtxUJK, &nrowUJK, &ncolUJK, &inc1, &inc2, &entUJK) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentUJK, entUJK, entUJ + first*nJ) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentUJK, entUJK, entUJ + 2*first*nJ) ; } } else if ( SUBMTX_IS_SPARSE_COLUMNS(mtxUJ) ) { SubMtx_sparseColumnsInfo(mtxUJK, &ncolUJK, &nentUJK, &sizesUJK, &indicesUJK, &entUJK) ; IVcopy(ncolUJK, sizesUJK, sizesUJ + first) ; IVcopy(nentUJK, indicesUJK, indicesUJ + offset) ; if ( FRONTMTX_IS_REAL(frontmtx) ) { DVcopy(nentUJK, entUJK, entUJ + offset) ; } else if ( FRONTMTX_IS_COMPLEX(frontmtx) ) { DVcopy(2*nentUJK, entUJK, entUJ + 2*offset) ; } count = 0 ; offset += nentUJK ; } /* ------------------------------------- initialize the row and column indices ------------------------------------- */ if ( msglvl > 2 ) { fprintf(msgFile, "\n setting row and column indices"); fflush(msgFile) ; } SubMtx_rowIndices(mtxUJK, &nrowUJK, &rowindUJK) ; IVramp(nJ, rowindUJK, 0, 1) ; SubMtx_columnIndices(mtxUJK, &ncolUJK, &colindUJK) ; for ( ii = 0, jj = first ; ii < ncolUJK ; ii++, jj++ ) { colindUJK[ii] = locmap[colindUJ[jj]] ; } /* ---------------------------------- insert U_{J,K} into the hash table ---------------------------------- */ if ( msglvl > 2 ) { fprintf(msgFile, "\n\n ## inserting U(%d,%d) ", J, K) ; SubMtx_writeForHumanEye(mtxUJK, msgFile) ; fflush(msgFile) ; } I2Ohash_insert(upperhash, J, K, (void *) mtxUJK) ; /* ----------------------------------- we jump to here if there were no entries to be stored in the matrix. ----------------------------------- */ no_entries : /* ---------------------------------------------------- reset first and K to new first location and front id ---------------------------------------------------- */ first = jcol ; if ( jcol < ncolUJ ) { K = colmap[colindUJ[jcol]] ; } } if ( jcol < ncolUJ && SUBMTX_IS_SPARSE_COLUMNS(mtxUJ) ) { count += sizesUJ[jcol] ; } } /* -------------------------------------------- give U_{J,bnd{J}} back to the matrix manager -------------------------------------------- */ SubMtxManager_releaseObject(manager, mtxUJ) ; } } } /* ------------------------ free the working storage ------------------------ */ IVfree(colmap) ; IVfree(locmap) ; return ; }
/* -------------------------------------------------------------------- purpose -- to setup two data structures for a QR serial or multithreaded factorization rowsIVL[J] -- list of rows of A to be assembled into front J firstnz[irow] -- column with location of leading nonzero of row in A created -- 98may29, cca -------------------------------------------------------------------- */ void FrontMtx_QR_setup ( FrontMtx *frontmtx, InpMtx *mtxA, IVL **prowsIVL, int **pfirstnz, int msglvl, FILE *msgFile ) { int count, irow, jcol, J, loc, neqns, nfront, nrowA, rowsize ; int *firstnz, *head, *link, *list, *rowind, *vtxToFront ; IVL *rowsIVL ; /* --------------- check the input --------------- */ if ( frontmtx == NULL || mtxA == NULL || prowsIVL == NULL || pfirstnz == NULL || (msglvl > 0 && msgFile == NULL) ) { fprintf(stderr, "\n fatal error in FrontMtx_QR_setup()" "\n bad input\n") ; exit(-1) ; } neqns = FrontMtx_neqns(frontmtx) ; nfront = FrontMtx_nfront(frontmtx) ; vtxToFront = ETree_vtxToFront(frontmtx->frontETree) ; /* ---------------------------------------------------------------- create the rowsIVL object, list(J) = list of rows that are assembled in front J firstnz[irowA] = first column with nonzero element in A(irowA,*) ---------------------------------------------------------------- */ InpMtx_changeCoordType(mtxA, INPMTX_BY_ROWS) ; InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; nrowA = 1 + IVmax(InpMtx_nent(mtxA), InpMtx_ivec1(mtxA), &loc) ; if ( msglvl > 3 ) { fprintf(msgFile, "\n nrowA = %d ", nrowA) ; fflush(msgFile) ; } firstnz = IVinit(nrowA, -1) ; head = IVinit(nfront, -1) ; link = IVinit(nrowA, -1) ; for ( irow = nrowA - 1 ; irow >= 0 ; irow-- ) { InpMtx_vector(mtxA, irow, &rowsize, &rowind) ; if ( rowsize > 0 ) { firstnz[irow] = jcol = rowind[0] ; J = vtxToFront[jcol] ; link[irow] = head[J] ; head[J] = irow ; } } rowsIVL = IVL_new() ; IVL_init2(rowsIVL, IVL_CHUNKED, nfront, nrowA) ; list = IVinit(neqns, -1) ; for ( J = 0 ; J < nfront ; J++ ) { count = 0 ; for ( irow = head[J] ; irow != -1 ; irow = link[irow] ) { list[count++] = irow ; } if ( count > 0 ) { IVL_setList(rowsIVL, J, count, list) ; } } IVfree(head) ; IVfree(link) ; IVfree(list) ; /* --------------------------- set the pointers for return --------------------------- */ *prowsIVL = rowsIVL ; *pfirstnz = firstnz ; return ; }