From a3d8d6655f4ff1062eadbfea4e5619dc1e95f63b Mon Sep 17 00:00:00 2001 From: Tong Dong Qiu Date: Fri, 2 Jul 2021 16:21:19 +0200 Subject: [PATCH] Added enum for amgcl_backend_type --- .../linalg/bda/amgclSolverBackend.cpp | 61 +++++++++++++++++-- .../linalg/bda/amgclSolverBackend.hpp | 11 +++- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/opm/simulators/linalg/bda/amgclSolverBackend.cpp b/opm/simulators/linalg/bda/amgclSolverBackend.cpp index a09676ac9..09a73aef0 100644 --- a/opm/simulators/linalg/bda/amgclSolverBackend.cpp +++ b/opm/simulators/linalg/bda/amgclSolverBackend.cpp @@ -68,14 +68,15 @@ void amgclSolverBackend::initialize(int N_, int nnz_, int dim, doubl // try to read amgcl parameters via json file std::string filename = "amgcl_options.json"; std::ifstream file(filename); + std::string backend_type_string; if (file.is_open()) { // if file exists, read parameters from file boost::property_tree::read_json(file, prm); - backend_type_cuda = prm.get("backend_type_cuda", false); // defaults to false if not specified + backend_type_string = prm.get("backend_type"); // defaults to cpu if not specified out << "Using parameters from " << filename << ":\n"; } else { // otherwise use default parameters, same as Dune - prm.put("backend_type_cuda", false); + prm.put("backend_type", "cpu"); prm.put("precond.class", "relaxation"); prm.put("precond.type", "ilu0"); prm.put("precond.damping", 0.9); @@ -87,9 +88,19 @@ void amgclSolverBackend::initialize(int N_, int nnz_, int dim, doubl } boost::property_tree::write_json(out, prm); // print amgcl parameters - prm.erase("backend_type_cuda"); // delete custom parameter, otherwise amgcl prints a warning + prm.erase("backend_type"); // delete custom parameter, otherwise amgcl prints a warning - if (backend_type_cuda) { + if (backend_type_string == "cpu") { + backend_type = Amgcl_backend_type::cpu; + } else if (backend_type_string == "cuda") { + backend_type = Amgcl_backend_type::cuda; + } else if (backend_type_string == "vexcl") { + backend_type = Amgcl_backend_type::vexcl; + } else { + OPM_THROW(std::logic_error, "Error unknown value for amgcl parameter 'backend_type'"); + } + + if (backend_type == Amgcl_backend_type::cuda) { #if HAVE_CUDA cudaDeviceProp prop; cudaGetDeviceProperties(&prop, deviceID); @@ -168,7 +179,7 @@ void amgclSolverBackend::solve_system(double *b, WellContributions & double error = 0.0; try { - if (backend_type_cuda) { // use CUDA + if (backend_type == Amgcl_backend_type::cuda) { // use CUDA #if HAVE_CUDA // create matrix object auto A = std::tie(N, A_rows, A_cols, A_vals); @@ -192,7 +203,7 @@ void amgclSolverBackend::solve_system(double *b, WellContributions & thrust::copy(X.begin(), X.end(), x.begin()); #endif - } else { // use builtin backend (CPU) + } else if (backend_type == Amgcl_backend_type::cpu) { // use builtin backend (CPU) // create matrix object auto Atmp = std::tie(N, A_rows, A_cols, A_vals); auto A = amgcl::adapter::block_matrix(Atmp); @@ -219,6 +230,44 @@ void amgclSolverBackend::solve_system(double *b, WellContributions & // actually solve std::tie(iters, error) = solve(B, X); + } else if (backend_type == Amgcl_backend_type::vexcl) { + // vex::Context ctx(vex::Filter::Env && vex::Filter::Count(1)); + // std::cout << ctx << std::endl; + + // // Enable support for block-valued matrices in the VexCL kernels: + // vex::scoped_program_header h1(ctx, amgcl::backend::vexcl_static_matrix_declaration()); + + // // typedef amgcl::static_matrix dmat_type; // matrix value type in double precision + // // typedef amgcl::static_matrix dvec_type; // the corresponding vector value type + // typedef amgcl::backend::vexcl Backend; + + // typedef amgcl::make_block_solver< + // amgcl::relaxation::as_preconditioner, + // amgcl::solver::bicgstab + // > Solver; + + // typename Backend::params bprm; + // bprm.q = ctx; // set vexcl context + + // typename Solver::params prm; + // prm.precond.damping = 0.9; + // prm.solver.maxiter = maxit; + // prm.solver.tol = tolerance; + // prm.solver.verbose = (verbosity >= 2); + + // auto A = std::tie(N, A_rows, A_cols, A_vals); + + // Solver solve(A, prm, bprm); + + // auto f_ptr = reinterpret_cast(rhs.data()); + // auto x_ptr = reinterpret_cast(x.data()); + // vex::vector F(ctx, N / block_size, f_ptr); + // vex::vector X(ctx, N / block_size, x_ptr); + + // std::tie(iters, error) = solve(F, X); + + // vex::copy(X, x_ptr); + } } catch (const std::exception& ex) { std::cerr << "Caught exception: " << ex.what() << std::endl; diff --git a/opm/simulators/linalg/bda/amgclSolverBackend.hpp b/opm/simulators/linalg/bda/amgclSolverBackend.hpp index 822f7ab04..c95ce3b16 100644 --- a/opm/simulators/linalg/bda/amgclSolverBackend.hpp +++ b/opm/simulators/linalg/bda/amgclSolverBackend.hpp @@ -79,13 +79,20 @@ class amgclSolverBackend : public BdaSolver typedef amgcl::make_solver, amgcl::runtime::solver::wrapper > CPU_Solver; private: + + // amgcl can use different backends, this lets the user choose + enum Amgcl_backend_type { + cpu, + cuda, + vexcl + }; + // store matrix in CSR format std::vector A_rows, A_cols; std::vector A_vals, rhs; std::vector x; std::once_flag print_info; - bool backend_type_cuda = false; // true if amgcl uses cuda, otherwise use cpu backend - // if more backend are supported (vexcl), turn into enum + Amgcl_backend_type backend_type = cpu; boost::property_tree::ptree prm; // amgcl parameters #if HAVE_CUDA