Skip to content

Commit

Permalink
add core test
Browse files Browse the repository at this point in the history
  • Loading branch information
yhmtsai committed Jun 23, 2020
1 parent 85cb2f0 commit e5e9f6c
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 9 deletions.
233 changes: 232 additions & 1 deletion core/test/multigrid/amgx_pgm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,235 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "core/test/utils.hpp"


namespace {} // namespace
namespace {


template <typename ValueIndexType>
class AmgxPgm : public ::testing::Test {
protected:
using value_type =
typename std::tuple_element<0, decltype(ValueIndexType())>::type;
using index_type =
typename std::tuple_element<1, decltype(ValueIndexType())>::type;
using Mtx = gko::matrix::Csr<value_type, index_type>;
using Vec = gko::matrix::Dense<value_type>;
using RestrictProlong = gko::multigrid::AmgxPgm<value_type, index_type>;
using T = value_type;
AmgxPgm()
: exec(gko::ReferenceExecutor::create()),
amgxpgm_factory(RestrictProlong::build()
.with_max_iterations(2u)
.with_max_unassigned_percentage(0.1)
.on(exec)),
mtx(Mtx::create(exec, gko::dim<2>(5, 5), 15,
std::make_shared<typename Mtx::classical>())),
agg(exec, 5),
coarse(Mtx::create(exec, gko::dim<2>(2, 2), 4,
std::make_shared<typename Mtx::classical>()))

{
this->create_mtx(mtx.get(), &agg, coarse.get());
rstr_prlg = amgxpgm_factory->generate(mtx);
}

void create_mtx(Mtx *fine, gko::Array<index_type> *agg, Mtx *coarse)
{
auto f_vals = fine->get_values();
auto f_cols = fine->get_col_idxs();
auto f_rows = fine->get_row_ptrs();
auto c_vals = coarse->get_values();
auto c_cols = coarse->get_col_idxs();
auto c_rows = coarse->get_row_ptrs();
auto agg_val = agg->get_data();
/* this matrix is stored:
* 5 -3 -3 0 0
* -3 5 0 -2 -1
* -3 0 5 0 -1
* 0 -3 0 5 0
* 0 -2 -2 0 5
*/
f_vals[0] = 5;
f_vals[1] = -3;
f_vals[2] = -3;
f_vals[3] = -3;
f_vals[4] = 5;
f_vals[5] = -2;
f_vals[6] = -1;
f_vals[7] = -3;
f_vals[8] = 5;
f_vals[9] = -1;
f_vals[10] = -3;
f_vals[11] = 5;
f_vals[12] = -2;
f_vals[13] = -2;
f_vals[14] = 5;

f_rows[0] = 0;
f_rows[1] = 3;
f_rows[2] = 7;
f_rows[3] = 10;
f_rows[4] = 12;
f_rows[5] = 15;

f_cols[0] = 0;
f_cols[1] = 1;
f_cols[2] = 2;
f_cols[3] = 0;
f_cols[4] = 1;
f_cols[5] = 3;
f_cols[6] = 4;
f_cols[7] = 0;
f_cols[8] = 2;
f_cols[9] = 4;
f_cols[10] = 1;
f_cols[11] = 3;
f_cols[12] = 1;
f_cols[13] = 2;
f_cols[14] = 4;

agg_val[0] = 0;
agg_val[1] = 1;
agg_val[2] = 0;
agg_val[3] = 1;
agg_val[4] = 0;
/* this coarse is stored:
* 6 -5
* -4 5
*/
c_vals[0] = 6;
c_vals[1] = -5;
c_vals[2] = -4;
c_vals[3] = 5;

c_rows[0] = 0;
c_rows[1] = 2;
c_rows[2] = 4;

c_cols[0] = 0;
c_cols[1] = 1;
c_cols[2] = 0;
c_cols[3] = 1;
}

static void assert_same_matrices(const Mtx *m1, const Mtx *m2)
{
ASSERT_EQ(m1->get_size()[0], m2->get_size()[0]);
ASSERT_EQ(m1->get_size()[1], m2->get_size()[1]);
ASSERT_EQ(m1->get_num_stored_elements(), m2->get_num_stored_elements());
for (gko::size_type i = 0; i < m1->get_size() + 1; i++) {
ASSERT_EQ(m1->get_const_row_ptrs()[i], m2->get_const_row_ptrs()[i]);
}
for (gko::size_type i = 0; i < m1->get_num_stored_elements(); ++i) {
EXPECT_EQ(m1->get_const_values()[i], m2->get_const_values()[i]);
EXPECT_EQ(m1->get_const_col_idxs()[i], m2->get_const_col_idxs()[i]);
}
}

static void assert_same_agg(const index_type *m1, const index_type *m2,
gko::size_type len)
{
for (gko::size_type i = 0; i < len; ++i) {
EXPECT_EQ(m1[i], m2[i]);
}
}

std::shared_ptr<const gko::Executor> exec;
std::shared_ptr<Mtx> mtx;
std::shared_ptr<Mtx> coarse;
gko::Array<index_type> agg;
std::unique_ptr<typename RestrictProlong::Factory> amgxpgm_factory;
std::unique_ptr<RestrictProlong> rstr_prlg;
};

TYPED_TEST_CASE(AmgxPgm, gko::test::ValueIndexTypes);


TYPED_TEST(AmgxPgm, FactoryKnowsItsExecutor)
{
ASSERT_EQ(this->amgxpgm_factory->get_executor(), this->exec);
}


TYPED_TEST(AmgxPgm, CanBeCopied)
{
using Mtx = typename TestFixture::Mtx;
using RestrictProlong = typename TestFixture::RestrictProlong;
auto copy = this->amgxpgm_factory->generate(Mtx::create(this->exec));

// copy->copy_from(this->rstr_prlg.get());

// auto copy_mtx =
// static_cast<RestrictProlong *>(copy.get())->get_system_matrix();
// auto copy_agg = static_cast<RestrictProlong
// *>(copy.get())->get_const_agg(); auto copy_coarse =
// copy->get_coarse_operator();

// this->assert_same_matrices(static_cast<const Mtx *>(copy_mtx.get()),
// this->mtx.get());
// this->assert_same_agg(copy_agg, this->agg.get_data(),
// this->agg.get_num_elems()); this->assert_same_matrices(static_cast<const
// Mtx *>(copy_coarse.get()), this->coarse.get());
}


TYPED_TEST(AmgxPgm, CanBeMoved)
{
using Mtx = typename TestFixture::Mtx;
using RestrictProlong = typename TestFixture::RestrictProlong;
auto copy = this->amgxpgm_factory->generate(Mtx::create(this->exec));

copy->copy_from(std::move(this->rstr_prlg));

auto copy_mtx =
static_cast<RestrictProlong *>(copy.get())->get_system_matrix();
auto copy_agg = static_cast<RestrictProlong *>(copy.get())->get_const_agg();
auto copy_coarse = copy->get_coarse_operator();

this->assert_same_matrices(static_cast<const Mtx *>(copy_mtx.get()),
this->mtx.get());
this->assert_same_agg(copy_agg, this->agg.get_data(),
this->agg.get_num_elems());
this->assert_same_matrices(static_cast<const Mtx *>(copy_coarse.get()),
this->coarse.get());
}


TYPED_TEST(AmgxPgm, CanBeCloned)
{
using Mtx = typename TestFixture::Mtx;
using RestrictProlong = typename TestFixture::RestrictProlong;
auto copy = this->amgxpgm_factory->generate(Mtx::create(this->exec));

auto clone = this->rstr_prlg->clone();

auto clone_mtx =
static_cast<RestrictProlong *>(clone.get())->get_system_matrix();
auto clone_agg =
static_cast<RestrictProlong *>(clone.get())->get_const_agg();
auto clone_coarse = clone->get_coarse_operator();

this->assert_same_matrices(static_cast<const Mtx *>(clone_mtx.get()),
this->mtx.get());
this->assert_same_agg(clone_agg, this->agg.get_data(),
this->agg.get_num_elems());
this->assert_same_matrices(static_cast<const Mtx *>(clone_coarse.get()),
this->coarse.get());
}


TYPED_TEST(AmgxPgm, CanBeCleared)
{
using RestrictProlong = typename TestFixture::RestrictProlong;
this->rstr_prlg->clear();

auto mtx = static_cast<RestrictProlong *>(this->rstr_prlg.get())
->get_system_matrix();
auto coarse = this->rstr_prlg->get_coarse_operator();
auto agg = static_cast<RestrictProlong *>(this->rstr_prlg.get())->get_agg();
ASSERT_EQ(mtx, nullptr);
ASSERT_EQ(coarse, nullptr);
ASSERT_EQ(agg, nullptr);
}


} // namespace
8 changes: 6 additions & 2 deletions include/ginkgo/core/multigrid/amgx_pgm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ namespace multigrid {
/**
* Amgx parallel graph match (AmgxPgm) is the aggregate method introduced in the
* paper M. Naumov et al., "AmgX: A Library for GPU Accelerated Algebraic
* Multigrid and Preconditioned Iterative Methods"
* Multigrid and Preconditioned Iterative Methods". Current implemenation only
* contains size = 2 version.
*
* AmgxPgm creates the aggreagate group according to the matrix value not the
* structure.
Expand Down Expand Up @@ -134,7 +135,10 @@ class AmgxPgm : public EnableRestrictProlong<AmgxPgm<ValueType, IndexType>> {
system_matrix_{std::move(system_matrix)},
agg_(factory->get_executor(), system_matrix_->get_size()[0])
{
this->generate();
if (system_matrix_->get_size()[0] != 0) {
// generate on the existed matrix
this->generate();
}
}

void generate();
Expand Down
12 changes: 6 additions & 6 deletions reference/test/multigrid/amgx_pgm_kernels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ class AmgxPgm : public ::testing::Test {
typename std::tuple_element<1, decltype(ValueIndexType())>::type;
using Mtx = gko::matrix::Csr<value_type, index_type>;
using Vec = gko::matrix::Dense<value_type>;
using Multigrid = gko::multigrid::AmgxPgm<value_type, index_type>;
using RestrictProlong = gko::multigrid::AmgxPgm<value_type, index_type>;
using T = value_type;
AmgxPgm()
: exec(gko::ReferenceExecutor::create()),
AmgxPgm_factory(Multigrid::build()
Amgxpgm_factory(RestrictProlong::build()
.with_max_iterations(2u)
.with_max_unassigned_percentage(0.1)
.on(exec)),
Expand Down Expand Up @@ -174,7 +174,7 @@ class AmgxPgm : public ::testing::Test {
std::shared_ptr<Vec> restrict_ans;
std::shared_ptr<Vec> prolong_ans;
std::shared_ptr<Vec> fine_x;
std::unique_ptr<typename Multigrid::Factory> AmgxPgm_factory;
std::unique_ptr<typename RestrictProlong::Factory> Amgxpgm_factory;
};

TYPED_TEST_CASE(AmgxPgm, gko::test::ValueIndexTypes);
Expand Down Expand Up @@ -269,7 +269,7 @@ TYPED_TEST(AmgxPgm, Renumber)

TYPED_TEST(AmgxPgm, Generate)
{
auto coarse_fine = this->AmgxPgm_factory->generate(this->mtx);
auto coarse_fine = this->Amgxpgm_factory->generate(this->mtx);

auto agg_result = coarse_fine->get_const_agg();

Expand All @@ -284,7 +284,7 @@ TYPED_TEST(AmgxPgm, Generate)
TYPED_TEST(AmgxPgm, CoarseFineRestrictApply)
{
std::unique_ptr<gko::multigrid::RestrictProlong> amgx_pgm{
this->AmgxPgm_factory->generate(this->mtx)};
this->Amgxpgm_factory->generate(this->mtx)};

// fine->coarse
using Vec = typename TestFixture::Vec;
Expand All @@ -299,7 +299,7 @@ TYPED_TEST(AmgxPgm, CoarseFineRestrictApply)
TYPED_TEST(AmgxPgm, CoarseFineProlongApplyadd)
{
std::unique_ptr<gko::multigrid::RestrictProlong> amgx_pgm{
this->AmgxPgm_factory->generate(this->mtx)};
this->Amgxpgm_factory->generate(this->mtx)};

using value_type = typename TestFixture::value_type;
auto x = gko::clone(this->fine_x);
Expand Down

0 comments on commit e5e9f6c

Please sign in to comment.