From 69f93791b6747c149ee92c4d5273b94bdacf7f56 Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Sun, 15 Oct 2023 19:49:54 +0200 Subject: [PATCH 1/2] add factorization unpack functions --- core/factorization/factorization.cpp | 74 ++++++++++++++++++- .../test/factorization/factorization.cpp | 45 +++++++++++ 2 files changed, 117 insertions(+), 2 deletions(-) diff --git a/core/factorization/factorization.cpp b/core/factorization/factorization.cpp index d38d18ca3e5..436359a417a 100644 --- a/core/factorization/factorization.cpp +++ b/core/factorization/factorization.cpp @@ -33,18 +33,88 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include +#include #include #include +#include "core/factorization/factorization_kernels.hpp" + + namespace gko { namespace experimental { namespace factorization { +namespace { + + +GKO_REGISTER_OPERATION(initialize_row_ptrs_l_u, + factorization::initialize_row_ptrs_l_u); +GKO_REGISTER_OPERATION(initialize_l_u, factorization::initialize_l_u); +GKO_REGISTER_OPERATION(initialize_row_ptrs_l, + factorization::initialize_row_ptrs_l); +GKO_REGISTER_OPERATION(initialize_l, factorization::initialize_l); + + +} // namespace template std::unique_ptr> -Factorization::unpack() const GKO_NOT_IMPLEMENTED; +Factorization::unpack() const +{ + const auto exec = this->get_executor(); + const auto size = this->get_size(); + switch (this->get_storage_type()) { + case storage_type::empty: + GKO_NOT_SUPPORTED(nullptr); + case storage_type::composition: + case storage_type::symm_composition: + return this->clone(); + case storage_type::combined_lu: { + // count nonzeros + array l_row_ptrs{exec, size[0] + 1}; + array u_row_ptrs{exec, size[0] + 1}; + const auto mtx = this->get_combined(); + exec->run(make_initialize_row_ptrs_l_u(mtx.get(), l_row_ptrs.get_data(), + u_row_ptrs.get_data())); + const auto l_nnz = static_cast( + exec->copy_val_to_host(l_row_ptrs.get_const_data() + size[0])); + const auto u_nnz = static_cast( + exec->copy_val_to_host(u_row_ptrs.get_const_data() + size[0])); + // create matrices + auto l_mtx = matrix_type::create( + exec, size, array{exec, l_nnz}, + array{exec, l_nnz}, std::move(l_row_ptrs)); + auto u_mtx = matrix_type::create( + exec, size, array{exec, u_nnz}, + array{exec, u_nnz}, std::move(u_row_ptrs)); + // fill matrices + exec->run(make_initialize_l_u(mtx.get(), l_mtx.get(), u_mtx.get())); + return create_from_composition( + composition_type::create(std::move(l_mtx), std::move(u_mtx))); + } + case storage_type::symm_combined_cholesky: { + // count nonzeros + array l_row_ptrs{exec, size[0] + 1}; + const auto mtx = this->get_combined(); + exec->run(make_initialize_row_ptrs_l(mtx.get(), l_row_ptrs.get_data())); + const auto l_nnz = static_cast( + exec->copy_val_to_host(l_row_ptrs.get_const_data() + size[0])); + // create matrices + auto l_mtx = matrix_type::create( + exec, size, array{exec, l_nnz}, + array{exec, l_nnz}, std::move(l_row_ptrs)); + // fill matrices + exec->run(make_initialize_l(mtx.get(), l_mtx.get(), false)); + auto u_mtx = l_mtx->conj_transpose(); + return create_from_symm_composition( + composition_type::create(std::move(l_mtx), std::move(u_mtx))); + } + case storage_type::combined_ldu: + case storage_type::symm_combined_ldl: + GKO_NOT_IMPLEMENTED; + } +} template @@ -58,7 +128,7 @@ template std::shared_ptr> Factorization::get_lower_factor() const { - switch (storage_type_) { + switch (this->get_storage_type()) { case storage_type::composition: case storage_type::symm_composition: GKO_ASSERT(factors_->get_operators().size() == 2 || diff --git a/reference/test/factorization/factorization.cpp b/reference/test/factorization/factorization.cpp index d9928491771..6abfd470385 100644 --- a/reference/test/factorization/factorization.cpp +++ b/reference/test/factorization/factorization.cpp @@ -71,9 +71,13 @@ class Factorization : public ::testing::Test { : ref(gko::ReferenceExecutor::create()), lower_mtx{gko::initialize( {{1.0, 0.0, 0.0}, {3.0, 1.0, 0.0}, {1.0, 2.0, 1.0}}, ref)}, + lower_cholesky_mtx{gko::initialize( + {{1.0, 0.0, 0.0}, {3.0, -1.0, 0.0}, {1.0, 2.0, 5.0}}, ref)}, diagonal{diag_type::create(ref, 3)}, upper_mtx(gko::initialize( {{1.0, 2.0, 1.0}, {0.0, 1.0, 3.0}, {0.0, 0.0, 1.0}}, ref)), + upper_nonunit_mtx(gko::initialize( + {{1.0, 2.0, 1.0}, {0.0, -1.0, 3.0}, {0.0, 0.0, 5.0}}, ref)), combined_mtx(gko::initialize( {{1.0, 2.0, 1.0}, {3.0, -1.0, 3.0}, {1.0, 2.0, 5.0}}, ref)), input(gko::initialize({1.0, 2.0, 3.0}, ref)), @@ -88,8 +92,10 @@ class Factorization : public ::testing::Test { std::shared_ptr ref; std::shared_ptr lower_mtx; + std::shared_ptr lower_cholesky_mtx; std::shared_ptr diagonal; std::shared_ptr upper_mtx; + std::shared_ptr upper_nonunit_mtx; std::shared_ptr combined_mtx; std::shared_ptr input; std::shared_ptr output; @@ -261,6 +267,45 @@ TYPED_TEST(Factorization, CreateSymmCombinedLDLWorks) } +TYPED_TEST(Factorization, UnpackCombinedLUWorks) +{ + using factorization_type = typename TestFixture::factorization_type; + auto fact = factorization_type::create_from_combined_lu( + this->combined_mtx->clone()); + + auto separated = fact->unpack(); + + ASSERT_EQ(separated->get_storage_type(), + gko::experimental::factorization::storage_type::composition); + ASSERT_EQ(separated->get_combined(), nullptr); + ASSERT_EQ(separated->get_diagonal(), nullptr); + GKO_ASSERT_MTX_NEAR(separated->get_lower_factor(), this->lower_mtx, 0.0); + GKO_ASSERT_MTX_NEAR(separated->get_upper_factor(), this->upper_nonunit_mtx, + 0.0); +} + + +TYPED_TEST(Factorization, UnpackSymmCombinedCholeskyWorks) +{ + using matrix_type = typename TestFixture::matrix_type; + using factorization_type = typename TestFixture::factorization_type; + auto fact = factorization_type::create_from_combined_cholesky( + this->combined_mtx->clone()); + + auto separated = fact->unpack(); + + ASSERT_EQ(separated->get_storage_type(), + gko::experimental::factorization::storage_type::symm_composition); + ASSERT_EQ(separated->get_combined(), nullptr); + ASSERT_EQ(separated->get_diagonal(), nullptr); + GKO_ASSERT_MTX_NEAR(separated->get_lower_factor(), this->lower_cholesky_mtx, + 0.0); + GKO_ASSERT_MTX_NEAR( + separated->get_upper_factor(), + gko::as(this->lower_cholesky_mtx->conj_transpose()), 0.0); +} + + TYPED_TEST(Factorization, ApplyFromCompositionWorks) { using factorization_type = typename TestFixture::factorization_type; From 22ae5bb97ff4395d8fdb77a4534d5d9ab693ba4d Mon Sep 17 00:00:00 2001 From: Tobias Ribizel Date: Mon, 16 Oct 2023 11:06:00 +0200 Subject: [PATCH 2/2] test composition unpacking --- .../test/factorization/factorization.cpp | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/reference/test/factorization/factorization.cpp b/reference/test/factorization/factorization.cpp index 6abfd470385..2f8231f1da7 100644 --- a/reference/test/factorization/factorization.cpp +++ b/reference/test/factorization/factorization.cpp @@ -306,6 +306,48 @@ TYPED_TEST(Factorization, UnpackSymmCombinedCholeskyWorks) } +TYPED_TEST(Factorization, UnpackCompositionWorks) +{ + using factorization_type = typename TestFixture::factorization_type; + using composition_type = typename TestFixture::composition_type; + auto fact = factorization_type::create_from_composition( + composition_type::create(this->lower_mtx, this->upper_nonunit_mtx)); + + auto separated = fact->unpack(); + + ASSERT_EQ(separated->get_storage_type(), + gko::experimental::factorization::storage_type::composition); + ASSERT_EQ(separated->get_combined(), nullptr); + ASSERT_EQ(separated->get_diagonal(), nullptr); + GKO_ASSERT_MTX_NEAR(separated->get_lower_factor(), this->lower_mtx, 0.0); + GKO_ASSERT_MTX_NEAR(separated->get_upper_factor(), this->upper_nonunit_mtx, + 0.0); +} + + +TYPED_TEST(Factorization, UnpackSymmCompositionWorks) +{ + using matrix_type = typename TestFixture::matrix_type; + using factorization_type = typename TestFixture::factorization_type; + using composition_type = typename TestFixture::composition_type; + auto fact = factorization_type::create_from_symm_composition( + composition_type::create(this->lower_cholesky_mtx, + this->lower_cholesky_mtx->conj_transpose())); + + auto separated = fact->unpack(); + + ASSERT_EQ(separated->get_storage_type(), + gko::experimental::factorization::storage_type::symm_composition); + ASSERT_EQ(separated->get_combined(), nullptr); + ASSERT_EQ(separated->get_diagonal(), nullptr); + GKO_ASSERT_MTX_NEAR(separated->get_lower_factor(), this->lower_cholesky_mtx, + 0.0); + GKO_ASSERT_MTX_NEAR( + separated->get_upper_factor(), + gko::as(this->lower_cholesky_mtx->conj_transpose()), 0.0); +} + + TYPED_TEST(Factorization, ApplyFromCompositionWorks) { using factorization_type = typename TestFixture::factorization_type;