Skip to content

Commit a3375d1

Browse files
committed
allow ValueType in LSolver and USolver
1 parent 2b7c086 commit a3375d1

10 files changed

Lines changed: 366 additions & 280 deletions

File tree

cmake/generate_ginkgo_hpp.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function(ginkgo_generate_ginkgo_hpp)
1313
(file MATCHES "^ginkgo/extensions/.*$")
1414
OR (file MATCHES "^ginkgo/core/stop/residual_norm_reduction.hpp$")
1515
OR (file MATCHES "^ginkgo/core/solver/.*_trs.hpp$")
16+
OR (file MATCHES "^ginkgo/core/preconditioner/utils.hpp$")
1617
)
1718
continue()
1819
endif()

core/config/preconditioner_ilu_config.cpp

Lines changed: 22 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
1-
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
22
//
33
// SPDX-License-Identifier: BSD-3-Clause
44

55
#include <ginkgo/core/base/exception_helpers.hpp>
66
#include <ginkgo/core/config/config.hpp>
77
#include <ginkgo/core/config/registry.hpp>
8-
#include <ginkgo/core/preconditioner/ic.hpp>
98
#include <ginkgo/core/preconditioner/ilu.hpp>
10-
#include <ginkgo/core/preconditioner/isai.hpp>
11-
#include <ginkgo/core/solver/gmres.hpp>
12-
#include <ginkgo/core/solver/ir.hpp>
13-
#include <ginkgo/core/solver/triangular.hpp>
149

1510
#include "core/config/config_helper.hpp"
1611
#include "core/config/dispatch.hpp"
@@ -22,123 +17,54 @@ namespace gko {
2217
namespace config {
2318

2419

25-
// For Ic and Ilu, we use additional ValueType to help Solver type decision
26-
template <typename LSolver, typename USolver, bool ReverseApply>
20+
template <bool ReverseApply>
2721
class IluSolverHelper {
2822
public:
2923
template <typename ValueType, typename IndexType>
3024
class Configurator {
3125
public:
32-
static typename preconditioner::Ilu<LSolver, USolver, ReverseApply,
26+
static typename preconditioner::Ilu<ValueType, ValueType, ReverseApply,
3327
IndexType>::parameters_type
3428
parse(const pnode& config, const registry& context,
3529
const type_descriptor& td_for_child)
3630
{
37-
return preconditioner::Ilu<LSolver, USolver, ReverseApply,
31+
return preconditioner::Ilu<ValueType, ValueType, ReverseApply,
3832
IndexType>::parse(config, context,
3933
td_for_child);
4034
}
4135
};
4236
};
4337

4438

45-
template <template <typename V> class LSolverBase,
46-
template <typename V> class USolverBase, bool ReverseApply>
47-
class IluHelper1 {
48-
public:
49-
template <typename ValueType, typename IndexType>
50-
class Configurator
51-
: public IluSolverHelper<
52-
LSolverBase<ValueType>, USolverBase<ValueType>,
53-
ReverseApply>::template Configurator<ValueType, IndexType> {};
54-
};
55-
56-
57-
template <template <typename V, typename I> class LSolverBase,
58-
template <typename V, typename I> class USolverBase,
59-
bool ReverseApply>
60-
class IluHelper2 {
61-
public:
62-
template <typename ValueType, typename IndexType>
63-
class Configurator
64-
: public IluSolverHelper<
65-
LSolverBase<ValueType, IndexType>,
66-
USolverBase<ValueType, IndexType>,
67-
ReverseApply>::template Configurator<ValueType, IndexType> {};
68-
};
69-
70-
7139
template <>
7240
deferred_factory_parameter<gko::LinOpFactory> parse<LinOpFactoryType::Ilu>(
7341
const pnode& config, const registry& context, const type_descriptor& td)
7442
{
7543
auto updated = update_type(config, td);
76-
auto dispatch_solver = [&](auto reverse_apply)
77-
-> deferred_factory_parameter<gko::LinOpFactory> {
78-
using ReverseApply = decltype(reverse_apply);
79-
// always use symmetric solver for USolverType
80-
if (config.get("u_solver_type")) {
81-
GKO_INVALID_STATE(
82-
"preconditioner::Ilu only allows l_solver_type. The "
83-
"u_solver_type automatically uses the transposed type of "
84-
"l_solver_type.");
85-
}
86-
std::string str("solver::LowerTrs");
87-
if (auto& obj = config.get("l_solver_type")) {
88-
str = obj.get_string();
89-
}
90-
if (str == "solver::LowerTrs") {
91-
return dispatch<
92-
gko::LinOpFactory,
93-
IluHelper2<solver::LowerTrs, solver::UpperTrs,
94-
ReverseApply::value>::template Configurator>(
95-
config, context, updated,
96-
make_type_selector(updated.get_value_typestr(),
97-
value_type_list()),
98-
make_type_selector(updated.get_index_typestr(),
99-
index_type_list()));
100-
} else if (str == "solver::Ir") {
101-
return dispatch<
102-
gko::LinOpFactory,
103-
IluHelper1<solver::Ir, solver::Ir,
104-
ReverseApply::value>::template Configurator>(
105-
config, context, updated,
106-
make_type_selector(updated.get_value_typestr(),
107-
value_type_list()),
108-
make_type_selector(updated.get_index_typestr(),
109-
index_type_list()));
110-
} else if (str == "preconditioner::LowerIsai") {
111-
return dispatch<
112-
gko::LinOpFactory,
113-
IluHelper2<preconditioner::LowerIsai, preconditioner::UpperIsai,
114-
ReverseApply::value>::template Configurator>(
115-
config, context, updated,
116-
make_type_selector(updated.get_value_typestr(),
117-
value_type_list()),
118-
make_type_selector(updated.get_index_typestr(),
119-
index_type_list()));
120-
} else if (str == "solver::Gmres") {
121-
return dispatch<
122-
gko::LinOpFactory,
123-
IluHelper1<solver::Gmres, solver::Gmres,
124-
ReverseApply::value>::template Configurator>(
125-
config, context, updated,
126-
make_type_selector(updated.get_value_typestr(),
127-
value_type_list()),
128-
make_type_selector(updated.get_index_typestr(),
129-
index_type_list()));
130-
} else {
131-
GKO_INVALID_CONFIG_VALUE("l_solver_type", str);
132-
}
133-
};
44+
if (config.get("l_solver_type_or_value_type") ||
45+
config.get("u_solver_type_or_value_type")) {
46+
GKO_INVALID_STATE(
47+
"preconditioner::Ilu only allows value_type from "
48+
"l_solver_type_or_value_type/u_solver_type_or_value_type. To "
49+
"avoid type confusion between these types and value_type, "
50+
"l_solver_type_or_value_type/u_solver_type_or_value_type uses "
51+
"the value_type directly.");
52+
}
13453
bool reverse_apply = false;
13554
if (auto& obj = config.get("reverse_apply")) {
13655
reverse_apply = obj.get_boolean();
13756
}
13857
if (reverse_apply) {
139-
return dispatch_solver(std::true_type{});
58+
return dispatch<gko::LinOpFactory, IluSolverHelper<true>::Configurator>(
59+
config, context, updated,
60+
make_type_selector(updated.get_value_typestr(), value_type_list()),
61+
make_type_selector(updated.get_index_typestr(), index_type_list()));
14062
} else {
141-
return dispatch_solver(std::false_type{});
63+
return dispatch<gko::LinOpFactory,
64+
IluSolverHelper<false>::Configurator>(
65+
config, context, updated,
66+
make_type_selector(updated.get_value_typestr(), value_type_list()),
67+
make_type_selector(updated.get_index_typestr(), index_type_list()));
14268
}
14369
}
14470

core/preconditioner/ilu.cpp

Lines changed: 36 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
1+
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
22
//
33
// SPDX-License-Identifier: BSD-3-Clause
44

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

77
#include <ginkgo/core/base/types.hpp>
8+
#include <ginkgo/core/base/utils.hpp>
89
#include <ginkgo/core/config/config.hpp>
910
#include <ginkgo/core/config/registry.hpp>
1011
#include <ginkgo/core/config/type_descriptor.hpp>
11-
#include <ginkgo/core/preconditioner/isai.hpp>
12-
#include <ginkgo/core/preconditioner/utils.hpp>
13-
#include <ginkgo/core/solver/gmres.hpp>
14-
#include <ginkgo/core/solver/ir.hpp>
1512

1613
#include "core/config/config_helper.hpp"
1714
#include "core/config/dispatch.hpp"
@@ -22,24 +19,27 @@ namespace preconditioner {
2219
namespace detail {
2320

2421

25-
template <typename Ilu,
26-
std::enable_if_t<support_ilu_parse<typename Ilu::l_solver_type,
27-
typename Ilu::u_solver_type>>*>
22+
template <typename Ilu, std::enable_if_t<support_ilu_parse<Ilu>>*>
2823
typename Ilu::parameters_type ilu_parse(
2924
const config::pnode& config, const config::registry& context,
3025
const config::type_descriptor& td_for_child)
3126
{
3227
auto params = Ilu::build();
33-
28+
using l_solver_type = typename Ilu::l_solver_type;
29+
using u_solver_type = typename Ilu::u_solver_type;
30+
static_assert(std::is_same_v<l_solver_type, LinOp>,
31+
"only support ILU parse when l_solver_type is LinOp.");
32+
static_assert(std::is_same_v<u_solver_type, LinOp>,
33+
"only support ILU parse when u_solver_type is LinOp.");
3434
if (auto& obj = config.get("l_solver")) {
3535
params.with_l_solver(
36-
gko::config::parse_or_get_specific_factory<
37-
const typename Ilu::l_solver_type>(obj, context, td_for_child));
36+
gko::config::parse_or_get_factory<const LinOpFactory>(
37+
obj, context, td_for_child));
3838
}
3939
if (auto& obj = config.get("u_solver")) {
4040
params.with_u_solver(
41-
gko::config::parse_or_get_specific_factory<
42-
const typename Ilu::u_solver_type>(obj, context, td_for_child));
41+
gko::config::parse_or_get_factory<const LinOpFactory>(
42+
obj, context, td_for_child));
4343
}
4444
if (auto& obj = config.get("factorization")) {
4545
params.with_factorization(
@@ -51,82 +51,33 @@ typename Ilu::parameters_type ilu_parse(
5151
}
5252

5353

54-
#define GKO_DECLARE_TRS_ILU_FALSE_PARSE(ValueType, IndexType) \
55-
typename Ilu<solver::LowerTrs<ValueType, IndexType>, \
56-
solver::UpperTrs<ValueType, IndexType>, false, \
57-
IndexType>::parameters_type \
58-
ilu_parse<Ilu<solver::LowerTrs<ValueType, IndexType>, \
59-
solver::UpperTrs<ValueType, IndexType>, false, IndexType>>( \
60-
const config::pnode&, const config::registry&, \
61-
const config::type_descriptor&)
62-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_TRS_ILU_FALSE_PARSE);
63-
64-
#define GKO_DECLARE_TRS_ILU_TRUE_PARSE(ValueType, IndexType) \
65-
typename Ilu<solver::LowerTrs<ValueType, IndexType>, \
66-
solver::UpperTrs<ValueType, IndexType>, true, \
67-
IndexType>::parameters_type \
68-
ilu_parse<Ilu<solver::LowerTrs<ValueType, IndexType>, \
69-
solver::UpperTrs<ValueType, IndexType>, true, IndexType>>( \
70-
const config::pnode&, const config::registry&, \
71-
const config::type_descriptor&)
72-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_TRS_ILU_TRUE_PARSE);
73-
74-
#define GKO_DECLARE_GMRES_ILU_FALSE_PARSE(ValueType, IndexType) \
75-
typename Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, false, \
76-
IndexType>::parameters_type \
77-
ilu_parse<Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, false, \
78-
IndexType>>(const config::pnode&, const config::registry&, \
79-
const config::type_descriptor&)
80-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(
81-
GKO_DECLARE_GMRES_ILU_FALSE_PARSE);
82-
83-
#define GKO_DECLARE_GMRES_ILU_TRUE_PARSE(ValueType, IndexType) \
84-
typename Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, true, \
85-
IndexType>::parameters_type \
86-
ilu_parse<Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, true, \
87-
IndexType>>(const config::pnode&, const config::registry&, \
88-
const config::type_descriptor&)
89-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GMRES_ILU_TRUE_PARSE);
90-
91-
#define GKO_DECLARE_IR_ILU_FALSE_PARSE(ValueType, IndexType) \
92-
typename Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, false, \
93-
IndexType>::parameters_type \
94-
ilu_parse< \
95-
Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, false, IndexType>>( \
96-
const config::pnode&, const config::registry&, \
97-
const config::type_descriptor&)
98-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_ILU_FALSE_PARSE);
99-
100-
#define GKO_DECLARE_IR_ILU_TRUE_PARSE(ValueType, IndexType) \
101-
typename Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, true, \
102-
IndexType>::parameters_type \
103-
ilu_parse< \
104-
Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, true, IndexType>>( \
105-
const config::pnode&, const config::registry&, \
54+
#define GKO_DECLARE_ILU_PARSE_FALSE(ValueType, IndexType) \
55+
typename Ilu<ValueType, ValueType, false, IndexType>::parameters_type \
56+
ilu_parse<Ilu<ValueType, ValueType, false, IndexType>>( \
57+
const config::pnode&, const config::registry&, \
10658
const config::type_descriptor&)
107-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_ILU_TRUE_PARSE);
108-
109-
#define GKO_DECLARE_ISAI_ILU_FALSE_PARSE(ValueType, IndexType) \
110-
typename Ilu<LowerIsai<ValueType, IndexType>, \
111-
UpperIsai<ValueType, IndexType>, false, \
112-
IndexType>::parameters_type \
113-
ilu_parse<Ilu<LowerIsai<ValueType, IndexType>, \
114-
UpperIsai<ValueType, IndexType>, false, IndexType>>( \
115-
const config::pnode&, const config::registry&, \
59+
#define GKO_DECLARE_ILU_PARSE_TRUE(ValueType, IndexType) \
60+
typename Ilu<ValueType, ValueType, true, IndexType>::parameters_type \
61+
ilu_parse<Ilu<ValueType, ValueType, true, IndexType>>( \
62+
const config::pnode&, const config::registry&, \
11663
const config::type_descriptor&)
117-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ISAI_ILU_FALSE_PARSE);
118-
119-
#define GKO_DECLARE_ISAI_ILU_TRUE_PARSE(ValueType, IndexType) \
120-
typename Ilu<LowerIsai<ValueType, IndexType>, \
121-
UpperIsai<ValueType, IndexType>, true, \
122-
IndexType>::parameters_type \
123-
ilu_parse<Ilu<LowerIsai<ValueType, IndexType>, \
124-
UpperIsai<ValueType, IndexType>, true, IndexType>>( \
125-
const config::pnode&, const config::registry&, \
126-
const config::type_descriptor&)
127-
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ISAI_ILU_TRUE_PARSE);
64+
65+
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_PARSE_FALSE);
66+
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_PARSE_TRUE);
12867

12968

13069
} // namespace detail
70+
71+
72+
// only instantiate the value type variants of ILU, whose solver is LinOp.
73+
#define GKO_DECLARE_ILU_FALSE(ValueType, IndexType) \
74+
class Ilu<ValueType, ValueType, false, IndexType>
75+
#define GKO_DECLARE_ILU_TRUE(ValueType, IndexType) \
76+
class Ilu<ValueType, ValueType, true, IndexType>
77+
78+
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_FALSE);
79+
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ILU_TRUE);
80+
81+
13182
} // namespace preconditioner
13283
} // namespace gko

core/test/config/preconditioner.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ struct Ilu
119119
static void change_template(pnode::map_type& config_map)
120120
{
121121
config_map["value_type"] = pnode{"float32"};
122-
config_map["l_solver_type"] = pnode{"solver::Ir"};
123122
config_map["reverse_apply"] = pnode{true};
124123
}
125124

@@ -129,24 +128,24 @@ struct Ilu
129128
{
130129
if (from_reg) {
131130
config_map["l_solver"] = pnode{"l_solver"};
132-
param.with_l_solver(detail::registry_accessor::get_data<
133-
typename changed_type::l_solver_type::Factory>(
134-
reg, "l_solver"));
131+
param.with_l_solver(
132+
detail::registry_accessor::get_data<gko::LinOpFactory>(
133+
reg, "l_solver"));
135134
config_map["u_solver"] = pnode{"u_solver"};
136-
param.with_u_solver(detail::registry_accessor::get_data<
137-
typename changed_type::u_solver_type::Factory>(
138-
reg, "u_solver"));
135+
param.with_u_solver(
136+
detail::registry_accessor::get_data<gko::LinOpFactory>(
137+
reg, "u_solver"));
139138
config_map["factorization"] = pnode{"factorization"};
140139
param.with_factorization(
141140
detail::registry_accessor::get_data<gko::LinOpFactory>(
142141
reg, "factorization"));
143142
} else {
144143
config_map["l_solver"] = pnode{{{"type", pnode{"solver::Ir"}},
145144
{"value_type", pnode{"float32"}}}};
146-
param.with_l_solver(changed_type::l_solver_type::build().on(exec));
145+
param.with_l_solver(DummyIr::build().on(exec));
147146
config_map["u_solver"] = pnode{{{"type", pnode{"solver::Ir"}},
148147
{"value_type", pnode{"float32"}}}};
149-
param.with_u_solver(changed_type::u_solver_type::build().on(exec));
148+
param.with_u_solver(DummyIr::build().on(exec));
150149
config_map["factorization"] =
151150
pnode{{{"type", pnode{"solver::Ir"}},
152151
{"value_type", pnode{"float32"}}}};

0 commit comments

Comments
 (0)