diff --git a/core/preconditioner/isai.cpp b/core/preconditioner/isai.cpp index ab9b63fd9f4..80946fff8ae 100644 --- a/core/preconditioner/isai.cpp +++ b/core/preconditioner/isai.cpp @@ -310,21 +310,40 @@ Isai::conj_transpose() const } -#define GKO_DECLARE_LOWER_ISAI(ValueType, IndexType, StorageType) \ - class Isai -GKO_INSTANTIATE_FOR_EACH_VALUE_INDEX_AND_STORAGE_TYPE(GKO_DECLARE_LOWER_ISAI); - -#define GKO_DECLARE_UPPER_ISAI(ValueType, IndexType, StorageType) \ - class Isai -GKO_INSTANTIATE_FOR_EACH_VALUE_INDEX_AND_STORAGE_TYPE(GKO_DECLARE_UPPER_ISAI); - -#define GKO_DECLARE_GENERAL_ISAI(ValueType, IndexType, StorageType) \ - class Isai -GKO_INSTANTIATE_FOR_EACH_VALUE_INDEX_AND_STORAGE_TYPE(GKO_DECLARE_GENERAL_ISAI); - -#define GKO_DECLARE_SPD_ISAI(ValueType, IndexType, StorageType) \ - class Isai -GKO_INSTANTIATE_FOR_EACH_VALUE_INDEX_AND_STORAGE_TYPE(GKO_DECLARE_SPD_ISAI); +#define GKO_DECLARE_LOWER_ISAI1(ValueType, IndexType) \ + class Isai +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWER_ISAI1); + +#define GKO_DECLARE_UPPER_ISAI1(ValueType, IndexType) \ + class Isai +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_UPPER_ISAI1); + +#define GKO_DECLARE_GENERAL_ISAI1(ValueType, IndexType) \ + class Isai +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GENERAL_ISAI1); + +#define GKO_DECLARE_SPD_ISAI1(ValueType, IndexType) \ + class Isai +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_SPD_ISAI1); + +#define GKO_DECLARE_LOWER_ISAI2(ValueType, IndexType) \ + class Isai> +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_LOWER_ISAI2); + +#define GKO_DECLARE_UPPER_ISAI2(ValueType, IndexType) \ + class Isai> +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_UPPER_ISAI2); + +#define GKO_DECLARE_GENERAL_ISAI2(ValueType, IndexType) \ + class Isai> +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_GENERAL_ISAI2); + +#define GKO_DECLARE_SPD_ISAI2(ValueType, IndexType) \ + class Isai> +GKO_INSTANTIATE_FOR_EACH_VALUE_AND_INDEX_TYPE(GKO_DECLARE_SPD_ISAI2); } // namespace preconditioner diff --git a/include/ginkgo/core/base/types.hpp b/include/ginkgo/core/base/types.hpp index deb854c0718..9d99831299e 100644 --- a/include/ginkgo/core/base/types.hpp +++ b/include/ginkgo/core/base/types.hpp @@ -539,25 +539,6 @@ GKO_ATTRIBUTES constexpr bool operator!=(precision_reduction x, std::complex, int64) -#define GKO_INSTANTIATE_FOR_EACH_VALUE_INDEX_AND_STORAGE_TYPE(_macro) \ - template _macro(float, int32, float); \ - template _macro(float, int32, double); \ - template _macro(double, int32, double); \ - template _macro(double, int32, float); \ - template _macro(std::complex, int32, std::complex); \ - template _macro(std::complex, int32, std::complex); \ - template _macro(std::complex, int32, std::complex); \ - template _macro(std::complex, int32, std::complex); \ - template _macro(float, int64, float); \ - template _macro(float, int64, double); \ - template _macro(double, int64, double); \ - template _macro(double, int64, float); \ - template _macro(std::complex, int64, std::complex); \ - template _macro(std::complex, int64, std::complex); \ - template _macro(std::complex, int64, std::complex); \ - template _macro(std::complex, int64, std::complex) - - /** * Instantiates a template for each value type conversion pair compiled by * Ginkgo. diff --git a/reference/test/preconditioner/isai_kernels.cpp b/reference/test/preconditioner/isai_kernels.cpp index 75644436ae6..437e1368267 100644 --- a/reference/test/preconditioner/isai_kernels.cpp +++ b/reference/test/preconditioner/isai_kernels.cpp @@ -73,6 +73,12 @@ class Isai : public ::testing::Test { using GeneralIsai = gko::preconditioner::GeneralIsai; using SpdIsai = gko::preconditioner::SpdIsai; + using GeneralIsai2 = + gko::preconditioner::GeneralIsai>; + using SpdIsai2 = + gko::preconditioner::SpdIsai>; using Mtx = gko::matrix::Csr; using Dense = gko::matrix::Dense; using Csr = gko::matrix::Csr; @@ -201,6 +207,8 @@ class Isai : public ::testing::Test { upper_isai_factory = UpperIsai::build().on(exec); general_isai_factory = GeneralIsai::build().on(exec); spd_isai_factory = SpdIsai::build().on(exec); + general_isai_factory2 = GeneralIsai2::build().on(exec); + spd_isai_factory2 = SpdIsai2::build().on(exec); a_dense->convert_to(lend(a_csr)); a_dense_inv->convert_to(lend(a_csr_inv)); l_dense->convert_to(lend(l_csr)); @@ -268,6 +276,8 @@ class Isai : public ::testing::Test { std::unique_ptr upper_isai_factory; std::unique_ptr general_isai_factory; std::unique_ptr spd_isai_factory; + std::unique_ptr general_isai_factory2; + std::unique_ptr spd_isai_factory2; std::shared_ptr a_dense; std::shared_ptr a_dense_inv; std::shared_ptr l_dense; @@ -323,7 +333,7 @@ class Isai : public ::testing::Test { std::shared_ptr spd_sparse_inv; }; -TYPED_TEST_SUITE(Isai, gko::test::RealValueIndexTypes); +TYPED_TEST_SUITE(Isai, gko::test::ValueIndexTypes); TYPED_TEST(Isai, KernelGenerateA) @@ -1009,6 +1019,18 @@ TYPED_TEST(Isai, ReturnsCorrectInverseA) } +TYPED_TEST(Isai, ReturnsCorrectInverseAMixed) +{ + using value_type = typename TestFixture::value_type; + const auto isai = this->general_isai_factory2->generate(this->a_sparse); + + auto l_inv = isai->get_approximate_inverse(); + + GKO_ASSERT_MTX_EQ_SPARSITY(l_inv, this->a_sparse_inv); + GKO_ASSERT_MTX_NEAR(l_inv, this->a_sparse_inv, r::value); +} + + TYPED_TEST(Isai, ReturnsCorrectInverseALongrow) { using value_type = typename TestFixture::value_type; @@ -1226,6 +1248,26 @@ TYPED_TEST(Isai, ReturnsCorrectInverseSpd) } +TYPED_TEST(Isai, ReturnsCorrectInverseSpdMixed) +{ + using Csr = typename TestFixture::Csr; + using value_type = typename TestFixture::value_type; + const auto isai = this->spd_isai_factory2->generate(this->spd_sparse); + const auto expected_transpose = + gko::as(this->spd_sparse_inv->transpose()); + + // In the spd case, the approximate inverse is a composition of L^T and L. + const auto composition = isai->get_approximate_inverse()->get_operators(); + const auto lower_t = gko::as(composition[0]); + const auto lower = gko::as(composition[1]); + + GKO_ASSERT_MTX_EQ_SPARSITY(lower, this->spd_sparse_inv); + GKO_ASSERT_MTX_EQ_SPARSITY(lower_t, expected_transpose); + GKO_ASSERT_MTX_NEAR(lower, this->spd_sparse_inv, r::value); + GKO_ASSERT_MTX_NEAR(lower_t, expected_transpose, r::value); +} + + TYPED_TEST(Isai, ReturnsCorrectInverseSpdLongrow) { using Csr = typename TestFixture::Csr;