bool IterativePardisoSolverInterface::InitializeImpl(const OptionsList& options, const std::string& prefix) { Index enum_int; options.GetEnumValue("pardiso_matching_strategy", enum_int, prefix); match_strat_ = PardisoMatchingStrategy(enum_int); options.GetBoolValue("pardiso_redo_symbolic_fact_only_if_inertia_wrong", pardiso_redo_symbolic_fact_only_if_inertia_wrong_, prefix); options.GetBoolValue("pardiso_repeated_perturbation_means_singular", pardiso_repeated_perturbation_means_singular_, prefix); Index pardiso_out_of_core_power; options.GetIntegerValue("pardiso_out_of_core_power", pardiso_out_of_core_power, prefix); options.GetBoolValue("pardiso_skip_inertia_check", skip_inertia_check_, prefix); // PD system options.GetIntegerValue("pardiso_max_iter", pardiso_max_iter_, prefix); options.GetNumericValue("pardiso_iter_relative_tol", pardiso_iter_relative_tol_, prefix); options.GetIntegerValue("pardiso_iter_coarse_size", pardiso_iter_coarse_size_, prefix); options.GetIntegerValue("pardiso_iter_max_levels", pardiso_iter_max_levels_, prefix); options.GetNumericValue("pardiso_iter_dropping_factor", pardiso_iter_dropping_factor_, prefix); options.GetNumericValue("pardiso_iter_dropping_schur", pardiso_iter_dropping_schur_, prefix); options.GetIntegerValue("pardiso_iter_max_row_fill", pardiso_iter_max_row_fill_, prefix); options.GetNumericValue("pardiso_iter_inverse_norm_factor", pardiso_iter_inverse_norm_factor_, prefix); // Normal system options.GetIntegerValue("pardiso_max_iter", normal_pardiso_max_iter_, prefix+"normal."); options.GetNumericValue("pardiso_iter_relative_tol", normal_pardiso_iter_relative_tol_, prefix+"normal."); options.GetIntegerValue("pardiso_iter_coarse_size", normal_pardiso_iter_coarse_size_, prefix+"normal."); options.GetIntegerValue("pardiso_iter_max_levels", normal_pardiso_iter_max_levels_, prefix+"normal."); options.GetNumericValue("pardiso_iter_dropping_factor", normal_pardiso_iter_dropping_factor_, prefix+"normal."); options.GetNumericValue("pardiso_iter_dropping_schur", normal_pardiso_iter_dropping_schur_, prefix+"normal."); options.GetIntegerValue("pardiso_iter_max_row_fill", normal_pardiso_iter_max_row_fill_, prefix+"normal."); options.GetNumericValue("pardiso_iter_inverse_norm_factor", normal_pardiso_iter_inverse_norm_factor_, prefix+"normal."); int pardiso_msglvl; options.GetIntegerValue("pardiso_msglvl", pardiso_msglvl, prefix); options.GetIntegerValue("pardiso_max_droptol_corrections", pardiso_max_droptol_corrections_, prefix); // Number value = 0.0; // Tell Pardiso to release all memory if it had been used before if (initialized_) { ipfint PHASE = -1; ipfint N = dim_; ipfint NRHS = 0; ipfint ERROR; ipfint idmy; double ddmy; F77_FUNC(pardiso,PARDISO)(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N, &ddmy, &idmy, &idmy, &idmy, &NRHS, IPARM_, &MSGLVL_, &ddmy, &ddmy, &ERROR, DPARM_) ; DBG_ASSERT(ERROR==0); } // Reset all private data dim_=0; nonzeros_=0; have_symbolic_factorization_=false; initialized_=false; delete[] a_; a_ = NULL; #ifdef HAVE_PARDISO_OLDINTERFACE THROW_EXCEPTION(OPTION_INVALID, "The inexact version works only with a new version of Pardiso (at least 4.0)"); #endif // Call Pardiso's initialization routine IPARM_[0] = 0; // Tell it to fill IPARM with default values(?) ipfint ERROR = 0; ipfint SOLVER = 1; // initialze only direct solver F77_FUNC(pardisoinit,PARDISOINIT)(PT_, &MTYPE_, &SOLVER, IPARM_, DPARM_, &ERROR); // Set some parameters for Pardiso IPARM_[0] = 1; // Don't use the default values #if defined(HAVE_PARDISO_PARALLEL) || ! defined(HAVE_PARDISO) // Obtain the numbers of processors from the value of OMP_NUM_THREADS char *var = getenv("OMP_NUM_THREADS"); int num_procs = 1; if (var != NULL) { sscanf( var, "%d", &num_procs ); if (num_procs < 1) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Invalid value for OMP_NUM_THREADS (\"%s\").\n", var); return false; } Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Using environment OMP_NUM_THREADS = %d as the number of processors.\n", num_procs); } #ifdef HAVE_PARDISO // If we run Pardiso through the linear solver loader, // we do not know whether it is the parallel version, so we do not report an error if OMP_NUM_THREADS is not set. else { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "You need to set environment variable OMP_NUM_THREADS to the number of processors used in Pardiso (e.g., 1).\n\n"); return false; } #endif IPARM_[2] = num_procs; // Set the number of processors #else IPARM_[2] = 1; #endif IPARM_[1] = 5; IPARM_[5] = 1; // Overwrite right-hand side // ToDo: decide if we need iterative refinement in Pardiso. For // now, switch it off ? IPARM_[7] = 0; // Options suggested by Olaf Schenk IPARM_[9] = 12; IPARM_[10] = 2; // Results in better scaling // Matching information: IPARM_[12] = 1 seems ok, but results in a // large number of pivot perturbation // Matching information: IPARM_[12] = 2 robust, but more expensive method IPARM_[12] = (int)match_strat_; Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pardiso matching strategy (IPARM(13)): %d\n", IPARM_[12]); IPARM_[20] = 3; // Results in better accuracy IPARM_[23] = 1; // parallel fac IPARM_[24] = 1; // parallel solve IPARM_[28] = 0; // 32-bit factorization IPARM_[29] = 1; // we need this for IPOPT interface IPARM_[31] = 1 ; // iterative solver MSGLVL_ = pardiso_msglvl; pardiso_iter_dropping_factor_used_ = pardiso_iter_dropping_factor_; pardiso_iter_dropping_schur_used_ = pardiso_iter_dropping_schur_; normal_pardiso_iter_dropping_factor_used_ = normal_pardiso_iter_dropping_factor_; normal_pardiso_iter_dropping_schur_used_ = normal_pardiso_iter_dropping_schur_; // TODO Make option decr_factor_ = 1./3.; // Option for the out of core variant // IPARM_[49] = pardiso_out_of_core_power; SetIpoptCallbackFunction(&IpoptTerminationTest); bool retval = normal_tester_->Initialize(Jnlst(), IpNLP(), IpData(), IpCq(), options, prefix); if (retval) { retval = pd_tester_->Initialize(Jnlst(), IpNLP(), IpData(), IpCq(), options, prefix); } return retval; }
bool PardisoSolverInterface::InitializeImpl(const OptionsList& options, const std::string& prefix) { Index enum_int; options.GetEnumValue("pardiso_matching_strategy", enum_int, prefix); match_strat_ = PardisoMatchingStrategy(enum_int); options.GetBoolValue("pardiso_redo_symbolic_fact_only_if_inertia_wrong", pardiso_redo_symbolic_fact_only_if_inertia_wrong_, prefix); options.GetBoolValue("pardiso_repeated_perturbation_means_singular", pardiso_repeated_perturbation_means_singular_, prefix); //Index pardiso_out_of_core_power; //options.GetIntegerValue("pardiso_out_of_core_power", // pardiso_out_of_core_power, prefix); options.GetBoolValue("pardiso_skip_inertia_check", skip_inertia_check_, prefix); int pardiso_msglvl; options.GetIntegerValue("pardiso_msglvl", pardiso_msglvl, prefix); int max_iterref_steps; options.GetIntegerValue("pardiso_max_iterative_refinement_steps", max_iterref_steps, prefix); int order; options.GetEnumValue("pardiso_order", order, prefix); #if !defined(HAVE_PARDISO_OLDINTERFACE) && !defined(HAVE_PARDISO_MKL) options.GetBoolValue("pardiso_iterative", pardiso_iterative_, prefix); int pardiso_max_iter; options.GetIntegerValue("pardiso_max_iter", pardiso_max_iter, prefix); Number pardiso_iter_relative_tol; options.GetNumericValue("pardiso_iter_relative_tol", pardiso_iter_relative_tol, prefix); Index pardiso_iter_coarse_size; options.GetIntegerValue("pardiso_iter_coarse_size", pardiso_iter_coarse_size, prefix); Index pardiso_iter_max_levels; options.GetIntegerValue("pardiso_iter_max_levels", pardiso_iter_max_levels, prefix); Number pardiso_iter_dropping_factor; options.GetNumericValue("pardiso_iter_dropping_factor", pardiso_iter_dropping_factor, prefix); Number pardiso_iter_dropping_schur; options.GetNumericValue("pardiso_iter_dropping_schur", pardiso_iter_dropping_schur, prefix); Index pardiso_iter_max_row_fill; options.GetIntegerValue("pardiso_iter_max_row_fill", pardiso_iter_max_row_fill, prefix); Number pardiso_iter_inverse_norm_factor; options.GetNumericValue("pardiso_iter_inverse_norm_factor", pardiso_iter_inverse_norm_factor, prefix); options.GetIntegerValue("pardiso_max_droptol_corrections", pardiso_max_droptol_corrections_, prefix); #else pardiso_iterative_ = false; #endif // Number value = 0.0; // Tell Pardiso to release all memory if it had been used before if (initialized_) { ipfint PHASE = -1; ipfint N = dim_; ipfint NRHS = 0; ipfint ERROR; ipfint idmy; double ddmy; PARDISO_FUNC(PT_, &MAXFCT_, &MNUM_, &MTYPE_, &PHASE, &N, &ddmy, &idmy, &idmy, &idmy, &NRHS, IPARM_, &MSGLVL_, &ddmy, &ddmy, &ERROR, DPARM_); DBG_ASSERT(ERROR==0); } // Reset all private data dim_=0; nonzeros_=0; have_symbolic_factorization_=false; initialized_=false; delete[] a_; a_ = NULL; #ifdef PARDISO_MATCHING_PREPROCESS delete[] ia2; ia2 = NULL; delete[] ja2; ja2 = NULL; delete[] a2_; a2_ = NULL; delete[] perm2; perm2 = NULL; delete[] scale2; scale2 = NULL; #endif // Call Pardiso's initialization routine IPARM_[0] = 0; // Tell it to fill IPARM with default values(?) #if ! defined(HAVE_PARDISO_OLDINTERFACE) && ! defined(HAVE_PARDISO_MKL) ipfint ERROR = 0; ipfint SOLVER = 0; // initialize only direct solver PARDISOINIT_FUNC(PT_, &MTYPE_, &SOLVER, IPARM_, DPARM_, &ERROR); #else PARDISOINIT_FUNC(PT_, &MTYPE_, IPARM_); #endif // Set some parameters for Pardiso IPARM_[0] = 1; // Don't use the default values int num_procs = 1; #if defined(HAVE_PARDISO_PARALLEL) || ! defined(HAVE_PARDISO) // Obtain the numbers of processors from the value of OMP_NUM_THREADS char* var = getenv("OMP_NUM_THREADS"); if (var != NULL) { sscanf( var, "%d", &num_procs ); if (num_procs < 1) { Jnlst().Printf(J_ERROR, J_LINEAR_ALGEBRA, "Invalid value for OMP_NUM_THREADS (\"%s\").\n", var); return false; } Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Using environment OMP_NUM_THREADS = %d as the number of processors for PARDISO.\n", num_procs); } #if defined(HAVE_PARDISO) && ! defined(HAVE_PARDISO_MKL) // If we run Pardiso through the linear solver loader, // we do not know whether it is the parallel version, so we do not report a warning if OMP_NUM_THREADS is not set. // If we run Pardiso from MKL, then OMP_NUM_THREADS does not need to be set, so no warning. else { Jnlst().Printf(J_WARNING, J_LINEAR_ALGEBRA, "You should set the environment variable OMP_NUM_THREADS to the number of processors used in Pardiso (e.g., 1).\n\n"); } #endif #endif #ifdef HAVE_PARDISO_MKL IPARM_[1] = order; // For MKL PARDSIO, the documentation says, "iparm(3) Reserved. Set to zero.", so we don't set IPARM_[2] IPARM_[5] = 1; // Overwrite right-hand side IPARM_[7] = max_iterref_steps; IPARM_[9] = 12; // pivot perturbation (as higher as less perturbation) IPARM_[10] = 2; // enable scaling (recommended for interior-point indefinite matrices) IPARM_[12] = (int)match_strat_; // enable matching (recommended, as above) IPARM_[20] = 3; // bunch-kaufman pivoting IPARM_[23] = 1; // parallel fac IPARM_[24] = 1; // parallel solve //IPARM_[26] = 1; // matrix checker #else IPARM_[1] = order; IPARM_[2] = num_procs; // Set the number of processors IPARM_[5] = 1; // Overwrite right-hand side IPARM_[7] = max_iterref_steps; // Options suggested by Olaf Schenk IPARM_[9] = 12; IPARM_[10] = 2; // Results in better scaling // Matching information: IPARM_[12] = 1 seems ok, but results in a // large number of pivot perturbation // Matching information: IPARM_[12] = 2 robust, but more expensive method IPARM_[12] = (int)match_strat_; IPARM_[20] = 3; // Results in better accuracy IPARM_[23] = 1; // parallel fac IPARM_[24] = 1; // parallel solve IPARM_[28] = 0; // 32-bit factorization IPARM_[29] = 1; //we need this for IPOPT interface //IPARM_[33] = 1; // bit-by-bit identical results in parallel run #endif Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pardiso matrix ordering (IPARM(2)): %d\n", IPARM_[1]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pardiso max. iterref. steps (IPARM(8)): %d\n", IPARM_[7]); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pardiso matching strategy (IPARM(13)): %d\n", IPARM_[12]); if (pardiso_iterative_) { #if defined(HAVE_PARDISO_OLDINTERFACE) || defined(HAVE_PARDISO_MKL) THROW_EXCEPTION(OPTION_INVALID, "You chose to use the iterative version of Pardiso, but you need to use a Pardiso version of at least 4.0."); #else IPARM_[31] = 1 ; // active direct solver DPARM_[ 0] = pardiso_max_iter; // maximum number of Krylov-Subspace Iteration // Default is 300 // 1 <= value <= e.g. 1000 DPARM_[ 1] = pardiso_iter_relative_tol; // Relative Residual Convergence // e.g. pardiso_iter_tol // Default is 1e-6 // 1e-16 <= value < 1 DPARM_[ 2] = pardiso_iter_coarse_size; // Maximum Size of Coarse Grid Matrix // e.g. pardiso_coarse_grid // Default is 5000 // 1 <= value < number of equations DPARM_[ 3] = pardiso_iter_max_levels; // Maximum Number of Grid Levels // e.g. pardiso_max_grid // Default is 10000 // 1 <= value < number of equations DPARM_[ 4] = pardiso_iter_dropping_factor; // dropping value for incomplete factor // e.g. pardiso_dropping_factor // Default is 0.5 // 1e-16 <= value < 1 DPARM_[ 5] = pardiso_iter_dropping_schur; // dropping value for sparsify schur complementfactor // e.g. pardiso_dropping_schur // Default is 0.1 // 1e-16 <= value < 1 DPARM_[ 6] = pardiso_iter_max_row_fill; // max fill for each row // e.g. pardiso_max_fill // Default is 1000 // 1 <= value < 100000 DPARM_[ 7] = pardiso_iter_inverse_norm_factor; // dropping value for sparsify schur complementfactor // e.g. pardiso_inverse_norm_factor // Default is 500 // 2 <= value < 50000 DPARM_[ 8] = 25; // maximum number of non-improvement steps #endif } MSGLVL_ = pardiso_msglvl; // Option for the out of core variant //IPARM_[49] = pardiso_out_of_core_power; return true; }