Skip to content

Commit

Permalink
Merge Add Schwarz config
Browse files Browse the repository at this point in the history
This pr adds the file config for schwarz preconditioner.
Moreover, it add the global_index into type_descriptor now

Related PR: #1658
  • Loading branch information
yhmtsai authored Aug 24, 2024
2 parents 70669c6 + 9335476 commit 9929854
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 40 deletions.
3 changes: 3 additions & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ set(config_source
config/registry.cpp
config/solver_config.cpp
)
if(GINKGO_BUILD_MPI)
list(APPEND config_source config/schwarz_config.cpp)
endif()
# MSVC: To solve LNK1189, we separate the library as a workaround
# To make ginkgo still be the major library, we make the original to ginkgo_core in MSVC/shared
# TODO: should think another way to solve it like dllexport or def file
Expand Down
3 changes: 2 additions & 1 deletion core/config/config_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ enum class LinOpFactoryType : int {
Isai,
Jacobi,
Multigrid,
Pgm
Pgm,
Schwarz
};


Expand Down
13 changes: 11 additions & 2 deletions core/config/registry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "ginkgo/core/config/registry.hpp"

#include <ginkgo/config.hpp>
#include <ginkgo/core/base/exception_helpers.hpp>
#include <ginkgo/core/config/config.hpp>

Expand All @@ -16,7 +17,9 @@ namespace config {

configuration_map generate_config_map()
{
return {{"solver::Cg", parse<LinOpFactoryType::Cg>},
return
{
{"solver::Cg", parse<LinOpFactoryType::Cg>},
{"solver::Bicg", parse<LinOpFactoryType::Bicg>},
{"solver::Bicgstab", parse<LinOpFactoryType::Bicgstab>},
{"solver::Fcg", parse<LinOpFactoryType::Fcg>},
Expand All @@ -42,7 +45,13 @@ configuration_map generate_config_map()
{"preconditioner::Isai", parse<LinOpFactoryType::Isai>},
{"preconditioner::Jacobi", parse<LinOpFactoryType::Jacobi>},
{"solver::Multigrid", parse<LinOpFactoryType::Multigrid>},
{"multigrid::Pgm", parse<LinOpFactoryType::Pgm>}};
{"multigrid::Pgm", parse<LinOpFactoryType::Pgm>},
#if GINKGO_BUILD_MPI
{
"preconditioner::Schwarz", parse<LinOpFactoryType::Schwarz>
}
#endif
};
}


Expand Down
52 changes: 52 additions & 0 deletions core/config/schwarz_config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

#include <ginkgo/core/config/config.hpp>
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/config/type_descriptor.hpp>
#include <ginkgo/core/distributed/preconditioner/schwarz.hpp>

#include "core/config/config_helper.hpp"
#include "core/config/dispatch.hpp"
#include "core/config/type_descriptor_helper.hpp"


namespace gko {
namespace config {


template <>
deferred_factory_parameter<gko::LinOpFactory> parse<LinOpFactoryType::Schwarz>(
const pnode& config, const registry& context, const type_descriptor& td)
{
auto updated = update_type(config, td);
// We can not directly dispatch the global index type without consider local
// index type, which leads the invalid index type <int64, int32> in
// compile time.
if (updated.get_index_typestr() == type_string<int32>::str()) {
return dispatch<
gko::LinOpFactory,
gko::experimental::distributed::preconditioner::Schwarz>(
config, context, updated,
make_type_selector(updated.get_value_typestr(), value_type_list()),
make_type_selector(updated.get_index_typestr(),
syn::type_list<int32>()),
make_type_selector(updated.get_global_index_typestr(),
index_type_list()));
} else {
return dispatch<
gko::LinOpFactory,
gko::experimental::distributed::preconditioner::Schwarz>(
config, context, updated,
make_type_selector(updated.get_value_typestr(), value_type_list()),
make_type_selector(updated.get_index_typestr(),
syn::type_list<int64>()),
make_type_selector(updated.get_global_index_typestr(),
syn::type_list<int64>()));
}
}


} // namespace config
} // namespace gko
58 changes: 38 additions & 20 deletions core/config/type_descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "ginkgo/core/config/type_descriptor.hpp"

#include <ginkgo/core/base/exception_helpers.hpp>
#include <ginkgo/core/base/types.hpp>

#include "core/config/type_descriptor_helper.hpp"

Expand All @@ -17,6 +18,7 @@ type_descriptor update_type(const pnode& config, const type_descriptor& td)
{
auto value_typestr = td.get_value_typestr();
auto index_typestr = td.get_index_typestr();
auto global_index_typestr = td.get_global_index_typestr();

if (auto& obj = config.get("value_type")) {
value_typestr = obj.get_string();
Expand All @@ -26,37 +28,44 @@ type_descriptor update_type(const pnode& config, const type_descriptor& td)
"Setting index_type in the config is not allowed. Please set the "
"proper index_type through type_descriptor of parse");
}
return type_descriptor{value_typestr, index_typestr};
if (auto& obj = config.get("global_index_type")) {
GKO_INVALID_STATE(
"Setting global_index_type in the config is not allowed. Please "
"set the proper global_index_type through type_descriptor of "
"parse");
}
return type_descriptor{value_typestr, index_typestr, global_index_typestr};
}


template <typename ValueType, typename IndexType>
template <typename ValueType, typename IndexType, typename GlobalIndexType>
type_descriptor make_type_descriptor()
{
return type_descriptor{type_string<ValueType>::str(),
type_string<IndexType>::str()};
type_string<IndexType>::str(),
type_string<GlobalIndexType>::str()};
}

template type_descriptor make_type_descriptor<void, void>();
template type_descriptor make_type_descriptor<float, void>();
template type_descriptor make_type_descriptor<double, void>();
template type_descriptor make_type_descriptor<std::complex<float>, void>();
template type_descriptor make_type_descriptor<std::complex<double>, void>();
template type_descriptor make_type_descriptor<void, int32>();
template type_descriptor make_type_descriptor<float, int32>();
template type_descriptor make_type_descriptor<double, int32>();
template type_descriptor make_type_descriptor<std::complex<float>, int32>();
template type_descriptor make_type_descriptor<std::complex<double>, int32>();
template type_descriptor make_type_descriptor<void, int64>();
template type_descriptor make_type_descriptor<float, int64>();
template type_descriptor make_type_descriptor<double, int64>();
template type_descriptor make_type_descriptor<std::complex<float>, int64>();
template type_descriptor make_type_descriptor<std::complex<double>, int64>();
#define GKO_DECLARE_MAKE_TYPE_DESCRIPTOR(ValueType, LocalIndexType, \
GlobalIndexType) \
type_descriptor \
make_type_descriptor<ValueType, LocalIndexType, GlobalIndexType>()
GKO_INSTANTIATE_FOR_EACH_VALUE_AND_LOCAL_GLOBAL_INDEX_TYPE(
GKO_DECLARE_MAKE_TYPE_DESCRIPTOR);

#define GKO_DECLARE_MAKE_VOID_TYPE_DESCRIPTOR(LocalIndexType, GlobalIndexType) \
type_descriptor \
make_type_descriptor<void, LocalIndexType, GlobalIndexType>()
GKO_INSTANTIATE_FOR_EACH_LOCAL_GLOBAL_INDEX_TYPE(
GKO_DECLARE_MAKE_VOID_TYPE_DESCRIPTOR);


type_descriptor::type_descriptor(std::string value_typestr,
std::string index_typestr)
: value_typestr_(value_typestr), index_typestr_(index_typestr)
std::string index_typestr,
std::string global_index_typestr)
: value_typestr_(value_typestr),
index_typestr_(index_typestr),
global_index_typestr_(global_index_typestr)
{}

const std::string& type_descriptor::get_value_typestr() const
Expand All @@ -69,6 +78,15 @@ const std::string& type_descriptor::get_index_typestr() const
return index_typestr_;
}

const std::string& type_descriptor::get_local_index_typestr() const
{
return this->get_index_typestr();
}

const std::string& type_descriptor::get_global_index_typestr() const
{
return global_index_typestr_;
}

} // namespace config
} // namespace gko
26 changes: 26 additions & 0 deletions core/distributed/preconditioner/schwarz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
#include <ginkgo/core/base/precision_dispatch.hpp>
#include <ginkgo/core/base/temporary_conversion.hpp>
#include <ginkgo/core/base/utils.hpp>
#include <ginkgo/core/config/config.hpp>
#include <ginkgo/core/config/registry.hpp>
#include <ginkgo/core/distributed/matrix.hpp>
#include <ginkgo/core/matrix/csr.hpp>
#include <ginkgo/core/matrix/dense.hpp>

#include "core/base/utils.hpp"
#include "core/config/config_helper.hpp"
#include "core/config/dispatch.hpp"
#include "core/distributed/helpers.hpp"


Expand All @@ -26,6 +30,28 @@ namespace distributed {
namespace preconditioner {


template <typename ValueType, typename LocalIndexType, typename GlobalIndexType>
typename Schwarz<ValueType, LocalIndexType, GlobalIndexType>::parameters_type
Schwarz<ValueType, LocalIndexType, GlobalIndexType>::parse(
const config::pnode& config, const config::registry& context,
const config::type_descriptor& td_for_child)
{
auto params = Schwarz<ValueType, LocalIndexType, GlobalIndexType>::build();

if (auto& obj = config.get("generated_local_solver")) {
params.with_generated_local_solver(
gko::config::get_stored_obj<const LinOp>(obj, context));
}
if (auto& obj = config.get("local_solver")) {
params.with_local_solver(
gko::config::parse_or_get_factory<const LinOpFactory>(
obj, context, td_for_child));
}

return params;
}


template <typename ValueType, typename LocalIndexType, typename GlobalIndexType>
void Schwarz<ValueType, LocalIndexType, GlobalIndexType>::apply_impl(
const LinOp* b, LinOp* x) const
Expand Down
1 change: 1 addition & 0 deletions core/test/config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ ginkgo_create_test(preconditioner)
ginkgo_create_test(property_tree)
ginkgo_create_test(registry)
ginkgo_create_test(solver)
ginkgo_create_test(type_descriptor)
74 changes: 73 additions & 1 deletion core/test/config/preconditioner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@

#include <gtest/gtest.h>

#include <ginkgo/config.hpp>
#include <ginkgo/core/base/executor.hpp>
#include <ginkgo/core/config/config.hpp>
#include <ginkgo/core/distributed/preconditioner/schwarz.hpp>
#include <ginkgo/core/matrix/dense.hpp>
#include <ginkgo/core/preconditioner/ic.hpp>
#include <ginkgo/core/preconditioner/ilu.hpp>
#include <ginkgo/core/preconditioner/isai.hpp>
Expand Down Expand Up @@ -297,6 +300,68 @@ struct Jacobi
};


#if GINKGO_BUILD_MPI


struct Schwarz
: PreconditionerConfigTest<
::gko::experimental::distributed::preconditioner::Schwarz<float, int,
gko::int64>,
::gko::experimental::distributed::preconditioner::Schwarz<
double, int, gko::int64>> {
static pnode::map_type setup_base()
{
return {{"type", pnode{"preconditioner::Schwarz"}}};
}

static void change_template(pnode::map_type& config_map)
{
config_map["value_type"] = pnode{"float32"};
}

template <bool from_reg, typename ParamType>
static void set(pnode::map_type& config_map, ParamType& param, registry reg,
std::shared_ptr<const gko::Executor> exec)
{
if (from_reg) {
config_map["local_solver"] = pnode{"solver"};
param.with_local_solver(
detail::registry_accessor::get_data<gko::LinOpFactory>(
reg, "solver"));
} else {
config_map["local_solver"] =
pnode{{{"type", pnode{"solver::Ir"}},
{"value_type", pnode{"float32"}}}};
param.with_local_solver(DummyIr::build().on(exec));
}
config_map["generated_local_solver"] = pnode{"linop"};
param.with_generated_local_solver(
detail::registry_accessor::get_data<gko::LinOp>(reg, "linop"));
}

template <bool from_reg, typename AnswerType>
static void validate(gko::LinOpFactory* result, AnswerType* answer)
{
auto res_param = gko::as<AnswerType>(result)->get_parameters();
auto ans_param = answer->get_parameters();

if (from_reg) {
ASSERT_EQ(res_param.local_solver, ans_param.local_solver);
} else {
ASSERT_NE(
std::dynamic_pointer_cast<const typename DummyIr::Factory>(
res_param.local_solver),
nullptr);
}
ASSERT_EQ(res_param.generated_local_solver,
ans_param.generated_local_solver);
}
};


#endif // GINKGO_BUILD_MPI


template <typename T>
class Preconditioner : public ::testing::Test {
protected:
Expand All @@ -309,12 +374,14 @@ class Preconditioner : public ::testing::Test {
l_solver(DummyIr::build().on(exec)),
u_solver(DummyIr::build().on(exec)),
factorization(DummyIr::build().on(exec)),
linop(gko::matrix::Dense<>::create(exec)),
reg()
{
reg.emplace("solver", solver_factory);
reg.emplace("l_solver", l_solver);
reg.emplace("u_solver", u_solver);
reg.emplace("factorization", factorization);
reg.emplace("linop", linop);
}

std::shared_ptr<const gko::Executor> exec;
Expand All @@ -323,11 +390,16 @@ class Preconditioner : public ::testing::Test {
std::shared_ptr<typename DummyIr::Factory> l_solver;
std::shared_ptr<typename DummyIr::Factory> u_solver;
std::shared_ptr<typename DummyIr::Factory> factorization;
std::shared_ptr<gko::LinOp> linop;
registry reg;
};


using PreconditionerTypes = ::testing::Types<::Ic, ::Ilu, ::Isai, ::Jacobi>;
using PreconditionerTypes = ::testing::Types<
#if GINKGO_BUILD_MPI
::Schwarz,
#endif // GINKGO_BUILD_MPI
::Ic, ::Ilu, ::Isai, ::Jacobi>;


TYPED_TEST_SUITE(Preconditioner, PreconditionerTypes, TypenameNameGenerator);
Expand Down
Loading

0 comments on commit 9929854

Please sign in to comment.