Skip to content

Commit

Permalink
keep preconditioner ic/ilu header-only but throw in other cases
Browse files Browse the repository at this point in the history
  • Loading branch information
yhmtsai committed May 27, 2024
1 parent 82f8a21 commit aac40f1
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 66 deletions.
65 changes: 41 additions & 24 deletions core/preconditioner/ic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ginkgo/core/config/config.hpp>
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/preconditioner/isai.hpp>
#include <ginkgo/core/preconditioner/parse_limit.hpp>
#include <ginkgo/core/solver/gmres.hpp>
#include <ginkgo/core/solver/ir.hpp>

Expand All @@ -19,20 +20,22 @@

namespace gko {
namespace preconditioner {
namespace detail {


template <typename LSolverType, typename IndexType>
typename Ic<LSolverType, IndexType>::parameters_type
Ic<LSolverType, IndexType>::parse(const config::pnode& config,
const config::registry& context,
const config::type_descriptor& td_for_child)
template <
typename Ic,
std::enable_if_t<support_ic_parse<typename Ic::l_solver_type>>* = nullptr>
typename Ic::parameters_type ic_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
auto params = preconditioner::Ic<LSolverType, IndexType>::build();
auto params = Ic::build();

if (auto& obj = config.get("l_solver")) {
params.with_l_solver(
gko::config::parse_or_get_specific_factory<const LSolverType>(
obj, context, td_for_child));
gko::config::parse_or_get_specific_factory<
const typename Ic::l_solver_type>(obj, context, td_for_child));
}
if (auto& obj = config.get("factorization")) {
params.with_factorization(
Expand All @@ -43,22 +46,36 @@ Ic<LSolverType, IndexType>::parse(const config::pnode& config,
return params;
}

#define GKO_DECLARE_LOWERTRS_IC(ValueType, IndexType) \
class Ic<solver::LowerTrs<ValueType, IndexType>, IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWERTRS_IC);

#define GKO_DECLARE_IR_IC(ValueType, IndexType) \
class Ic<solver::Ir<ValueType>, IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_IC);

#define GKO_DECLARE_GMRES_IC(ValueType, IndexType) \
class Ic<solver::Gmres<ValueType>, IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GMRES_IC);

#define GKO_DECLARE_LOWERISAI_IC(ValueType, IndexType) \
class Ic<preconditioner::LowerIsai<ValueType, IndexType>, IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWERISAI_IC);


#define GKO_DECLARE_LOWERTRS_IC_PARSE(ValueType, IndexType) \
typename Ic<solver::LowerTrs<ValueType, IndexType>, \
IndexType>::parameters_type \
ic_parse<Ic<solver::LowerTrs<ValueType, IndexType>, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWERTRS_IC_PARSE);

#define GKO_DECLARE_IR_IC_PARSE(ValueType, IndexType) \
typename Ic<solver::Ir<ValueType>, IndexType>::parameters_type \
ic_parse<Ic<solver::Ir<ValueType>, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_IC_PARSE);

#define GKO_DECLARE_GMRES_IC_PARSE(ValueType, IndexType) \
typename Ic<solver::Gmres<ValueType>, IndexType>::parameters_type \
ic_parse<Ic<solver::Gmres<ValueType>, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GMRES_IC_PARSE);

#define GKO_DECLARE_LOWERISAI_IC_PARSE(ValueType, IndexType) \
typename Ic<LowerIsai<ValueType, IndexType>, IndexType>::parameters_type \
ic_parse<Ic<LowerIsai<ValueType, IndexType>, IndexType>>( \
const config::pnode&, const config::registry&, \
const config::type_descriptor&)
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWERISAI_IC_PARSE);

} // namespace detail
} // namespace preconditioner
} // namespace gko
128 changes: 88 additions & 40 deletions core/preconditioner/ilu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@

namespace gko {
namespace preconditioner {
namespace detail {


template <typename LSolverType, typename USolverType, bool ReverseApply,
typename IndexType>
typename Ilu<LSolverType, USolverType, ReverseApply, IndexType>::parameters_type
Ilu<LSolverType, USolverType, ReverseApply, IndexType>::parse(
template <
typename Ilu,
std::enable_if_t<support_ilu_parse<typename Ilu::l_solver_type,
typename Ilu::u_solver_type>>* = nullptr>
typename Ilu::parameters_type ilu_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
auto params = preconditioner::Ilu<LSolverType, USolverType, ReverseApply,
IndexType>::build();
auto params = Ilu::build();

if (auto& obj = config.get("l_solver")) {
params.with_l_solver(
gko::config::parse_or_get_specific_factory<const LSolverType>(
obj, context, td_for_child));
gko::config::parse_or_get_specific_factory<
const typename Ilu::l_solver_type>(obj, context, td_for_child));
}
if (auto& obj = config.get("u_solver")) {
params.with_u_solver(
gko::config::parse_or_get_specific_factory<const USolverType>(
obj, context, td_for_child));
gko::config::parse_or_get_specific_factory<
const typename Ilu::u_solver_type>(obj, context, td_for_child));
}
if (auto& obj = config.get("factorization")) {
params.with_factorization(
Expand All @@ -51,36 +52,83 @@ Ilu<LSolverType, USolverType, ReverseApply, IndexType>::parse(
return params;
}

#define GKO_DECLARE_TRS_ILU(ValueType, IndexType) \
class Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, true, IndexType>; \
template class Ilu<solver::LowerTrs<ValueType, IndexType>, \
solver::UpperTrs<ValueType, IndexType>, false, \
IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_TRS_ILU);

#define GKO_DECLARE_IR_ILU(ValueType, IndexType) \
class Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, true, IndexType>; \
template class Ilu<solver::Ir<ValueType>, solver::Ir<ValueType>, false, \
IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_IR_ILU);

#define GKO_DECLARE_GMRES_ILU(ValueType, IndexType) \
class Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, true, \
IndexType>; \
template class Ilu<solver::Gmres<ValueType>, solver::Gmres<ValueType>, \
false, IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GMRES_ILU);

#define GKO_DECLARE_ISAI_ILU(ValueType, IndexType) \
class Ilu<preconditioner::LowerIsai<ValueType, IndexType>, \
preconditioner::UpperIsai<ValueType, IndexType>, true, \
IndexType>; \
template class Ilu<preconditioner::LowerIsai<ValueType, IndexType>, \
preconditioner::UpperIsai<ValueType, IndexType>, false, \
IndexType>
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_ISAI_ILU);


#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&, \
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&, \
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);


} // namespace detail
} // namespace preconditioner
} // namespace gko
39 changes: 38 additions & 1 deletion include/ginkgo/core/preconditioner/ic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/factorization/par_ic.hpp>
#include <ginkgo/core/matrix/dense.hpp>
#include <ginkgo/core/preconditioner/isai.hpp>
#include <ginkgo/core/preconditioner/parse_limit.hpp>
#include <ginkgo/core/solver/gmres.hpp>
#include <ginkgo/core/solver/ir.hpp>
#include <ginkgo/core/solver/solver_traits.hpp>
#include <ginkgo/core/solver/triangular.hpp>
#include <ginkgo/core/stop/combined.hpp>
Expand All @@ -30,8 +34,38 @@

namespace gko {
namespace preconditioner {
namespace detail {


template <typename Type>
constexpr bool support_ic_parse =
is_instance_of<Type, solver::LowerTrs>::value ||
is_instance_of<Type, solver::Ir>::value ||
is_instance_of<Type, solver::Gmres>::value ||
is_instance_of<Type, preconditioner::LowerIsai>::value;


template <
typename Ic,
std::enable_if_t<!support_ic_parse<typename Ic::l_solver_type>>* = nullptr>
typename Ic::parameters_type ic_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
GKO_INVALID_STATE(
"preconditioner::Ic only supports limited type for parse.");
}

template <
typename Ic,
std::enable_if_t<support_ic_parse<typename Ic::l_solver_type>>* = nullptr>
typename Ic::parameters_type ic_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child);


} // namespace detail

/**
* The Incomplete Cholesky (IC) preconditioner solves the equation $LL^H*x = b$
* for a given lower triangular matrix L and the right hand side b (can contain
Expand Down Expand Up @@ -178,7 +212,10 @@ class Ic : public EnableLinOp<Ic<LSolverType, IndexType>>, public Transposable {
static parameters_type parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child =
config::make_type_descriptor<value_type, index_type>());
config::make_type_descriptor<value_type, index_type>())
{
return detail::ic_parse<Ic>(config, context, td_for_child);
}

/**
* Returns the solver which is used for the provided L matrix.
Expand Down
42 changes: 41 additions & 1 deletion include/ginkgo/core/preconditioner/ilu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/factorization/par_ilu.hpp>
#include <ginkgo/core/matrix/dense.hpp>
#include <ginkgo/core/preconditioner/isai.hpp>
#include <ginkgo/core/preconditioner/parse_limit.hpp>
#include <ginkgo/core/solver/gmres.hpp>
#include <ginkgo/core/solver/ir.hpp>
#include <ginkgo/core/solver/solver_traits.hpp>
#include <ginkgo/core/solver/triangular.hpp>
#include <ginkgo/core/stop/combined.hpp>
Expand All @@ -30,6 +34,39 @@

namespace gko {
namespace preconditioner {
namespace detail {


template <typename LSolverType, typename USolverType>
constexpr bool support_ilu_parse =
std::is_same<typename USolverType::transposed_type, LSolverType>::value &&
(is_instance_of<LSolverType, solver::LowerTrs>::value ||
is_instance_of<LSolverType, solver::Ir>::value ||
is_instance_of<LSolverType, solver::Gmres>::value ||
is_instance_of<LSolverType, preconditioner::LowerIsai>::value);


template <typename Ilu,
std::enable_if_t<!support_ilu_parse<typename Ilu::l_solver_type,
typename Ilu::u_solver_type>>* =
nullptr>
typename Ilu::parameters_type ilu_parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
GKO_INVALID_STATE(
"preconditioner::Ilu only supports limited type for parse.");
}

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

} // namespace detail


/**
Expand Down Expand Up @@ -221,7 +258,10 @@ class Ilu : public EnableLinOp<
static parameters_type parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child =
config::make_type_descriptor<value_type, index_type>());
config::make_type_descriptor<value_type, index_type>())
{
return detail::ilu_parse<Ilu>(config, context, td_for_child);
}

/**
* Returns the solver which is used for the provided L matrix.
Expand Down
Loading

0 comments on commit aac40f1

Please sign in to comment.