/* ---------------------------------- return an IVL object that contains the adjacency structure of A^TA. created -- 98jan28, cca ---------------------------------- */ IVL * InpMtx_adjForATA ( InpMtx *inpmtxA ) { InpMtx *inpmtxATA ; int firstcol, firstrow, irow, jvtx, lastcol, lastrow, loc, ncol, nent, nrow, size ; int *ind, *ivec1, *ivec2 ; IVL *adjIVL ; /* --------------- check the input --------------- */ if ( inpmtxA == NULL ) { fprintf(stderr, "\n fatal error in InpMtx_adjForATA(%p)" "\n NULL input\n", inpmtxA) ; exit(-1) ; } /* ---------------------------------------------------------- change the coordinate type and storage mode to row vectors ---------------------------------------------------------- */ InpMtx_changeCoordType(inpmtxA, INPMTX_BY_ROWS) ; InpMtx_changeStorageMode(inpmtxA, INPMTX_BY_VECTORS) ; nent = InpMtx_nent(inpmtxA) ; ivec1 = InpMtx_ivec1(inpmtxA) ; ivec2 = InpMtx_ivec2(inpmtxA) ; firstrow = IVmin(nent, ivec1, &loc) ; lastrow = IVmax(nent, ivec1, &loc) ; firstcol = IVmin(nent, ivec2, &loc) ; lastcol = IVmax(nent, ivec2, &loc) ; if ( firstrow < 0 || firstcol < 0 ) { fprintf(stderr, "\n fatal error" "\n firstrow = %d, firstcol = %d" "\n lastrow = %d, lastcol = %d", firstrow, firstcol, lastrow, lastcol) ; exit(-1) ; } nrow = 1 + lastrow ; ncol = 1 + lastcol ; /* ----------------------------------------------------------- create the new InpMtx object to hold the structure of A^TA ----------------------------------------------------------- */ inpmtxATA = InpMtx_new() ; InpMtx_init(inpmtxATA, INPMTX_BY_ROWS, INPMTX_INDICES_ONLY, 0, 0) ; for ( irow = 0 ; irow < nrow ; irow++ ) { InpMtx_vector(inpmtxA, irow, &size, &ind) ; InpMtx_inputMatrix(inpmtxATA, size, size, 1, size, ind, ind) ; } for ( jvtx = 0 ; jvtx < nrow ; jvtx++ ) { InpMtx_inputEntry(inpmtxATA, jvtx, jvtx) ; } InpMtx_changeStorageMode(inpmtxATA, INPMTX_BY_VECTORS) ; /* ------------------- fill the IVL object ------------------- */ adjIVL = IVL_new() ; IVL_init1(adjIVL, IVL_CHUNKED, nrow) ; for ( jvtx = 0 ; jvtx < ncol ; jvtx++ ) { InpMtx_vector(inpmtxATA, jvtx, &size, &ind) ; IVL_setList(adjIVL, jvtx, size, ind) ; } /* ------------------------------ free the working InpMtx object ------------------------------ */ InpMtx_free(inpmtxATA) ; return(adjIVL) ; }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) { /* -------------------------------------------------- QR all-in-one program (1) read in matrix entries and form InpMtx object of A and A^TA (2) form Graph object of A^TA (3) order matrix and form front tree (4) get the permutation, permute the matrix and front tree and get the symbolic factorization (5) compute the numeric factorization (6) read in right hand side entries (7) compute the solution created -- 98jun11, cca -------------------------------------------------- */ /*--------------------------------------------------------------------*/ char *matrixFileName, *rhsFileName ; ChvManager *chvmanager ; DenseMtx *mtxB, *mtxX ; double facops, imag, real, value ; double cpus[10] ; ETree *frontETree ; FILE *inputFile, *msgFile ; FrontMtx *frontmtx ; Graph *graph ; int ient, irow, jcol, jrhs, jrow, msglvl, neqns, nedges, nent, nrhs, nrow, seed, type ; InpMtx *mtxA ; IV *newToOldIV, *oldToNewIV ; IVL *adjIVL, *symbfacIVL ; SubMtxManager *mtxmanager ; /*--------------------------------------------------------------------*/ /* -------------------- get input parameters -------------------- */ if ( argc != 7 ) { fprintf(stdout, "\n usage: %s msglvl msgFile type matrixFileName rhsFileName seed" "\n msglvl -- message level" "\n msgFile -- message file" "\n type -- type of entries" "\n 1 (SPOOLES_REAL) -- real entries" "\n 2 (SPOOLES_COMPLEX) -- complex entries" "\n matrixFileName -- matrix file name, format" "\n nrow ncol nent" "\n irow jcol entry" "\n ..." "\n note: indices are zero based" "\n rhsFileName -- right hand side file name, format" "\n nrow " "\n entry[0]" "\n ..." "\n entry[nrow-1]" "\n seed -- random number seed, used for ordering" "\n", argv[0]) ; return(0) ; } msglvl = atoi(argv[1]) ; if ( strcmp(argv[2], "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) { fprintf(stderr, "\n fatal error in %s" "\n unable to open file %s\n", argv[0], argv[2]) ; return(-1) ; } type = atoi(argv[3]) ; matrixFileName = argv[4] ; rhsFileName = argv[5] ; seed = atoi(argv[6]) ; /*--------------------------------------------------------------------*/ /* -------------------------------------------- STEP 1: read the entries from the input file and create the InpMtx object of A -------------------------------------------- */ inputFile = fopen(matrixFileName, "r") ; fscanf(inputFile, "%d %d %d", &nrow, &neqns, &nent) ; mtxA = InpMtx_new() ; InpMtx_init(mtxA, INPMTX_BY_ROWS, type, nent, 0) ; if ( type == SPOOLES_REAL ) { for ( ient = 0 ; ient < nent ; ient++ ) { fscanf(inputFile, "%d %d %le", &irow, &jcol, &value) ; InpMtx_inputRealEntry(mtxA, irow, jcol, value) ; } } else { for ( ient = 0 ; ient < nent ; ient++ ) { fscanf(inputFile, "%d %d %le %le", &irow, &jcol, &real, &imag) ; InpMtx_inputComplexEntry(mtxA, irow, jcol, real, imag) ; } } fclose(inputFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n input matrix") ; InpMtx_writeForHumanEye(mtxA, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ---------------------------------------- STEP 2: read the right hand side entries ---------------------------------------- */ inputFile = fopen(rhsFileName, "r") ; fscanf(inputFile, "%d %d", &nrow, &nrhs) ; mtxB = DenseMtx_new() ; DenseMtx_init(mtxB, type, 0, 0, nrow, nrhs, 1, nrow) ; DenseMtx_zero(mtxB) ; if ( type == SPOOLES_REAL ) { for ( irow = 0 ; irow < nrow ; irow++ ) { fscanf(inputFile, "%d", &jrow) ; for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) { fscanf(inputFile, "%le", &value) ; DenseMtx_setRealEntry(mtxB, jrow, jrhs, value) ; } } } else { for ( irow = 0 ; irow < nrow ; irow++ ) { fscanf(inputFile, "%d", &jrow) ; for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) { fscanf(inputFile, "%le %le", &real, &imag) ; DenseMtx_setComplexEntry(mtxB, jrow, jrhs, real, imag) ; } } } fclose(inputFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n rhs matrix in original ordering") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------------- STEP 3 : find a low-fill ordering (1) create the Graph object for A^TA or A^HA (2) order the graph using multiple minimum degree ------------------------------------------------- */ graph = Graph_new() ; adjIVL = InpMtx_adjForATA(mtxA) ; nedges = IVL_tsize(adjIVL) ; Graph_init2(graph, 0, neqns, 0, nedges, neqns, nedges, adjIVL, NULL, NULL) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n graph of A^T A") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } frontETree = orderViaMMD(graph, seed, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n front tree from ordering") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ----------------------------------------------------- STEP 4: get the permutation, permute the matrix and front tree and get the symbolic factorization ----------------------------------------------------- */ oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ; newToOldIV = ETree_newToOldVtxPerm(frontETree) ; InpMtx_permute(mtxA, NULL, IV_entries(oldToNewIV)) ; InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; symbfacIVL = SymbFac_initFromGraph(frontETree, graph) ; IVL_overwrite(symbfacIVL, oldToNewIV) ; IVL_sortUp(symbfacIVL) ; ETree_permuteVertices(frontETree, oldToNewIV) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n old-to-new permutation vector") ; IV_writeForHumanEye(oldToNewIV, msgFile) ; fprintf(msgFile, "\n\n new-to-old permutation vector") ; IV_writeForHumanEye(newToOldIV, msgFile) ; fprintf(msgFile, "\n\n front tree after permutation") ; ETree_writeForHumanEye(frontETree, msgFile) ; fprintf(msgFile, "\n\n input matrix after permutation") ; InpMtx_writeForHumanEye(mtxA, msgFile) ; fprintf(msgFile, "\n\n symbolic factorization") ; IVL_writeForHumanEye(symbfacIVL, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------ STEP 5: initialize the front matrix object ------------------------------------------ */ frontmtx = FrontMtx_new() ; mtxmanager = SubMtxManager_new() ; SubMtxManager_init(mtxmanager, NO_LOCK, 0) ; if ( type == SPOOLES_REAL ) { FrontMtx_init(frontmtx, frontETree, symbfacIVL, type, SPOOLES_SYMMETRIC, FRONTMTX_DENSE_FRONTS, SPOOLES_NO_PIVOTING, NO_LOCK, 0, NULL, mtxmanager, msglvl, msgFile) ; } else { FrontMtx_init(frontmtx, frontETree, symbfacIVL, type, SPOOLES_HERMITIAN, FRONTMTX_DENSE_FRONTS, SPOOLES_NO_PIVOTING, NO_LOCK, 0, NULL, mtxmanager, msglvl, msgFile) ; } /*--------------------------------------------------------------------*/ /* ----------------------------------------- STEP 6: compute the numeric factorization ----------------------------------------- */ chvmanager = ChvManager_new() ; ChvManager_init(chvmanager, NO_LOCK, 1) ; DVzero(10, cpus) ; facops = 0.0 ; FrontMtx_QR_factor(frontmtx, mtxA, chvmanager, cpus, &facops, msglvl, msgFile) ; ChvManager_free(chvmanager) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n factor matrix") ; fprintf(msgFile, "\n facops = %9.2f", facops) ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* -------------------------------------- STEP 7: post-process the factorization -------------------------------------- */ FrontMtx_postProcess(frontmtx, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n factor matrix after post-processing") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------- STEP 8: solve the linear system ------------------------------- */ mtxX = DenseMtx_new() ; DenseMtx_init(mtxX, type, 0, 0, neqns, nrhs, 1, neqns) ; FrontMtx_QR_solve(frontmtx, mtxA, mtxX, mtxB, mtxmanager, cpus, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n solution matrix in new ordering") ; DenseMtx_writeForHumanEye(mtxX, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------------------- STEP 9: permute the solution into the original ordering ------------------------------------------------------- */ DenseMtx_permuteRows(mtxX, newToOldIV) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n\n solution matrix in original ordering") ; DenseMtx_writeForHumanEye(mtxX, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------ free the working storage ------------------------ */ InpMtx_free(mtxA) ; FrontMtx_free(frontmtx) ; Graph_free(graph) ; DenseMtx_free(mtxX) ; DenseMtx_free(mtxB) ; ETree_free(frontETree) ; IV_free(newToOldIV) ; IV_free(oldToNewIV) ; IVL_free(symbfacIVL) ; SubMtxManager_free(mtxmanager) ; /*--------------------------------------------------------------------*/ return(1) ; }
/* ------------------------------------------------------------------- InpMtx_readFromAIJ2file reads in an AIJ2 matrix from file and converts to InpMtx object. created -- 98dec01, jwu ------------------------------------------------------------------- */ int InpMtx_readFromAIJ2file(InpMtx *mtxA, char *srcFileName) { FILE *srcFile; int rc, nrow, ncol, irow, icol, jrow, jcol, ient, nentInRow; double ent; /* ---------------------------- open the input file and read #rows #columns ---------------------------- */ if ( (srcFile = fopen(srcFileName, "r")) == NULL ) { fprintf(stderr, "\n fatal error in InpMtx_readFromAIJ2file" "\n unable to open file %s\n", srcFileName) ; return(-1) ; } rc = fscanf(srcFile, "%d %d", &nrow, &ncol) ; if ( rc != 2 ) { fprintf(stderr, "\n fatal error in InpMtx_readFromAIJ2file" "\n %d of 2 fields read on first line of file %s", rc, srcFileName) ; return(-1) ; } /* -------------------------------------------------- initialize the object set coordType = INPMTX_BY_ROWS --> row coordinates -------------------------------------------------- */ InpMtx_init(mtxA, INPMTX_BY_ROWS, SPOOLES_REAL, 10*nrow, 0) ; /* ------------------------------------------------- read in the entries and load them into the object ------------------------------------------------- */ ient=0; for ( irow = 0 ; irow < nrow ; irow++ ) { rc = fscanf(srcFile, "%d %d", &jrow, &nentInRow) ; if ( rc != 2 ) { fprintf(stderr, "\n fatal error in InpMtx_readFromAIJ2file" "\n %d of 2 fields read on entry %d of file %s", rc, ient, srcFileName) ; return(-1) ; } for ( icol = 0 ; icol < nentInRow ; icol++ ) { rc = fscanf(srcFile, "%d %lf", &jcol, &ent) ; if ( rc != 2 ) { fprintf(stderr, "\n fatal error in InpMtx_readFromAIJ2file" "\n %d of 2 fields read on entry %d of file %s", rc, ient, srcFileName) ; return(-1) ; } InpMtx_inputRealEntry(mtxA, jrow-1, jcol-1, ent) ; ient++; } } /* ----------------------------- sort and compress the entries ----------------------------- */ InpMtx_changeStorageMode(mtxA, 3) ; fclose(srcFile); return(1) ; }
/* ------------------------------------------------------------------ purpose -- to initialize the semi-implicit matrix using as input a FrontMtx and a map from fronts to domains (map[J] != 0) or the schur complement (map[J] = 0) return value -- 1 -- normal return -1 -- semimtx is NULL -2 -- frontmtx is NULL -3 -- inpmtx is NULL -4 -- frontmapIV is NULL -5 -- frontmapIV is invalid -6 -- unable to create domains' front matrix -7 -- unable to create schur complement front matrix created -- 98oct17, cca ------------------------------------------------------------------ */ int SemiImplMtx_initFromFrontMtx ( SemiImplMtx *semimtx, FrontMtx *frontmtx, InpMtx *inpmtx, IV *frontmapIV, int msglvl, FILE *msgFile ) { FrontMtx *domMtx, *schurMtx ; InpMtx *A12, *A21 ; int ii, J, ncol, nfront, nrow, rc, size ; int *cols, *frontmap, *rows ; IV *domColsIV, *domidsIV, *domRowsIV, *schurColsIV, *schuridsIV, *schurRowsIV ; /* -------------- check the data -------------- */ if ( semimtx == NULL ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n semimtx is NULL\n") ; return(-1) ; } if ( frontmtx == NULL ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n frontmtx is NULL\n") ; return(-2) ; } if ( inpmtx == NULL ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n inpmtx is NULL\n") ; return(-3) ; } if ( frontmapIV == NULL ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n frontmapIV is NULL\n") ; return(-4) ; } nfront = FrontMtx_nfront(frontmtx) ; IV_sizeAndEntries(frontmapIV, &size, &frontmap) ; if ( nfront != size ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n nfront %d, size of front map %d\n", nfront, size) ; return(-5) ; } domidsIV = IV_new() ; schuridsIV = IV_new() ; for ( J = 0 ; J < nfront ; J++ ) { if ( frontmap[J] == 0 ) { IV_push(schuridsIV, J) ; } else if ( frontmap[J] > 0 ) { IV_push(domidsIV, J) ; } else { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n frontmap[%d] = %d, invalid\n", J, frontmap[J]) ; IV_free(domidsIV) ; IV_free(schuridsIV) ; return(-5) ; } } /* ----------------------------------------------------------- clear the data for the semi-implicit matrix and set scalars ----------------------------------------------------------- */ SemiImplMtx_clearData(semimtx) ; semimtx->neqns = frontmtx->neqns ; semimtx->type = frontmtx->type ; semimtx->symmetryflag = frontmtx->symmetryflag ; /* ---------------------------------------------- get the front matrix that contains the domains ---------------------------------------------- */ if ( msglvl > 4 ) { fprintf(msgFile, "\n\n working on domain front matrix") ; fflush(msgFile) ; } domMtx = semimtx->domainMtx = FrontMtx_new() ; domRowsIV = semimtx->domRowsIV = IV_new() ; domColsIV = semimtx->domColsIV = IV_new() ; rc = FrontMtx_initFromSubmatrix(domMtx, frontmtx, domidsIV, domRowsIV, domColsIV, msglvl, msgFile) ; if ( rc != 1 ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n unable to initialize the domains' front matrix" "\n error return = %d\n", rc) ; return(-6) ; } semimtx->ndomeqns = IV_size(domRowsIV) ; if ( msglvl > 4 ) { fprintf(msgFile, "\n\n---------------------------------------- ") ; fprintf(msgFile, "\n\n submatrix for domains") ; FrontMtx_writeForHumanEye(domMtx, msgFile) ; fflush(msgFile) ; } if ( msglvl > 4 ) { FrontMtx_writeForMatlab(domMtx, "L11", "D11", "U11", msgFile) ; IV_writeForMatlab(domRowsIV, "domrows", msgFile) ; IV_writeForMatlab(domColsIV, "domcols", msgFile) ; fflush(msgFile) ; } /* ------------------------------------------------------- get the front matrix that contains the schur complement ------------------------------------------------------- */ if ( msglvl > 4 ) { fprintf(msgFile, "\n\n working on domain front matrix") ; fflush(msgFile) ; } schurMtx = semimtx->schurMtx = FrontMtx_new() ; schurRowsIV = semimtx->schurRowsIV = IV_new() ; schurColsIV = semimtx->schurColsIV = IV_new() ; rc = FrontMtx_initFromSubmatrix(schurMtx, frontmtx, schuridsIV, schurRowsIV, schurColsIV, msglvl, msgFile) ; if ( rc != 1 ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n unable to initialize the schur complement front matrix" "\n error return = %d\n", rc) ; return(-6) ; } semimtx->nschureqns = IV_size(schurRowsIV) ; if ( msglvl > 4 ) { fprintf(msgFile, "\n\n---------------------------------------- ") ; fprintf(msgFile, "\n\n submatrix for schur complement") ; FrontMtx_writeForHumanEye(schurMtx, msgFile) ; fflush(msgFile) ; } if ( msglvl > 4 ) { FrontMtx_writeForMatlab(schurMtx, "L22", "D22", "U22", msgFile) ; IV_writeForMatlab(schurRowsIV, "schurrows", msgFile) ; IV_writeForMatlab(schurColsIV, "schurcols", msgFile) ; fflush(msgFile) ; } /* ------------------------- get the A12 InpMtx object ------------------------- */ A12 = semimtx->A12 = InpMtx_new() ; rc = InpMtx_initFromSubmatrix(A12, inpmtx, domRowsIV, schurColsIV, semimtx->symmetryflag, msglvl, msgFile) ; if ( rc != 1 ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n unable to create A21 matrix" "\n error return = %d\n", rc) ; return(-6) ; } InpMtx_changeCoordType(A12, INPMTX_BY_ROWS) ; InpMtx_changeStorageMode(A12, INPMTX_BY_VECTORS) ; if ( msglvl > 4 ) { fprintf(msgFile, "\n\n---------------------------------------- ") ; fprintf(msgFile, "\n\n domRowsIV ") ; IV_writeForHumanEye(domRowsIV, msgFile) ; fprintf(msgFile, "\n\n schurColsIV ") ; IV_writeForHumanEye(schurColsIV, msgFile) ; fprintf(msgFile, "\n\n A12 matrix") ; InpMtx_writeForHumanEye(A12, msgFile) ; fflush(msgFile) ; } if ( msglvl > 4 ) { fprintf(msgFile, "\n\n A12 = zeros(%d,%d) ;", IV_size(domRowsIV), IV_size(schurColsIV)) ; InpMtx_writeForMatlab(A12, "A12", msgFile) ; fflush(msgFile) ; } if ( FRONTMTX_IS_NONSYMMETRIC(frontmtx) ) { /* ------------------------- get the A21 InpMtx object ------------------------- */ A21 = semimtx->A21 = InpMtx_new() ; rc = InpMtx_initFromSubmatrix(A21, inpmtx, schurRowsIV, domColsIV, semimtx->symmetryflag, msglvl, msgFile) ; if ( rc != 1 ) { fprintf(stderr, "\n error in SemiImplMtx_initFromFrontMtx()" "\n unable to create A21 matrix" "\n error return = %d\n", rc) ; return(-6) ; } InpMtx_changeCoordType(A21, INPMTX_BY_COLUMNS) ; InpMtx_changeStorageMode(A21, INPMTX_BY_VECTORS) ; if ( msglvl > 4 ) { fprintf(msgFile, "\n\n--------------------------------------- ") ; fprintf(msgFile, "\n\n schurRowsIV ") ; IV_writeForHumanEye(schurRowsIV, msgFile) ; fprintf(msgFile, "\n\n domColsIV ") ; IV_writeForHumanEye(domColsIV, msgFile) ; fprintf(msgFile, "\n\n A21 matrix") ; InpMtx_writeForHumanEye(A21, msgFile) ; fflush(msgFile) ; } if ( msglvl > 4 ) { fprintf(msgFile, "\n\n A21 = zeros(%d,%d) ;", IV_size(schurRowsIV), IV_size(domColsIV)) ; InpMtx_writeForMatlab(A21, "A21", msgFile) ; fflush(msgFile) ; } } /* ------------------------ free the working storage ------------------------ */ IV_free(domidsIV) ; IV_free(schuridsIV) ; return(1) ; }
SPOOLESSolverMT::SPOOLESSolverMT(const SparseMatrix * A, int numThreads, int verbose) { n = A->Getn(); this->verbose = verbose; msgFile = fopen("SPOOLES.message","w"); // prepare SPOOLES input matrix if (verbose >= 1) printf("Converting matrix to SPOOLES format...\n"); InpMtx * mtxA = InpMtx_new(); InpMtx_init(mtxA, INPMTX_BY_ROWS, SPOOLES_REAL, A->GetNumEntries(), n); for(int row=0; row<n; row++) { int rowLength = A->GetRowLength(row); for(int j=0; j< rowLength; j++) { if (A->GetColumnIndex(row,j) >= row) InpMtx_inputRealEntry(mtxA, row, A->GetColumnIndex(row, j), A->GetEntry(row, j) ); } } InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS); //InpMtx_writeForHumanEye(mtxA, msgFile); // compute the factorization if (verbose >= 1) printf("Factoring the %d x %d matrix...\n",n,n); BridgeMT * bridgeMT = BridgeMT_new(); BridgeMT_setMatrixParams(bridgeMT, n, SPOOLES_REAL, SPOOLES_SYMMETRIC); BridgeMT_setMessageInfo(bridgeMT, 1, msgFile); int rc = BridgeMT_setup(bridgeMT, mtxA); if (rc != 1) { printf("Error: BridgeMT setup returned exit code %d.\n", rc); throw 1; } int type = 1; // real entries int nfront, nfind, nfent; double nfactorops; rc = BridgeMT_factorStats(bridgeMT, type, SPOOLES_SYMMETRIC, &nfront, &nfind, &nfent, &nsolveops, &nfactorops); if ( rc != 1 ) { printf("Error: BridgeMT_factorStats returned exit code %d.\n", rc); throw 1; } fprintf(msgFile, "\n\n factor matrix statistics" "\n %d fronts, %d indices, %d entries" "\n %d solve operations, %12.4e factor operations", nfront, nfind, nfent, nsolveops, nfactorops) ; fflush(msgFile) ; // setup the parallel factorization rc = BridgeMT_factorSetup(bridgeMT, numThreads, 0, 0.0) ; fprintf(msgFile, "\n\n ----- PARALLEL FACTOR SETUP -----\n") ; fprintf(msgFile, "\n CPU %8.3f : time to setup parallel factorization", bridgeMT->cpus[5]) ; fprintf(msgFile, "\n total factor operations = %.0f", DV_sum(bridgeMT->cumopsDV)) ; fprintf(msgFile, "\n upper bound on speedup due to load balance = %.2f", DV_sum(bridgeMT->cumopsDV)/DV_max(bridgeMT->cumopsDV)) ; fprintf(msgFile, "\n operations distributions over threads") ; DV_writeForHumanEye(bridgeMT->cumopsDV, msgFile) ; fflush(msgFile) ; // factor the matrix int permuteflag = 1 ; int error; rc = BridgeMT_factor(bridgeMT, mtxA, permuteflag, &error); if ( rc == 1 ) { fprintf(msgFile, "\n\n factorization completed successfully\n") ; } else { printf("Error: factorization returned exit code %d (error %d).\n", rc, error); throw 1; } fprintf(msgFile, "\n\n ----- FACTORIZATION -----\n") ; fprintf(msgFile, "\n CPU %8.3f : time to permute original matrix" "\n CPU %8.3f : time to initialize factor matrix" "\n CPU %8.3f : time to compute factorization" "\n CPU %8.3f : time to post-process factorization" "\n CPU %8.3f : total factorization time\n", bridgeMT->cpus[6], bridgeMT->cpus[7], bridgeMT->cpus[8], bridgeMT->cpus[9], bridgeMT->cpus[10]) ; fprintf(msgFile, "\n\n factorization statistics" "\n %d pivots, %d pivot tests, %d delayed vertices" "\n %d entries in D, %d entries in L, %d entries in U", bridgeMT->stats[0], bridgeMT->stats[1], bridgeMT->stats[2], bridgeMT->stats[3], bridgeMT->stats[4], bridgeMT->stats[5]) ; fprintf(msgFile, "\n\n factorization: raw mflops %8.3f, overall mflops %8.3f", 1.e-6*nfactorops/bridgeMT->cpus[8], 1.e-6*nfactorops/bridgeMT->cpus[10]) ; fflush(msgFile) ; // construct dense SPOOLES matrix for rhs and x DenseMtx *mtx_rhs = DenseMtx_new(); DenseMtx_init(mtx_rhs, SPOOLES_REAL, 0, 0, n, 1, 1, n); mtx_rhsPointer = (void*) mtx_rhs; DenseMtx *mtx_x = DenseMtx_new(); DenseMtx_init(mtx_x, SPOOLES_REAL, 0, 0, n, 1, 1, n); mtx_xPointer = (void*) mtx_x; bridgeMTPointer = (void*) bridgeMT; APointer = (void*) mtxA; if (verbose >= 1) printf("Factorization completed.\n"); }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) /* ----------------------------------------------------- test the factor method for a grid matrix (0) read in matrix from source file (1) conver data matrix to InpMtx object if necessary (2) create Graph and ETree object if necessary (3) read in/create an ETree object (4) create a solution matrix object (5) multiply the solution with the matrix to get a right hand side matrix object (6) factor the matrix (7) solve the system created -- 98dec30, jwu ----------------------------------------------------- */ { char etreeFileName[80], mtxFileName[80], *cpt, rhsFileName[80], srcFileName[80], ctemp[81], msgFileName[80], slnFileName[80] ; Chv *chv, *rootchv ; ChvManager *chvmanager ; DenseMtx *mtxB, *mtxQ, *mtxX, *mtxZ ; double one[2] = { 1.0, 0.0 } ; FrontMtx *frontmtx ; InpMtx *mtxA ; SubMtxManager *mtxmanager ; double cputotal, droptol, conv_tol, factorops ; double cpus[9] ; Drand drand ; double nops, tau, t1, t2 ; ETree *frontETree ; Graph *graph ; FILE *msgFile, *inFile ; int error, loc, msglvl, neqns, nzf, iformat, pivotingflag, rc, seed, sparsityflag, symmetryflag, method[METHODS], type, nrhs, etreeflag ; int stats[6] ; int nnzA, Ik, itermax, zversion, iterout ; IV *newToOldIV, *oldToNewIV ; IVL *symbfacIVL ; int i, j, k, m, n, imethod, maxdomainsize, maxzeros, maxsize; int nouter,ninner ; if ( argc != 2 ) { fprintf(stdout, "\n\n usage : %s inFile" "\n inFile -- input filename" "\n", argv[0]) ; return(-1) ; } /* read input file */ inFile = fopen(argv[1], "r"); if (inFile == (FILE *)NULL) { fprintf(stderr, "\n fatal error in %s: unable to open file %s\n", argv[0], argv[1]) ; return(-1) ; } for (i=0; i<METHODS; i++) method[i]=-1; imethod=0; k=0; while (1) { fgets(ctemp, 80, inFile); if (ctemp[0] != '*') { /*printf("l=%2d:%s\n", strlen(ctemp),ctemp);*/ if (strlen(ctemp)==80) { fprintf(stderr, "\n fatal error in %s: input line contains more than " "80 characters.\n",argv[0]); exit(-1); } if (k==0) { sscanf(ctemp, "%d", &iformat); if (iformat < 0 || iformat > 2) { fprintf(stderr, "\n fatal error in %s: " "invalid source matrix format\n",argv[0]) ; return(-1) ; } } else if (k==1) sscanf(ctemp, "%s", srcFileName); else if (k==2) sscanf(ctemp, "%s", mtxFileName); else if (k==3) { sscanf(ctemp, "%d", &etreeflag); if (etreeflag < 0 || etreeflag > 4) { fprintf(stderr, "\n fatal error in %s: " "invalid etree file status\n",argv[0]) ; return(-1) ; } } else if (k==4) sscanf(ctemp, "%s", etreeFileName); else if (k==5) sscanf(ctemp, "%s", rhsFileName); else if (k==6) sscanf(ctemp, "%s", slnFileName); else if (k==7){ sscanf(ctemp, "%s", msgFileName); if ( strcmp(msgFileName, "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(msgFileName, "a")) == NULL ) { fprintf(stderr, "\n fatal error in %s" "\n unable to open file %s\n", argv[0], ctemp) ; return(-1) ; } } else if (k==8) sscanf(ctemp, "%d %d %d %d %d %d", &msglvl, &seed, &nrhs, &Ik, &itermax, &iterout); else if (k==9) sscanf(ctemp, "%d %d %d", &symmetryflag, &sparsityflag, &pivotingflag); else if (k==10) sscanf(ctemp, "%lf %lf %lf", &tau, &droptol, &conv_tol); else if (k==11) { /* for (j=0; j<strlen(ctemp); j++) { printf("j=%2d:%s",j,ctemp+j); if (ctemp[j] == ' ' && ctemp[j+1] != ' ') { sscanf(ctemp+j, "%d", method+imethod); printf("method[%d]=%d\n",imethod,method[imethod]); if (method[imethod] < 0) break; imethod++; } } */ imethod = sscanf(ctemp,"%d %d %d %d %d %d %d %d %d %d", method, method+1, method+2, method+3, method+4, method+5, method+6, method+7, method+8, method+9); /*printf("imethod=%d\n",imethod);*/ for (j=0; j<imethod; j++) { /*printf("method[%d]=%d\n",j,method[j]);*/ if (method[j]<0) { imethod=j; break; } } if (imethod == 0) { fprintf(msgFile,"No method assigned in input file\n"); return(-1); } } k++; } if (k==12) break; } fclose(inFile); /* reset nrhs to 1 */ if (nrhs > 1) { fprintf(msgFile,"*** Multiple right-hand-side vectors is not allowed yet.\n"); fprintf(msgFile,"*** nrhs is reset to 1.\n"); nrhs =1; } fprintf(msgFile, "\n %s " "\n srcFileName -- %s" "\n mtxFileName -- %s" "\n etreeFileName -- %s" "\n rhsFileName -- %s" "\n msglvl -- %d" "\n seed -- %d" "\n symmetryflag -- %d" "\n sparsityflag -- %d" "\n pivotingflag -- %d" "\n tau -- %e" "\n droptol -- %e" "\n conv_tol -- %e" "\n method -- ", argv[0], srcFileName, mtxFileName, etreeFileName, rhsFileName, msglvl, seed, symmetryflag, sparsityflag, pivotingflag, tau, droptol, conv_tol) ; for (k=0; k<imethod; k++) fprintf(msgFile, "%d ", method[k]); fprintf(msgFile, "\n ", method[k]); fflush(msgFile) ; /* -------------------------------------- initialize the random number generator -------------------------------------- */ Drand_setDefaultFields(&drand) ; Drand_init(&drand) ; Drand_setSeed(&drand, seed) ; /*Drand_setUniform(&drand, 0.0, 1.0) ;*/ Drand_setNormal(&drand, 0.0, 1.0) ; /* ---------------------------------------------- read in or convert source to the InpMtx object ---------------------------------------------- */ rc = 1; if ( strcmp(srcFileName, "none") == 0 ) { fprintf(msgFile, "\n no file to read from") ; exit(-1) ; } mtxA = InpMtx_new() ; MARKTIME(t1) ; if (iformat == 0) { /* InpMtx source format */ rc = InpMtx_readFromFile(mtxA, srcFileName) ; strcpy(mtxFileName, srcFileName); if ( rc != 1 ) fprintf(msgFile, "\n return value %d from InpMtx_readFromFile(%p,%s)", rc, mtxA, srcFileName) ; } else if (iformat == 1) { /* HBF source format */ rc = InpMtx_readFromHBfile(mtxA, srcFileName) ; if ( rc != 1 ) fprintf(msgFile, "\n return value %d from InpMtx_readFromHBfile(%p,%s)", rc, mtxA, srcFileName) ; } else { /* AIJ2 source format */ rc = InpMtx_readFromAIJ2file(mtxA, srcFileName) ; if ( rc != 1 ) fprintf(msgFile, "\n return value %d from InpMtx_readFromAIJ2file(%p,%s)", rc, mtxA, srcFileName) ; } MARKTIME(t2) ; if (iformat>0 && strcmp(mtxFileName, "none") != 0 ) { rc = InpMtx_writeToFile(mtxA, mtxFileName) ; if ( rc != 1 ) fprintf(msgFile, "\n return value %d from InpMtx_writeToFile(%p,%s)", rc, mtxA, mtxFileName) ; } fprintf(msgFile, "\n CPU %8.3f : read in (+ convert to) mtxA from file %s", t2 - t1, mtxFileName) ; if (rc != 1) { goto end_read; } type = mtxA->inputMode ; neqns = 1 + IVmax(mtxA->nent, InpMtx_ivec1(mtxA), &loc) ; if ( INPMTX_IS_BY_ROWS(mtxA) ) { fprintf(msgFile, "\n matrix coordinate type is rows") ; } else if ( INPMTX_IS_BY_COLUMNS(mtxA) ) { fprintf(msgFile, "\n matrix coordinate type is columns") ; } else if ( INPMTX_IS_BY_CHEVRONS(mtxA) ) { fprintf(msgFile, "\n matrix coordinate type is chevrons") ; } else { fprintf(msgFile, "\n\n, error, bad coordinate type") ; rc=-1; goto end_read; } if ( INPMTX_IS_RAW_DATA(mtxA) ) { fprintf(msgFile, "\n matrix storage mode is raw data\n") ; } else if ( INPMTX_IS_SORTED(mtxA) ) { fprintf(msgFile, "\n matrix storage mode is sorted\n") ; } else if ( INPMTX_IS_BY_VECTORS(mtxA) ) { fprintf(msgFile, "\n matrix storage mode is by vectors\n") ; } else { fprintf(msgFile, "\n\n, error, bad storage mode") ; rc=-1; goto end_read; } if ( msglvl > 1 ) { fprintf(msgFile, "\n\n after reading InpMtx object from file %s", mtxFileName) ; if ( msglvl == 2 ) { InpMtx_writeStats(mtxA, msgFile) ; } else { InpMtx_writeForHumanEye(mtxA, msgFile) ; } fflush(msgFile) ; } /* Get the nonzeros in matrix A and print it */ nnzA = InpMtx_nent( mtxA ); fprintf(msgFile, "\n\n Input matrix size %d NNZ %d", neqns, nnzA) ; /* -------------------------------------------------------- generate the linear system 1. generate solution matrix and fill with random numbers 2. generate rhs matrix and fill with zeros 3. compute matrix-matrix multiply -------------------------------------------------------- */ MARKTIME(t1) ; mtxX = DenseMtx_new() ; DenseMtx_init(mtxX, type, 0, -1, neqns, nrhs, 1, neqns) ; mtxB = DenseMtx_new() ; if (strcmp(rhsFileName, "none")) { rc = DenseMtx_readFromFile(mtxB, rhsFileName) ; if ( rc != 1 ) fprintf(msgFile, "\n return value %d from DenseMtx_readFromFile(%p,%s)", rc, mtxB, rhsFileName) ; DenseMtx_zero(mtxX) ; } else { DenseMtx_init(mtxB, type, 1, -1, neqns, nrhs, 1, neqns) ; DenseMtx_fillRandomEntries(mtxX, &drand) ; DenseMtx_zero(mtxB) ; switch ( symmetryflag ) { case SPOOLES_SYMMETRIC : InpMtx_sym_mmm(mtxA, mtxB, one, mtxX) ; break ; case SPOOLES_HERMITIAN : InpMtx_herm_mmm(mtxA, mtxB, one, mtxX) ; break ; case SPOOLES_NONSYMMETRIC : InpMtx_nonsym_mmm(mtxA, mtxB, one, mtxX) ; break ; default : break ; } } MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : set up the solution and rhs ", t2 - t1) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n original mtxX") ; DenseMtx_writeForHumanEye(mtxX, msgFile) ; fprintf(msgFile, "\n\n original mtxB") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fflush(msgFile) ; } if (rc != 1) { InpMtx_free(mtxA); DenseMtx_free(mtxX); DenseMtx_free(mtxB); goto end_init; } /* ------------------------ read in/create the ETree object ------------------------ */ MARKTIME(t1) ; if (etreeflag == 0) { /* read in ETree from file */ if ( strcmp(etreeFileName, "none") == 0 ) fprintf(msgFile, "\n no file to read from") ; frontETree = ETree_new() ; rc = ETree_readFromFile(frontETree, etreeFileName) ; if (rc!=1) fprintf(msgFile, "\n return value %d from ETree_readFromFile(%p,%s)", rc, frontETree, etreeFileName) ; } else { graph = Graph_new() ; rc = InpMtx_createGraph(mtxA, graph); if (rc!=1) { fprintf(msgFile, "\n return value %d from InpMtx_createGraph(%p,%p)", rc, mtxA, graph) ; Graph_free(graph); goto end_tree; } if (etreeflag == 1) { /* Via BestOfNDandMS */ maxdomainsize = 500; maxzeros = 1000; maxsize = 64 ; frontETree = orderViaBestOfNDandMS(graph, maxdomainsize, maxzeros, maxsize, seed, msglvl, msgFile) ; } else if (etreeflag == 2) { /* Via MMD */ frontETree = orderViaMMD(graph, seed, msglvl, msgFile) ; } else if (etreeflag == 3) { /* Via MS */ maxdomainsize = 500; frontETree = orderViaMS(graph, maxdomainsize, seed, msglvl, msgFile) ; } else if (etreeflag == 4) { /* Via ND */ maxdomainsize = 500; frontETree = orderViaND(graph, maxdomainsize, seed, msglvl, msgFile) ; } Graph_free(graph); /* optionally write out the ETree object */ if ( strcmp(etreeFileName, "none") != 0 ) { fprintf(msgFile, "\n\n writing out ETree to file %s", etreeFileName) ; ETree_writeToFile(frontETree, etreeFileName) ; } } MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : read in/create frontETree from file %s", t2 - t1, etreeFileName) ; if ( rc != 1 ) { ETree_free(frontETree); goto end_tree; } ETree_leftJustify(frontETree) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n after reading ETree object from file %s", etreeFileName) ; if ( msglvl == 2 ) { ETree_writeStats(frontETree, msgFile) ; } else { ETree_writeForHumanEye(frontETree, msgFile) ; } } fflush(msgFile) ; /* -------------------------------------------------- get the permutations, permute the matrix and the front tree, and compute the symbolic factorization -------------------------------------------------- */ MARKTIME(t1) ; oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ; newToOldIV = ETree_newToOldVtxPerm(frontETree) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : get permutations", t2 - t1) ; MARKTIME(t1) ; ETree_permuteVertices(frontETree, oldToNewIV) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : permute front tree", t2 - t1) ; MARKTIME(t1) ; InpMtx_permute(mtxA, IV_entries(oldToNewIV), IV_entries(oldToNewIV)) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : permute mtxA", t2 - t1) ; if ( symmetryflag == SPOOLES_SYMMETRIC || symmetryflag == SPOOLES_HERMITIAN ) { MARKTIME(t1) ; InpMtx_mapToUpperTriangle(mtxA) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : map to upper triangle", t2 - t1) ; } if ( ! INPMTX_IS_BY_CHEVRONS(mtxA) ) { MARKTIME(t1) ; InpMtx_changeCoordType(mtxA, INPMTX_BY_CHEVRONS) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : change coordinate type", t2 - t1) ; } if ( INPMTX_IS_RAW_DATA(mtxA) ) { MARKTIME(t1) ; InpMtx_changeStorageMode(mtxA, INPMTX_SORTED) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : sort entries ", t2 - t1) ; } if ( INPMTX_IS_SORTED(mtxA) ) { MARKTIME(t1) ; InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : convert to vectors ", t2 - t1) ; } MARKTIME(t1) ; symbfacIVL = SymbFac_initFromInpMtx(frontETree, mtxA) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : symbolic factorization", t2 - t1) ; MARKTIME(t1) ; DenseMtx_permuteRows(mtxB, oldToNewIV) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : permute rhs", t2 - t1) ; /* ------------------------------ initialize the FrontMtx object ------------------------------ */ MARKTIME(t1) ; frontmtx = FrontMtx_new() ; mtxmanager = SubMtxManager_new() ; SubMtxManager_init(mtxmanager, NO_LOCK, 0) ; FrontMtx_init(frontmtx, frontETree, symbfacIVL, type, symmetryflag, sparsityflag, pivotingflag, NO_LOCK, 0, NULL, mtxmanager, msglvl, msgFile) ; MARKTIME(t2) ; fprintf(msgFile, "\n\n CPU %8.3f : initialize the front matrix", t2 - t1) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n nendD = %d, nentL = %d, nentU = %d", frontmtx->nentD, frontmtx->nentL, frontmtx->nentU) ; SubMtxManager_writeForHumanEye(mtxmanager, msgFile) ; } if ( msglvl > 2 ) { fprintf(msgFile, "\n front matrix initialized") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; fflush(msgFile) ; } /* ----------------- factor the matrix ----------------- */ nzf = ETree_nFactorEntries(frontETree, symmetryflag) ; factorops = ETree_nFactorOps(frontETree, type, symmetryflag) ; fprintf(msgFile, "\n %d factor entries, %.0f factor ops, %8.3f ratio", nzf, factorops, factorops/nzf) ; IVzero(6, stats) ; DVzero(9, cpus) ; chvmanager = ChvManager_new() ; ChvManager_init(chvmanager, NO_LOCK, 1) ; MARKTIME(t1) ; rootchv = FrontMtx_factorInpMtx(frontmtx, mtxA, tau, droptol, chvmanager, &error, cpus, stats, msglvl, msgFile) ; MARKTIME(t2) ; fprintf(msgFile, "\n\n CPU %8.3f : factor matrix, %8.3f mflops", t2 - t1, 1.e-6*factorops/(t2-t1)) ; if ( rootchv != NULL ) { fprintf(msgFile, "\n\n factorization did not complete") ; for ( chv = rootchv ; chv != NULL ; chv = chv->next ) { fprintf(stdout, "\n chv %d, nD = %d, nL = %d, nU = %d", chv->id, chv->nD, chv->nL, chv->nU) ; } } if ( error >= 0 ) { fprintf(msgFile, "\n\n error encountered at front %d\n", error) ; rc=error ; goto end_front; } fprintf(msgFile, "\n %8d pivots, %8d pivot tests, %8d delayed rows and columns", stats[0], stats[1], stats[2]) ; if ( frontmtx->rowadjIVL != NULL ) { fprintf(msgFile, "\n %d entries in rowadjIVL", frontmtx->rowadjIVL->tsize) ; } if ( frontmtx->coladjIVL != NULL ) { fprintf(msgFile, ", %d entries in coladjIVL", frontmtx->coladjIVL->tsize) ; } if ( frontmtx->upperblockIVL != NULL ) { fprintf(msgFile, "\n %d fronts, %d entries in upperblockIVL", frontmtx->nfront, frontmtx->upperblockIVL->tsize) ; } if ( frontmtx->lowerblockIVL != NULL ) { fprintf(msgFile, ", %d entries in lowerblockIVL", frontmtx->lowerblockIVL->tsize) ; } fprintf(msgFile, "\n %d entries in D, %d entries in L, %d entries in U", stats[3], stats[4], stats[5]) ; fprintf(msgFile, "\n %d locks", frontmtx->nlocks) ; if ( FRONTMTX_IS_SYMMETRIC(frontmtx) || FRONTMTX_IS_HERMITIAN(frontmtx) ) { int nneg, npos, nzero ; FrontMtx_inertia(frontmtx, &nneg, &nzero, &npos) ; fprintf(msgFile, "\n %d negative, %d zero and %d positive eigenvalues", nneg, nzero, npos) ; fflush(msgFile) ; } 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 > 1 ) { SubMtxManager_writeForHumanEye(mtxmanager, msgFile) ; ChvManager_writeForHumanEye(chvmanager, msgFile) ; } if ( msglvl > 2 ) { fprintf(msgFile, "\n\n front factor matrix") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; } /* ------------------------------ post-process the factor matrix ------------------------------ */ MARKTIME(t1) ; FrontMtx_postProcess(frontmtx, msglvl, msgFile) ; MARKTIME(t2) ; fprintf(msgFile, "\n\n CPU %8.3f : post-process the matrix", t2 - t1) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n front factor matrix after post-processing") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; } fprintf(msgFile, "\n\n after post-processing") ; if ( msglvl > 1 ) SubMtxManager_writeForHumanEye(frontmtx->manager, msgFile) ; /* ---------------- solve the system ---------------- */ neqns = mtxB->nrow ; mtxZ = DenseMtx_new() ; DenseMtx_init(mtxZ, type, 0, 0, neqns, nrhs, 1, neqns) ; zversion=INPMTX_IS_COMPLEX_ENTRIES(mtxA); for (k=0; k<imethod; k++) { DenseMtx_zero(mtxZ) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n rhs") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fflush(stdout) ; } fprintf(msgFile, "\n\n itemax %d", itermax) ; DVzero(6, cpus) ; MARKTIME(t1) ; switch ( method[k] ) { case BiCGStabR : if (zversion) rc=zbicgstabr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=bicgstabr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case BiCGStabL : if (zversion) rc=zbicgstabl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=bicgstabl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case TFQMRR : if (zversion) rc=ztfqmrr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=tfqmrr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case TFQMRL : if (zversion) rc=ztfqmrl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=tfqmrl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case PCGR : if (zversion) rc=zpcgr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=pcgr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case PCGL : if (zversion) rc=zpcgl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=pcgl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); break; case MLBiCGStabR : mtxQ = DenseMtx_new() ; DenseMtx_init(mtxQ, type, 0, -1, neqns, Ik, 1, neqns) ; Drand_setUniform(&drand, 0.0, 1.0) ; DenseMtx_fillRandomEntries(mtxQ, &drand) ; if (zversion) rc=zmlbicgstabr(neqns, type, symmetryflag, mtxA, frontmtx, mtxQ, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=mlbicgstabr(neqns, type, symmetryflag, mtxA, frontmtx, mtxQ, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); DenseMtx_free(mtxQ) ; break; case MLBiCGStabL : mtxQ = DenseMtx_new() ; DenseMtx_init(mtxQ, type, 0, -1, neqns, Ik, 1, neqns) ; Drand_setUniform(&drand, 0.0, 1.0) ; DenseMtx_fillRandomEntries(mtxQ, &drand) ; if (zversion) rc=zmlbicgstabl(neqns, type, symmetryflag, mtxA, frontmtx, mtxQ, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); else rc=mlbicgstabl(neqns, type, symmetryflag, mtxA, frontmtx, mtxQ, mtxZ, mtxB, itermax, conv_tol, msglvl, msgFile); DenseMtx_free(mtxQ) ; break; case BGMRESR: if (zversion) fprintf(msgFile, "\n\n *** BGMRESR complex version is not available " "at this moment. ") ; else rc=bgmresr(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, iterout, itermax, &nouter, &ninner, conv_tol, msglvl, msgFile); break; case BGMRESL: if (zversion) fprintf(msgFile, "\n\n *** BGMRESR complex version is not available " "at this moment. ") ; else rc=bgmresl(neqns, type, symmetryflag, mtxA, frontmtx, mtxZ, mtxB, iterout, itermax, &nouter, &ninner, conv_tol, msglvl, msgFile); break; default: fprintf(msgFile, "\n\n *** Invalid method number ") ; } MARKTIME(t2) ; fprintf(msgFile, "\n\n CPU %8.3f : solve the system", t2 - t1) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n computed solution") ; DenseMtx_writeForHumanEye(mtxZ, msgFile) ; fflush(stdout) ; } /* ------------------------------------------------------------- permute the computed solution back into the original ordering ------------------------------------------------------------- */ MARKTIME(t1) ; DenseMtx_permuteRows(mtxZ, newToOldIV) ; MARKTIME(t2) ; fprintf(msgFile, "\n CPU %8.3f : permute solution", t2 - t1) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n permuted solution") ; DenseMtx_writeForHumanEye(mtxZ, msgFile) ; fflush(stdout) ; } /* ------------- save solution ------------- */ if ( strcmp(slnFileName, "none") != 0 ) { DenseMtx_writeToFile(mtxZ, slnFileName) ; } /* ----------------- compute the error ----------------- */ if (!strcmp(rhsFileName, "none")) { DenseMtx_sub(mtxZ, mtxX) ; if (method[k] <8) { mtxQ = DenseMtx_new() ; DenseMtx_init(mtxQ, type, 0, -1, neqns, 1, 1, neqns) ; rc=DenseMtx_initAsSubmatrix (mtxQ, mtxZ, 0, neqns-1, 0, 0); fprintf(msgFile, "\n\n maxabs error = %12.4e", DenseMtx_maxabs(mtxQ)) ; DenseMtx_free(mtxQ) ; } else fprintf(msgFile, "\n\n maxabs error = %12.4e", DenseMtx_maxabs(mtxZ)) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n error") ; DenseMtx_writeForHumanEye(mtxZ, msgFile) ; fflush(stdout) ; } if ( msglvl > 1 ) SubMtxManager_writeForHumanEye(frontmtx->manager, msgFile) ; } fprintf(msgFile, "\n--------- End of Method %d -------\n",method[k]) ; } /* ------------------------ free the working storage ------------------------ */ DenseMtx_free(mtxZ) ; end_front: ChvManager_free(chvmanager) ; SubMtxManager_free(mtxmanager) ; FrontMtx_free(frontmtx) ; IVL_free(symbfacIVL) ; IV_free(oldToNewIV) ; IV_free(newToOldIV) ; end_tree: ETree_free(frontETree) ; end_init: DenseMtx_free(mtxB) ; DenseMtx_free(mtxX) ; end_read: InpMtx_free(mtxA) ; fprintf(msgFile, "\n") ; fclose(msgFile) ; return(rc) ; }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) /* --------------------------------------------------- read in (i, j, a(i,j)) triples, construct a InpMtx object and write it out to a file created -- 97oct17, cca --------------------------------------------------- */ { char *inFileName, *outFileName ; InpMtx *inpmtx ; FILE *inputFile, *msgFile ; int dataType, flag, ient, msglvl, ncol, nent, nrow, rc ; int *ivec1, *ivec2 ; if ( argc != 7 ) { fprintf(stdout, "\n\n usage : readAIJ msglvl msgFile dataType inputFile outFile flag" "\n msglvl -- message level" "\n msgFile -- message file" "\n dataType -- 0 for indices only, 1 for double, 2 for complex" "\n inputFile -- input file for a(i,j) entries" "\n the first line must be \"nrow ncol nentries\"" "\n if dataType == 0 then" "\n next lines are \"irow jcol\"" "\n else if dataType == 1 then" "\n next lines are \"irow jcol entry\"" "\n else if dataType == 2 then" "\n next lines are \"irow jcol realEntry imagEntry\"" "\n endif" "\n outFile -- output file, must be *.inpmtxf or *.inpmtxb" "\n flag -- flag for 0-based or 1-based addressing" "\n") ; return(0) ; } msglvl = atoi(argv[1]) ; if ( strcmp(argv[2], "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) { fprintf(stderr, "\n fatal error in %s" "\n unable to open file %s\n", argv[0], argv[2]) ; return(-1) ; } dataType = atoi(argv[3]) ; inFileName = argv[4] ; outFileName = argv[5] ; flag = atoi(argv[6]) ; fprintf(msgFile, "\n readAIJ " "\n msglvl -- %d" "\n msgFile -- %s" "\n dataType -- %d" "\n inputFile -- %s" "\n outFile -- %s" "\n flag -- %d" "\n", msglvl, argv[2], dataType, inFileName, outFileName, flag) ; fflush(msgFile) ; /* ---------------------------- open the input file and read #rows #columns #entries ---------------------------- */ if ( (inputFile = fopen(inFileName, "r")) == NULL ) { fprintf(stderr, "\n fatal error in %s" "\n unable to open file %s\n", argv[0], inFileName) ; return(-1) ; } rc = fscanf(inputFile, "%d %d %d", &nrow, &ncol, &nent) ; if ( rc != 3 ) { fprintf(stderr, "\n fatal error in %s" "\n %d of 3 fields read on first line of file %s", argv[0], rc, inFileName) ; return(-1) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n\n read in nrow = %d, ncol = %d, nent = %d", nrow, ncol, nent) ; fflush(msgFile) ; } /* -------------------------------------------------- initialize the object set coordType = INPMTX_BY_ROWS --> row coordinates set inputMode = dataType -------------------------------------------------- */ inpmtx = InpMtx_new() ; InpMtx_init(inpmtx, INPMTX_BY_ROWS, dataType, nent, 0) ; /* ------------------------------------------------- read in the entries and load them into the object ------------------------------------------------- */ ivec1 = InpMtx_ivec1(inpmtx) ; ivec2 = InpMtx_ivec2(inpmtx) ; if ( INPMTX_IS_INDICES_ONLY(inpmtx) ) { for ( ient = 0 ; ient < nent ; ient++ ) { rc = fscanf(inputFile, "%d %d", ivec1 + ient, ivec2 + ient) ; if ( rc != 2 ) { fprintf(stderr, "\n fatal error in %s" "\n %d of 2 fields read on entry %d of file %s", argv[0], rc, ient, inFileName) ; return(-1) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n entry %d, row %d, column %d", ient, ivec1[ient], ivec2[ient]) ; fflush(msgFile) ; } } } else if ( INPMTX_IS_REAL_ENTRIES(inpmtx) ) { double *dvec = InpMtx_dvec(inpmtx) ; for ( ient = 0 ; ient < nent ; ient++ ) { rc = fscanf(inputFile, "%d %d %le", ivec1 + ient, ivec2 + ient, dvec + ient) ; if ( rc != 3 ) { fprintf(stderr, "\n fatal error in %s" "\n %d of 3 fields read on entry %d of file %s", argv[0], rc, ient, argv[3]) ; return(-1) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n entry %d, row %d, column %d, value %e", ient, ivec1[ient], ivec2[ient], dvec[ient]) ; fflush(msgFile) ; } } } else if ( INPMTX_IS_COMPLEX_ENTRIES(inpmtx) ) { double *dvec = InpMtx_dvec(inpmtx) ; for ( ient = 0 ; ient < nent ; ient++ ) { rc = fscanf(inputFile, "%d %d %le %le", ivec1 + ient, ivec2 + ient, dvec + 2*ient, dvec + 2*ient+1) ; if ( rc != 4 ) { fprintf(stderr, "\n fatal error in %s" "\n %d of 4 fields read on entry %d of file %s", argv[0], rc, ient, argv[3]) ; return(-1) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n entry %d, row %d, column %d, value %12.4e + %12.4e*i", ient, ivec1[ient], ivec2[ient], dvec[2*ient], dvec[2*ient+1]) ; fflush(msgFile) ; } } } inpmtx->nent = nent ; if ( flag == 1 ) { /* -------------------------------------------------- indices were in FORTRAN mode, decrement for C mode -------------------------------------------------- */ for ( ient = 0 ; ient < nent ; ient++ ) { ivec1[ient]-- ; ivec2[ient]-- ; } } /* ----------------------------- sort and compress the entries ----------------------------- */ InpMtx_changeStorageMode(inpmtx, 3) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n sorted, compressed and vector form") ; InpMtx_writeForHumanEye(inpmtx, msgFile) ; fflush(msgFile) ; } /* --------------------------- write out the InpMtx object --------------------------- */ if ( strcmp(outFileName, "none") != 0 ) { rc = InpMtx_writeToFile(inpmtx, outFileName) ; fprintf(msgFile, "\n return value %d from InpMtx_writeToFile(%p,%s)", rc, inpmtx, outFileName) ; } /* --------------------- free the working data --------------------- */ InpMtx_free(inpmtx) ; fprintf(msgFile, "\n") ; fclose(msgFile) ; return(1) ; }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) { /* -------------------------------------------------- all-in-one program to solve A X = B using a multithreaded factorization and solve We use a patch-and-go strategy for the factorization without pivoting (1) read in matrix entries and form DInpMtx object (2) form Graph object (3) order matrix and form front tree (4) get the permutation, permute the matrix and front tree and get the symbolic factorization (5) compute the numeric factorization (6) read in right hand side entries (7) compute the solution created -- 98jun04, cca -------------------------------------------------- */ /*--------------------------------------------------------------------*/ char *matrixFileName, *rhsFileName ; DenseMtx *mtxB, *mtxX ; Chv *rootchv ; ChvManager *chvmanager ; double fudge, imag, real, tau = 100., toosmall, value ; double cpus[10] ; DV *cumopsDV ; ETree *frontETree ; FrontMtx *frontmtx ; FILE *inputFile, *msgFile ; Graph *graph ; InpMtx *mtxA ; int error, ient, irow, jcol, jrhs, jrow, lookahead, msglvl, ncol, nedges, nent, neqns, nfront, nrhs, nrow, nthread, patchAndGoFlag, seed, storeids, storevalues, symmetryflag, type ; int *newToOld, *oldToNew ; int stats[20] ; IV *newToOldIV, *oldToNewIV, *ownersIV ; IVL *adjIVL, *symbfacIVL ; SolveMap *solvemap ; SubMtxManager *mtxmanager ; /*--------------------------------------------------------------------*/ /* -------------------- get input parameters -------------------- */ if ( argc != 14 ) { fprintf(stdout, "\n" "\n usage: %s msglvl msgFile type symmetryflag patchAndGoFlag" "\n fudge toosmall storeids storevalues" "\n matrixFileName rhsFileName seed" "\n msglvl -- message level" "\n msgFile -- message file" "\n type -- type of entries" "\n 1 (SPOOLES_REAL) -- real entries" "\n 2 (SPOOLES_COMPLEX) -- complex entries" "\n symmetryflag -- type of matrix" "\n 0 (SPOOLES_SYMMETRIC) -- symmetric entries" "\n 1 (SPOOLES_HERMITIAN) -- Hermitian entries" "\n 2 (SPOOLES_NONSYMMETRIC) -- nonsymmetric entries" "\n patchAndGoFlag -- flag for the patch-and-go strategy" "\n 0 -- none, stop factorization" "\n 1 -- optimization strategy" "\n 2 -- structural analysis strategy" "\n fudge -- perturbation parameter" "\n toosmall -- upper bound on a small pivot" "\n storeids -- flag to store ids of small pivots" "\n storevalues -- flag to store perturbations" "\n matrixFileName -- matrix file name, format" "\n nrow ncol nent" "\n irow jcol entry" "\n ..." "\n note: indices are zero based" "\n rhsFileName -- right hand side file name, format" "\n nrow nrhs " "\n ..." "\n jrow entry(jrow,0) ... entry(jrow,nrhs-1)" "\n ..." "\n seed -- random number seed, used for ordering" "\n nthread -- number of threads" "\n", argv[0]) ; return(0) ; } msglvl = atoi(argv[1]) ; if ( strcmp(argv[2], "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) { fprintf(stderr, "\n fatal error in %s" "\n unable to open file %s\n", argv[0], argv[2]) ; return(-1) ; } type = atoi(argv[3]) ; symmetryflag = atoi(argv[4]) ; patchAndGoFlag = atoi(argv[5]) ; fudge = atof(argv[6]) ; toosmall = atof(argv[7]) ; storeids = atoi(argv[8]) ; storevalues = atoi(argv[9]) ; matrixFileName = argv[10] ; rhsFileName = argv[11] ; seed = atoi(argv[12]) ; nthread = atoi(argv[13]) ; /*--------------------------------------------------------------------*/ /* -------------------------------------------- STEP 1: read the entries from the input file and create the InpMtx object -------------------------------------------- */ if ( (inputFile = fopen(matrixFileName, "r")) == NULL ) { fprintf(stderr, "\n unable to open file %s", matrixFileName) ; spoolesFatal(); } fscanf(inputFile, "%d %d %d", &nrow, &ncol, &nent) ; neqns = nrow ; mtxA = InpMtx_new() ; InpMtx_init(mtxA, INPMTX_BY_ROWS, type, nent, 0) ; if ( type == SPOOLES_REAL ) { for ( ient = 0 ; ient < nent ; ient++ ) { fscanf(inputFile, "%d %d %le", &irow, &jcol, &value) ; InpMtx_inputRealEntry(mtxA, irow, jcol, value) ; } } else { for ( ient = 0 ; ient < nent ; ient++ ) { fscanf(inputFile, "%d %d %le %le", &irow, &jcol, &real, &imag) ; InpMtx_inputComplexEntry(mtxA, irow, jcol, real, imag) ; } } fclose(inputFile) ; InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n input matrix") ; InpMtx_writeForHumanEye(mtxA, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------------- STEP 2 : find a low-fill ordering (1) create the Graph object (2) order the graph using multiple minimum degree ------------------------------------------------- */ graph = Graph_new() ; adjIVL = InpMtx_fullAdjacency(mtxA) ; nedges = IVL_tsize(adjIVL) ; Graph_init2(graph, 0, neqns, 0, nedges, neqns, nedges, adjIVL, NULL, NULL) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n graph of the input matrix") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } frontETree = orderViaMMD(graph, seed, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n front tree from ordering") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ----------------------------------------------------- STEP 3: get the permutation, permute the matrix and front tree and get the symbolic factorization ----------------------------------------------------- */ oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ; oldToNew = IV_entries(oldToNewIV) ; newToOldIV = ETree_newToOldVtxPerm(frontETree) ; newToOld = IV_entries(newToOldIV) ; ETree_permuteVertices(frontETree, oldToNewIV) ; InpMtx_permute(mtxA, oldToNew, oldToNew) ; InpMtx_mapToUpperTriangle(mtxA) ; InpMtx_changeCoordType(mtxA, INPMTX_BY_CHEVRONS) ; InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; symbfacIVL = SymbFac_initFromInpMtx(frontETree, mtxA) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n old-to-new permutation vector") ; IV_writeForHumanEye(oldToNewIV, msgFile) ; fprintf(msgFile, "\n\n new-to-old permutation vector") ; IV_writeForHumanEye(newToOldIV, msgFile) ; fprintf(msgFile, "\n\n front tree after permutation") ; ETree_writeForHumanEye(frontETree, msgFile) ; fprintf(msgFile, "\n\n input matrix after permutation") ; InpMtx_writeForHumanEye(mtxA, msgFile) ; fprintf(msgFile, "\n\n symbolic factorization") ; IVL_writeForHumanEye(symbfacIVL, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------ STEP 4: initialize the front matrix object and the PatchAndGoInfo object to handle small pivots ------------------------------------------ */ frontmtx = FrontMtx_new() ; mtxmanager = SubMtxManager_new() ; SubMtxManager_init(mtxmanager, LOCK_IN_PROCESS, 0) ; FrontMtx_init(frontmtx, frontETree, symbfacIVL, type, symmetryflag, FRONTMTX_DENSE_FRONTS, SPOOLES_NO_PIVOTING, LOCK_IN_PROCESS, 0, NULL, mtxmanager, msglvl, msgFile) ; if ( patchAndGoFlag == 1 ) { frontmtx->patchinfo = PatchAndGoInfo_new() ; PatchAndGoInfo_init(frontmtx->patchinfo, 1, toosmall, fudge, storeids, storevalues) ; } else if ( patchAndGoFlag == 2 ) { frontmtx->patchinfo = PatchAndGoInfo_new() ; PatchAndGoInfo_init(frontmtx->patchinfo, 2, toosmall, fudge, storeids, storevalues) ; } /*--------------------------------------------------------------------*/ /* ------------------------------------------ STEP 5: setup the domain decomposition map ------------------------------------------ */ if ( nthread > (nfront = FrontMtx_nfront(frontmtx)) ) { nthread = nfront ; } cumopsDV = DV_new() ; DV_init(cumopsDV, nthread, NULL) ; ownersIV = ETree_ddMap(frontETree, type, symmetryflag, cumopsDV, 1./(2.*nthread)) ; DV_free(cumopsDV) ; /*--------------------------------------------------------------------*/ /* ----------------------------------------------------- STEP 6: compute the numeric factorization in parallel ----------------------------------------------------- */ chvmanager = ChvManager_new() ; ChvManager_init(chvmanager, LOCK_IN_PROCESS, 1) ; DVfill(10, cpus, 0.0) ; IVfill(20, stats, 0) ; lookahead = 0 ; rootchv = FrontMtx_MT_factorInpMtx(frontmtx, mtxA, tau, 0.0, chvmanager, ownersIV, lookahead, &error, cpus, stats, msglvl, msgFile) ; if ( patchAndGoFlag == 1 ) { if ( frontmtx->patchinfo->fudgeIV != NULL ) { fprintf(msgFile, "\n small pivots found at these locations") ; IV_writeForHumanEye(frontmtx->patchinfo->fudgeIV, msgFile) ; } PatchAndGoInfo_free(frontmtx->patchinfo) ; } else if ( patchAndGoFlag == 2 ) { if ( frontmtx->patchinfo->fudgeIV != NULL ) { fprintf(msgFile, "\n small pivots found at these locations") ; IV_writeForHumanEye(frontmtx->patchinfo->fudgeIV, msgFile) ; } if ( frontmtx->patchinfo->fudgeDV != NULL ) { fprintf(msgFile, "\n perturbations") ; DV_writeForHumanEye(frontmtx->patchinfo->fudgeDV, msgFile) ; } PatchAndGoInfo_free(frontmtx->patchinfo) ; } ChvManager_free(chvmanager) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n factor matrix") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; fflush(msgFile) ; } if ( rootchv != NULL ) { fprintf(msgFile, "\n\n matrix found to be singular\n") ; spoolesFatal(); } if ( error >= 0 ) { fprintf(msgFile, "\n\n fatal error at front %d\n", error) ; spoolesFatal(); } /* -------------------------------------- STEP 7: post-process the factorization -------------------------------------- */ FrontMtx_postProcess(frontmtx, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n factor matrix after post-processing") ; FrontMtx_writeForHumanEye(frontmtx, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ----------------------------------------- STEP 8: read the right hand side matrix B ----------------------------------------- */ if ( (inputFile = fopen(rhsFileName, "r")) == NULL ) { fprintf(stderr, "\n unable to open file %s", rhsFileName) ; spoolesFatal(); } fscanf(inputFile, "%d %d", &nrow, &nrhs) ; mtxB = DenseMtx_new() ; DenseMtx_init(mtxB, type, 0, 0, neqns, nrhs, 1, neqns) ; DenseMtx_zero(mtxB) ; if ( type == SPOOLES_REAL ) { for ( irow = 0 ; irow < nrow ; irow++ ) { fscanf(inputFile, "%d", &jrow) ; for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) { fscanf(inputFile, "%le", &value) ; DenseMtx_setRealEntry(mtxB, jrow, jrhs, value) ; } } } else { for ( irow = 0 ; irow < nrow ; irow++ ) { fscanf(inputFile, "%d", &jrow) ; for ( jrhs = 0 ; jrhs < nrhs ; jrhs++ ) { fscanf(inputFile, "%le %le", &real, &imag) ; DenseMtx_setComplexEntry(mtxB, jrow, jrhs, real, imag) ; } } } fclose(inputFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n rhs matrix in original ordering") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* -------------------------------------------------------------- STEP 9: permute the right hand side into the original ordering -------------------------------------------------------------- */ DenseMtx_permuteRows(mtxB, oldToNewIV) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n right hand side matrix in new ordering") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* -------------------------------------------------------- STEP 10: get the solve map object for the parallel solve -------------------------------------------------------- */ solvemap = SolveMap_new() ; SolveMap_ddMap(solvemap, type, FrontMtx_upperBlockIVL(frontmtx), FrontMtx_lowerBlockIVL(frontmtx), nthread, ownersIV, FrontMtx_frontTree(frontmtx), seed, msglvl, msgFile) ; /*--------------------------------------------------------------------*/ /* -------------------------------------------- STEP 11: solve the linear system in parallel -------------------------------------------- */ mtxX = DenseMtx_new() ; DenseMtx_init(mtxX, type, 0, 0, neqns, nrhs, 1, neqns) ; DenseMtx_zero(mtxX) ; FrontMtx_MT_solve(frontmtx, mtxX, mtxB, mtxmanager, solvemap, cpus, msglvl, msgFile) ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n solution matrix in new ordering") ; DenseMtx_writeForHumanEye(mtxX, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* -------------------------------------------------------- STEP 12: permute the solution into the original ordering -------------------------------------------------------- */ DenseMtx_permuteRows(mtxX, newToOldIV) ; if ( msglvl > 0 ) { fprintf(msgFile, "\n\n solution matrix in original ordering") ; DenseMtx_writeForHumanEye(mtxX, msgFile) ; fflush(msgFile) ; } /*--------------------------------------------------------------------*/ /* ----------- free memory ----------- */ FrontMtx_free(frontmtx) ; DenseMtx_free(mtxX) ; DenseMtx_free(mtxB) ; IV_free(newToOldIV) ; IV_free(oldToNewIV) ; InpMtx_free(mtxA) ; ETree_free(frontETree) ; IVL_free(symbfacIVL) ; SubMtxManager_free(mtxmanager) ; Graph_free(graph) ; SolveMap_free(solvemap) ; IV_free(ownersIV) ; /*--------------------------------------------------------------------*/ return(1) ; }
/* -------------------------------------------------------------------- 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 ; }
/* ---------------------------------------------------------------- purpose -- given InpMtx objects that contain A and B, initialize the bridge data structure for the serial factor's, solve's and mvm's. data -- pointer to a Bridge object pprbtype -- pointer to value containing problem type *prbtype = 1 --> A X = B X Lambda, vibration problem *prbtype = 2 --> A X = B X Lambda, buckling problem *prbtype = 3 --> A X = X Lambda, simple eigenvalue problem pneqns -- pointer to value containing number of equations pmxbsz -- pointer to value containing blocksize A -- pointer to InpMtx object containing A B -- pointer to InpMtx object containing B pseed -- pointer to value containing a random number seed pmsglvl -- pointer to value containing a message level msgFile -- message file pointer return value -- 1 -- normal return -1 -- data is NULL -2 -- pprbtype is NULL -3 -- *pprbtype is invalid -4 -- pneqns is NULL -5 -- *pneqns is invalid -6 -- pmxbsz is NULL -7 -- *pmxbsz is invalid -8 -- A and B are NULL -9 -- pseed is NULL -10 -- pmsglvl is NULL -11 -- *pmsglvl > 0 and msgFile is NULL created -- 98aug10, cca ---------------------------------------------------------------- */ int Setup ( void *data, int *pprbtype, int *pneqns, int *pmxbsz, InpMtx *A, InpMtx *B, int *pseed, int *pmsglvl, FILE *msgFile ) { Bridge *bridge = (Bridge *) data ; double sigma[2] ; Graph *graph ; int maxdomainsize, maxsize, maxzeros, msglvl, mxbsz, nedges, neqns, prbtype, seed ; IVL *adjIVL ; #if MYDEBUG > 0 double t1, t2 ; MARKTIME(t1) ; count_Setup++ ; fprintf(stdout, "\n (%d) Setup()", count_Setup) ; fflush(stdout) ; #endif /* -------------------- check the input data -------------------- */ if ( data == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n data is NULL\n") ; return(-1) ; } if ( pprbtype == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n prbtype is NULL\n") ; return(-2) ; } prbtype = *pprbtype ; if ( prbtype < 1 || prbtype > 3 ) { fprintf(stderr, "\n fatal error in Setup()" "\n prbtype = %d, is invalid\n", prbtype) ; return(-3) ; } if ( pneqns == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n pneqns is NULL\n") ; return(-4) ; } neqns = *pneqns ; if ( neqns <= 0 ) { fprintf(stderr, "\n fatal error in Setup()" "\n neqns = %d, is invalid\n", neqns) ; return(-5) ; } if ( pmxbsz == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n pmxbsz is NULL\n") ; return(-6) ; } mxbsz = *pmxbsz ; if ( mxbsz <= 0 ) { fprintf(stderr, "\n fatal error in Setup()" "\n *pmxbsz = %d, is invalid\n", mxbsz) ; return(-7) ; } if ( A == NULL && B == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n A and B are NULL\n") ; return(-8) ; } if ( pseed == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n pseed is NULL\n") ; return(-9) ; } seed = *pseed ; if ( pmsglvl == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n pmsglvl is NULL\n") ; return(-10) ; } msglvl = *pmsglvl ; if ( msglvl > 0 && msgFile == NULL ) { fprintf(stderr, "\n fatal error in Setup()" "\n msglvl = %d, msgFile = NULL\n", msglvl) ; return(-11) ; } bridge->msglvl = msglvl ; bridge->msgFile = msgFile ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n inside Setup()" "\n neqns = %d, prbtype = %d, mxbsz = %d, seed = %d", neqns, prbtype, mxbsz, seed) ; if ( A != NULL ) { fprintf(msgFile, "\n\n matrix A") ; InpMtx_writeForHumanEye(A, msgFile) ; } if ( B != NULL ) { fprintf(msgFile, "\n\n matrix B") ; InpMtx_writeForHumanEye(B, msgFile) ; } fflush(msgFile) ; } bridge->prbtype = prbtype ; bridge->neqns = neqns ; bridge->mxbsz = mxbsz ; bridge->A = A ; bridge->B = B ; bridge->seed = seed ; /* ---------------------------- create and initialize pencil ---------------------------- */ sigma[0] = 1.0; sigma[1] = 0.0; bridge->pencil = Pencil_new() ; Pencil_setDefaultFields(bridge->pencil) ; Pencil_init(bridge->pencil, SPOOLES_REAL, SPOOLES_SYMMETRIC, A, sigma, B) ; /* -------------------------------- convert to row or column vectors -------------------------------- */ if ( A != NULL ) { if ( ! INPMTX_IS_BY_ROWS(A) && ! INPMTX_IS_BY_COLUMNS(A) ) { InpMtx_changeCoordType(A, INPMTX_BY_ROWS) ; } if ( ! INPMTX_IS_BY_VECTORS(A) ) { InpMtx_changeStorageMode(A, INPMTX_BY_VECTORS) ; } } if ( B != NULL ) { if ( ! INPMTX_IS_BY_ROWS(B) && ! INPMTX_IS_BY_COLUMNS(B) ) { InpMtx_changeCoordType(B, INPMTX_BY_ROWS) ; } if ( ! INPMTX_IS_BY_VECTORS(B) ) { InpMtx_changeStorageMode(B, INPMTX_BY_VECTORS) ; } } /* ------------------------------- create a Graph object for A + B ------------------------------- */ graph = Graph_new() ; adjIVL = Pencil_fullAdjacency(bridge->pencil) ; nedges = IVL_tsize(adjIVL), Graph_init2(graph, 0, bridge->neqns, 0, nedges, bridge->neqns, nedges, adjIVL, NULL, NULL) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n graph of the input matrix") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } /* --------------- order the graph --------------- */ maxdomainsize = neqns / 64 ; if ( maxdomainsize == 0 ) { maxdomainsize = 1 ; } maxzeros = (int) (0.01*neqns) ; maxsize = 64 ; bridge->frontETree = orderViaBestOfNDandMS(graph, maxdomainsize, maxzeros, maxsize, bridge->seed, msglvl, msgFile) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n front tree from ordering") ; ETree_writeForHumanEye(bridge->frontETree, msgFile) ; fflush(msgFile) ; } /* ---------------------------------------------- get the old-to-new and new-to-old permutations ---------------------------------------------- */ bridge->oldToNewIV = ETree_oldToNewVtxPerm(bridge->frontETree) ; bridge->newToOldIV = ETree_newToOldVtxPerm(bridge->frontETree) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n old-to-new permutation") ; IV_writeForHumanEye(bridge->oldToNewIV, msgFile) ; fprintf(msgFile, "\n\n new-to-old permutation") ; IV_writeForHumanEye(bridge->newToOldIV, msgFile) ; fflush(msgFile) ; } /* -------------------------------------- permute the vertices in the front tree -------------------------------------- */ ETree_permuteVertices(bridge->frontETree, bridge->oldToNewIV) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n permuted front etree") ; ETree_writeForHumanEye(bridge->frontETree, msgFile) ; fflush(msgFile) ; } /* ------------------------------------------- permute the entries in the pencil. note, after the permutation the entries are mapped into the upper triangle. ------------------------------------------- */ Pencil_permute(bridge->pencil, bridge->oldToNewIV, bridge->oldToNewIV) ; Pencil_mapToUpperTriangle(bridge->pencil) ; Pencil_changeCoordType(bridge->pencil, INPMTX_BY_CHEVRONS) ; Pencil_changeStorageMode(bridge->pencil, INPMTX_BY_VECTORS) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n permuted pencil") ; Pencil_writeForHumanEye(bridge->pencil, msgFile) ; fflush(msgFile) ; } /* ---------------------------------- compute the symbolic factorization ---------------------------------- */ bridge->symbfacIVL = SymbFac_initFromPencil(bridge->frontETree, bridge->pencil) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n symbolic factorization") ; IVL_writeForHumanEye(bridge->symbfacIVL, msgFile) ; fflush(msgFile) ; } /* -------------------------------------------------- create a FrontMtx object to hold the factorization -------------------------------------------------- */ bridge->frontmtx = FrontMtx_new() ; /* ------------------------------------------------------------ create a SubMtxManager object to hold the factor submatrices ------------------------------------------------------------ */ bridge->mtxmanager = SubMtxManager_new() ; SubMtxManager_init(bridge->mtxmanager, NO_LOCK, 0) ; /* ------------------------------------------------------------ allocate the working objects X and Y for the matrix multiply ------------------------------------------------------------ */ bridge->X = DenseMtx_new() ; DenseMtx_init(bridge->X, SPOOLES_REAL, 0, 0, neqns, mxbsz, 1, neqns) ; bridge->Y = DenseMtx_new() ; DenseMtx_init(bridge->Y, SPOOLES_REAL, 0, 0, neqns, mxbsz, 1, neqns) ; /* ------------------------ free the working storage ------------------------ */ Graph_free(graph) ; #if MYDEBUG > 0 MARKTIME(t2) ; time_Setup += t2 - t1 ; fprintf(stdout, ", %8.3f seconds, %8.3f total time", t2 - t1, time_Setup) ; fflush(stdout) ; #endif return(1) ; }
/* -------------------------------------------------------------- purpose -- to permute (if necessary) the original matrix, and to initialize, factor and postprocess the factor matrix return value --- 1 -- normal return, factorization complete 0 -- factorization did not complete, see error flag -1 -- bridge is NULL -2 -- mtxA is NULL -3 -- perror is NULL created -- 98sep18, cca -------------------------------------------------------------- */ int BridgeMT_factor ( BridgeMT *bridge, InpMtx *mtxA, int permuteflag, int *perror ) { Chv *rootchv ; ChvManager *chvmanager ; double cputotal, nfops, t0, t1, t2 ; double cpus[11] ; int msglvl, nzf ; int stats[16] ; FILE *msgFile ; FrontMtx *frontmtx ; SubMtxManager *mtxmanager ; /*--------------------------------------------------------------------*/ MARKTIME(t0) ; /* --------------- check the input --------------- */ if ( bridge == NULL ) { fprintf(stderr, "\n error in BridgeMT_factor()" "\n bridge is NULL\n") ; return(-1) ; } if ( mtxA == NULL ) { fprintf(stderr, "\n error in BridgeMT_factor()" "\n mtxA is NULL\n") ; return(-2) ; } if ( perror == NULL ) { fprintf(stderr, "\n error in BridgeMT_factor()" "\n perror is NULL\n") ; return(-3) ; } msglvl = bridge->msglvl ; msgFile = bridge->msgFile ; /*--------------------------------------------------------------------*/ MARKTIME(t1) ; 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[6] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : permute and format A", t2 - t1) ; fflush(msgFile) ; } /* --------------------------- initialize the front matrix --------------------------- */ MARKTIME(t1) ; if ( (mtxmanager = bridge->mtxmanager) == NULL ) { mtxmanager = bridge->mtxmanager = SubMtxManager_new() ; SubMtxManager_init(mtxmanager, LOCK_IN_PROCESS, 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, LOCK_IN_PROCESS, 0, NULL, mtxmanager, msglvl, msgFile) ; frontmtx->patchinfo = bridge->patchinfo ; MARKTIME(t2) ; bridge->cpus[7] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : initialize front matrix", t2 - t1) ; 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(16, stats) ; DVzero(11, cpus) ; chvmanager = ChvManager_new() ; ChvManager_init(chvmanager, LOCK_IN_PROCESS, 1) ; MARKTIME(t1) ; rootchv = FrontMtx_MT_factorInpMtx(frontmtx, mtxA, bridge->tau, bridge->droptol, chvmanager, bridge->ownersIV, bridge->lookahead, perror, cpus, stats, msglvl, msgFile) ; MARKTIME(t2) ; IVcopy(6, bridge->stats, stats) ; bridge->cpus[8] += 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) ; FrontMtx_postProcess(frontmtx, msglvl, msgFile) ; MARKTIME(t2) ; bridge->cpus[9] += 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[10] += t2 - t0 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n\n CPU %8.3f : total factor time", t2 - t0) ; fflush(msgFile) ; } return(1) ; }
/* ---------------------------------------------------------------- purpose -- to create an InpMtx object filled with random entries input -- mtx -- matrix object, if NULL, it is created inputMode -- input mode for the object, indices only, real or complex entries coordType -- coordinate type for the object, by rows, by columns or by chevrons storageMode -- storage mode for the object, raw data, sorted or by vectors nrow -- # of rows ncol -- # of columns symflag -- symmetry flag for the matrix, symmetric, hermitian or nonsymmetric nonzerodiag -- if 1, entries are placed on the diagonal nitem -- # of items to be placed into the matrix seed -- random number seed return value --- 1 -- normal return -1 -- mtx is NULL -2 -- bad input mode -3 -- bad coordinate type -4 -- bad storage mode -5 -- nrow or ncol <= 0 -6 -- bad symmetry flag -7 -- hermitian matrix but not complex -8 -- symmetric or hermitian matrix but nrow != ncol -9 -- nitem < 0 ---------------------------------------------------------------- */ int InpMtx_randomMatrix ( InpMtx *mtx, int inputMode, int coordType, int storageMode, int nrow, int ncol, int symflag, int nonzerodiag, int nitem, int seed ) { double *dvec ; Drand *drand ; int col, ii, neqns, row ; int *colids, *rowids ; /* --------------- check the input --------------- */ if ( mtx == NULL ) { fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n mtx is NULL\n") ; return(-1) ; } switch ( inputMode ) { case INPMTX_INDICES_ONLY : case SPOOLES_REAL : case SPOOLES_COMPLEX : break ; default : fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n bad input mode %d\n", inputMode) ; return(-2) ; break ; } switch ( coordType ) { case INPMTX_BY_ROWS : case INPMTX_BY_COLUMNS : case INPMTX_BY_CHEVRONS : break ; default : fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n bad coordinate type %d\n", coordType) ; return(-3) ; break ; } switch ( storageMode ) { case INPMTX_RAW_DATA : case INPMTX_SORTED : case INPMTX_BY_VECTORS : break ; default : fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n bad storage mode%d\n", storageMode) ; return(-4) ; break ; } if ( nrow <= 0 || ncol <= 0 ) { fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n nrow = %d, ncol = %d\n", nrow, ncol) ; return(-5) ; } switch ( symflag ) { case SPOOLES_SYMMETRIC : case SPOOLES_HERMITIAN : case SPOOLES_NONSYMMETRIC : break ; default : fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n bad symmetry flag%d\n", symflag) ; return(-6) ; break ; } if ( symflag == SPOOLES_HERMITIAN && inputMode != SPOOLES_COMPLEX ) { fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n symmetryflag is Hermitian, requires complex type\n") ; return(-7) ; } if ( (symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN) && nrow != ncol ) { fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n symmetric or hermitian matrix, nrow %d, ncol%d\n", nrow, ncol) ; return(-8) ; } if ( nitem < 0 ) { fprintf(stderr, "\n fatal error in InpMtx_randomMatrix" "\n nitem = %d\n", nitem) ; return(-9) ; } /*--------------------------------------------------------------------*/ neqns = (nrow <= ncol) ? nrow : ncol ; if ( nonzerodiag == 1 ) { nitem += neqns ; } /* --------------------- initialize the object --------------------- */ InpMtx_init(mtx, INPMTX_BY_ROWS, inputMode, nitem, 0) ; /* ---------------- fill the triples ---------------- */ drand = Drand_new() ; Drand_setSeed(drand, seed) ; rowids = IVinit(nitem, -1) ; colids = IVinit(nitem, -1) ; if ( nonzerodiag == 1 ) { IVramp(neqns, rowids, 0, 1) ; Drand_setUniform(drand, 0, nrow) ; Drand_fillIvector(drand, nitem - neqns, rowids + neqns) ; Drand_setUniform(drand, 0, ncol) ; IVramp(neqns, colids, 0, 1) ; Drand_fillIvector(drand, nitem - neqns, colids + neqns) ; } else { Drand_setUniform(drand, 0, nrow) ; Drand_fillIvector(drand, nitem, rowids) ; Drand_setUniform(drand, 0, ncol) ; Drand_fillIvector(drand, nitem, colids) ; } if ( symflag == SPOOLES_SYMMETRIC || symflag == SPOOLES_HERMITIAN ) { for ( ii = 0 ; ii < nitem ; ii++ ) { if ( (row = rowids[ii]) > (col = colids[ii]) ) { rowids[ii] = col ; colids[ii] = row ; } } } if ( inputMode == SPOOLES_REAL ) { dvec = DVinit(nitem, 0.0) ; Drand_setUniform(drand, 0.0, 1.0) ; Drand_fillDvector(drand, nitem, dvec) ; } else if ( inputMode == SPOOLES_COMPLEX ) { dvec = DVinit(2*nitem, 0.0) ; Drand_setUniform(drand, 0.0, 1.0) ; Drand_fillDvector(drand, 2*nitem, dvec) ; if ( symflag == SPOOLES_HERMITIAN ) { for ( ii = 0 ; ii < nitem ; ii++ ) { if ( rowids[ii] == colids[ii] ) { dvec[2*ii+1] = 0.0 ; } } } } else { dvec = NULL ; } /* ---------------- load the triples ---------------- */ switch ( inputMode ) { case INPMTX_INDICES_ONLY : InpMtx_inputTriples(mtx, nitem, rowids, colids) ; break ; case SPOOLES_REAL : InpMtx_inputRealTriples(mtx, nitem, rowids, colids, dvec) ; break ; case SPOOLES_COMPLEX : InpMtx_inputComplexTriples(mtx, nitem, rowids, colids, dvec) ; break ; } /* ---------------------------------------- set the coordinate type and storage mode ---------------------------------------- */ InpMtx_changeCoordType(mtx, coordType) ; InpMtx_changeStorageMode(mtx, storageMode) ; /* ------------------------ free the working storage ------------------------ */ Drand_free(drand) ; IVfree(rowids) ; IVfree(colids) ; if ( dvec != NULL ) { DVfree(dvec) ; } return(1) ; }
/* ------------------------------------------------------------------- purpose -- given an InpMtx object that contains the structure of A, initialize the bridge data structure for the serial factor's and solve's. note: all parameters are pointers to be compatible with fortran's call by reference. return value -- 1 -- normal return -1 -- bridge is NULL -2 -- mtxA is NULL created -- 98sep17, cca ------------------------------------------------------------------- */ int BridgeMT_setup ( BridgeMT *bridge, InpMtx *mtxA ) { double t0, t1, t2 ; ETree *frontETree ; FILE *msgFile ; Graph *graph ; int compressed, msglvl, nedges, neqns, Neqns ; IV *eqmapIV ; IVL *adjIVL, *symbfacIVL ; MARKTIME(t0) ; /* -------------------- check the input data -------------------- */ if ( bridge == NULL ) { fprintf(stderr, "\n fatal error in BridgeMT_setup()" "\n data is NULL\n") ; return(-1) ; } if ( mtxA == NULL ) { fprintf(stderr, "\n fatal error in BridgeMT_setup()" "\n A is NULL\n") ; return(-2) ; } msglvl = bridge->msglvl ; msgFile = bridge->msgFile ; neqns = bridge->neqns ; if ( ! (INPMTX_IS_BY_ROWS(mtxA) || INPMTX_IS_BY_COLUMNS(mtxA)) ) { /* ------------------------------ change coordinate type to rows ------------------------------ */ InpMtx_changeCoordType(mtxA, INPMTX_BY_ROWS) ; } if ( ! INPMTX_IS_BY_VECTORS(mtxA) ) { /* ------------------------------ change storage mode to vectors ------------------------------ */ InpMtx_changeStorageMode(mtxA, INPMTX_BY_VECTORS) ; } /* --------------------------- create a Graph object for A --------------------------- */ MARKTIME(t1) ; graph = Graph_new() ; adjIVL = InpMtx_fullAdjacency(mtxA); nedges = bridge->nedges = IVL_tsize(adjIVL), Graph_init2(graph, 0, neqns, 0, nedges, neqns, nedges, adjIVL, NULL, NULL) ; MARKTIME(t2) ; bridge->cpus[0] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to create Graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n graph of the input matrix") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } /* ------------------ compress the graph ------------------ */ MARKTIME(t1) ; eqmapIV = Graph_equivMap(graph) ; Neqns = bridge->Neqns = 1 + IV_max(eqmapIV) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n graph's equivalence map") ; IV_writeForHumanEye(eqmapIV, msgFile) ; fflush(msgFile) ; } if ( Neqns < bridge->compressCutoff * neqns ) { Graph *cgraph ; /* ------------------ compress the graph ------------------ */ cgraph = Graph_compress2(graph, eqmapIV, 1) ; Graph_free(graph) ; graph = cgraph ; compressed = 1 ; bridge->Nedges = graph->nedges ; } else { compressed = 0 ; } MARKTIME(t2) ; bridge->cpus[1] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to create compressed graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n graph to order") ; Graph_writeForHumanEye(graph, msgFile) ; fflush(msgFile) ; } /* --------------- order the graph --------------- */ MARKTIME(t1) ; if ( bridge->maxdomainsize <= 0 ) { bridge->maxdomainsize = neqns/32 ; } if ( bridge->maxdomainsize <= 0 ) { bridge->maxdomainsize = 1 ; } if ( bridge->maxnzeros < 0 ) { bridge->maxnzeros = 0.01*neqns ; } if ( bridge->maxsize < 0 ) { bridge->maxsize = neqns ; } frontETree = orderViaBestOfNDandMS(graph, bridge->maxdomainsize, bridge->maxnzeros, bridge->maxsize, bridge->seed, msglvl, msgFile) ; MARKTIME(t2) ; bridge->cpus[2] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time to order graph", t2 - t1) ; fflush(msgFile) ; } if ( msglvl > 3 ) { fprintf(msgFile, "\n\n front tree from ordering") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } MARKTIME(t1) ; if ( compressed == 1 ) { ETree *etree ; IVL *tempIVL ; /* ---------------------------------------------------------- compute the symbolic factorization of the compressed graph ---------------------------------------------------------- */ tempIVL = SymbFac_initFromGraph(frontETree, graph) ; /* ------------------------------------------------------- expand the symbolic factorization to the original graph ------------------------------------------------------- */ symbfacIVL = IVL_expand(tempIVL, eqmapIV) ; IVL_free(tempIVL) ; /* --------------------- expand the front tree --------------------- */ etree = ETree_expand(frontETree, eqmapIV) ; ETree_free(frontETree) ; frontETree = etree ; } else { /* -------------------------------------------------------- compute the symbolic factorization of the original graph -------------------------------------------------------- */ symbfacIVL = SymbFac_initFromGraph(frontETree, graph) ; } MARKTIME(t2) ; bridge->frontETree = frontETree ; bridge->symbfacIVL = symbfacIVL ; /* ---------------------------------------------- get the old-to-new and new-to-old permutations ---------------------------------------------- */ bridge->oldToNewIV = ETree_oldToNewVtxPerm(frontETree) ; bridge->newToOldIV = ETree_newToOldVtxPerm(frontETree) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n old-to-new permutation") ; IV_writeForHumanEye(bridge->oldToNewIV, msgFile) ; fprintf(msgFile, "\n\n new-to-old permutation") ; IV_writeForHumanEye(bridge->newToOldIV, msgFile) ; fflush(msgFile) ; } /* ------------------------------------------------------ overwrite the symbolic factorization with the permuted indices and sort the lists into ascending order ------------------------------------------------------ */ IVL_overwrite(symbfacIVL, bridge->oldToNewIV) ; IVL_sortUp(symbfacIVL) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n symbolic factorization") ; IVL_writeForHumanEye(symbfacIVL, msgFile) ; fflush(msgFile) ; } /* -------------------------------------- permute the vertices in the front tree -------------------------------------- */ ETree_permuteVertices(frontETree, bridge->oldToNewIV) ; if ( msglvl > 2 ) { fprintf(msgFile, "\n\n permuted front etree") ; ETree_writeForHumanEye(frontETree, msgFile) ; fflush(msgFile) ; } MARKTIME(t2) ; bridge->cpus[3] += t2 - t1 ; if ( msglvl > 1 ) { fprintf(msgFile, "\n CPU %8.3f : time for symbolic factorization", t2 - t1) ; fflush(msgFile) ; } /* ------------------------ free the working storage ------------------------ */ Graph_free(graph) ; IV_free(eqmapIV) ; MARKTIME(t2) ; bridge->cpus[4] += t2 - t0 ; return(1) ; }