MKL_INT PardisoSolver::FactorMatrix(const SparseMatrix * A) { if (directIterative) return 0; mkl_set_num_threads(numThreads); // compute the factorization if (verbose >= 1) printf("Factoring the %d x %d matrix (%d threads)...\n", n, n, numThreads); int upperTriangleOnly = 1; int oneIndexed = 1; if ((mtype == REAL_SPD) || (mtype == REAL_SYM_INDEFINITE)) // matrix is symmetric upperTriangleOnly = 1; // symmetric matrix can only be represented by its upper triangle elements else // structural symmetric or unsymmetric upperTriangleOnly = 0; // unsymmetric matrix must store all its elements A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed); // factor phase = 22; PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error); if (error != 0) printf("Error: Pardiso Cholesky decomposition returned non-zero exit code %d.\n", error); if (verbose >= 1) printf("Factorization completed.\n"); return error; }
MKL_INT PardisoSolver::SolveLinearSystemDirectIterative(const SparseMatrix * A, double * x, const double * rhs) { if (directIterative != 1) { printf("Error: direct-iterative flag was not specified in the constructor.\n"); return 102; } mkl_set_num_threads(numThreads); if (verbose >= 2) printf("Solving linear system...(%d threads, direct-iterative)\n", numThreads); int upperTriangleOnly = 1; int oneIndexed = 1; A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed); phase = 23; PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)rhs, x, &error); if (error != 0) printf("Error: Pardiso solve returned non-zero exit code %d.\n", error); if (verbose >= 2) printf("Solve completed.\n"); return error; }
MKL_INT PardisoSolver::BackwardSubstitution(double * x, const double * y) { if (directIterative != 0) { printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n"); return 101; } mkl_set_num_threads(numThreads); if (verbose >= 2) printf("Performing forward substitution...(%d threads)\n", numThreads); int maxIterRefinementSteps = iparm[7]; iparm[7] = 0; phase = 333; PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)y, x, &error); iparm[7] = maxIterRefinementSteps; if (error != 0) printf("Error: Pardiso solve returned non-zero exit code %d.\n", error); if (verbose >= 2) printf("Solve completed.\n"); return error; }
MKL_INT PardisoSolver::ComputeCholeskyDecomposition(const SparseMatrix * A) { if (directIterative) return 0; // compute the factorization if (verbose >= 1) printf("Factoring the %d x %d matrix (%d threads)...\n",n,n, numThreads); int upperTriangleOnly = 1; int oneIndexed = 1; A->GenerateCompressedRowMajorFormat(a, NULL, NULL, upperTriangleOnly, oneIndexed); // factor phase = 22; PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error); if (error != 0) printf("Error: Pardiso Cholesky decomposition returned non-zero exit code %d.\n", error); if (verbose >= 1) printf("Factorization completed.\n"); return error; }
MKL_INT PardisoSolver::DiagonalSubstitution(double * v, const double * y) { if (directIterative != 0) { printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n"); return 101; } if (positiveDefinite == 1) { printf("Error: diagonal substitution should not be used for positive-definite matrices.\n"); return 102; } if (verbose >= 2) printf("Performing forward substitution...(%d threads, using previously computed LU)\n", numThreads); int maxIterRefinementSteps = iparm[7]; iparm[7] = 0; phase = 332; PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)y, v, &error); iparm[7] = maxIterRefinementSteps; if (error != 0) printf("Error: Pardiso solve returned non-zero exit code %d.\n", error); if (verbose >= 2) printf("Solve completed.\n"); return error; }
PardisoSolver::~PardisoSolver() { phase = -1; PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error); if (error != 0) printf("Error: Pardiso Cholesky dealloacation returned non-zero exit code %d.\n", error); free(a); free(ia); free(ja); }
int PardisoSolver::SolveLinearSystem(double * x, const double * rhs) { if (directIterative != 0) { printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n"); return 101; } if (verbose >= 2) printf("Solving linear system...(%d threads, using previously computed LU)\n", numThreads); phase = 33; PARDISO(pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, (double*)rhs, x, &error); if (error != 0) printf("Error: Pardiso solve returned non-zero exit code %d.\n", error); if (verbose >= 2) printf("Solve completed.\n"); return (int)error; }
MKL_INT PardisoSolver::SolveLinearSystemMultipleRHS(double * x, const double * rhs, int numRHS) { if (directIterative != 0) { printf("Error: direct-iterative flag was specified in the constructor (must use SolveLinearSystemDirectIterative routine).\n"); return 101; } if (verbose >= 2) printf("Solving linear system...(%d threads)\n", numThreads); mkl_set_num_threads(numThreads); phase = 33; PARDISO(pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &numRHS, iparm, &msglvl, (double*)rhs, x, &error); if (error != 0) printf("Error: Pardiso solve returned non-zero exit code %d.\n", error); if (verbose >= 2) printf("Solve completed.\n"); return error; }
int LinearSparseSolver( static_sparse_CSR_Matrix<double, std::int32_t, M_PROP::SYM>& A, Matrix<double, M_PROP::GE, M_SHAPE::RE, M_ORD::COL>& B, Matrix<double, M_PROP::GE, M_SHAPE::RE, M_ORD::COL>& X, std::ostream& log, int threads) { typedef MML3_INT_TYPE int_t; int len=100; char buf[100]; //MKLGetVersionString(buf, len); mkl_get_version_string(buf, len); log << "Solutore lineare per matrici sparse basato su:\n" << "\tMKL-PARDISO: " << std::string(buf,len); log << "\nCaratteristiche del sistema:" << "\n\t N =" << A.nrows() << "\n\t NNZ =" << A.nonzeros() << "\n\t NRHS=" << B.ncols() << std::endl; // pardiso parameters MML3::Vector<int_t> pardiso_pt(64); pardiso_pt=0; int_t pardiso_maxfct = 1; // una sola matrice da fattorizzare int_t pardiso_mnum = 1; // la matrice numero 1 int_t pardiso_mtype = 2; // matrici simmetriche definite positive int_t pardiso_phase = 0; int_t pardiso_n = A.nrows(); double* pardiso_a=A.column_value(); int_t* pardiso_ia = A.row_pos(); int_t* pardiso_ja = A.column_index(); MML3::Vector<int_t> pardiso_perm(pardiso_n); int_t pardiso_nrhs = 0; MML3::Vector<int_t> pardiso_iparam(64); pardiso_iparam = 0; int_t pardiso_msglvl = 0; // 1=messaggi a run time, 0=no messaggi double* pardiso_b=0; double* pardiso_x=0; int_t pardiso_error=0; pardiso_iparam(1) = 1; /* No solver default*/ pardiso_iparam(2) = 2; /* Fill-in reordering from METIS, 1 for AMD */ pardiso_iparam(3) = threads; /* Numbers of thread processors */ pardiso_iparam(4) = 0; /* No iterative-direct algorithm */ pardiso_iparam(5) = 0; /* No user fill-in reducing permutation */ pardiso_iparam(6) = 0; /* Write solution into x */ pardiso_iparam(7) = 16; /* Default logical fortran unit number for output */ pardiso_iparam(8) = 0; /* Max numbers of iterative refinement steps */ pardiso_iparam(9) = 0; /* Not in use*/ pardiso_iparam(10) = 13; /* Perturb the pivot elements with 1E-13 */ pardiso_iparam(11) = 0; /* Use nonsymmetric permutation and scaling MPS */ pardiso_iparam(12) = 0; /* Not in use*/ pardiso_iparam(13) = 0; /* Not in use*/ pardiso_iparam(14) = 0; /* Output: Number of perturbed pivots */ pardiso_iparam(15) = 0; /* Not in use*/ pardiso_iparam(16) = 0; /* Not in use*/ pardiso_iparam(17) = 0; /* Not in use*/ pardiso_iparam(18) = -1; /* Output: Number of nonzeros in the factor LU */ pardiso_iparam(19) = -1; /* Output: Mflops for LU factorization */ pardiso_iparam(20) = 0; /* Output: Numbers of CG Iterations */ // -------------------------------------------------------------------- // Reordering and Symbolic Factorization. This step also allocates // all memory that is necessary for the factorization. // -------------------------------------------------------------------- pardiso_phase = 11; PARDISO( pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, &pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error); if (pardiso_error != 0) { log << "riordino e fattorizzazione simbolica falliti, codice: " << pardiso_error << "\n"; return -1; } log << "\tRiordino e fattorizzazione simbolica completata" << "\n\t\tFactor NNZ=" << pardiso_iparam(18) << "\n\t\tMFLOPS =" << pardiso_iparam(19); // -------------------------------------------------------------------- // Numerical factorization. // -------------------------------------------------------------------- pardiso_phase = 22; PARDISO( pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, &pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error); if (pardiso_error != 0) { log << " fattorizzazione numerica fallita, codice pardiso=" << pardiso_error << "\n"; return -1; } // --------------------------------------------------------------------*/ // Back substitution and iterative refinement. */ // --------------------------------------------------------------------*/ pardiso_phase = 33; pardiso_nrhs=B.nrows(); pardiso_iparam(6) = 0; // Write solution into x. Attenzione, anche se lo pongo ad 1 in modo che la soluzione sovrascriva F, X viene comunque usato PARDISO( pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, &pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, pardiso_iparam.begin(), &pardiso_msglvl, B.begin(), X.begin(), &pardiso_error); if (pardiso_error != 0) { log << "Errore nella fase di sostituzione all'indietro e rifinitura iteritava, codice: " << pardiso_error << "\n"; return -1; } // -------------------------------------------------------------------- // Termination and release of memory. // -------------------------------------------------------------------- pardiso_phase = -1; /* Release internal memory. */ PARDISO( pardiso_pt.begin(), &pardiso_maxfct, &pardiso_mnum, &pardiso_mtype, &pardiso_phase, &pardiso_n, pardiso_a, pardiso_ia, pardiso_ja, pardiso_perm.begin(), &pardiso_nrhs, pardiso_iparam.begin(), &pardiso_msglvl, 0, 0, &pardiso_error); return 1; }
int main (int argc, char **argv) { /* Matrix data. */ CRS_MATRIX *M1, *M2; double *b1, *x1, *b2, *x2, *r; int n; int nvals; FILE *fp; if (argc == 1) { fp = stdin; } else if (argc == 2) { fp = fopen (*argv, "r"); } else { fprintf (stderr, "Usage: pardisoTestExample [<fileName>]\n"); exit (1); } M1 = readCRSMatrix (fp, /*symmetric=*/1); n = M1->nrows; b1 = readVector (fp, n); x1 = (double*)malloc(n*sizeof(double)); r = (double*)malloc(n*sizeof(double)); // ja -> M1->colIdxs; // a -> M1->vals; // ia -> M1->rowOffs int mtype = -2; /* Real symmetric matrix */ int nrhs = 1; /* Number of right hand sides. */ /* Internal solver memory pointer pt, */ /* 32-bit: int pt[64]; 64-bit: long int pt[64] */ /* or void *pt[64] should be OK on both architectures */ void *pt[64]; /* Pardiso control parameters. */ int iparm[64]; int maxfct, mnum, phase, error, msglvl; /* Number of processors. */ int num_procs; /* Auxiliary variables. */ char *var; int i; double ddum; /* Double dummy */ int idum; /* Integer dummy. */ double t0, t1; /* -------------------------------------------------------------------- */ /* .. Setup Pardiso control parameters. */ /* -------------------------------------------------------------------- */ error = 0; //solver = 0; /* use sparse direct solver */ // do we need this, or will init take care of it? for (i=0; i<64; i++) { pt[i] = (void*)0; } for (i=0; i<64; i++) { iparm[i] = 0; } iparm[0] = 1; /* Don't use solver default values */ iparm[1] = 3; /* Fill-in reordering from OpenMP METIS */ /* Numbers of processors; if 0, defaults to max number or MKL_NUM_THREADS */ iparm[2] = 0; iparm[3] = 0; /* No iterative-direct algorithm */ iparm[4] = 0; /* No user fill-in reducing permutation */ iparm[5] = 0; /* Write solution into x */ iparm[6] = 0; /* Not in use */ iparm[7] = 0; /* Max numbers of iterative refinement steps */ iparm[8] = 0; /* Not in use */ iparm[9] = 13; /* Perturb the pivot elements with 1E-13 */ iparm[10] = 1; /* Use nonsymmetric permutation and scaling MPS */ iparm[11] = 0; /* Not in use */ iparm[12] = 0; /* Maximum weighted matching algorithm is switched-off (default for symmetric). Try iparm[12] = 1 in case of inappropriate accuracy */ iparm[13] = 0; /* Output: Number of perturbed pivots */ iparm[14] = 0; /* Not in use */ iparm[15] = 0; /* Not in use */ iparm[16] = 0; /* Not in use */ iparm[17] = -1; /* Output: Number of nonzeros in the factor LU */ iparm[18] = -1; /* Output: Mflops for LU factorization */ iparm[19] = 0; /* Output: Numbers of CG Iterations */ iparm[20] = 1; /* use 1x1 and 2x2 pivoting //F77_FUNC(pardisoinit) (pt, &mtype, &solver, iparm, &error); if (error != 0) { if (error == -10 ) printf("No license file found \n"); if (error == -11 ) printf("License is expired \n"); if (error == -12 ) printf("Wrong username or hostname \n"); return 1; } else { printf("PARDISO license check was successful ... \n"); } /* Numbers of processors, value of OMP_NUM_THREADS */ var = getenv("OMP_NUM_THREADS"); if(var != NULL) sscanf( var, "%d", &num_procs ); else { printf("Set environment OMP_NUM_THREADS to 1"); exit(1); } iparm[2] = num_procs; // other special settings iparm[1] = 3; // 2 for metis, 0 for AMD iparm[9] = 12; iparm[10] = 1; iparm[12] = 1; // setting this to 2 can cause errors sometimes maxfct = 1; /* Maximum number of numerical factorizations. */ mnum = 1; /* Which factorization to use. */ msglvl = 0; /* Print statistical information */ error = 0; /* Initialize error flag */ /* -------------------------------------------------------------------- */ /* .. Reordering and Symbolic Factorization. This step also allocates */ /* all memory that is necessary for the factorization. */ /* -------------------------------------------------------------------- */ phase = 11; t0 = currentTimeUsec(); PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs, iparm, &msglvl, &ddum, &ddum, &error); t1 = currentTimeUsec(); if (error != 0) { printf("ERROR during symbolic factorization: %d\n", error); exit(1); } printf("Analyze: msec=%8.1f\n", (t1-t0)/1000.0); printf("Number of nonzeros in factors = %d\n", iparm[17]); printf("Number of factorization MFLOPS = %d\n", iparm[18]); /* -------------------------------------------------------------------- */ /* .. Numerical factorization. */ /* -------------------------------------------------------------------- */ phase = 22; t0 = currentTimeUsec(); PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs, iparm, &msglvl, &ddum, &ddum, &error); t1 = currentTimeUsec(); if (error != 0) { printf("ERROR during numerical factorization: %d\n", error); exit(2); } printf("Factor: msec=%8.1f\n", (t1-t0)/1000.0); /* -------------------------------------------------------------------- */ /* .. Back substitution and iterative refinement. */ /* -------------------------------------------------------------------- */ phase = 33; iparm[7] = 1; /* Max numbers of iterative refinement steps. */ t0 = currentTimeUsec(); PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, M1->vals, M1->rowOffs, M1->colIdxs, &idum, &nrhs, iparm, &msglvl, b1, x1, &error); t1 = currentTimeUsec(); if (error != 0) { printf("ERROR during solution: %d\n", error); exit(3); } mulVector (r, M1, x1); subVector (r, r, b1, n); printf("Solve: msec=%8.1f\n\n", (t1-t0)/1000.0); /* for (i=0; i<n; i++) { */ /* printf ("%g ", x1[i]); */ /* } */ /* printf ("\n"); */ printf("residual=%g\n", normVector(r, n)); #if 0 M2 = readCRSMatrix (fp, /*symmetric=*/1); n = M2->nrows; b2 = readVector (fp, n); x2 = (double*)malloc(n*sizeof(double)); setVector (x2, x1, n); iparm[7] = 1; /* Max numbers of iterative refinement steps. */ iparm[3] = 102; printf ("maxfct=%d\n", maxfct); printf ("mnum=%d\n", mnum); printf ("mtype=%d\n", mtype); printf ("phase=%d\n", phase); printf ("idum=%d\n", idum); for (i=0; i<64; i++) { printf ("%d ", iparm[i]); } printf ("\n"); t0 = currentTimeUsec(); PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, M2->vals, M2->rowOffs, M2->colIdxs, &idum, &nrhs, iparm, &msglvl, b2, x2, &error); t1 = currentTimeUsec(); if (error != 0) { printf("ERROR during solution: %d\n", error); exit(3); } printf ("num iterations=%d\n", iparm[19]); for (i=0; i<n; i++) { printf ("%g ", x2[i]); } printf ("\n"); printf("Solve: msec=%8.1f\n\n", (t1-t0)/1000.0); mulVector (r, M2, x2); subVector (r, r, b2, n); printf("residual=%g\n", normVector(r, n)); #endif /* -------------------------------------------------------------------- */ /* .. Termination and release of memory. */ /* -------------------------------------------------------------------- */ phase = -1; /* Release internal memory. */ PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, &ddum, M1->rowOffs, M1->colIdxs, &idum, &nrhs, iparm, &msglvl, &ddum, &ddum, &error); return 0; }
PardisoSolver::PardisoSolver(const SparseMatrix * A, int numThreads_, matrixType mtype_, reorderingType rtype_, int directIterative_, int verbose_): numThreads(numThreads_), mtype(mtype_), rtype(rtype_), directIterative(directIterative_), verbose(verbose_) { mkl_set_num_threads(numThreads); n = A->Getn(); if (verbose >= 1) printf("Converting matrix to Pardiso format...\n"); int numEntries; int upperTriangleOnly; if ((mtype == REAL_SPD) || (mtype == REAL_SYM_INDEFINITE)) // matrix is symmetric { numEntries = A->GetNumUpperTriangleEntries(); upperTriangleOnly = 1; } else { // structural symmetric or unsymmetric numEntries = A->GetNumEntries(); upperTriangleOnly = 0; } a = (double*) malloc (sizeof(double) * numEntries); ia = (int*) malloc (sizeof(int) * (A->GetNumRows() + 1)); ja = (int*) malloc (sizeof(int) * numEntries); int oneIndexed = 1; A->GenerateCompressedRowMajorFormat(a, ia, ja, upperTriangleOnly, oneIndexed); if (verbose >= 2) printf("numEntries: %d\n", numEntries); // permute & do symbolic factorization nrhs = 1; // Number of right hand sides. maxfct = 1; // Maximum number of numerical factorizations. mnum = 1; // Which factorization to use. msglvl = verbose >= 1 ? verbose - 1 : 0; // Print statistical information to the output file error = 0; // Initialize error flag for (int i = 0; i < 64; i++) iparm[i] = 0; iparm[0] = 1; // Do not use the solver default values (use custom values, provided below) iparm[1] = rtype; // matrix re-ordering algorithm iparm[2] = 0; // unused // use iterative-direct algorithm if requested if (directIterative) { if (mtype == REAL_SPD) iparm[3] = 62; // matrix is symmetric positive-definite; use CGS iteration for symmetric positive-definite matrices else iparm[3] = 61; // use CGS iteration } else iparm[3] = 0; iparm[4] = 0; // No user fill-in reducing permutation iparm[5] = 0; // Write solution into x iparm[6] = 0; // Output: number of iterative refinement steps performed iparm[7] = 0; // Max numbers of iterative refinement steps (used during the solving stage). Value of 0 (default) means: The solver automatically performs two steps of iterative refinement when perturbed pivots are obtained during the numerical factorization. iparm[8] = 0; // Reserved. Must set to 0. // Pivoting perturbation; the values below are Pardiso's default values // Pivoting only applies to REAL_UNSYM and REAL_SYM_INDEFINITE if (mtype == REAL_UNSYM) iparm[9] = 13; // For non-symmetric matrices, perturb the pivot elements with 1E-13 else iparm[9] = 8; // Use 1.0E-8 for symmetric indefinite matrices // Scaling and matching. The following below are the Pardiso defaults. if (mtype == REAL_UNSYM) // unsymmetric matrices { iparm[10] = 1; // enable scaling iparm[12] = 1; // enable matching } else { iparm[10] = 0; // disable scaling iparm[12] = 0; // disable matching } iparm[11] = 0; // Solve with transposed or conjugate transposed matrix A. Not in use here. iparm[13] = 0; // Output: Number of perturbed pivots iparm[14] = 0; // Output: Peak memory on symbolic factorization (in KB) iparm[15] = 0; // Output: Permanent memory on symbolic factorization (in KB) iparm[16] = 0; // Output: Size of factors/Peak memory on numerical factorization and solution (in KB) iparm[17] = -1; // Output: Report the number of non-zero elements in the factors. iparm[18] = 0; // Report number of floating point operations (in 10^6 floating point operations) that are necessary to factor the matrix A. Disabled. iparm[19] = 0; // Output: Report CG/CGS diagnostics. iparm[20] = 1; // Pivoting for symmetric indefinite matrices: Apply 1x1 and 2x2 Bunch-Kaufman pivoting during the factorization process. iparm[21] = 0; // Output: Inertia: number of positive eigenvalues. iparm[22] = 0; // Output: Inertia: number of negative eigenvalues. iparm[23] = 0; // Parallel factorization control. Use default. iparm[24] = 0; // Parallel forward/backward solve control. Intel MKL PARDISO uses a parallel algorithm for the solve step. // the other iparms (above 24) are left at 0 /* -------------------------------------------------------------------- *\ .. Initialize the internal solver memory pointer. This is only necessary for the FIRST call of the PARDISO solver. \* -------------------------------------------------------------------- */ for (int i=0; i<64; i++) pt[i] = 0; if (verbose >= 1) printf("Reordering and symbolically factorizing the matrix...\n"); /* -------------------------------------------------------------------- *\ .. Reordering and Symbolic Factorization. This step also allocates all memory that is necessary for the factorization. \* -------------------------------------------------------------------- */ phase = 11; PARDISO (pt, &maxfct, &mnum, (MKL_INT*)&mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error); if (error != 0) { printf("Error: Pardiso matrix re-ordering/symbolic factorization returned non-zero exit code %d.\n", error); throw error; } if (verbose >= 2) { printf("\nReordering and symbolic factorization completed...\n"); printf("Number of nonzeros in factors = %d\n", iparm[17]); printf("Number of factorization MFLOPS = %d\n", iparm[18]); } }
PardisoSolver::PardisoSolver(const SparseMatrix * A, int numThreads_, int positiveDefinite_, int directIterative_, int verbose_) : numThreads(numThreads_), positiveDefinite(positiveDefinite_), directIterative(directIterative_), verbose(verbose_) { mkl_set_num_threads(numThreads); n = A->Getn(); if (verbose >= 1) printf("Converting matrix to Pardiso format...\n"); int numUpperTriangleEntries = A->GetNumUpperTriangleEntries(); a = (double*) malloc (sizeof(double) * numUpperTriangleEntries); ia = (int*) malloc (sizeof(int) * (A->GetNumRows() + 1)); ja = (int*) malloc (sizeof(int) * numUpperTriangleEntries); int upperTriangleOnly = 1; int oneIndexed = 1; A->GenerateCompressedRowMajorFormat(a, ia, ja, upperTriangleOnly, oneIndexed); if (verbose >= 2) printf("numUpperTriEntries: %d\n", numUpperTriangleEntries); // permute & do symbolic factorization mtype = positiveDefinite ? 2 : -2; nrhs = 1; /* Number of right hand sides. */ maxfct = 1; /* Maximum number of numerical factorizations. */ mnum = 1; /* Which factorization to use. */ msglvl = verbose >= 1 ? verbose-1 : 0; /* Print statistical information in file */ error = 0; /* Initialize error flag */ for (int i = 0; i < 64; i++) iparm[i] = 0; iparm[0] = 1; // No solver default iparm[1] = 2; // 0=minimum degree ordering, 2=Fill-in reordering from METIS iparm[2] = numThreads; // Numbers of processors, value of OMP_NUM_THREADS iparm[3] = directIterative ? 62 : 0; //62; // No iterative-direct algorithm iparm[4] = 0; // No user fill-in reducing permutation iparm[5] = 0; // Write solution into x iparm[6] = 0; // Not in use iparm[7] = 2; // Max numbers of iterative refinement steps iparm[8] = 0; // Not in use iparm[9] = 8; //13; // Perturb the pivot elements with 1E-13 iparm[10] = 0; //1; // Use nonsymmetric permutation and scaling MPS iparm[11] = 0; // Not in use iparm[12] = 0; // matchings for highly indefinite symmetric matrices iparm[13] = 0; // Output: Number of perturbed pivots iparm[14] = 0; // Not in use iparm[15] = 0; // Not in use iparm[16] = 0; // Not in use iparm[17] = -1; // Output: Number of nonzeros in the factor LU iparm[18] = 0; // no Output: Mflops for LU factorization iparm[19] = 0; // Output: Numbers of CG Iterations iparm[20] = 1; // pivoting method /* iparm[0] = 0; iparm[2] = numThreads; */ /* -------------------------------------------------------------------- */ /* .. Initialize the internal solver memory pointer. This is only */ /* necessary for the FIRST call of the PARDISO solver. */ /* -------------------------------------------------------------------- */ for (int i=0; i<64; i++) pt[i] = 0; if (verbose >= 1) printf("Reordering matrix...\n"); /* -------------------------------------------------------------------- */ /* .. Reordering and Symbolic Factorization. This step also allocates */ /* all memory that is necessary for the factorization. */ /* -------------------------------------------------------------------- */ phase = 11; PARDISO (pt, &maxfct, &mnum, &mtype, &phase, &n, a, ia, ja, NULL, &nrhs, iparm, &msglvl, NULL, NULL, &error); if (error != 0) { printf("Error: Pardiso matrix re-ordering returned non-zero exit code %d.\n", error); throw error; } if (verbose >= 2) { printf("\nReordering completed ...\n"); printf("Number of nonzeros in factors = %d\n", iparm[17]); printf("Number of factorization MFLOPS = %d\n", iparm[18]); } }