diff --git a/resolve/SystemSolver.cpp b/resolve/SystemSolver.cpp index 9cad0bb4b..381ee3cd0 100644 --- a/resolve/SystemSolver.cpp +++ b/resolve/SystemSolver.cpp @@ -179,6 +179,12 @@ namespace ReSolve auto* rgmres = dynamic_cast(iterativeSolver_); status += rgmres->setup(A_); status += gs_->setup(rgmres->getKrand(), rgmres->getRestart()); + } else if (solveMethod_ == "fgmres") { + auto* fgmres = dynamic_cast(iterativeSolver_); + status += fgmres->setup(A_); + status += gs_->setup(A_->getNumRows(), fgmres->getRestart()); + } else { + // do nothing } return status; @@ -427,7 +433,7 @@ namespace ReSolve int status = 0; // Use Krylov solver if selected - if (solveMethod_ == "randgmres") { + if (solveMethod_ == "randgmres" || solveMethod_ == "fgmres") { status += iterativeSolver_->resetMatrix(A_); status += iterativeSolver_->solve(rhs, x); return status; diff --git a/resolve/SystemSolver.hpp b/resolve/SystemSolver.hpp index a27ae438b..150ca236a 100644 --- a/resolve/SystemSolver.hpp +++ b/resolve/SystemSolver.hpp @@ -85,9 +85,9 @@ namespace ReSolve int setSolveMethod(std::string method); void setRefinementMethod(std::string method, std::string gs = "cgs2"); int setSketchingMethod(std::string method); + int setGramSchmidtMethod(std::string gs_method); private: - int setGramSchmidtMethod(std::string gs_method); LinSolverDirect* factorizationSolver_{nullptr}; LinSolverDirect* refactorizationSolver_{nullptr}; diff --git a/resolve/utilities/params/CliOptions.hpp b/resolve/utilities/params/CliOptions.hpp index 687aa387b..77f34a7cd 100644 --- a/resolve/utilities/params/CliOptions.hpp +++ b/resolve/utilities/params/CliOptions.hpp @@ -12,7 +12,7 @@ namespace ReSolve */ class CliOptions { - public: + public: using Option = std::pair; CliOptions(int argc, char *argv[]); virtual ~CliOptions(); @@ -20,7 +20,7 @@ namespace ReSolve bool hasKey(const std::string&) const; Option* getParamFromKey(const std::string&) const; void printOptions() const; - private: + private: using Options = std::map; void parse(); const char* const *begin() const; diff --git a/tests/functionality/CMakeLists.txt b/tests/functionality/CMakeLists.txt index fd1ffff25..9f0bd15f0 100644 --- a/tests/functionality/CMakeLists.txt +++ b/tests/functionality/CMakeLists.txt @@ -10,6 +10,7 @@ add_executable(version.exe testVersion.cpp) target_link_libraries(version.exe PRIVATE ReSolve) +# Build test for Krylov solvers add_executable(sys_rand_gmres_test.exe testSysRandGMRES.cpp) target_link_libraries(sys_rand_gmres_test.exe PRIVATE ReSolve) @@ -19,12 +20,6 @@ if(RESOLVE_USE_KLU) target_link_libraries(klu_klu_test.exe PRIVATE ReSolve) endif(RESOLVE_USE_KLU) -# if(NOT RESOLVE_USE_GPU) -# # Build Random GMRES test -# add_executable(rand_gmres_cpu_test.exe testSysRandGMRES.cpp) -# target_link_libraries(rand_gmres_cpu_test.exe PRIVATE ReSolve) -# endif() - if(RESOLVE_USE_CUDA) @@ -52,8 +47,8 @@ if(RESOLVE_USE_CUDA) add_executable(rand_gmres_cuda_test.exe testRandGMRES_Cuda.cpp) target_link_libraries(rand_gmres_cuda_test.exe PRIVATE ReSolve) - add_executable(sys_rand_gmres_cuda_test.exe testSysRandGMRES.cpp) - target_link_libraries(sys_rand_gmres_cuda_test.exe PRIVATE ReSolve) + # add_executable(sys_rand_gmres_cuda_test.exe testSysRandGMRES.cpp) + # target_link_libraries(sys_rand_gmres_cuda_test.exe PRIVATE ReSolve) endif(RESOLVE_USE_CUDA) @@ -76,9 +71,6 @@ if(RESOLVE_USE_HIP) add_executable(rand_gmres_hip_test.exe testRandGMRES_Rocm.cpp) target_link_libraries(rand_gmres_hip_test.exe PRIVATE ReSolve) - # add_executable(sys_rand_gmres_hip_test.exe testSysRandGMRES.cpp) - # target_link_libraries(sys_rand_gmres_hip_test.exe PRIVATE ReSolve) - endif(RESOLVE_USE_HIP) set(installable_tests version.exe) @@ -88,10 +80,6 @@ if(RESOLVE_USE_KLU) list(APPEND installable_tests klu_klu_test.exe) endif() -# if(NOT RESOLVE_USE_GPU) -# list(APPEND installable_tests rand_gmres_cpu_test.exe) -# endif() - if(RESOLVE_USE_CUDA) list(APPEND installable_tests klu_rf_test.exe klu_rf_fgmres_test.exe @@ -107,9 +95,7 @@ if(RESOLVE_USE_HIP) list(APPEND installable_tests rocsolver_rf_test.exe rocsolver_rf_fgmres_test.exe sys_refactor_hip_test.exe - rand_gmres_hip_test.exe - #sys_rand_gmres_hip_test.exe - ) + rand_gmres_hip_test.exe) endif(RESOLVE_USE_HIP) install(TARGETS ${installable_tests} @@ -126,12 +112,21 @@ if(RESOLVE_USE_KLU) add_test(NAME klu_klu_test COMMAND $ "${test_data_dir}") endif() -add_test(NAME sys_rand_count_gmres_test COMMAND $ "-s" "count") -add_test(NAME sys_rand_fwht_gmres_test COMMAND $ "-s" "fwht") - -# if(NOT RESOLVE_USE_GPU) -# add_test(NAME sys_rand_gmres_cpu_test COMMAND $) -# endif() +add_test(NAME sys_rand_count_gmres_cgs2_test COMMAND $ "-i" "randgmres" "-g" "cgs2" "-s" "count") +add_test(NAME sys_rand_count_gmres_mgs_test COMMAND $ "-i" "randgmres" "-g" "mgs" "-s" "count") +add_test(NAME sys_rand_count_gmres_mgs2sync_test COMMAND $ "-i" "randgmres" "-g" "mgs_two_synch" "-s" "count") +add_test(NAME sys_rand_count_gmres_mgspm_test COMMAND $ "-i" "randgmres" "-g" "mgs_pm" "-s" "count") +#add_test(NAME sys_rand_count_gmres_cgs_test COMMAND $ "-i" "randgmres" "-g" "cgs1" "-s" "count") +add_test(NAME sys_rand_fwht_gmres_cgs2_test COMMAND $ "-i" "randgmres" "-g" "cgs2" "-s" "fwht") +add_test(NAME sys_rand_fwht_gmres_mgs_test COMMAND $ "-i" "randgmres" "-g" "mgs" "-s" "fwht") +add_test(NAME sys_rand_fwht_gmres_mgs2sync_test COMMAND $ "-i" "randgmres" "-g" "mgs_two_synch" "-s" "fwht") +add_test(NAME sys_rand_fwht_gmres_mgspm_test COMMAND $ "-i" "randgmres" "-g" "mgs_pm" "-s" "fwht") +#add_test(NAME sys_rand_fwht_gmres_cgs_test COMMAND $ "-i" "randgmres" "-g" "cgs1" "-s" "fwht") +add_test(NAME sys_fgmres_cgs2_test COMMAND $ "-i" "fgmres" "-g" "cgs2") +add_test(NAME sys_fgmres_mgs_test COMMAND $ "-i" "fgmres" "-g" "mgs") +add_test(NAME sys_fgmres_mgs2sync_test COMMAND $ "-i" "fgmres" "-g" "mgs_two_synch") +add_test(NAME sys_fgmres_mgspm_test COMMAND $ "-i" "fgmres" "-g" "mgs_pm") +#add_test(NAME sys_fgmres_cgs_test COMMAND $ "-i" "fgmres" "-g" "cgs1") if(RESOLVE_USE_CUDA) add_test(NAME klu_rf_test COMMAND $ "${test_data_dir}") @@ -148,6 +143,4 @@ if(RESOLVE_USE_HIP) add_test(NAME rocsolver_rf_fgmres_test COMMAND $ "${test_data_dir}") add_test(NAME sys_refactor_hip_test COMMAND $ "${test_data_dir}") add_test(NAME rand_gmres_hip_test COMMAND $) - # add_test(NAME sys_rand_count_gmres_hip_test COMMAND $ "-s" "count") - # add_test(NAME sys_rand_fwht_gmres_hip_test COMMAND $ "-s" "fwht") endif(RESOLVE_USE_HIP) diff --git a/tests/functionality/testSysRandGMRES.cpp b/tests/functionality/testSysRandGMRES.cpp index c77637d12..e5245d192 100644 --- a/tests/functionality/testSysRandGMRES.cpp +++ b/tests/functionality/testSysRandGMRES.cpp @@ -58,16 +58,24 @@ int main(int argc, char *argv[]) int status = 0; ReSolve::CliOptions options(argc, argv); - ReSolve::CliOptions::Option* opt = options.getParamFromKey("-s"); + ReSolve::CliOptions::Option* opt = nullptr; + + opt = options.getParamFromKey("-N"); + const index_type N = opt ? atoi((*opt).second.c_str()) : 10000; + + opt = options.getParamFromKey("-i"); + std::string krylov = opt ? (*opt).second : "randgmres"; + + opt = options.getParamFromKey("-g"); + std::string gs = opt ? (*opt).second : "cgs2"; + + opt = options.getParamFromKey("-s"); const std::string sketching = opt ? (*opt).second : ""; if ((sketching != "count") && (sketching != "fwht")) { std::cout << "Sketching method " << sketching << " not recognized.\n"; std::cout << "Setting sketching to the default (count).\n\n"; } - opt = options.getParamFromKey("-N"); - const index_type N = opt ? atoi((*opt).second.c_str()) : 10000; - // Generate linear system data ReSolve::matrix::Csr* A = generateMatrix(N); @@ -82,62 +90,74 @@ int main(int argc, char *argv[]) ReSolve::VectorHandler vector_handler(&workspace); // Create system solver - ReSolve::SystemSolver* solver = new ReSolve::SystemSolver(&workspace, "none", "none", "randgmres", "ilu0", "none"); + ReSolve::SystemSolver solver(&workspace, "none", "none", krylov, "ilu0", "none"); + solver.setGramSchmidtMethod(gs); // Create solution vector - vector_type* vec_x = new vector_type(A->getNumRows()); - vec_x->allocate(ReSolve::memory::HOST); + vector_type vec_x(A->getNumRows()); + vec_x.allocate(ReSolve::memory::HOST); // Set the initial guess to 0 - vec_x->allocate(memspace); - vec_x->setToZero(memspace); + vec_x.allocate(memspace); + vec_x.setToZero(memspace); // Norm of rhs vector real_type norm_b = 0.0; // Set solver options - solver->setSketchingMethod(sketching); - solver->getIterativeSolver().setRestart(200); - solver->getIterativeSolver().setMaxit(2500); - solver->getIterativeSolver().setTol(1e-12); + if (krylov == "randgmres") { + solver.setSketchingMethod(sketching); + } + solver.getIterativeSolver().setRestart(200); + solver.getIterativeSolver().setMaxit(2500); + solver.getIterativeSolver().setTol(1e-12); matrix_handler.setValuesChanged(true, memspace); // Set system matrix and initialize iterative solver - status = solver->setMatrix(A); + status = solver.setMatrix(A); error_sum += status; // Set preconditioner (default in this case ILU0) - status = solver->preconditionerSetup(); + status = solver.preconditionerSetup(); error_sum += status; // Solve system - status = solver->solve(vec_rhs, vec_x); + status = solver.solve(vec_rhs, &vec_x); error_sum += status; // Get residual norm norm_b = vector_handler.dot(vec_rhs, vec_rhs, memspace); norm_b = std::sqrt(norm_b); - real_type final_norm_first = solver->getIterativeSolver().getFinalResidualNorm(); + real_type final_norm = solver.getIterativeSolver().getFinalResidualNorm(); std::cout << std::scientific << std::setprecision(16) - << "Randomized FGMRES results (first run): \n" + << "Iterative solver results: \n" << "\t Sketching method: : " << sketching << "\n" << "\t Initial residual norm: ||b-Ax_0||_2 : " - << solver->getIterativeSolver().getInitResidualNorm() << " \n" + << solver.getIterativeSolver().getInitResidualNorm() << " \n" << "\t Initial relative residual norm: ||b-Ax_0||_2/||b||_2 : " - << solver->getIterativeSolver().getInitResidualNorm()/norm_b << " \n" + << solver.getIterativeSolver().getInitResidualNorm()/norm_b << " \n" << "\t Final residual norm: ||b-Ax||_2 : " - << solver->getIterativeSolver().getFinalResidualNorm() << " \n" + << solver.getIterativeSolver().getFinalResidualNorm() << " \n" << "\t Final relative residual norm: ||b-Ax||_2/||b||_2 : " - << solver->getIterativeSolver().getFinalResidualNorm()/norm_b << " \n" + << solver.getIterativeSolver().getFinalResidualNorm()/norm_b << " \n" << "\t Number of iterations : " - << solver->getIterativeSolver().getNumIter() << "\n"; + << solver.getIterativeSolver().getNumIter() << "\n"; + + if (final_norm/norm_b > 1e-11 ) { + std::cout << "Result inaccurate!\n"; + error_sum++; + } + if (error_sum == 0) { + std::cout<<"Test PASSED"<