Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add full test case for variadic delayed Matrix allocation #420

Open
wants to merge 6 commits into
base: development
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 181 additions & 15 deletions dash/test/container/MatrixTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEST_F(MatrixTest, LocalAccess)
"matrix local view:", mat.local.extents());

int lcount = (myid + 1) * 1000;
dash::generate(mat.begin(), mat.end(),
dash::generate(mat.begin(), mat.end(),
[&]() {
return (lcount++);
});
Expand Down Expand Up @@ -964,11 +964,83 @@ TEST_F(MatrixTest, DelayedAlloc)
}
}
}
}

TEST_F(MatrixTest, VariadicDelayedAlloc)
{

/*
* similar test as MatrixTest.DelayedAlloc but using variadic
* delayed allocation
*/

dash::team_unit_t myid(dash::myid());
auto num_units = dash::size();

if (num_units < 4) {
LOG_MESSAGE("MatrixTest.VariadicDelayedAlloc requires at least 4 units");
return;
}

// Default constructor creates team spec with extents (nunits, 1, 1):
dash::TeamSpec<3> teamspec;
// Automatic balancing of team spec in three dimensions:
teamspec.balance_extents();

// reverse team extents
auto team_extents = teamspec.extents();
if (team_extents[0] > team_extents[2]) {
std::swap(team_extents[0], team_extents[2]);
teamspec.resize(team_extents);
}

if (myid == 0) {
DASH_LOG_TRACE_VAR("MatrixTest.VariadicDelayedAlloc", teamspec.extents());
}

// re-allocate to test variadic allocate
mx.deallocate();
auto num_units_i = teamspec.extent(0);
auto num_units_j = teamspec.extent(1);
auto num_units_k = teamspec.extent(2);

// Cartesian dimensions for row-major storage order:
// index (i,j,k) = Cartesian offset (z,y,x)
auto tilesize_i = 2;
auto tilesize_j = 5;
auto tilesize_k = 3;
auto blocksize = tilesize_i * tilesize_j * tilesize_k;
auto num_blocks_i = num_units_i > 1 ? 2 * num_units_i : 1;
auto num_blocks_j = num_units_j > 1 ? 3 * num_units_j : 1;
auto num_blocks_k = num_units_k > 1 ? 2 * num_units_k : 1;
auto extent_i = num_blocks_i * tilesize_i;
auto extent_j = num_blocks_j * tilesize_j;
auto extent_k = num_blocks_k * tilesize_k;

typedef double
value_t;
typedef dash::default_index_t
index_t;
typedef dash::default_extent_t
extent_t;
typedef dash::CartesianIndexSpace<3, dash::ROW_MAJOR, index_t>
index_space_t;

dash::barrier();
DASH_LOG_DEBUG("MatrixTest.VariadicDelayedAlloc",
"Calling dash::Matrix default constructor");

dash::Matrix<
value_t,
3,
index_t,
dash::TilePattern<3> > mx;

ASSERT_EQ_U(num_units, teamspec.size());

dash::barrier();
DASH_LOG_DEBUG("MatrixTest.DelayedAlloc",
"Calling dash::Matrix.allocate");

// Delayed allocation of matrix using variadic allocate():
mx.allocate(
extent_i,
extent_j,
Expand All @@ -978,6 +1050,100 @@ TEST_F(MatrixTest, DelayedAlloc)
dash::TILE(tilesize_k),
teamspec
);

auto pattern = mx.pattern();
auto blockspec = pattern.blockspec().extents();
auto blocksizespec = pattern.block(0).extents();
auto n_local_blocks = pattern.local_blockspec().size();
auto n_local_elem = n_local_blocks * blocksize;

DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", blockspec);
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", blocksizespec);
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", blocksize);
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", mx.local.extents());
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", mx.local.offsets());
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", n_local_blocks);
DASH_LOG_DEBUG_VAR("MatrixTest.VariadicDelayedAlloc", n_local_elem);

ASSERT_EQ_U(mx.local.size(), n_local_elem);

// Initialize values:
for (extent_t lbi = 0; lbi < n_local_blocks; ++lbi) {
// submatrix view on local block obtained from matrix relative to global
// memory space:
auto g_matrix_block = mx.local.block(lbi);
// index space view on local block obtained from pattern relative to
// global index space:
auto g_pattern_block = mx.pattern().local_block(myid, lbi);

value_t * block_lbegin = g_matrix_block.lbegin();
value_t * block_lend = g_matrix_block.lend();
DASH_LOG_DEBUG("MatrixTest.VariadicDelayedAlloc",
"local block idx:", lbi,
"block offset:", g_matrix_block.offsets(),
"block extents:", g_matrix_block.extents(),
"block lend-lbegin:", block_lend - block_lbegin);

// block views should be identical:
ASSERT_EQ_U(g_matrix_block.extents(),
g_pattern_block.extents());
ASSERT_EQ_U(g_matrix_block.offsets(),
g_pattern_block.offsets());
// element phase, canonical element offset in block:
index_t phase = 0;
for (auto lbv = block_lbegin; lbv != block_lend; ++lbv, ++phase) {
*lbv = myid + (0.01 * lbi) + (0.0001 * phase);
}
}

mx.barrier();

if (myid == 0) {
dash::test::print_matrix("Matrix<3>", mx, 4);
}

// Validate values.
// Testing view specifiers for every index explicitly, intentionally
// inefficient.
if (myid == 0) {
for (index_t i = 0; i < static_cast<index_t>(extent_i); ++i) {
for (index_t j = 0; j < static_cast<index_t>(extent_j); ++j) {
for (index_t k = 0; k < static_cast<index_t>(extent_k); ++k) {
DASH_LOG_TRACE("MatrixTest.VariadicDelayedAlloc",
"coords:", i, j, k);
// global coordinate:
std::array<index_t, 3> gcoords {{ i, j, k }};
// block index in global memory space:
auto block_index = mx.pattern().block_at(gcoords);
// block index in local memory space:
auto lbi = mx.pattern().local_block_at(gcoords).index;
// block at global block index:
auto block_extents = mx.pattern().block(block_index).extents();
auto block_i_space = index_space_t(block_extents);
auto block_unit = mx.pattern().unit_at(gcoords);
// Cartesian offsets of element in block:
std::array<index_t, 3> phase_coords {{ i % tilesize_i,
j % tilesize_j,
k % tilesize_k }};
DASH_LOG_TRACE("MatrixTest.VariadicDelayedAlloc",
"block extents:", block_extents,
"phase coords:", phase_coords);
// canonical offset of element in block:
index_t phase = block_i_space.at(phase_coords);
value_t expected = block_unit + (0.01 * lbi) + (0.0001 * phase);
value_t actual = mx[i][j][k];
DASH_LOG_TRACE("MatrixTest.VariadicDelayedAlloc",
"coords:", i, j, k,
"block index:", block_index,
"unit:", block_unit,
"phase:", phase_coords, "=", phase,
"expected:", expected,
"actual:", actual);
EXPECT_EQ_U(expected, actual);
}
}
}
}
}

TEST_F(MatrixTest, PatternScope)
Expand Down Expand Up @@ -1119,7 +1285,7 @@ TEST_F(MatrixTest, UnderfilledLocalViewSpec){
distspec, dash::Team::All(), teamspec );

narray.barrier();

if ( 0 == myid ) {
LOG_MESSAGE("global extent is %lu x %lu",
narray.extent(0), narray.extent(1));
Expand All @@ -1131,21 +1297,21 @@ TEST_F(MatrixTest, UnderfilledLocalViewSpec){

// test lbegin, lend
std::fill(narray.lbegin(), narray.lend(), 1);
std::for_each(narray.lbegin(), narray.lend(),
std::for_each(narray.lbegin(), narray.lend(),
[](uint32_t & el){
ASSERT_EQ_U(el, 1);
});
dash::barrier();
// test local view
std::fill(narray.local.begin(), narray.local.end(), 2);
std::for_each(narray.local.begin(), narray.local.end(),
std::for_each(narray.local.begin(), narray.local.end(),
[](uint32_t el){
ASSERT_EQ_U(el, 2);
});

uint32_t elementsvisited = std::distance(narray.lbegin(), narray.lend());
uint32_t elementsvisited = std::distance(narray.lbegin(), narray.lend());
auto local_elements= narray.local.extent(0) * narray.local.extent(1);

ASSERT_EQ_U(elementsvisited, local_elements);
ASSERT_EQ_U(elementsvisited, narray.local.size());

Expand Down Expand Up @@ -1321,17 +1487,17 @@ TEST_F(MatrixTest, ConstMatrix)
DASH_LOG_DEBUG_VAR("MatrixTest.ConstMatrix",
matrix.pattern().teamspec());
}

auto const & matrix_by_ref = matrix;
auto & matrix_local = matrix.local;

dash::fill(matrix.begin(), matrix.end(), 0);
dash::barrier();

int el = matrix(0,0);
el = matrix[0][0];
ASSERT_EQ_U(el, 0);

el = matrix.local[0][0];
ASSERT_EQ_U(el, 0);

Expand All @@ -1356,7 +1522,7 @@ TEST_F(MatrixTest, ConstMatrix)
// el = ++(*(matrix_by_ref.local.lbegin()));
// el = ++(*(matrix_by_ref.local.row(0).lbegin()));
// matrix_by_ref.local.row(0)[0] = 5;

// test access using non-const & matrix.local
matrix.barrier();
*(matrix_local.lbegin()) = 5;
Expand Down Expand Up @@ -1523,7 +1689,7 @@ TEST_F(MatrixTest, SubViewMatrix3Dim)
EXPECT_EQ_U(dim_2_ext, matrix.extent(2));

dash::fill(matrix.begin(), matrix.end(), 0.0);

if (dash::myid() == 0) {
for (int i = 0; i < matrix.extent(0); ++i) {
for (int j = 0; j < matrix.extent(1); ++j) {
Expand Down Expand Up @@ -1564,7 +1730,7 @@ TEST_F(MatrixTest, SubViewMatrix3Dim)
EXPECT_EQ_U(sub_0_size, matrix[0].size());
EXPECT_EQ_U(sub_0_size, std::distance(matrix[0].begin(),
matrix[0].end()));

if (dash::myid().id == 0) {
int visited = 0;
for (auto it = matrix[0].begin(); it != matrix[0].end();
Expand Down