int zpcgr ( int n_matrixSize, int type, int symmetryflag, InpMtx *mtxA, FrontMtx *Precond, DenseMtx *mtxX, DenseMtx *mtxB, int itermax, double convergetol, int msglvl, FILE *msgFile ) { Chv *chv, *rootchv ; ChvManager *chvmanager ; DenseMtx *mtxZ ; DenseMtx *vecP, *vecR, *vecQ ; DenseMtx *vecX, *vecZ ; double Alpha[2], Beta[2], Rho[2], Rho0[2], Rtmp[2]; double Init_norm, ratio, Res_norm ; double t1, t2, cpus[9] ; double one[2] = {1.0, 0.0}, zero[2] = {0.0, 0.0} ; double Tiny[2] = {0.1e-28, 0.0}; int Iter, neqns; int stats[6] ; if (symmetryflag != SPOOLES_HERMITIAN){ fprintf(msgFile, "\n\n Fatal Error, \n" " Matrix is not Hermitian in ZPCGR !!") ; exit(-1); }; neqns = n_matrixSize; /* -------------------- init the vectors in ZPCGR -------------------- */ vecP = DenseMtx_new() ; DenseMtx_init(vecP, type, 0, 0, neqns, 1, 1, neqns) ; vecR = DenseMtx_new() ; DenseMtx_init(vecR, type, 0, 0, neqns, 1, 1, neqns) ; vecX = DenseMtx_new() ; DenseMtx_init(vecX, type, 0, 0, neqns, 1, 1, neqns) ; vecQ = DenseMtx_new() ; DenseMtx_init(vecQ, type, 0, 0, neqns, 1, 1, neqns) ; vecZ = DenseMtx_new() ; DenseMtx_init(vecZ, type, 0, 0, neqns, 1, 1, neqns) ; /* -------------------------- Initialize the iterations -------------------------- */ Init_norm = DenseMtx_twoNormOfColumn (mtxB, 0); if ( Init_norm == 0.0 ){ Init_norm = 1.0; }; ratio = 1.0; DenseMtx_zero(vecX) ; DenseMtx_colCopy (vecR, 0, mtxB, 0); MARKTIME(t1) ; Iter = 0; /* ------------------------------ Main Loop of the iterations ------------------------------ */ while ( ratio > convergetol && Iter <= itermax ) { Iter++; /* */ FrontMtx_solve(Precond, vecZ, vecR, Precond->manager, cpus, msglvl, msgFile) ; DenseMtx_colDotProduct(vecR, 0, vecZ, 0, Rho); if ( Rho[0] == 0.0 & Rho[1] == 0.0){ fprintf(stderr, "\n breakdown in ZPCGR !! " "\n Fatal error \n"); exit(-1) ; } /* */ if ( Iter == 1 ) { DenseMtx_colCopy (vecP, 0, vecZ, 0); } else { zdiv(Rho, Rho0, Beta); DenseMtx_colGenAxpy (Beta, vecP, 0, one, vecZ, 0); }; InpMtx_herm_gmmm(mtxA, zero, vecQ, one, vecP) ; DenseMtx_colDotProduct (vecP, 0, vecQ,0, Rtmp); zdiv(Rho, Rtmp, Alpha); DenseMtx_colGenAxpy (one, vecX, 0, Alpha, vecP, 0); Rtmp[0] = -Alpha[0]; Rtmp[1] = -Alpha[1]; DenseMtx_colGenAxpy (one, vecR, 0, Rtmp, vecQ, 0); Rho0[0] = Rho[0]; Rho0[1] = Rho[1]; /* */ Res_norm = DenseMtx_twoNormOfColumn (vecR, 0); ratio = Res_norm/Init_norm; fprintf(msgFile, "\n\n At iteration %d" " the convergence ratio is %12.4e", Iter, ratio) ; } /* End of while loop */ MARKTIME(t2) ; fprintf(msgFile, "\n CPU : Converges in time: %8.3f ", t2 - t1) ; fprintf(msgFile, "\n # iterations = %d", Iter) ; fprintf(msgFile, "\n\n after ZPCGR") ; DenseMtx_colCopy (mtxX, 0, vecX, 0); /* ------------------------ free the working storage ------------------------ */ DenseMtx_free(vecP) ; DenseMtx_free(vecR) ; DenseMtx_free(vecX) ; DenseMtx_free(vecQ) ; DenseMtx_free(vecZ) ; fprintf(msgFile, "\n") ; 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) ; }
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"); }
/* -------------------------------------------------- purpose -- to solve a linear system (A - sigma*B) sol[] = rhs[] data -- pointer to bridge data object *pnrows -- # of rows in x[] and y[] *pncols -- # of columns in x[] and y[] rhs[] -- vector that holds right hand sides NOTE: the rhs[] vector is global, not a portion sol[] -- vector to hold solutions NOTE: the sol[] vector is global, not a portion note: rhs[] and sol[] can be the same array. on return, *perror holds an error code. created -- 98aug28, cca & jcp -------------------------------------------------- */ void JimSolveMPI ( int *pnrows, int *pncols, double rhs[], double sol[], void *data, int *perror ) { BridgeMPI *bridge = (BridgeMPI *) data ; DenseMtx *mtx, *newmtx ; int irow, jj, jcol, kk, myid, ncols = *pncols, neqns, nowned, tag = 0 ; int *vtxmap ; int stats[4] ; IV *mapIV ; #if MYDEBUG > 0 double t1, t2 ; count_JimSolve++ ; MARKTIME(t1) ; if ( bridge->myid == 0 ) { fprintf(stdout, "\n (%d) JimSolve() start", count_JimSolve) ; fflush(stdout) ; } #endif #if MYDEBUG > 1 fprintf(bridge->msgFile, "\n (%d) JimSolve() start", count_JimSolve) ; fflush(bridge->msgFile) ; #endif MPI_Barrier(bridge->comm) ; /* --------------------------------------------- slide the owned rows of rhs down in the array --------------------------------------------- */ vtxmap = IV_entries(bridge->vtxmapIV) ; neqns = bridge->neqns ; myid = bridge->myid ; nowned = IV_size(bridge->myownedIV) ; for ( jcol = jj = kk = 0 ; jcol < ncols ; jcol++ ) { for ( irow = 0 ; irow < neqns ; irow++, jj++ ) { if ( vtxmap[irow] == myid ) { sol[kk++] = rhs[jj] ; } } } if ( kk != nowned * ncols ) { fprintf(stderr, "\n proc %d : kk %d, nowned %d, ncols %d", myid, kk, nowned, ncols) ; exit(-1) ; } /* ---------------------------------------- call the method that assumes local input ---------------------------------------- */ if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n calling SolveMPI()") ; fflush(bridge->msgFile) ; } SolveMPI(&nowned, pncols, sol, sol, data, perror) ; if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n return from SolveMPI()") ; fflush(bridge->msgFile) ; } /* ------------------------------------------ gather all the entries onto processor zero ------------------------------------------ */ mtx = DenseMtx_new() ; DenseMtx_init(mtx, SPOOLES_REAL, 0, 0, nowned, ncols, 1, nowned) ; DVcopy (nowned*ncols, DenseMtx_entries(mtx), sol) ; IVcopy(nowned, mtx->rowind, IV_entries(bridge->myownedIV)) ; mapIV = IV_new() ; IV_init(mapIV, neqns, NULL) ; IV_fill(mapIV, 0) ; IVfill(4, stats, 0) ; if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n calling DenseMtx_split()()") ; fflush(bridge->msgFile) ; } newmtx = DenseMtx_MPI_splitByRows(mtx, mapIV, stats, bridge->msglvl, bridge->msgFile, tag, bridge->comm) ; if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n return from DenseMtx_split()()") ; fflush(bridge->msgFile) ; } DenseMtx_free(mtx) ; mtx = newmtx ; IV_free(mapIV) ; if ( myid == 0 ) { DVcopy(neqns*ncols, sol, DenseMtx_entries(mtx)) ; } DenseMtx_free(mtx) ; /* --------------------------------------------- broadcast the entries to the other processors --------------------------------------------- */ if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n calling MPI_Bcast()()") ; fflush(bridge->msgFile) ; } MPI_Bcast((void *) sol, neqns*ncols, MPI_DOUBLE, 0, bridge->comm) ; if ( bridge->msglvl > 1 ) { fprintf(bridge->msgFile, "\n return from MPI_Bcast()()") ; fflush(bridge->msgFile) ; } MPI_Barrier(bridge->comm) ; /* ------------------------------------------------------------------ set the error. (this is simple since when the spooles codes detect a fatal error, they print out a message to stderr and exit.) ------------------------------------------------------------------ */ *perror = 0 ; #if MYDEBUG > 0 MARKTIME(t2) ; time_JimSolve += t2 - t1 ; if ( bridge->myid == 0 ) { fprintf(stdout, "\n (%d) JimSolve() end", count_JimSolve) ; fprintf(stdout, ", %8.3f seconds, %8.3f total time", t2 - t1, time_JimSolve) ; fflush(stdout) ; } #endif #if MYDEBUG > 1 fprintf(bridge->msgFile, "\n (%d) JimSolve() end", count_JimSolve) ; fprintf(bridge->msgFile, ", %8.3f seconds, %8.3f total time", t2 - t1, time_JimSolve) ; fflush(bridge->msgFile) ; #endif return ; }
/* ------------------------------------------- set up the nthread MTmvmObj data structures ------------------------------------------- */ static MTmvmObj * setup ( InpMtx *A, DenseMtx *Y, double alpha[], DenseMtx *X, int nthread ) { double *dvec ; int ithread, nentA, nextra, nlocal, offset ; int *ivec1, *ivec2 ; MTmvmObj *MTmvmObjs, *obj ; /* --------------------------------- allocate nthread MTmvmObj objects --------------------------------- */ ALLOCATE(MTmvmObjs, struct _MTmvmObj, nthread) ; for ( ithread = 0, obj = MTmvmObjs ; ithread < nthread ; ithread++, obj++ ) { obj->A = InpMtx_new() ; if ( ithread == 0 ) { obj->Y = Y ; } else { obj->Y = DenseMtx_new() ; } obj->alpha[0] = alpha[0] ; obj->alpha[1] = alpha[1] ; obj->X = X ; } /* ---------------------------------------- set up and zero the replicated Y objects ---------------------------------------- */ for ( ithread = 0, obj = MTmvmObjs ; ithread < nthread ; ithread++, obj++ ) { if ( ithread > 0 ) { DenseMtx_init(obj->Y, Y->type, Y->rowid, Y->colid, Y->nrow, Y->ncol, Y->inc1, Y->inc2) ; DenseMtx_zero(obj->Y) ; } } /* ------------------------------------- set up the partitioned InpMtx objects ------------------------------------- */ nentA = InpMtx_nent(A) ; nlocal = nentA / nthread ; nextra = nentA % nthread ; ivec1 = InpMtx_ivec1(A) ; ivec2 = InpMtx_ivec2(A) ; if ( INPMTX_IS_REAL_ENTRIES(A) || INPMTX_IS_COMPLEX_ENTRIES(A) ) { dvec = InpMtx_dvec(A) ; } else { dvec = NULL ; } offset = 0 ; for ( ithread = 0, obj = MTmvmObjs ; ithread < nthread ; ithread++, obj++ ) { InpMtx_init(obj->A, A->coordType, A->inputMode, 0, 0) ; obj->A->storageMode = A->storageMode ; if ( ithread < nextra ) { obj->A->nent = nlocal + 1 ; } else { obj->A->nent = nlocal ; } IV_init(&(obj->A->ivec1IV), obj->A->nent, ivec1 + offset) ; IV_init(&(obj->A->ivec2IV), obj->A->nent, ivec2 + offset) ; if ( INPMTX_IS_REAL_ENTRIES(A) ) { DV_init(&(obj->A->dvecDV), obj->A->nent, dvec + offset) ; } else if ( INPMTX_IS_COMPLEX_ENTRIES(A) ) { DV_init(&(obj->A->dvecDV), obj->A->nent, dvec + 2*offset) ; } offset += obj->A->nent ; } return(MTmvmObjs) ; }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) /* ----------------------------------------------- test the DenseMtx_twoNormOfColumn routine. when msglvl > 1, the output of this program can be fed into Matlab to check for errors created -- 98dec03, ycp ----------------------------------------------- */ { DenseMtx *A ; double t1, t2, value ; Drand *drand ; FILE *msgFile ; int inc1, inc2, jcol, msglvl, nrow, ncol, seed, type ; if ( argc != 10 ) { fprintf(stdout, "\n\n usage : %s msglvl msgFile type nrow ncol inc1 inc2 " "\n , jcol, seed " "\n msglvl -- message level" "\n msgFile -- message file" "\n type -- entries type" "\n 1 -- real" "\n 2 -- complex" "\n nrow -- # of rows " "\n ncol -- # of columns " "\n inc1 -- row increment " "\n inc2 -- column increment " "\n jcol -- vector x: j-th column of A " "\n seed -- random number seed" "\n", argv[0]) ; return(0) ; } if ( (msglvl = atoi(argv[1])) < 0 ) { fprintf(stderr, "\n message level must be positive\n") ; exit(-1) ; } if ( strcmp(argv[2], "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) { fprintf(stderr, "\n unable to open file %s\n", argv[2]) ; return(-1) ; } type = atoi(argv[3]) ; nrow = atoi(argv[4]) ; ncol = atoi(argv[5]) ; inc1 = atoi(argv[6]) ; inc2 = atoi(argv[7]) ; if ( type < 1 || type > 2 || nrow < 0 || ncol < 0 || inc1 < 1 || inc2 < 1 ) { fprintf(stderr, "\n fatal error, type %d, nrow %d, ncol %d, inc1 %d, inc2 %d", type, nrow, ncol, inc1, inc2) ; exit(-1) ; } jcol = atoi(argv[8]) ; seed = atoi(argv[9]) ; fprintf(msgFile, "\n\n %% %s :" "\n %% msglvl = %d" "\n %% msgFile = %s" "\n %% type = %d" "\n %% nrow = %d" "\n %% ncol = %d" "\n %% inc1 = %d" "\n %% inc2 = %d" "\n %% jcol = %d" "\n %% seed = %d" "\n", argv[0], msglvl, argv[2], type, nrow, ncol, inc1, inc2, jcol, seed) ; /* ---------------------------- initialize the matrix object ---------------------------- */ MARKTIME(t1) ; A = DenseMtx_new() ; DenseMtx_init(A, type, 0, 0, nrow, ncol, inc1, inc2) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to initialize matrix object", t2 - t1) ; MARKTIME(t1) ; drand = Drand_new() ; Drand_setSeed(drand, seed) ; seed++ ; Drand_setUniform(drand, -1.0, 1.0) ; DenseMtx_fillRandomEntries(A, drand) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to fill matrix with random numbers", t2 - t1) ; if ( msglvl > 3 ) { fprintf(msgFile, "\n matrix A") ; DenseMtx_writeForHumanEye(A, msgFile) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n %% matrix A") ; fprintf(msgFile, "\n nrow = %d ;", nrow) ; fprintf(msgFile, "\n ncol = %d ;", ncol) ; fprintf(msgFile, "\n"); DenseMtx_writeForMatlab(A, "A", msgFile) ; } /* -------------------------- compute the frobenius norm -------------------------- */ value = DenseMtx_twoNormOfColumn(A,jcol); if ( msglvl > 1 ) { fprintf(msgFile, "\n %% Two Norm = %e", value) ; fprintf(msgFile, "\n"); fflush(msgFile) ; } /* ------------------------ free the working storage ------------------------ */ DenseMtx_free(A) ; Drand_free(drand) ; return(1) ; }
/* ---------------------------------------------------------------- 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) ; }
/*--------------------------------------------------------------------*/ int main ( int argc, char *argv[] ) /* ------------------------------------------------------- test the DenseMtx_mmm routine. C = alpha*A*B + beta*C, where A, B and C are DenseMtx. alpha and beta are scalars. when msglvl > 1, the output of this program can be fed into Matlab to check for errors created -- 98dec14, ycp ------------------------------------------------------- */ { DenseMtx *mtxA, *mtxB, *mtxC; double t1, t2, value[2] = {1.0, 1.0} ; Drand *drand ; FILE *msgFile ; int i, j, k, msglvl, nrow, nk, ncol, cnrow, cncol, seed, type ; int ainc1, ainc2, binc1, binc2, cinc1, cinc2; double alpha[2], beta[2], one[2] = {1.0, 0.0}, rvalue; char A_opt[1]=" ", B_opt[1]=" "; if ( argc != 20 ) { fprintf(stdout, "\n\n usage : %s msglvl msgFile type nrow nk ncol ainc1 ainc2 binc1 " "\n binc2 cinc1 cinc2 A_opt B_opt ralpha ialpha rbeta ibeta seed " "\n msglvl -- message level" "\n msgFile -- message file" "\n type -- entries type" "\n 1 -- real" "\n 2 -- complex" "\n nrow -- # of rows of mtxA " "\n nk -- # of columns of mtxA " "\n ncol -- # of columns of mtxB " "\n ainc1 -- A row increment " "\n ainc2 -- A column increment " "\n binc1 -- B row increment " "\n binc2 -- B column increment " "\n binc1 -- C row increment " "\n binc2 -- C column increment " "\n A_opt -- A option " "\n B_opt -- B option " "\n ralpha -- real(alpha)" "\n ialpha -- imag(alpha)" "\n rbeta -- real(beta)" "\n ibeta -- imag(beta)" "\n seed -- random number seed" "\n", argv[0]) ; return(0) ; } if ( (msglvl = atoi(argv[1])) < 0 ) { fprintf(stderr, "\n message level must be positive\n") ; spoolesFatal(); } if ( strcmp(argv[2], "stdout") == 0 ) { msgFile = stdout ; } else if ( (msgFile = fopen(argv[2], "a")) == NULL ) { fprintf(stderr, "\n unable to open file %s\n", argv[2]) ; return(-1) ; } type = atoi(argv[3]) ; nrow = atoi(argv[4]) ; nk = atoi(argv[5]) ; ncol = atoi(argv[6]) ; ainc1= atoi(argv[7]) ; ainc2= atoi(argv[8]) ; binc1= atoi(argv[9]) ; binc2= atoi(argv[10]) ; cinc1= atoi(argv[11]) ; cinc2= atoi(argv[12]) ; if ( type < 1 || type > 2 || nrow < 0 || ncol < 0 || ainc1 < 1 || ainc2 < 1 || binc1 < 1 || binc2 < 1 ) { fprintf(stderr, "\n fatal error, type %d, nrow %d, ncol %d, ainc1 %d, ainc2 %d" ", binc1 %d, binc2 %d", type, nrow, ncol, ainc1, ainc2, binc1, binc2) ; spoolesFatal(); } A_opt[0] = *argv[13] ; B_opt[0] = *argv[14] ; alpha[0]= atof (argv[15]); alpha[1]= atof (argv[16]); beta[0] = atof (argv[17]); beta[1] = atof (argv[18]); seed = atoi (argv[19]) ; fprintf(msgFile, "\n\n %% %s :" "\n %% msglvl = %d" "\n %% msgFile = %s" "\n %% type = %d" "\n %% nrow = %d" "\n %% nk = %d" "\n %% ncol = %d" "\n %% ainc1 = %d" "\n %% ainc2 = %d" "\n %% binc1 = %d" "\n %% binc2 = %d" "\n %% cinc1 = %d" "\n %% cinc2 = %d" "\n %% a_opt = %c" "\n %% b_opt = %c" "\n %% ralpha = %e" "\n %% ialpha = %e" "\n %% rbeta = %e" "\n %% ibeta = %e" "\n %% seed = %d" "\n", argv[0], msglvl, argv[2], type, nrow, nk, ncol, ainc1, ainc2, binc1, binc2, cinc1, cinc2, A_opt[0], B_opt[0], alpha[0], alpha[1], beta[0], beta[1], seed) ; /* ---------------------------- initialize the matrix object ---------------------------- */ MARKTIME(t1) ; mtxA = DenseMtx_new() ; DenseMtx_init(mtxA, type, 0, 0, nrow, nk, ainc1, ainc2) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to initialize matrix object", t2 - t1) ; MARKTIME(t1) ; drand = Drand_new() ; Drand_setSeed(drand, seed) ; seed++ ; Drand_setUniform(drand, -1.0, 1.0) ; DenseMtx_fillRandomEntries(mtxA, drand) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to fill matrix A with random numbers", t2 - t1) ; MARKTIME(t1) ; mtxB = DenseMtx_new() ; DenseMtx_init(mtxB, type, 0, 0, nk, ncol, binc1, binc2) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to initialize matrix object", t2 - t1) ; MARKTIME(t1) ; drand = Drand_new() ; Drand_setSeed(drand, seed) ; seed++ ; Drand_setUniform(drand, -1.0, 1.0) ; DenseMtx_fillRandomEntries(mtxB, drand) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to fill matrix B with random numbers", t2 - t1) ; cnrow = nrow; cncol = ncol; MARKTIME(t1) ; mtxC = DenseMtx_new() ; if ( A_opt[0] == 't' || A_opt[0] == 'T' || A_opt[0] == 'c' || A_opt[0] == 'C') { cnrow = nk; } if ( B_opt[0] == 't' || B_opt[0] == 'T' || B_opt[0] == 'c' || B_opt[0] == 'C') { cncol = nk; } if ( cinc1 == 1 && cinc2 == nrow ){ /* stored by column */ cinc1 = 1; cinc2 = cnrow; } else { /* stored by row */ cinc1 = cncol; cinc2 = 1; } DenseMtx_init(mtxC, type, 0, 0, cnrow, cncol, cinc1, cinc2) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to initialize matrix object", t2 - t1) ; MARKTIME(t1) ; drand = Drand_new() ; Drand_setSeed(drand, seed) ; seed++ ; Drand_setUniform(drand, -1.0, 1.0) ; DenseMtx_fillRandomEntries(mtxC, drand) ; MARKTIME(t2) ; fprintf(msgFile, "\n %% CPU : %.3f to fill matrix C with random numbers", t2 - t1) ; if ( msglvl > 3 ) { fprintf(msgFile, "\n matrix A") ; DenseMtx_writeForHumanEye(mtxA, msgFile) ; fprintf(msgFile, "\n matrix B") ; DenseMtx_writeForHumanEye(mtxB, msgFile) ; fprintf(msgFile, "\n matrix C") ; DenseMtx_writeForHumanEye(mtxC, msgFile) ; } if ( msglvl > 1 ) { fprintf(msgFile, "\n\n %% beta = (%f, %f)", beta[0], beta[1]) ; fprintf(msgFile, "\n %% alpha = (%f, %f)\n", alpha[0], alpha[1]) ; fprintf(msgFile, "\n %% matrix A") ; fprintf(msgFile, "\n nrow = %d ;", nrow) ; fprintf(msgFile, "\n ncol = %d ;", nk) ; DenseMtx_writeForMatlab(mtxA, "A", msgFile) ; fprintf(msgFile, "\n"); fprintf(msgFile, "\n %% matrix B") ; fprintf(msgFile, "\n nrow = %d ;", nk) ; fprintf(msgFile, "\n ncol = %d ;", ncol) ; DenseMtx_writeForMatlab(mtxB, "B", msgFile) ; fprintf(msgFile, "\n"); fprintf(msgFile, "\n %% matrix C") ; fprintf(msgFile, "\n nrow = %d ;", cnrow) ; fprintf(msgFile, "\n ncol = %d ;", cncol) ; DenseMtx_writeForMatlab(mtxC, "C", msgFile) ; } /* -------------------------- performs the matrix-matrix operations C = alpha*(A)*(B) + beta*C -------------------------- */ DenseMtx_mmm(A_opt, B_opt, &beta, mtxC, &alpha, mtxA, mtxB); if ( msglvl > 1 ) { fprintf(msgFile, "\n"); fprintf(msgFile, "\n %% *** Output matrix C ***") ; fprintf(msgFile, "\n nrow = %d ;", cnrow) ; fprintf(msgFile, "\n ncol = %d ;", cncol) ; DenseMtx_writeForMatlab(mtxC, "C", msgFile) ; fprintf(msgFile, "\n"); fflush(msgFile) ; } /* ------------------------ free the working storage ------------------------ */ DenseMtx_free(mtxA) ; DenseMtx_free(mtxB) ; DenseMtx_free(mtxC) ; Drand_free(drand) ; return(1) ; }