Skip to content

Commit

Permalink
collect common trisolve, rename template, update doc
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Grützmacher <[email protected]>
  • Loading branch information
yhmtsai and Thomas Grützmacher committed May 24, 2024
1 parent e4b7379 commit c1c03a5
Show file tree
Hide file tree
Showing 30 changed files with 429 additions and 106 deletions.
2 changes: 1 addition & 1 deletion core/config/dispatch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ deferred_factory_parameter<ReturnType> dispatch(
using value_type_list =
syn::type_list<double, float, std::complex<double>, std::complex<float>>;

using index_type_list = syn::type_list<gko::int32, gko::int64>;
using index_type_list = syn::type_list<int32, int64>;

} // namespace config
} // namespace gko
Expand Down
39 changes: 39 additions & 0 deletions core/config/factorization_config.cpp
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
4 changes: 2 additions & 2 deletions core/config/parse_macro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


// for value_type only
#define PARSE_VALUE_TYPE(_type, _configurator) \
#define GKO_PARSE_VALUE_TYPE(_type, _configurator) \
template <> \
deferred_factory_parameter<gko::LinOpFactory> \
parse<gko::config::LinOpFactoryType::_type>( \
Expand All @@ -37,7 +37,7 @@


// for value_type and index_type
#define PARSE_VALUE_AND_INDEX_TYPE(_type, _configurator) \
#define GKO_PARSE_VALUE_AND_INDEX_TYPE(_type, _configurator) \
template <> \
deferred_factory_parameter<gko::LinOpFactory> \
parse<gko::config::LinOpFactoryType::_type>( \
Expand Down
295 changes: 295 additions & 0 deletions core/config/preconditioner_config.cpp
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
26 changes: 13 additions & 13 deletions core/config/solver_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ namespace gko {
namespace config {


PARSE_VALUE_TYPE(Cg, gko::solver::Cg);
PARSE_VALUE_TYPE(Bicg, gko::solver::Bicg);
PARSE_VALUE_TYPE(Bicgstab, gko::solver::Bicgstab);
PARSE_VALUE_TYPE(Cgs, gko::solver::Cgs);
PARSE_VALUE_TYPE(Fcg, gko::solver::Fcg);
PARSE_VALUE_TYPE(Ir, gko::solver::Ir);
PARSE_VALUE_TYPE(Idr, gko::solver::Idr);
PARSE_VALUE_TYPE(Gcr, gko::solver::Gcr);
PARSE_VALUE_TYPE(Gmres, gko::solver::Gmres);
PARSE_VALUE_TYPE(CbGmres, gko::solver::CbGmres);
PARSE_VALUE_AND_INDEX_TYPE(Direct, gko::experimental::solver::Direct);
PARSE_VALUE_AND_INDEX_TYPE(LowerTrs, gko::solver::LowerTrs);
PARSE_VALUE_AND_INDEX_TYPE(UpperTrs, gko::solver::UpperTrs);
GKO_PARSE_VALUE_TYPE(Cg, gko::solver::Cg);
GKO_PARSE_VALUE_TYPE(Bicg, gko::solver::Bicg);
GKO_PARSE_VALUE_TYPE(Bicgstab, gko::solver::Bicgstab);
GKO_PARSE_VALUE_TYPE(Cgs, gko::solver::Cgs);
GKO_PARSE_VALUE_TYPE(Fcg, gko::solver::Fcg);
GKO_PARSE_VALUE_TYPE(Ir, gko::solver::Ir);
GKO_PARSE_VALUE_TYPE(Idr, gko::solver::Idr);
GKO_PARSE_VALUE_TYPE(Gcr, gko::solver::Gcr);
GKO_PARSE_VALUE_TYPE(Gmres, gko::solver::Gmres);
GKO_PARSE_VALUE_TYPE(CbGmres, gko::solver::CbGmres);
GKO_PARSE_VALUE_AND_INDEX_TYPE(Direct, gko::experimental::solver::Direct);
GKO_PARSE_VALUE_AND_INDEX_TYPE(LowerTrs, gko::solver::LowerTrs);
GKO_PARSE_VALUE_AND_INDEX_TYPE(UpperTrs, gko::solver::UpperTrs);


} // namespace config
Expand Down
Loading

0 comments on commit c1c03a5

Please sign in to comment.