Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/generate_ginkgo_hpp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function(ginkgo_generate_ginkgo_hpp)
(file MATCHES "^ginkgo/extensions/.*$")
OR (file MATCHES "^ginkgo/core/stop/residual_norm_reduction.hpp$")
OR (file MATCHES "^ginkgo/core/solver/.*_trs.hpp$")
OR (file MATCHES "^ginkgo/core/preconditioner/utils.hpp$")
)
continue()
endif()
Expand Down
6 changes: 3 additions & 3 deletions core/config/preconditioner_ic_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ parse<gko::config::LinOpFactoryType::Ic>(const gko::config::pnode& config,
if (config.get("l_solver_type_or_value_type")) {
GKO_INVALID_STATE(
"preconditioner::Ic only allows value_type from "
"l_solver_type_or_value_type. To avoid type confusion between "
"these types and value_type, l_solver_type_or_value_type uses "
"the value_type directly.");
"l_solver_type_or_value_type. Please use value_type key to set the "
"value type used by the preconditioner and the l_lover key to set "
"the solvers used for the lower triangular systems.");
}
return gko::config::dispatch<gko::LinOpFactory, gko::preconditioner::Ic>(
config, context, updated,
Expand Down
118 changes: 22 additions & 96 deletions core/config/preconditioner_ilu_config.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
// SPDX-FileCopyrightText: 2017 - 2025 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/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"
Expand All @@ -22,123 +17,54 @@ namespace gko {
namespace config {


// For Ic and Ilu, we use additional ValueType to help Solver type decision
template <typename LSolver, typename USolver, bool ReverseApply>
template <bool ReverseApply>
class IluSolverHelper {
public:
template <typename ValueType, typename IndexType>
class Configurator {
public:
static typename preconditioner::Ilu<LSolver, USolver, ReverseApply,
static typename preconditioner::Ilu<ValueType, ValueType, ReverseApply,
IndexType>::parameters_type
parse(const pnode& config, const registry& context,
const type_descriptor& td_for_child)
{
return preconditioner::Ilu<LSolver, USolver, ReverseApply,
return preconditioner::Ilu<ValueType, ValueType, ReverseApply,
IndexType>::parse(config, context,
td_for_child);
}
};
};


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
if (config.get("u_solver_type")) {
GKO_INVALID_STATE(
"preconditioner::Ilu only allows l_solver_type. The "
"u_solver_type automatically uses the transposed type of "
"l_solver_type.");
}
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);
}
};
if (config.get("l_solver_type_or_value_type") ||
config.get("u_solver_type_or_value_type")) {
GKO_INVALID_STATE(
"preconditioner::Ilu only allows value_type from "
"l_solver_type_or_value_type/u_solver_type_or_value_type. Please "
"use value_type key to set the value type used by the "
"preconditioner and the l_lover or u_solver key to set the solvers "
"used for the lower and upper triangular systems.");
}
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{});
return dispatch<gko::LinOpFactory, IluSolverHelper<true>::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 {
return dispatch_solver(std::false_type{});
return dispatch<gko::LinOpFactory,
IluSolverHelper<false>::Configurator>(
config, context, updated,
make_type_selector(updated.get_value_typestr(), value_type_list()),
make_type_selector(updated.get_index_typestr(), index_type_list()));
}
}

Expand Down
121 changes: 36 additions & 85 deletions core/preconditioner/ilu.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

#include "ginkgo/core/preconditioner/ilu.hpp"

#include <ginkgo/core/base/types.hpp>
#include <ginkgo/core/base/utils.hpp>
#include <ginkgo/core/config/config.hpp>
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/config/type_descriptor.hpp>
#include <ginkgo/core/preconditioner/isai.hpp>
#include <ginkgo/core/preconditioner/utils.hpp>
#include <ginkgo/core/solver/gmres.hpp>
#include <ginkgo/core/solver/ir.hpp>

#include "core/config/config_helper.hpp"
#include "core/config/dispatch.hpp"
Expand All @@ -22,24 +19,27 @@ namespace preconditioner {
namespace detail {


template <typename Ilu,
std::enable_if_t<support_ilu_parse<typename Ilu::l_solver_type,
typename Ilu::u_solver_type>>*>
template <typename Ilu, std::enable_if_t<support_ilu_parse<Ilu>>*>
typename Ilu::parameters_type ilu_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
auto params = Ilu::build();

using l_solver_type = typename Ilu::l_solver_type;
using u_solver_type = typename Ilu::u_solver_type;
static_assert(std::is_same_v<l_solver_type, LinOp>,
"only support ILU parse when l_solver_type is LinOp.");
static_assert(std::is_same_v<u_solver_type, LinOp>,
"only support ILU parse when u_solver_type is LinOp.");
if (auto& obj = config.get("l_solver")) {
params.with_l_solver(
gko::config::parse_or_get_specific_factory<
const typename Ilu::l_solver_type>(obj, context, td_for_child));
gko::config::parse_or_get_factory<const LinOpFactory>(
obj, context, td_for_child));
}
if (auto& obj = config.get("u_solver")) {
params.with_u_solver(
gko::config::parse_or_get_specific_factory<
const typename Ilu::u_solver_type>(obj, context, td_for_child));
gko::config::parse_or_get_factory<const LinOpFactory>(
obj, context, td_for_child));
}
if (auto& obj = config.get("factorization")) {
params.with_factorization(
Expand All @@ -51,82 +51,33 @@ typename Ilu::parameters_type ilu_parse(
}


#define GKO_DECLARE_TRS_ILU_FALSE_PARSE(ValueType, IndexType) \
typename Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, false, \
IndexType>::parameters_type \
ilu_parse<Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, false, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_TRS_ILU_FALSE_PARSE);

#define GKO_DECLARE_TRS_ILU_TRUE_PARSE(ValueType, IndexType) \
typename Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, true, \
IndexType>::parameters_type \
ilu_parse<Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, true, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_TRS_ILU_TRUE_PARSE);

#define GKO_DECLARE_GMRES_ILU_FALSE_PARSE(ValueType, IndexType) \
typename Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, false, \
IndexType>::parameters_type \
ilu_parse<Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, false, \
IndexType>>(const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
GKO_DECLARE_GMRES_ILU_FALSE_PARSE);

#define GKO_DECLARE_GMRES_ILU_TRUE_PARSE(ValueType, IndexType) \
typename Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, true, \
IndexType>::parameters_type \
ilu_parse<Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, true, \
IndexType>>(const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GMRES_ILU_TRUE_PARSE);

#define GKO_DECLARE_IR_ILU_FALSE_PARSE(ValueType, IndexType) \
typename Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, false, \
IndexType>::parameters_type \
ilu_parse< \
Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, false, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_ILU_FALSE_PARSE);

#define GKO_DECLARE_IR_ILU_TRUE_PARSE(ValueType, IndexType) \
typename Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, true, \
IndexType>::parameters_type \
ilu_parse< \
Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, true, IndexType>>( \
const config::pnode&, const config::registry&, \
#define GKO_DECLARE_ILU_PARSE_FALSE(ValueType, IndexType) \
typename Ilu<ValueType, ValueType, false, IndexType>::parameters_type \
ilu_parse<Ilu<ValueType, ValueType, false, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_ILU_TRUE_PARSE);

#define GKO_DECLARE_ISAI_ILU_FALSE_PARSE(ValueType, IndexType) \
typename Ilu<LowerIsai<ValueType, IndexType>, \
UpperIsai<ValueType, IndexType>, false, \
IndexType>::parameters_type \
ilu_parse<Ilu<LowerIsai<ValueType, IndexType>, \
UpperIsai<ValueType, IndexType>, false, IndexType>>( \
const config::pnode&, const config::registry&, \
#define GKO_DECLARE_ILU_PARSE_TRUE(ValueType, IndexType) \
typename Ilu<ValueType, ValueType, true, IndexType>::parameters_type \
ilu_parse<Ilu<ValueType, ValueType, true, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ISAI_ILU_FALSE_PARSE);

#define GKO_DECLARE_ISAI_ILU_TRUE_PARSE(ValueType, IndexType) \
typename Ilu<LowerIsai<ValueType, IndexType>, \
UpperIsai<ValueType, IndexType>, true, \
IndexType>::parameters_type \
ilu_parse<Ilu<LowerIsai<ValueType, IndexType>, \
UpperIsai<ValueType, IndexType>, true, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ISAI_ILU_TRUE_PARSE);

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_PARSE_FALSE);
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_PARSE_TRUE);


} // namespace detail


// only instantiate the value type variants of ILU, whose solver is LinOp.
#define GKO_DECLARE_ILU_FALSE(ValueType, IndexType) \
class Ilu<ValueType, ValueType, false, IndexType>
#define GKO_DECLARE_ILU_TRUE(ValueType, IndexType) \
class Ilu<ValueType, ValueType, true, IndexType>

GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_FALSE);
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_TRUE);


} // namespace preconditioner
} // namespace gko
Loading
Loading