LCOV - code coverage report
Current view: top level - test - MatrixTest.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 469 470 99.8 %
Date: 2016-06-29 12:30:40 Functions: 64 64 100.0 %

          Line data    Source code
       1             : #include <libdash.h>
       2             : #include <gtest/gtest.h>
       3             : #include "TestBase.h"
       4             : #include "TestLogHelpers.h"
       5             : #include "MatrixTest.h"
       6             : 
       7             : #include <iostream>
       8             : #include <iomanip>
       9             : 
      10          20 : TEST_F(MatrixTest, OddSize)
      11             : {
      12             :   typedef dash::Pattern<2>                 pattern_t;
      13             :   typedef typename pattern_t::index_type   index_t;
      14             : 
      15          12 :   dash::Matrix<int, 2, index_t, pattern_t> matrix(dash::SizeSpec<2>(8, 15));
      16             : 
      17          36 :   for (int i = 0; i < matrix.extent(0); i++) {
      18         512 :     for (int j = 0; j < matrix.extent(1); j++) {
      19         480 :       if (matrix(i,j).is_local()) {
      20             :         DASH_LOG_TRACE("MatrixText.OddSize", "(", i, ",", j, ")",
      21             :                        "unit:", _dash_id);
      22             :       }
      23             :     }
      24             :   }
      25           4 : }
      26             : 
      27          20 : TEST_F(MatrixTest, Views)
      28             : {
      29           4 :   const size_t block_size_x  = 3;
      30           4 :   const size_t block_size_y  = 2;
      31           4 :   const size_t block_size    = block_size_x * block_size_y;
      32           4 :   size_t num_local_blocks_x  = 3;
      33           4 :   size_t num_local_blocks_y  = 2;
      34           4 :   size_t num_blocks_x        = _dash_size * num_local_blocks_x;
      35           4 :   size_t num_blocks_y        = _dash_size * num_local_blocks_y;
      36           4 :   size_t num_blocks_total    = num_blocks_x * num_blocks_y;
      37           4 :   size_t extent_x            = block_size_x * num_blocks_x;
      38           4 :   size_t extent_y            = block_size_y * num_blocks_y;
      39           4 :   size_t num_elem_total      = extent_x * extent_y;
      40             :   // Assuming balanced mapping:
      41           4 :   size_t num_elem_per_unit   = num_elem_total / _dash_size;
      42           4 :   size_t num_blocks_per_unit = num_elem_per_unit / block_size;
      43             : 
      44             :   LOG_MESSAGE("nunits:%d elem_total:%d elem_per_unit:%d blocks_per_unit:d%",
      45             :               _dash_size, num_elem_total,
      46             :               num_elem_per_unit, num_blocks_per_unit);
      47             : 
      48             :   typedef dash::default_index_t                 index_t;
      49             :   typedef dash::default_size_t                  extent_t;
      50             :   typedef dash::TilePattern<2, dash::COL_MAJOR> pattern_t;
      51             : 
      52             :   pattern_t pattern(
      53             :     dash::SizeSpec<2>(
      54             :       extent_x,
      55             :       extent_y),
      56             :     dash::DistributionSpec<2>(
      57           8 :       dash::TILE(block_size_x),
      58           8 :       dash::TILE(block_size_y))
      59           4 :   );
      60             : 
      61           8 :   dash::Matrix<int, 2, index_t, pattern_t> matrix(pattern);
      62             : 
      63             :   // Test viewspecs of blocks in global index domain:
      64           4 :   if (dash::myid() == 0) {
      65             :     LOG_MESSAGE("Testing viewspecs of blocks in global index domain");
      66          97 :     for (size_t b = 0; b < num_blocks_total; ++b) {
      67             :       LOG_MESSAGE("Testing viewspec of block %d", b);
      68          96 :       auto g_block       = matrix.block(b);
      69          96 :       auto g_block_first = g_block.begin();
      70          96 :       auto g_block_view  = g_block_first.viewspec();
      71             :       LOG_MESSAGE("Block viewspec: offset:(%d,%d) extent:(%d,%d)",
      72             :                   g_block_view.offset(0), g_block_view.offset(1),
      73             :                   g_block_view.extent(0), g_block_view.extent(1));
      74             :       // Global block coordinates:
      75          96 :       auto g_block_x     = b % num_blocks_x;
      76          96 :       auto g_block_y     = b / num_blocks_x;
      77             :       // Global coordinates of first block element:
      78          96 :       auto g_elem_x      = g_block_x * block_size_x;
      79          96 :       auto g_elem_y      = g_block_y * block_size_y;
      80          96 :       ASSERT_EQ_U(g_elem_x, g_block_view.offset(0));
      81          96 :       ASSERT_EQ_U(g_elem_y, g_block_view.offset(1));
      82             :       // Extent (block_size_x, block_size_y):
      83          96 :       ASSERT_EQ_U(block_size_x, g_block_view.extent(0));
      84          96 :       ASSERT_EQ_U(block_size_y, g_block_view.extent(1));
      85             :     }
      86             :   }
      87             : 
      88             :   // To improve readability of log output:
      89           4 :   dash::barrier();
      90             : 
      91             :   // Test viewspecs of blocks in local index domain:
      92             :   LOG_MESSAGE("Testing viewspecs of blocks in local index domain");
      93           4 :   int lb = 0;
      94         388 :   for (size_t b = 0; b < num_blocks_total; ++b) {
      95         384 :     auto g_block       = matrix.block(b);
      96         384 :     auto g_block_first = g_block.begin();
      97         384 :     auto g_block_view  = g_block_first.viewspec();
      98             :     LOG_MESSAGE("Checking if block %d is local", b);
      99         384 :     if (g_block_first.is_local()) {
     100             :       LOG_MESSAGE("Testing viewspec of local block %d", lb);
     101          96 :       auto l_block       = matrix.local.block(lb);
     102          96 :       auto l_block_first = l_block.begin();
     103          96 :       auto l_block_view  = l_block_first.viewspec();
     104             :       LOG_MESSAGE("Global block viewspec: offset:(%d,%d) extent:(%d,%d)",
     105             :                   g_block_view.offset(0), g_block_view.offset(1),
     106             :                   g_block_view.extent(0), g_block_view.extent(1));
     107             :       LOG_MESSAGE("Local block viewspec: offset:(%d,%d) extent:(%d,%d)",
     108             :                   l_block_view.offset(0), l_block_view.offset(1),
     109             :                   l_block_view.extent(0), l_block_view.extent(1));
     110             :       // Verify matrix.block(b) == matrix.local.block(lb):
     111          96 :       ASSERT_EQ_U(g_block_view, l_block_view);
     112          96 :       ++lb;
     113             :     }
     114             :   }
     115             :   // Validate number of local blocks found:
     116           4 :   ASSERT_EQ_U(num_blocks_per_unit, lb);
     117             : }
     118             : 
     119          20 : TEST_F(MatrixTest, SingleWriteMultipleRead)
     120             : {
     121           4 :   size_t num_units   = dash::Team::All().size();
     122           4 :   size_t tilesize_x  = 7;
     123           4 :   size_t tilesize_y  = 3;
     124           4 :   size_t extent_cols = tilesize_x * num_units * 2;
     125           4 :   size_t extent_rows = tilesize_y * num_units * 2;
     126             :   dash::Matrix<int, 2> matrix(
     127             :                          dash::SizeSpec<2>(
     128             :                            extent_cols,
     129             :                            extent_rows),
     130             :                          dash::DistributionSpec<2>(
     131           8 :                            dash::TILE(tilesize_x),
     132          20 :                            dash::TILE(tilesize_y)));
     133           4 :   size_t matrix_size = extent_cols * extent_rows;
     134           4 :   ASSERT_EQ(matrix_size, matrix.size());
     135           4 :   ASSERT_EQ(extent_cols, matrix.extent(0));
     136           4 :   ASSERT_EQ(extent_rows, matrix.extent(1));
     137             :   LOG_MESSAGE("Matrix size: %d", matrix_size);
     138             :   // Fill matrix
     139           4 :   if(_dash_id == 0) {
     140             :     LOG_MESSAGE("Assigning matrix values");
     141          57 :     for(size_t i = 0; i < matrix.extent(0); ++i) {
     142        1400 :       for(size_t k = 0; k < matrix.extent(1); ++k) {
     143        1344 :         matrix[i][k] = (i * 11) + (k * 97);
     144             :       }
     145             :     }
     146             :   }
     147             :   // Units waiting for value initialization
     148           4 :   dash::Team::All().barrier();
     149             : 
     150             :   // Read and assert values in matrix
     151         228 :   for(size_t i = 0; i < matrix.extent(0); ++i) {
     152        5600 :     for(size_t k = 0; k < matrix.extent(1); ++k) {
     153        5376 :       int value    = matrix[i][k];
     154        5376 :       int expected = (i * 11) + (k * 97);
     155        5376 :       ASSERT_EQ_U(expected, value);
     156             :     }
     157             :   }
     158             : }
     159             : 
     160          20 : TEST_F(MatrixTest, Distribute1DimBlockcyclicY)
     161             : {
     162           4 :   size_t num_units   = dash::Team::All().size();
     163           4 :   size_t extent_cols = 43;
     164           4 :   size_t extent_rows = 54;
     165             :   typedef dash::Pattern<2> pattern_t;
     166             :   LOG_MESSAGE("Initialize matrix ...");
     167           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     168             :   dash::Matrix<int, 2, pattern_t::index_type, pattern_t> matrix(
     169             :                  dash::SizeSpec<2>(
     170             :                    extent_cols,
     171             :                    extent_rows),
     172             :                  dash::DistributionSpec<2>(
     173             :                    dash::NONE,
     174           8 :                    dash::BLOCKCYCLIC(5)),
     175           4 :                  dash::Team::All(),
     176           8 :                  team_spec);
     177             : 
     178             :   LOG_MESSAGE("Matrix initialized, wait for barrier ...");
     179           4 :   dash::Team::All().barrier();
     180             :   LOG_MESSAGE("Team barrier passed");
     181             : 
     182           4 :   size_t matrix_size = extent_cols * extent_rows;
     183           4 :   ASSERT_EQ(matrix_size, matrix.size());
     184           4 :   ASSERT_EQ(extent_cols, matrix.extent(0));
     185           4 :   ASSERT_EQ(extent_rows, matrix.extent(1));
     186             :   LOG_MESSAGE("Matrix size: %d", matrix_size);
     187             :   // Fill matrix
     188           4 :   if(_dash_id == 0) {
     189             :     LOG_MESSAGE("Assigning matrix values");
     190          44 :     for(size_t i = 0; i < matrix.extent(0); ++i) {
     191        2365 :       for(size_t k = 0; k < matrix.extent(1); ++k) {
     192        2322 :         auto value = (i * 11) + (k * 97);
     193             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     194             :                     i, k, value);
     195        2322 :         matrix[i][k] = value;
     196             :       }
     197             :     }
     198             :   }
     199             :   // Units waiting for value initialization
     200             :   LOG_MESSAGE("Values assigned, wait for barrier ...");
     201           4 :   dash::Team::All().barrier();
     202             :   LOG_MESSAGE("Team barrier passed");
     203             : 
     204             :   // Read and assert values in matrix
     205         176 :   for(size_t i = 0; i < matrix.extent(0); ++i) {
     206        9460 :     for(size_t k = 0; k < matrix.extent(1); ++k) {
     207             :       LOG_MESSAGE("Testing matrix[%d][%d]", i, k);
     208        9288 :       int value    = matrix[i][k];
     209        9288 :       int expected = (i * 11) + (k * 97);
     210        9288 :       ASSERT_EQ_U(expected, value);
     211             :     }
     212             :   }
     213             : }
     214             : 
     215          20 : TEST_F(MatrixTest, Distribute2DimTileXY)
     216             : {
     217           4 :   dart_unit_t myid   = dash::myid();
     218           4 :   size_t num_units   = dash::Team::All().size();
     219           4 :   size_t tilesize_x  = 3;
     220           4 :   size_t tilesize_y  = 2;
     221           4 :   size_t extent_cols = tilesize_x * num_units * 2;
     222           4 :   size_t extent_rows = tilesize_y * num_units * 2;
     223             :   typedef dash::TilePattern<2> pattern_t;
     224             :   LOG_MESSAGE("Initialize matrix ...");
     225           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     226             :   dash::Matrix<int, 2, pattern_t::index_type, pattern_t> matrix(
     227             :                  dash::SizeSpec<2>(
     228             :                    extent_rows,
     229             :                    extent_cols),
     230             :                  dash::DistributionSpec<2>(
     231           8 :                    dash::TILE(tilesize_y),
     232           8 :                    dash::TILE(tilesize_x)),
     233           4 :                  dash::Team::All(),
     234           8 :                  team_spec);
     235             : 
     236             :   LOG_MESSAGE("Wait for team barrier ...");
     237           4 :   dash::Team::All().barrier();
     238             :   LOG_MESSAGE("Team barrier passed");
     239             : 
     240           4 :   size_t matrix_size = extent_cols * extent_rows;
     241           4 :   ASSERT_EQ(matrix_size, matrix.size());
     242           4 :   ASSERT_EQ(extent_rows, matrix.extent(0));
     243           4 :   ASSERT_EQ(extent_cols, matrix.extent(1));
     244             :   LOG_MESSAGE("Matrix size: %d", matrix_size);
     245             :   // Fill matrix
     246           4 :   if(myid == 0) {
     247             :     LOG_MESSAGE("Assigning matrix values");
     248          17 :     for(size_t i = 0; i < matrix.extent(0); ++i) {
     249         400 :       for(size_t k = 0; k < matrix.extent(1); ++k) {
     250         384 :         auto value = (i * 11) + (k * 97);
     251             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     252             :                     i, k, value);
     253         384 :         matrix[i][k] = value;
     254             :       }
     255             :     }
     256             :   }
     257             : 
     258             :   // Units waiting for value initialization
     259             :   LOG_MESSAGE("Wait for team barrier ...");
     260           4 :   dash::Team::All().barrier();
     261             :   LOG_MESSAGE("Team barrier passed");
     262             : 
     263             :   // Read and assert values in matrix
     264          68 :   for(size_t i = 0; i < matrix.extent(0); ++i) {
     265        1600 :     for(size_t k = 0; k < matrix.extent(1); ++k) {
     266             :       LOG_MESSAGE("Testing matrix[%d][%d]", i, k);
     267        1536 :       int value    = matrix[i][k];
     268        1536 :       int expected = (i * 11) + (k * 97);
     269        1536 :       ASSERT_EQ_U(expected, value);
     270             :     }
     271             :   }
     272             : }
     273             : 
     274          20 : TEST_F(MatrixTest, Distribute2DimBlockcyclicXY)
     275             : {
     276           4 :   dart_unit_t myid   = dash::myid();
     277           4 :   size_t num_units   = dash::Team::All().size();
     278           4 :   size_t blocksize_x = 3;
     279           4 :   size_t blocksize_y = 2;
     280           4 :   size_t extent_cols = blocksize_x * num_units * 2;
     281           4 :   size_t extent_rows = blocksize_y * num_units * 2;
     282             :   typedef dash::Pattern<2> pattern_t;
     283             :   LOG_MESSAGE("Initialize matrix ...");
     284           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     285           4 :   EXPECT_EQ_U(team_spec.size(), num_units);
     286           4 :   EXPECT_EQ_U(team_spec.rank(), 1);
     287             :   dash::Matrix<int, 2, pattern_t::index_type, pattern_t> matrix(
     288             :                  dash::SizeSpec<2>(
     289             :                    extent_cols,
     290             :                    extent_rows),
     291             :                  dash::DistributionSpec<2>(
     292           8 :                    dash::BLOCKCYCLIC(blocksize_x),
     293           8 :                    dash::BLOCKCYCLIC(blocksize_y)),
     294           4 :                  dash::Team::All(),
     295           8 :                  team_spec);
     296             : 
     297             :   LOG_MESSAGE("Wait for team barrier ...");
     298           4 :   dash::Team::All().barrier();
     299             :   LOG_MESSAGE("Team barrier passed");
     300             : 
     301           4 :   size_t matrix_size = extent_cols * extent_rows;
     302           4 :   ASSERT_EQ(matrix_size, matrix.size());
     303           4 :   ASSERT_EQ(extent_cols, matrix.extent(0));
     304           4 :   ASSERT_EQ(extent_rows, matrix.extent(1));
     305             :   LOG_MESSAGE("Matrix size: %d", matrix_size);
     306             :   // Fill matrix
     307           4 :   if(myid == 0) {
     308             :     LOG_MESSAGE("Assigning matrix values");
     309          25 :     for(size_t i = 0; i < matrix.extent(0); ++i) {
     310         408 :       for(size_t k = 0; k < matrix.extent(1); ++k) {
     311         384 :         auto value = (i * 11) + (k * 97);
     312             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     313             :                     i, k, value);
     314         384 :         matrix[i][k] = value;
     315             :       }
     316             :     }
     317             :   }
     318             :   // Units waiting for value initialization
     319             :   LOG_MESSAGE("Wait for team barrier ...");
     320           4 :   dash::Team::All().barrier();
     321             :   LOG_MESSAGE("Team barrier passed");
     322             : 
     323             :   // Read and assert values in matrix
     324         100 :   for(size_t i = 0; i < matrix.extent(0); ++i) {
     325        1632 :     for(size_t k = 0; k < matrix.extent(1); ++k) {
     326             :       LOG_MESSAGE("Testing matrix[%d][%d]", i, k);
     327        1536 :       int value    = matrix[i][k];
     328        1536 :       int expected = (i * 11) + (k * 97);
     329        1536 :       ASSERT_EQ_U(expected, value);
     330             :     }
     331             :   }
     332             : }
     333             : 
     334          20 : TEST_F(MatrixTest, Submat2DimDefault)
     335             : {
     336           4 :   size_t num_units   = dash::Team::All().size();
     337           4 :   size_t tilesize_x  = 3;
     338           4 :   size_t tilesize_y  = 2;
     339           4 :   size_t extent_cols = tilesize_x * num_units * 2;
     340           4 :   size_t extent_rows = tilesize_y * num_units * 2;
     341             :   typedef dash::Pattern<2> pattern_t;
     342             :   LOG_MESSAGE("Initialize matrix ...");
     343           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     344             :   dash::Matrix<int, 2, pattern_t::index_type, pattern_t> matrix(
     345             :                  dash::SizeSpec<2>(
     346             :                    extent_cols,
     347             :                    extent_rows),
     348             :                  dash::DistributionSpec<2>(
     349           8 :                    dash::TILE(tilesize_x),
     350           8 :                    dash::TILE(tilesize_y)),
     351           4 :                  dash::Team::All(),
     352           8 :                  team_spec);
     353             :   LOG_MESSAGE("Wait for team barrier ...");
     354           4 :   dash::Team::All().barrier();
     355             :   LOG_MESSAGE("Team barrier passed");
     356             : 
     357           4 :   auto matrix_size = matrix.size();
     358           4 :   ASSERT_EQ_U(extent_cols * extent_rows, matrix_size);
     359             : 
     360             :   // Columns 0 ... (J/2)
     361             :   LOG_MESSAGE("Testing sub<0>(0, J/2)");
     362             :   auto submatrix_x_lower = matrix.sub<0>(0,
     363           4 :                                             extent_cols / 2);
     364           4 :   ASSERT_EQ_U(matrix_size/2, submatrix_x_lower.size());
     365             :   // Columns (J/2) ... (J-1)
     366             :   LOG_MESSAGE("Testing sub<0>(J/2, J-1)");
     367             :   auto submatrix_x_upper = matrix.sub<0>(extent_cols / 2,
     368           4 :                                             extent_cols / 2);
     369           4 :   ASSERT_EQ_U(matrix_size/2, submatrix_x_upper.size());
     370             :   // Rows 0 ... (J/2)
     371             :   LOG_MESSAGE("Testing sub<1>(0, I/2)");
     372             :   auto submatrix_y_lower = matrix.sub<1>(0,
     373           4 :                                             extent_rows / 2);
     374           4 :   ASSERT_EQ_U(matrix_size/2, submatrix_y_lower.size());
     375             :   // Rows (J/2) ... (J-1)
     376             :   LOG_MESSAGE("Testing sub<1>(I/2, I-1)");
     377             :   auto submatrix_y_upper = matrix.sub<1>(extent_rows / 2,
     378           4 :                                             extent_rows / 2);
     379           4 :   ASSERT_EQ_U(matrix_size/2, submatrix_y_upper.size());
     380             : }
     381             : 
     382          20 : TEST_F(MatrixTest, Sub2DimDefault)
     383             : {
     384             :   typedef dash::default_index_t index_t;
     385             :   typedef int                   element_t;
     386           4 :   size_t num_units   = dash::Team::All().size();
     387           4 :   size_t tilesize_x  = 3;
     388           4 :   size_t tilesize_y  = 2;
     389           4 :   size_t extent_cols = tilesize_x * num_units * 2;
     390           4 :   size_t extent_rows = tilesize_y * num_units * 2;
     391             :   typedef dash::TilePattern<2> pattern_t;
     392             :   LOG_MESSAGE("Initialize matrix ...");
     393           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     394             :   dash::Matrix<element_t, 2, pattern_t::index_type, pattern_t> matrix(
     395             :                  dash::SizeSpec<2>(
     396             :                    extent_cols,
     397             :                    extent_rows),
     398             :                  dash::DistributionSpec<2>(
     399           8 :                    dash::TILE(tilesize_x),
     400           8 :                    dash::TILE(tilesize_y)),
     401           4 :                  dash::Team::All(),
     402           8 :                  team_spec);
     403             :   LOG_MESSAGE("Wait for team barrier ...");
     404           4 :   dash::Team::All().barrier();
     405             :   LOG_MESSAGE("Team barrier passed");
     406             : 
     407           4 :   auto matrix_size = matrix.size();
     408             :   // Check matrix size:
     409           4 :   ASSERT_EQ_U(extent_cols * extent_rows, matrix_size);
     410             :   // Plausibility checks of matrix pattern:
     411           4 :   const pattern_t & pattern = matrix.pattern();
     412           4 :   ASSERT_EQ_U(matrix_size, pattern.size());
     413           4 :   ASSERT_EQ_U(matrix.local_size(), pattern.local_size());
     414           4 :   ASSERT_EQ_U(matrix.local_capacity(), pattern.local_capacity());
     415             :   // Check local range:
     416           4 :   ASSERT_EQ_U(matrix_size / num_units, matrix.local_capacity());
     417           4 :   ASSERT_EQ_U(matrix_size / num_units, matrix.local_size());
     418           4 :   element_t * lit  = matrix.lbegin();
     419           4 :   element_t * lend = matrix.lend();
     420             :   LOG_MESSAGE("Local range: lend(%p) - lbegin(%p) = %d",
     421             :               lend, lit, lend - lit);
     422           4 :   ASSERT_EQ_U(matrix.lend() - matrix.lbegin(),
     423             :               matrix.local_size());
     424             :   // Assign unit-specific values in local matrix range:
     425         388 :   for (index_t lidx = 0; lit != lend; ++lidx, ++lit) {
     426         384 :     ASSERT_LT_U(lidx, matrix.local_size());
     427         384 :     auto value = ((dash::myid() + 1) * 1000) + lidx;
     428             :     LOG_MESSAGE("Assigning local address (%p) %d = %d",
     429             :                 lit, lidx, value);
     430         384 :     *lit = value;
     431             :   }
     432             : 
     433           4 :   matrix.barrier();
     434             :   LOG_MESSAGE("Testing values");
     435             : 
     436             :   // Test values by column:
     437           4 :   size_t num_visited_total = 0;
     438           4 :   size_t num_visited_local = 0;
     439         100 :   for (index_t col = 0; col < static_cast<index_t>(extent_cols); ++col) {
     440          96 :     auto column = matrix.sub<0>(col);
     441        1632 :     for (index_t row = 0; row < static_cast<index_t>(extent_rows); ++row) {
     442        1536 :       auto g_coords   = std::array<index_t, 2> {{ col, row }};
     443        1536 :       auto l_coords   = pattern.local_coords(g_coords);
     444        1536 :       auto unit_id    = pattern.unit_at(g_coords);
     445        1536 :       auto local_idx  = pattern.local_at(l_coords);
     446        1536 :       auto global_idx = pattern.memory_layout().at(g_coords);
     447        1536 :       auto exp_value  = ((unit_id + 1) * 1000) + local_idx;
     448        1536 :       bool is_local   = unit_id == dash::myid();
     449             :       LOG_MESSAGE("Testing g(%d,%d) l(%d,%d) u(%d) li(%d) == %d",
     450             :                   col, row,
     451             :                   l_coords[0], l_coords[1],
     452             :                   unit_id,
     453             :                   local_idx,
     454             :                   exp_value);
     455        1536 :       element_t value = column[row];
     456        1536 :       ASSERT_EQ_U(exp_value, value);
     457        1536 :       ASSERT_EQ_U(is_local, matrix.is_local(global_idx));
     458        1536 :       if (is_local) {
     459         384 :         ++num_visited_local;
     460             :       }
     461        1536 :       ++num_visited_total;
     462             :     }
     463             :   }
     464             :   // Check number of iterated local and total elements:
     465           4 :   ASSERT_EQ_U(matrix_size, num_visited_total);
     466           4 :   ASSERT_EQ_U(matrix.local_size(), num_visited_local);
     467             : }
     468             : 
     469          20 : TEST_F(MatrixTest, BlockViews)
     470             : {
     471             :   typedef int element_t;
     472           4 :   dart_unit_t myid   = dash::myid();
     473           4 :   size_t num_units   = dash::Team::All().size();
     474           4 :   size_t tilesize_x  = 3;
     475           4 :   size_t tilesize_y  = 2;
     476           4 :   size_t tilesize    = tilesize_x * tilesize_y;
     477           4 :   size_t extent_cols = tilesize_x * num_units * 4;
     478           4 :   size_t extent_rows = tilesize_y * num_units * 4;
     479             :   typedef dash::TilePattern<2> pattern_t;
     480             :   LOG_MESSAGE("Initialize matrix ...");
     481           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     482             :   dash::Matrix<element_t, 2, pattern_t::index_type, pattern_t> matrix(
     483             :                  dash::SizeSpec<2>(
     484             :                    extent_cols,
     485             :                    extent_rows),
     486             :                  dash::DistributionSpec<2>(
     487           8 :                    dash::TILE(tilesize_x),
     488           8 :                    dash::TILE(tilesize_y)),
     489           4 :                  dash::Team::All(),
     490           8 :                  team_spec);
     491             :   // Fill matrix
     492           4 :   if(myid == 0) {
     493             :     LOG_MESSAGE("Assigning matrix values");
     494          49 :     for(size_t col = 0; col < matrix.extent(0); ++col) {
     495        1584 :       for(size_t row = 0; row < matrix.extent(1); ++row) {
     496        1536 :         auto value = (row * matrix.extent(0)) + col;
     497             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     498             :                     col, row, value);
     499        1536 :         matrix[col][row] = value;
     500             :       }
     501             :     }
     502             :   }
     503             :   LOG_MESSAGE("Wait for team barrier ...");
     504           4 :   dash::Team::All().barrier();
     505             :   LOG_MESSAGE("Team barrier passed");
     506             : 
     507             :   element_t exp_val;
     508             : 
     509             :   // View at block at global block offset 0 (first global block):
     510           4 :   auto block_gi_0 = matrix.block(0);
     511           4 :   ASSERT_EQ_U(tilesize, block_gi_0.size());
     512             : 
     513             :   // Test first element in block at global block index 0:
     514           4 :   exp_val = matrix[0][0];
     515           4 :   ASSERT_EQ_U(exp_val,
     516             :               *(block_gi_0.begin()));
     517             :   // Test last element in block at global block index 0:
     518           4 :   exp_val = matrix[tilesize_x-1][tilesize_y-1];
     519           4 :   ASSERT_EQ_U(exp_val,
     520             :               *(block_gi_0.begin() + (tilesize-1)));
     521             : 
     522             :   // View at block at global block offset 6
     523             :   // (first global block of lower right matrix quarter):
     524           4 :   auto nblocks_x  = matrix.extents()[0] / tilesize_x;
     525           4 :   auto nblocks_y  = matrix.extents()[1] / tilesize_y;
     526             :   // Block index of first block in lower right quarter of the matrix:
     527           4 :   auto block_q_gi = ((nblocks_x * nblocks_y) / 2) + (nblocks_x / 2);
     528           4 :   auto block_gi_q = matrix.block(block_q_gi);
     529           4 :   ASSERT_EQ_U(tilesize, block_gi_q.size());
     530             : 
     531             :   // Test first element in first block at lower right quarter of the matrix:
     532           4 :   auto block_6_x = matrix.extents()[0] / 2;
     533           4 :   auto block_6_y = matrix.extents()[1] / 2;
     534           4 :   exp_val = matrix[block_6_x][block_6_y];
     535           4 :   ASSERT_EQ_U(exp_val,
     536             :               *(block_gi_q.begin()));
     537             :   // Test last element in first block at lower right quarter of the matrix:
     538           4 :   exp_val = matrix[block_6_x+tilesize_x-1][block_6_y+tilesize_y-1];
     539           4 :   ASSERT_EQ_U(exp_val,
     540             :               *(block_gi_q.begin() + (tilesize-1)));
     541             : }
     542             : 
     543          20 : TEST_F(MatrixTest, ViewIteration)
     544             : {
     545             :   typedef int                                   element_t;
     546             :   typedef dash::TilePattern<2, dash::COL_MAJOR> pattern_t;
     547             : 
     548           4 :   dart_unit_t myid   = dash::myid();
     549           4 :   size_t num_units   = dash::Team::All().size();
     550           4 :   size_t tilesize_x  = 3;
     551           4 :   size_t tilesize_y  = 2;
     552           4 :   size_t extent_cols = tilesize_x * num_units * 4;
     553           4 :   size_t extent_rows = tilesize_y * num_units * 4;
     554             : 
     555             :   LOG_MESSAGE("Initialize matrix ...");
     556           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     557             :   dash::Matrix<element_t, 2, pattern_t::index_type, pattern_t> matrix(
     558             :                  dash::SizeSpec<2>(
     559             :                    extent_cols,
     560             :                    extent_rows),
     561             :                  dash::DistributionSpec<2>(
     562           8 :                    dash::TILE(tilesize_x),
     563           8 :                    dash::TILE(tilesize_y)),
     564           4 :                  dash::Team::All(),
     565           8 :                  team_spec);
     566             :   // Fill matrix
     567           4 :   if(myid == 0) {
     568             :     LOG_MESSAGE("Assigning matrix values");
     569          49 :     for(size_t i = 0; i < matrix.extent(0); ++i) {
     570        1584 :       for(size_t k = 0; k < matrix.extent(1); ++k) {
     571        1536 :         auto value = (i * 1000) + (k * 1);
     572             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     573             :                     i, k, value);
     574        1536 :         matrix[i][k] = value;
     575             :       }
     576             :     }
     577             :   }
     578             :   LOG_MESSAGE("Wait for team barrier ...");
     579           4 :   dash::Team::All().barrier();
     580             :   LOG_MESSAGE("Team barrier passed");
     581             : 
     582             :   // Partition matrix into 4 blocks (upper/lower left/right):
     583             : 
     584             :   // First create two views for left and right half:
     585           4 :   auto left        = matrix.sub<0>(0,               extent_cols / 2);
     586           4 :   auto right       = matrix.sub<0>(extent_cols / 2, extent_cols / 2);
     587             : 
     588             :   // Refine views on left and right half into top/bottom:
     589           4 :   auto topleft     = left.sub<1>(0,               extent_rows / 2);
     590           4 :   auto bottomleft  = left.sub<1>(extent_rows / 2, extent_rows / 2);
     591           4 :   auto topright    = right.sub<1>(0,               extent_rows / 2);
     592           4 :   auto bottomright = right.sub<1>(extent_rows / 2, extent_rows / 2);
     593             : 
     594             :   dash__unused(topleft);
     595             :   dash__unused(bottomleft);
     596             :   dash__unused(topright);
     597             : 
     598           4 :   auto g_br_x      = extent_cols / 2;
     599           4 :   auto g_br_y      = extent_rows / 2;
     600             : 
     601             :   // Initial plausibility check: Access same element by global- and view
     602             :   // coordinates:
     603           4 :   ASSERT_EQ_U((int)bottomright[0][0],
     604             :               (int)matrix[g_br_x][g_br_y]);
     605             : 
     606           4 :   int  phase              = 0;
     607             :   // Extents of the view projection:
     608           4 :   int  view_size_x        = extent_cols / 2;
     609             :   // Global coordinates of first element in bottom right block:
     610           4 :   int  block_base_coord_x = extent_cols / 2;
     611           4 :   int  block_base_coord_y = extent_rows / 2;
     612           4 :   auto b_it               = bottomright.begin();
     613           4 :   auto b_end              = bottomright.end();
     614           4 :   int  block_index_offset = b_it.pos();
     615             :   LOG_MESSAGE("Testing block values");
     616        3076 :   for (; b_it != b_end; ++b_it, ++phase) {
     617        1536 :     int phase_x  = phase % view_size_x;
     618        1536 :     int phase_y  = phase / view_size_x;
     619        1536 :     int gcoord_x = block_base_coord_x + phase_x;
     620        1536 :     int gcoord_y = block_base_coord_y + phase_y;
     621             :     LOG_MESSAGE("phase:%d = %d,%d it_pos:%d end_pos:%d gcoord:%d,%d",
     622             :                 phase,
     623             :                 phase_x, phase_y,
     624             :                 b_it.pos(),
     625             :                 b_end.pos(),
     626             :                 gcoord_x, gcoord_y);
     627        1536 :     ASSERT_EQ_U(phase, (b_it.pos() - block_index_offset));
     628             :     // Apply view projection by converting to GlobPtr:
     629             :     dash::GlobPtr<int, pattern_t> block_elem_gptr =
     630        1536 :       (dash::GlobPtr<int, pattern_t>)(b_it);
     631             :     // Compare with GlobPtr from global iterator without view projection:
     632             :     dash::GlobPtr<int, pattern_t> glob_elem_gptr  =
     633        1536 :       (dash::GlobPtr<int, pattern_t>)(matrix[gcoord_x][gcoord_y]);
     634        1536 :     int block_value = *block_elem_gptr;
     635        1536 :     int glob_value  = *glob_elem_gptr;
     636        1536 :     ASSERT_EQ_U(glob_value,
     637             :                 block_value);
     638        1536 :     ASSERT_EQ_U(glob_elem_gptr, block_elem_gptr);
     639             :   }
     640             : }
     641             : 
     642          20 : TEST_F(MatrixTest, BlockCopy)
     643             : {
     644             :   typedef int element_t;
     645           4 :   dart_unit_t myid   = dash::myid();
     646           4 :   size_t num_units   = dash::Team::All().size();
     647           4 :   size_t tilesize_x  = 3;
     648           4 :   size_t tilesize_y  = 2;
     649           4 :   size_t extent_cols = tilesize_x * num_units * 4;
     650           4 :   size_t extent_rows = tilesize_y * num_units * 4;
     651             :   typedef dash::TilePattern<2> pattern_t;
     652             :   LOG_MESSAGE("Initialize matrix ...");
     653           4 :   dash::TeamSpec<2> team_spec(num_units, 1);
     654             :   dash::Matrix<element_t, 2, pattern_t::index_type, pattern_t>
     655             :                matrix_a(
     656             :                  dash::SizeSpec<2>(
     657             :                    extent_cols,
     658             :                    extent_rows),
     659             :                  dash::DistributionSpec<2>(
     660           8 :                    dash::TILE(tilesize_x),
     661           8 :                    dash::TILE(tilesize_y)),
     662           4 :                  dash::Team::All(),
     663           8 :                  team_spec);
     664             :   dash::Matrix<element_t, 2, pattern_t::index_type, pattern_t>
     665             :                matrix_b(
     666             :                  dash::SizeSpec<2>(
     667             :                    extent_cols,
     668             :                    extent_rows),
     669             :                  dash::DistributionSpec<2>(
     670           8 :                    dash::TILE(tilesize_x),
     671           8 :                    dash::TILE(tilesize_y)),
     672           4 :                  dash::Team::All(),
     673           8 :                  team_spec);
     674             :   // Fill matrix
     675           4 :   if(myid == 0) {
     676             :     LOG_MESSAGE("Assigning matrix values");
     677          49 :     for(size_t col = 0; col < matrix_a.extent(0); ++col) {
     678        1584 :       for(size_t row = 0; row < matrix_a.extent(1); ++row) {
     679        1536 :         auto value = (row * matrix_a.extent(0)) + col;
     680             :         LOG_MESSAGE("Setting matrix[%d][%d] = %d",
     681             :                     col, row, value);
     682        1536 :         matrix_a[col][row] = value;
     683        1536 :         matrix_b[col][row] = value;
     684             :       }
     685             :     }
     686             :   }
     687             :   LOG_MESSAGE("Wait for team barrier ...");
     688           4 :   dash::barrier();
     689             :   LOG_MESSAGE("Team barrier passed");
     690             : 
     691             :   // Copy block 1 of matrix_a to block 0 of matrix_b:
     692           8 :   dash::copy<element_t>(matrix_a.block(1).begin(),
     693           8 :                         matrix_a.block(1).end(),
     694          16 :                         matrix_b.block(0).begin());
     695             : 
     696             :   LOG_MESSAGE("Wait for team barrier ...");
     697           4 :   dash::barrier();
     698             :   LOG_MESSAGE("Team barrier passed");
     699           4 : }
     700             : 
     701          20 : TEST_F(MatrixTest, StorageOrder)
     702             : {
     703           4 :   size_t num_units = dash::size();
     704             : 
     705           4 :   size_t tilesize_row = 5;
     706           4 :   size_t tilesize_col = 4;
     707           4 :   size_t nrows = tilesize_row * num_units * 2;
     708           4 :   size_t ncols = tilesize_col * num_units * 2;
     709             : 
     710             :   dash::TilePattern<2, dash::ROW_MAJOR> pat_row(
     711           4 :     nrows, ncols, dash::TILE(tilesize_row), dash::TILE(tilesize_col));
     712             :   dash::TilePattern<2, dash::COL_MAJOR> pat_col(
     713           4 :     nrows, ncols, dash::TILE(tilesize_row), dash::TILE(tilesize_col));
     714             : 
     715             :   typedef dash::default_index_t index_t;
     716             : 
     717           4 :   if (dash::myid() == 0) {
     718           2 :     dash::test::print_pattern_mapping(
     719             :       "pattern.row-major.local_index", pat_row, 3,
     720        1280 :       [](const decltype(pat_row) & _pattern, int _x, int _y) -> index_t {
     721        1280 :           return _pattern.local_index(std::array<index_t, 2> {_x, _y}).index;
     722           1 :       });
     723           2 :     dash::test::print_pattern_mapping(
     724             :       "pattern.col-major.local_index", pat_col, 3,
     725        1280 :       [](const decltype(pat_col) & _pattern, int _x, int _y) -> index_t {
     726        1280 :           return _pattern.local_index(std::array<index_t, 2> {_x, _y}).index;
     727           1 :       });
     728             :   }
     729             : 
     730           8 :   dash::Matrix<int, 2, index_t, decltype(pat_col)> mat_col(pat_col);
     731           8 :   dash::Matrix<int, 2, index_t, decltype(pat_row)> mat_row(pat_row);
     732             : 
     733           4 :   ASSERT_EQ_U(mat_row.local_size(), mat_row.local.size());
     734           4 :   ASSERT_GT_U(mat_row.local.size(), 0);
     735           4 :   ASSERT_EQ_U(mat_col.local_size(), mat_col.local.size());
     736           4 :   ASSERT_GT_U(mat_col.local.size(), 0);
     737             : 
     738        1284 :   for (int i = 0; i < static_cast<int>(mat_row.local.size()); ++i) {
     739        1280 :      mat_row.lbegin()[i] = 1000 * (dash::myid() + 1) + i;
     740        1280 :      mat_col.lbegin()[i] = 1000 * (dash::myid() + 1) + i;
     741             :   }
     742             : 
     743           4 :   dash::barrier();
     744             : 
     745           4 :   if (dash::myid() == 0) {
     746           1 :     std::cout << "row major:" << std::endl;
     747          41 :     for (int row = 0; row < static_cast<int>(nrows); ++row) {
     748        1320 :       for (int col = 0; col < static_cast<int>(ncols); ++col) {
     749        1280 :         std::cout << std::setw(5) << (int)(mat_row[row][col]) << " ";
     750             :       }
     751          40 :       std::cout << std::endl;
     752             :     }
     753           1 :     std::cout << "column major:" << std::endl;
     754          41 :     for (int row = 0; row < static_cast<int>(nrows); ++row) {
     755        1320 :       for (int col = 0; col < static_cast<int>(ncols); ++col) {
     756        1280 :         std::cout << std::setw(5) << (int)(mat_col[row][col]) << " ";
     757             :       }
     758          40 :       std::cout << std::endl;
     759             :     }
     760             :   }
     761             : }
     762             : 
     763          20 : TEST_F(MatrixTest, DelayedAlloc)
     764             : {
     765           4 :   dart_unit_t myid = dash::myid();
     766           4 :   auto num_units   = dash::size();
     767             : 
     768           4 :   if (num_units < 4) {
     769             :     LOG_MESSAGE("MatrixTest.DelayedAlloc requires at least 4 units");
     770           0 :     return;
     771             :   }
     772             : 
     773             :   // Default constructor creates team spec with extents (nunits, 1, 1):
     774           4 :   dash::TeamSpec<3> teamspec;
     775             :   // Automatic balancing of team spec in three dimensions:
     776           4 :   teamspec.balance_extents();
     777             : 
     778             :   // reverse team extents
     779           4 :   auto team_extents = teamspec.extents();
     780           4 :   if (team_extents[0] > team_extents[2]) {
     781           4 :     std::swap(team_extents[0], team_extents[2]);
     782           4 :     teamspec.resize(team_extents);
     783             :   }
     784             : 
     785           4 :   if (myid == 0) {
     786           1 :     DASH_LOG_TRACE_VAR("MatrixTest.DelayedAlloc", teamspec.extents());
     787             :   }
     788             : 
     789           4 :   auto num_units_i = teamspec.extent(0);
     790           4 :   auto num_units_j = teamspec.extent(1);
     791           4 :   auto num_units_k = teamspec.extent(2);
     792             : 
     793             :   // Cartesian dimensions for row-major storage order:
     794             :   // index (i,j,k) = Cartesian offset (z,y,x)
     795           4 :   auto tilesize_i   = 2;
     796           4 :   auto tilesize_j   = 5;
     797           4 :   auto tilesize_k   = 3;
     798           4 :   auto blocksize    = tilesize_i * tilesize_j * tilesize_k;
     799           4 :   auto num_blocks_i = num_units_i > 1 ? 2 * num_units_i : 1;
     800           4 :   auto num_blocks_j = num_units_j > 1 ? 3 * num_units_j : 1;
     801           4 :   auto num_blocks_k = num_units_k > 1 ? 2 * num_units_k : 1;
     802           4 :   auto extent_i     = num_blocks_i * tilesize_i;
     803           4 :   auto extent_j     = num_blocks_j * tilesize_j;
     804           4 :   auto extent_k     = num_blocks_k * tilesize_k;
     805             : 
     806             :   typedef double
     807             :     value_t;
     808             :   typedef dash::default_index_t
     809             :     index_t;
     810             :   typedef dash::default_extent_t
     811             :     extent_t;
     812             :   typedef dash::CartesianIndexSpace<3, dash::ROW_MAJOR, index_t>
     813             :     index_space_t;
     814             : 
     815           4 :   dash::barrier();
     816             :   DASH_LOG_DEBUG("MatrixTest.DelayedAlloc",
     817             :                  "Calling dash::Matrix default constructor");
     818             : 
     819             :   dash::Matrix<
     820             :           value_t,
     821             :           3,
     822             :           index_t,
     823           8 :           dash::TilePattern<3> > mx;
     824             : 
     825           4 :   ASSERT_EQ_U(num_units, teamspec.size());
     826             : 
     827           4 :   dash::barrier();
     828             :   DASH_LOG_DEBUG("MatrixTest.DelayedAlloc",
     829             :                  "Calling dash::Matrix.allocate");
     830             : 
     831             :   // Delayed allocation of matrix:
     832           8 :   mx.allocate(
     833             :       dash::SizeSpec<3>(
     834             :         extent_i,
     835             :         extent_j,
     836             :         extent_k),
     837             :       dash::DistributionSpec<3>(
     838             :         num_units_i < 2 ? dash::NONE : dash::TILE(tilesize_i),
     839             :         num_units_j < 2 ? dash::NONE : dash::TILE(tilesize_j),
     840             :         num_units_k < 2 ? dash::NONE : dash::TILE(tilesize_k)),
     841             :       teamspec
     842           4 :   );
     843             : 
     844           4 :   auto pattern        = mx.pattern();
     845           4 :   auto blockspec      = pattern.blockspec().extents();
     846           4 :   auto blocksizespec  = pattern.block(0).extents();
     847           4 :   auto n_local_blocks = pattern.local_blockspec().size();
     848           4 :   auto n_local_elem   = n_local_blocks * blocksize;
     849             : 
     850             :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", blockspec);
     851             :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", blocksizespec);
     852             :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", blocksize);
     853           4 :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", mx.local.extents());
     854           4 :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", mx.local.offsets());
     855             :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", n_local_blocks);
     856             :   DASH_LOG_DEBUG_VAR("MatrixTest.DelayedAlloc", n_local_elem);
     857             : 
     858           4 :   ASSERT_EQ_U(mx.local.size(), n_local_elem);
     859             : 
     860             :   // Initialize values:
     861          28 :   for (extent_t lbi = 0; lbi < n_local_blocks; ++lbi) {
     862             :     // submatrix view on local block obtained from matrix relative to global
     863             :     // memory space:
     864          24 :     auto g_matrix_block  = mx.local.block(lbi);
     865             :     // index space view on local block obtained from pattern relative to
     866             :     // global index space:
     867          24 :     auto g_pattern_block = mx.pattern().local_block(myid, lbi);
     868             : 
     869          24 :     value_t * block_lbegin = g_matrix_block.lbegin();
     870          24 :     value_t * block_lend   = g_matrix_block.lend();
     871             :     DASH_LOG_DEBUG("MatrixTest.DelayedAlloc",
     872             :                    "local block idx:",   lbi,
     873             :                    "block offset:",      g_matrix_block.offsets(),
     874             :                    "block extents:",     g_matrix_block.extents(),
     875             :                    "block lend-lbegin:", block_lend - block_lbegin);
     876             : 
     877             :     // block views should be identical:
     878          24 :     ASSERT_EQ_U(g_matrix_block.extents(),
     879             :                 g_pattern_block.extents());
     880          24 :     ASSERT_EQ_U(g_matrix_block.offsets(),
     881             :                 g_pattern_block.offsets());
     882             :     // element phase, canonical element offset in block:
     883          24 :     index_t phase = 0;
     884         744 :     for (auto lbv = block_lbegin; lbv != block_lend; ++lbv, ++phase) {
     885         720 :       *lbv = myid + (0.01 * lbi) + (0.0001 * phase);
     886             :     }
     887             :   }
     888             : 
     889           4 :   mx.barrier();
     890             : 
     891           4 :   if (myid == 0) {
     892           1 :     dash::test::print_matrix("Matrix<3>", mx, 4);
     893             :   }
     894             : 
     895             :   // Validate values.
     896             :   // Testing view specifiers for every index explicitly, intentionally
     897             :   // inefficient.
     898           4 :   if (myid == 0) {
     899           3 :     for (index_t i = 0; i < static_cast<index_t>(extent_i); ++i) {
     900          62 :       for (index_t j = 0; j < static_cast<index_t>(extent_j); ++j) {
     901         780 :         for (index_t k = 0; k < static_cast<index_t>(extent_k); ++k) {
     902             :           DASH_LOG_TRACE("MatrixTest.DelayedAlloc",
     903             :                          "coords:", i, j, k);
     904             :           // global coordinate:
     905         720 :           std::array<index_t, 3> gcoords {{ i, j, k }};
     906             :           // block index in global memory space:
     907         720 :           auto block_index   = mx.pattern().block_at(gcoords);
     908             :           // block index in local memory space:
     909         720 :           auto lbi           = mx.pattern().local_block_at(gcoords).index;
     910             :           // block at global block index:
     911         720 :           auto block_extents = mx.pattern().block(block_index).extents();
     912         720 :           auto block_i_space = index_space_t(block_extents);
     913         720 :           auto block_unit    = mx.pattern().unit_at(gcoords);
     914             :           // Cartesian offsets of element in block:
     915         720 :           std::array<index_t, 3> phase_coords {{ i % tilesize_i,
     916         720 :                                                  j % tilesize_j,
     917        1440 :                                                  k % tilesize_k }};
     918             :           DASH_LOG_TRACE("MatrixTest.DelayedAlloc",
     919             :                          "block extents:", block_extents,
     920             :                          "phase coords:",  phase_coords);
     921             :           // canonical offset of element in block:
     922         720 :           index_t phase     = block_i_space.at(phase_coords);
     923         720 :           value_t expected  = block_unit + (0.01 * lbi) + (0.0001 * phase);
     924         720 :           value_t actual    = mx[i][j][k];
     925             :           DASH_LOG_TRACE("MatrixTest.DelayedAlloc",
     926             :                          "coords:",      i, j, k,
     927             :                          "block index:", block_index,
     928             :                          "unit:",        block_unit,
     929             :                          "phase:",       phase_coords, "=", phase,
     930             :                          "expected:",    expected,
     931             :                          "actual:",      actual);
     932         720 :           ASSERT_EQ_U(expected, actual);
     933             :         }
     934             :       }
     935             :     }
     936             :   }
     937             : }
     938             : 
     939             : /**
     940             :  * Allocate a matrix with extents that cannot fit into full blocks
     941             :  */
     942          20 : TEST_F(MatrixTest, UnderfilledPattern)
     943             : {
     944             :   typedef dash::Pattern<2, dash::ROW_MAJOR> pattern_t;
     945             : 
     946           4 :   size_t team_size    = dash::Team::All().size();
     947             : 
     948           4 :   dash::TeamSpec<2> teamspec_2d(team_size, 1);
     949           4 :   teamspec_2d.balance_extents();
     950             : 
     951           4 :   auto block_size_x = 10;
     952           4 :   auto block_size_y = 15;
     953           4 :   auto ext_x        = (block_size_x * teamspec_2d.num_units(0)) - 3;
     954           4 :   auto ext_y        = (block_size_y * teamspec_2d.num_units(1)) - 1;
     955             : 
     956           4 :   auto size_spec = dash::SizeSpec<2>(ext_x, ext_y);
     957             : 
     958          12 :   auto matrix_a = dash::Matrix<int, 2, long, pattern_t>(size_spec);
     959             : 
     960             :   // test bottom right corner
     961           4 :   if (dash::myid() == 0) {
     962           1 :     matrix_a[ext_x - 1][ext_y - 1] = 10;
     963           1 :     ASSERT_EQ( matrix_a[ext_x - 1][ext_y - 1], 10 );
     964             :   }
     965             : 
     966           4 :   matrix_a.deallocate();
     967             : 
     968             :   // Check BlockPattern
     969             :   const pattern_t pattern(
     970             :     size_spec,
     971             :     dash::DistributionSpec<2>(
     972           8 :       dash::TILE(block_size_x),
     973           8 :       dash::TILE(block_size_y)),
     974             :     teamspec_2d,
     975           8 :     dash::Team::All());
     976             : 
     977           8 :   dash::Matrix<int, 2, long, pattern_t> matrix_b;
     978           4 :   matrix_b.allocate(pattern);
     979             : }
     980             : 
     981          20 : TEST_F(MatrixTest, SimpleConstructor)
     982             : {
     983           4 :         size_t ext_x = dash::size();
     984           4 :         size_t ext_y = 5*dash::size();
     985           8 :         dash::Matrix<int, 2> matrix(ext_x, ext_y);
     986             : 
     987           4 :         dash::fill(matrix.begin(), matrix.end(), dash::myid());
     988             : 
     989           4 :         matrix.barrier();
     990             : 
     991           4 :         ASSERT_EQ_U(ext_x, matrix.extent(0));
     992           4 :         ASSERT_EQ_U(ext_y, matrix.extent(1));
     993          12 : }
     994             : 
     995             : 

Generated by: LCOV version 1.12