-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
collect common trisolve, rename template, update doc
Co-authored-by: Thomas Grützmacher <[email protected]>
- Loading branch information
Showing
30 changed files
with
429 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors | ||
// | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <ginkgo/core/base/exception_helpers.hpp> | ||
#include <ginkgo/core/config/config.hpp> | ||
#include <ginkgo/core/config/registry.hpp> | ||
#include <ginkgo/core/factorization/cholesky.hpp> | ||
#include <ginkgo/core/factorization/ic.hpp> | ||
#include <ginkgo/core/factorization/ilu.hpp> | ||
#include <ginkgo/core/factorization/lu.hpp> | ||
#include <ginkgo/core/factorization/par_ic.hpp> | ||
#include <ginkgo/core/factorization/par_ict.hpp> | ||
#include <ginkgo/core/factorization/par_ilu.hpp> | ||
#include <ginkgo/core/factorization/par_ilut.hpp> | ||
|
||
|
||
#include "core/config/config_helper.hpp" | ||
#include "core/config/dispatch.hpp" | ||
#include "core/config/parse_macro.hpp" | ||
|
||
|
||
namespace gko { | ||
namespace config { | ||
|
||
|
||
GKO_PARSE_VALUE_AND_INDEX_TYPE(Factorization_Ic, gko::factorization::Ic); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(Factorization_Ilu, gko::factorization::Ilu); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(Cholesky, | ||
gko::experimental::factorization::Cholesky); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(Lu, gko::experimental::factorization::Lu); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(ParIlu, gko::factorization::ParIlu); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(ParIlut, gko::factorization::ParIlut); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(ParIc, gko::factorization::ParIc); | ||
GKO_PARSE_VALUE_AND_INDEX_TYPE(ParIct, gko::factorization::ParIct); | ||
|
||
|
||
} // namespace config | ||
} // namespace gko |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,295 @@ | ||
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors | ||
// | ||
// SPDX-License-Identifier: BSD-3-Clause | ||
|
||
#include <ginkgo/core/base/exception_helpers.hpp> | ||
#include <ginkgo/core/config/config.hpp> | ||
#include <ginkgo/core/config/registry.hpp> | ||
#include <ginkgo/core/preconditioner/ic.hpp> | ||
#include <ginkgo/core/preconditioner/ilu.hpp> | ||
#include <ginkgo/core/preconditioner/isai.hpp> | ||
#include <ginkgo/core/preconditioner/jacobi.hpp> | ||
#include <ginkgo/core/solver/gmres.hpp> | ||
#include <ginkgo/core/solver/ir.hpp> | ||
#include <ginkgo/core/solver/triangular.hpp> | ||
|
||
|
||
#include "core/config/config_helper.hpp" | ||
#include "core/config/dispatch.hpp" | ||
#include "core/config/parse_macro.hpp" | ||
#include "core/config/type_descriptor_helper.hpp" | ||
|
||
|
||
namespace gko { | ||
namespace config { | ||
|
||
|
||
// For Ic and Ilu, we use additional ValueType to help Solver type decision | ||
template <typename Solver> | ||
class IcSolverHelper { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator { | ||
public: | ||
static | ||
typename gko::preconditioner::Ic<Solver, IndexType>::parameters_type | ||
parse(const pnode& config, const registry& context, | ||
const type_descriptor& td_for_child) | ||
{ | ||
return gko::preconditioner::Ic<Solver, IndexType>::parse( | ||
config, context, td_for_child); | ||
} | ||
}; | ||
}; | ||
|
||
|
||
template <typename LSolver, typename USolver, bool ReverseApply> | ||
class IluSolverHelper { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator { | ||
public: | ||
static typename preconditioner::Ilu<LSolver, USolver, ReverseApply, | ||
IndexType>::parameters_type | ||
parse(const pnode& config, const registry& context, | ||
const type_descriptor& td_for_child) | ||
{ | ||
return preconditioner::Ilu<LSolver, USolver, ReverseApply, | ||
IndexType>::parse(config, context, | ||
td_for_child); | ||
} | ||
}; | ||
}; | ||
|
||
|
||
template <preconditioner::isai_type IsaiType> | ||
class IsaiHelper { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator { | ||
public: | ||
static typename preconditioner::Isai<IsaiType, ValueType, | ||
IndexType>::parameters_type | ||
parse(const pnode& config, const registry& context, | ||
const type_descriptor& td_for_child) | ||
{ | ||
return preconditioner::Isai<IsaiType, ValueType, IndexType>::parse( | ||
config, context, td_for_child); | ||
} | ||
}; | ||
}; | ||
|
||
// Do not use the partial specialization for SolverBase<V> and SolverBase<V, I> | ||
// because the default template arguments are allowed for a template template | ||
// argument (detail: CWG 150 after c++17 | ||
// https://en.cppreference.com/w/cpp/language/template_parameters#Template_template_arguments) | ||
template <template <typename V> class SolverBase> | ||
class IcHelper1 { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator | ||
: public IcSolverHelper<SolverBase<ValueType>>::template Configurator< | ||
ValueType, IndexType> {}; | ||
}; | ||
|
||
|
||
template <template <typename V, typename I> class SolverBase> | ||
class IcHelper2 { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator | ||
: public IcSolverHelper<SolverBase<ValueType, IndexType>>:: | ||
template Configurator<ValueType, IndexType> {}; | ||
}; | ||
|
||
|
||
template <> | ||
deferred_factory_parameter<gko::LinOpFactory> parse<LinOpFactoryType::Ic>( | ||
const pnode& config, const registry& context, const type_descriptor& td) | ||
{ | ||
auto updated = update_type(config, td); | ||
std::string str("solver::LowerTrs"); | ||
if (auto& obj = config.get("l_solver_type")) { | ||
str = obj.get_string(); | ||
} | ||
if (str == "solver::LowerTrs") { | ||
return dispatch<gko::LinOpFactory, | ||
IcHelper2<solver::LowerTrs>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), index_type_list())); | ||
} else if (str == "solver::Ir") { | ||
return dispatch<gko::LinOpFactory, IcHelper1<solver::Ir>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), index_type_list())); | ||
} else if (str == "preconditioner::LowerIsai") { | ||
return dispatch<gko::LinOpFactory, | ||
IcHelper2<preconditioner::LowerIsai>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), index_type_list())); | ||
} else if (str == "solver::Gmres") { | ||
return dispatch<gko::LinOpFactory, | ||
IcHelper1<solver::Gmres>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), index_type_list())); | ||
} else { | ||
GKO_INVALID_CONFIG_VALUE("l_solver_type", str); | ||
} | ||
} | ||
|
||
|
||
template <template <typename V> class LSolverBase, | ||
template <typename V> class USolverBase, bool ReverseApply> | ||
class IluHelper1 { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator | ||
: public IluSolverHelper< | ||
LSolverBase<ValueType>, USolverBase<ValueType>, | ||
ReverseApply>::template Configurator<ValueType, IndexType> {}; | ||
}; | ||
|
||
|
||
template <template <typename V, typename I> class LSolverBase, | ||
template <typename V, typename I> class USolverBase, | ||
bool ReverseApply> | ||
class IluHelper2 { | ||
public: | ||
template <typename ValueType, typename IndexType> | ||
class Configurator | ||
: public IluSolverHelper< | ||
LSolverBase<ValueType, IndexType>, | ||
USolverBase<ValueType, IndexType>, | ||
ReverseApply>::template Configurator<ValueType, IndexType> {}; | ||
}; | ||
|
||
|
||
template <> | ||
deferred_factory_parameter<gko::LinOpFactory> parse<LinOpFactoryType::Ilu>( | ||
const pnode& config, const registry& context, const type_descriptor& td) | ||
{ | ||
auto updated = update_type(config, td); | ||
auto dispatch_solver = [&](auto reverse_apply) | ||
-> deferred_factory_parameter<gko::LinOpFactory> { | ||
using ReverseApply = decltype(reverse_apply); | ||
// always use symmetric solver for USolverType | ||
std::string str("solver::LowerTrs"); | ||
if (auto& obj = config.get("l_solver_type")) { | ||
str = obj.get_string(); | ||
} | ||
if (str == "solver::LowerTrs") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IluHelper2<solver::LowerTrs, solver::UpperTrs, | ||
ReverseApply::value>::template Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "solver::Ir") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IluHelper1<solver::Ir, solver::Ir, | ||
ReverseApply::value>::template Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "preconditioner::LowerIsai") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IluHelper2<preconditioner::LowerIsai, preconditioner::UpperIsai, | ||
ReverseApply::value>::template Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "solver::Gmres") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IluHelper1<solver::Gmres, solver::Gmres, | ||
ReverseApply::value>::template Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else { | ||
GKO_INVALID_CONFIG_VALUE("l_solver_type", str); | ||
} | ||
}; | ||
bool reverse_apply = false; | ||
if (auto& obj = config.get("reverse_apply")) { | ||
reverse_apply = obj.get_boolean(); | ||
} | ||
if (reverse_apply) { | ||
return dispatch_solver(std::true_type{}); | ||
} else { | ||
return dispatch_solver(std::false_type{}); | ||
} | ||
} | ||
|
||
|
||
template <> | ||
deferred_factory_parameter<gko::LinOpFactory> parse<LinOpFactoryType::Isai>( | ||
const pnode& config, const registry& context, const type_descriptor& td) | ||
{ | ||
auto updated = update_type(config, td); | ||
if (auto& obj = config.get("isai_type")) { | ||
auto str = obj.get_string(); | ||
if (str == "lower") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IsaiHelper<preconditioner::isai_type::lower>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "upper") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IsaiHelper<preconditioner::isai_type::upper>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "general") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IsaiHelper<preconditioner::isai_type::general>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else if (str == "spd") { | ||
return dispatch< | ||
gko::LinOpFactory, | ||
IsaiHelper<preconditioner::isai_type::spd>::Configurator>( | ||
config, context, updated, | ||
make_type_selector(updated.get_value_typestr(), | ||
value_type_list()), | ||
make_type_selector(updated.get_index_typestr(), | ||
index_type_list())); | ||
} else { | ||
GKO_INVALID_CONFIG_VALUE("isai_type", str); | ||
} | ||
} else { | ||
GKO_MISS_CONFIG_ENTRY("isai_type"); | ||
} | ||
} | ||
|
||
|
||
GKO_PARSE_VALUE_AND_INDEX_TYPE(Jacobi, gko::preconditioner::Jacobi); | ||
|
||
|
||
} // namespace config | ||
} // namespace gko |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.