LCOV - code coverage report
Current view: top level - test - GlobDynamicMemTest.cc (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 215 236 91.1 %
Date: 2016-06-29 12:30:40 Functions: 18 18 100.0 %

          Line data    Source code
       1             : #include <libdash.h>
       2             : #include <gtest/gtest.h>
       3             : 
       4             : #include "TestBase.h"
       5             : #include "GlobDynamicMemTest.h"
       6             : 
       7          20 : TEST_F(GlobDynamicMemTest, BalancedAlloc)
       8             : {
       9             :   typedef int value_t;
      10             : 
      11           4 :   if (dash::size() < 2) {
      12             :     LOG_MESSAGE(
      13             :       "GlobDynamicMemTest.BalancedAlloc requires at least two units");
      14           0 :     return;
      15             :   }
      16             : 
      17             :   LOG_MESSAGE("initializing GlobDynamicMem<T>");
      18             : 
      19           4 :   size_t initial_local_capacity  = 10;
      20           4 :   size_t initial_global_capacity = dash::size() * initial_local_capacity;
      21           8 :   dash::GlobDynamicMem<value_t> gdmem(initial_local_capacity);
      22             : 
      23             :   LOG_MESSAGE("initial global capacity: %d, initial local capacity: %d",
      24             :               initial_global_capacity, initial_local_capacity);
      25             : 
      26           4 :   EXPECT_EQ_U(initial_local_capacity,  gdmem.local_size());
      27           4 :   EXPECT_EQ_U(initial_local_capacity,  gdmem.lend(dash::myid()) -
      28           0 :                                        gdmem.lbegin(dash::myid()));
      29           4 :   EXPECT_EQ_U(initial_global_capacity, gdmem.size());
      30             : 
      31             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "initial local:",
      32             :                  gdmem.local_size());
      33             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "initial global:",
      34             :                  gdmem.size());
      35             :   // Wait for validation of initial capacity at all units:
      36           4 :   dash::barrier();
      37             : 
      38           4 :   size_t bucket_1_size = 5;
      39           4 :   size_t bucket_2_size = 7;
      40             : 
      41           4 :   gdmem.grow(3);
      42           4 :   gdmem.grow(bucket_1_size);
      43           4 :   gdmem.grow(bucket_2_size);
      44           4 :   gdmem.shrink(3);
      45             : 
      46           4 :   size_t precommit_local_capacity  = initial_local_capacity +
      47           4 :                                      bucket_1_size + bucket_2_size;
      48           4 :   size_t precommit_global_capacity = initial_global_capacity +
      49           4 :                                      bucket_1_size + bucket_2_size;
      50           4 :   EXPECT_EQ_U(precommit_local_capacity,  gdmem.local_size());
      51           4 :   EXPECT_EQ_U(precommit_local_capacity,  gdmem.lend(dash::myid()) -
      52           0 :                                          gdmem.lbegin(dash::myid()));
      53           4 :   EXPECT_EQ_U(precommit_global_capacity, gdmem.size());
      54             : 
      55             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "pre-commit local:",
      56             :                  gdmem.local_size());
      57             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "pre-commit global:",
      58             :                  gdmem.size());
      59             :   // Wait for validation of changes of local capacity at all units:
      60           4 :   dash::barrier();
      61             : 
      62           4 :   gdmem.commit();
      63             : 
      64             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "post-commit local:",
      65             :                  gdmem.local_size());
      66             :   DASH_LOG_TRACE("GlobDynamicMemTest.BalancedAlloc", "post-commit global:",
      67             :                  gdmem.size());
      68           4 :   size_t postcommit_local_capacity  = precommit_local_capacity;
      69           4 :   size_t postcommit_global_capacity = dash::size() *
      70           4 :                                       postcommit_local_capacity;
      71           4 :   EXPECT_EQ_U(postcommit_local_capacity,  gdmem.local_size());
      72           4 :   EXPECT_EQ_U(postcommit_local_capacity,  gdmem.lend(dash::myid()) -
      73           0 :                                           gdmem.lbegin(dash::myid()));
      74           4 :   EXPECT_EQ_U(postcommit_global_capacity, gdmem.size());
      75             : }
      76             : 
      77          20 : TEST_F(GlobDynamicMemTest, UnbalancedRealloc)
      78             : {
      79             :   typedef int value_t;
      80             : 
      81           4 :   if (dash::size() < 2) {
      82             :     LOG_MESSAGE(
      83             :       "GlobDynamicMemTest.UnbalancedRealloc requires at least two units");
      84           0 :     return;
      85             :   }
      86             : 
      87             :   LOG_MESSAGE("initializing GlobDynamicMem<T>");
      88             : 
      89           4 :   size_t initial_local_capacity  = 10;
      90           4 :   size_t initial_global_capacity = dash::size() * initial_local_capacity;
      91           8 :   dash::GlobDynamicMem<value_t> gdmem(initial_local_capacity);
      92             : 
      93             :   LOG_MESSAGE("initial global capacity: %d, initial local capacity: %d",
      94             :               initial_global_capacity, initial_local_capacity);
      95             : 
      96           4 :   EXPECT_EQ_U(initial_local_capacity,  gdmem.local_size());
      97           4 :   EXPECT_EQ_U(initial_local_capacity,  gdmem.lend(dash::myid()) -
      98           0 :                                        gdmem.lbegin(dash::myid()));
      99           4 :   EXPECT_EQ_U(initial_global_capacity, gdmem.size());
     100             : 
     101           4 :   dash::barrier();
     102             : 
     103             :   // Total changes of local capacity:
     104           4 :   int unit_0_lsize_diff = 120;
     105           4 :   int unit_1_lsize_diff =   6;
     106           4 :   int unit_x_lsize_diff =   5;
     107           4 :   int gsize_diff        = unit_0_lsize_diff +
     108             :                           unit_1_lsize_diff +
     109           4 :                           (dash::size() - 2) * unit_x_lsize_diff;
     110             : 
     111             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     112             :                  "begin local reallocation");
     113             :   // Extend local size, changes should be locally visible immediately:
     114           4 :   if (dash::myid() == 0) {
     115           1 :     gdmem.grow(unit_0_lsize_diff);
     116           1 :     EXPECT_EQ_U(initial_local_capacity + unit_0_lsize_diff,
     117           0 :                 gdmem.local_size());
     118             :   }
     119           3 :   else if (dash::myid() == 1) {
     120           1 :     gdmem.grow(unit_1_lsize_diff);
     121           1 :     EXPECT_EQ_U(initial_local_capacity + unit_1_lsize_diff,
     122           0 :                 gdmem.local_size());
     123             :   } else {
     124           2 :     gdmem.grow(unit_x_lsize_diff);
     125           2 :     EXPECT_EQ_U(initial_local_capacity + unit_x_lsize_diff,
     126           0 :                 gdmem.local_size());
     127             :   }
     128             : 
     129           4 :   dash::barrier();
     130             :   LOG_MESSAGE("before commit: global size: %d, local size: %d",
     131             :                gdmem.size(), gdmem.local_size());
     132             : 
     133           4 :   gdmem.commit();
     134             : 
     135             :   LOG_MESSAGE("after commit: global size: %d, local size: %d",
     136             :                gdmem.size(), gdmem.local_size());
     137             : 
     138             :   // Global size should be updated after commit:
     139           4 :   EXPECT_EQ_U(initial_global_capacity + gsize_diff, gdmem.size());
     140             : 
     141             :   // Local sizes should be unchanged after commit:
     142           4 :   if (dash::myid() == 0) {
     143           1 :     EXPECT_EQ_U(initial_local_capacity + unit_0_lsize_diff,
     144           0 :                 gdmem.local_size());
     145             :   }
     146           3 :   else if (dash::myid() == 1) {
     147           1 :     EXPECT_EQ_U(initial_local_capacity + unit_1_lsize_diff,
     148           0 :                 gdmem.local_size());
     149             :   } else {
     150           2 :     EXPECT_EQ_U(initial_local_capacity + unit_x_lsize_diff,
     151           0 :                 gdmem.local_size());
     152             :   }
     153           4 :   dash::barrier();
     154             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     155             :                  "size checks after commit completed");
     156             : 
     157             :   // Initialize values in reallocated memory:
     158           4 :   auto lmem = gdmem.lbegin();
     159           4 :   auto lcap = gdmem.local_size();
     160         180 :   for (int li = 0; li < lcap; ++li) {
     161         176 :     auto value = 1000 * (dash::myid() + 1) + li;
     162             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     163             :                    "setting local offset", li, "at unit", dash::myid(),
     164             :                    "value:", value);
     165         176 :     lmem[li] = value;
     166             :   }
     167           4 :   dash::barrier();
     168             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     169             :                  "initialization of local values completed");
     170             : 
     171           4 :   if (dash::myid() == 0) {
     172             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     173             :                    "testing basic iterator arithmetic");
     174             : 
     175             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc", "git_first");
     176           1 :     auto git_first  = gdmem.begin();
     177             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc", "git_second");
     178           1 :     auto git_second = git_first + 1;
     179             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc", "git_remote");
     180           1 :     auto git_remote = git_first + gdmem.local_size() + 1;
     181             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc", "git_last");
     182           1 :     auto git_last   = git_first + gdmem.size() - 1;
     183             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc", "git_end");
     184           1 :     auto git_end    = git_first + gdmem.size();
     185             :   }
     186           4 :   dash::barrier();
     187             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     188             :                  "testing basic iterator arithmetic completed");
     189             : 
     190             :   // Test memory space of units separately:
     191          20 :   for (dart_unit_t unit = 0; unit < dash::size(); ++unit) {
     192          16 :     if (dash::myid() != unit) {
     193          12 :       auto unit_git_begin = gdmem.at(unit, 0);
     194          12 :       auto unit_git_end   = gdmem.at(unit, gdmem.local_size(unit));
     195          12 :       auto exp_l_capacity = initial_local_capacity;
     196          12 :       if (unit == 0) {
     197           3 :         exp_l_capacity += unit_0_lsize_diff;
     198           9 :       } else if (unit == 1) {
     199           3 :         exp_l_capacity += unit_1_lsize_diff;
     200             :       } else {
     201           6 :         exp_l_capacity += unit_x_lsize_diff;
     202             :       }
     203             :       DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     204             :                      "remote unit:",          unit,
     205             :                      "expected local size:",  exp_l_capacity,
     206             :                      "gdm.local_size(unit):", gdmem.local_size(unit),
     207             :                      "git_end - git_begin:",  unit_git_end - unit_git_begin);
     208          12 :       EXPECT_EQ_U(exp_l_capacity, gdmem.local_size(unit));
     209          12 :       EXPECT_EQ_U(exp_l_capacity, unit_git_end - unit_git_begin);
     210          12 :       int l_idx = 0;
     211         540 :       for(auto it = unit_git_begin; it != unit_git_end; ++it, ++l_idx) {
     212             :         DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     213             :                        "requesting element at",
     214             :                        "local offset", l_idx,
     215             :                        "from unit",    unit);
     216         528 :         auto gptr = it.dart_gptr();
     217             :         DASH_LOG_TRACE_VAR("GlobDynamicMemTest.UnbalancedRealloc", gptr);
     218             : 
     219             :         // request value via DART global pointer:
     220             :         value_t dart_gptr_value;
     221         528 :         dart_get_blocking(&dart_gptr_value, gptr, sizeof(value_t));
     222             :         DASH_LOG_TRACE_VAR("GlobDynamicMemTest.UnbalancedRealloc", dart_gptr_value);
     223             : 
     224             :         // request value via DASH global iterator:
     225         528 :         value_t git_value = *it;
     226             :         DASH_LOG_TRACE_VAR("GlobDynamicMemTest.UnbalancedRealloc", git_value);
     227             : 
     228         528 :         value_t expected = 1000 * (unit + 1) + l_idx;
     229         528 :         EXPECT_EQ_U(expected, dart_gptr_value);
     230         528 :         EXPECT_EQ_U(expected, git_value);
     231             :       }
     232             :     }
     233             :   }
     234           4 :   dash::barrier();
     235             : 
     236             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     237             :                  "testing reverse iteration");
     238             : 
     239             :   // Test memory space of all units by iterating global index space:
     240           4 :   auto unit         = dash::size() - 1;
     241           4 :   auto local_offset = gdmem.local_size(unit) - 1;
     242             :   // Invert order to test reverse iterators:
     243           4 :   auto rgend        = gdmem.rend();
     244           4 :   EXPECT_EQ_U(gdmem.size(), gdmem.rend() - gdmem.rbegin());
     245         708 :   for (auto rgit = gdmem.rbegin(); rgit != rgend; ++rgit) {
     246             :     DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     247             :                    "requesting element at",
     248             :                    "local offset", local_offset,
     249             :                    "from unit",    unit);
     250         704 :     value_t expected   = 1000 * (unit + 1) + local_offset;
     251         704 :     value_t rgit_value = *rgit;
     252             :     DASH_LOG_TRACE_VAR("GlobDynamicMemTest.UnbalancedRealloc", rgit_value);
     253         704 :     value_t git_value  = *gdmem.at(unit, local_offset);
     254             :     DASH_LOG_TRACE_VAR("GlobDynamicMemTest.UnbalancedRealloc", git_value);
     255             : 
     256         704 :     EXPECT_EQ_U(expected, rgit_value);
     257         704 :     EXPECT_EQ_U(expected, git_value);
     258         704 :     if (local_offset == 0 && unit > 0) {
     259          12 :       --unit;
     260          12 :       local_offset = gdmem.local_size(unit);
     261             :     }
     262         704 :     --local_offset;
     263             :   }
     264             : 
     265             :   DASH_LOG_TRACE("GlobDynamicMemTest.UnbalancedRealloc",
     266             :                  "testing reverse iteration completed");
     267             : }
     268             : 
     269          20 : TEST_F(GlobDynamicMemTest, LocalVisibility)
     270             : {
     271             :   typedef int value_t;
     272             : 
     273           4 :   if (dash::size() < 2) {
     274             :     LOG_MESSAGE(
     275             :       "GlobDynamicMemTest.LocalVisibility requires at least two units");
     276           0 :     return;
     277             :   }
     278             : 
     279             :   LOG_MESSAGE("initializing GlobDynamicMem<T>");
     280             : 
     281           4 :   size_t initial_local_capacity  = 10;
     282           4 :   size_t initial_global_capacity = dash::size() * initial_local_capacity;
     283           8 :   dash::GlobDynamicMem<value_t> gdmem(initial_local_capacity);
     284             : 
     285             :   LOG_MESSAGE("initial global capacity: %d, initial local capacity: %d",
     286             :               initial_global_capacity, initial_local_capacity);
     287           4 :   dash::barrier();
     288             : 
     289             :   // Total changes of local capacity:
     290           4 :   int unit_0_lsize_diff =  5;
     291           4 :   int unit_1_lsize_diff = -2;
     292             : 
     293           4 :   if (dash::myid() == 0) {
     294             :     // results in 2 buckets to attach, 0 to detach
     295           1 :     gdmem.grow(3);
     296           1 :     gdmem.shrink(2);
     297           1 :     gdmem.grow(5);
     298           1 :     gdmem.shrink(1);
     299             :   }
     300           4 :   if (dash::myid() == 1) {
     301             :     // results in 0 buckets to attach, 0 to detach
     302           1 :     gdmem.shrink(2);
     303           1 :     gdmem.grow(5);
     304           1 :     gdmem.shrink(2);
     305           1 :     gdmem.shrink(3);
     306             :   }
     307             : 
     308           4 :   dash::barrier();
     309             :   LOG_MESSAGE("global size: %d, local size: %d",
     310             :                gdmem.size(), gdmem.local_size());
     311             : 
     312             :   // Global memory space has not been updated yet, changes are only
     313             :   // visible locally.
     314             :   //
     315             :   // NOTE:
     316             :   // Local changes at units in same shared memory domain are visible
     317             :   // even when not committed yet.
     318           8 :   std::string my_host     = dash::util::Locality::Hostname(dash::myid());
     319           8 :   std::string unit_0_host = dash::util::Locality::Hostname(0);
     320           8 :   std::string unit_1_host = dash::util::Locality::Hostname(1);
     321             : 
     322           4 :   size_t expected_visible_size = initial_global_capacity;
     323           4 :   size_t expected_global_size  = initial_global_capacity;
     324           4 :   if (dash::myid() == 0) {
     325           1 :     expected_visible_size += unit_0_lsize_diff;
     326           1 :     if (my_host == unit_1_host) {
     327             :       LOG_MESSAGE("expected visible size: %d (locally) or %d (shmem)",
     328             :                   expected_visible_size,
     329             :                   expected_visible_size + unit_1_lsize_diff);
     330             :       // same shared memory domain as unit 1, changes at unit 1 might already
     331             :       // be visible to this unit:
     332           1 :       EXPECT_TRUE_U(
     333             :         gdmem.size() == expected_visible_size ||
     334           0 :         gdmem.size() == expected_visible_size + unit_1_lsize_diff);
     335             :     } else {
     336           0 :       EXPECT_EQ_U(expected_visible_size, gdmem.size());
     337             :     }
     338             :   }
     339           4 :   if (dash::myid() == 1) {
     340           1 :     expected_visible_size += unit_1_lsize_diff;
     341           1 :     if (my_host == unit_0_host) {
     342             :       LOG_MESSAGE("expected visible size: %d (locally) or %d (shmem)",
     343             :                   expected_visible_size,
     344             :                   expected_visible_size + unit_0_lsize_diff);
     345             :       // same shared memory domain as unit 0, changes at unit 0 might already
     346             :       // be visible to this unit:
     347           1 :       EXPECT_TRUE_U(
     348             :         gdmem.size() == expected_visible_size ||
     349           0 :         gdmem.size() == expected_visible_size + unit_0_lsize_diff);
     350             :     } else {
     351           0 :       EXPECT_EQ_U(expected_visible_size, gdmem.size());
     352             :     }
     353             :   }
     354             : 
     355           4 :   dash::barrier();
     356             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     357             :                  "tests of visible memory size before commit passed");
     358             : 
     359             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     360             :                  "testing local capacities after grow/shrink");
     361           4 :   auto local_size = gdmem.lend() - gdmem.lbegin();
     362           4 :   EXPECT_EQ_U(local_size, gdmem.local_size());
     363           4 :   if (dash::myid() == 0) {
     364           1 :     EXPECT_EQ_U(local_size, initial_local_capacity + unit_0_lsize_diff);
     365           3 :   } else if (dash::myid() == 1) {
     366           1 :     EXPECT_EQ_U(local_size, initial_local_capacity + unit_1_lsize_diff);
     367             :   } else {
     368           2 :     EXPECT_EQ_U(local_size, initial_local_capacity);
     369             :   }
     370             : 
     371             :   // Initialize values in local memory:
     372             :   LOG_MESSAGE("initialize local values");
     373           4 :   auto lbegin = gdmem.lbegin();
     374          47 :   for (size_t li = 0; li < gdmem.local_size(); ++li) {
     375          43 :     value_t value = 100 * (dash::myid() + 1) + li;
     376             :     DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     377             :                    "local[", li, "] =", value);
     378          43 :     *(lbegin + li) = value;
     379             :   }
     380             : 
     381           4 :   dash::barrier();
     382             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     383             :                  "tests of local capacities after grow/shrink passed");
     384             : 
     385             :   // Memory marked for deallocation is still accessible by other units:
     386             : 
     387             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     388             :                  "committing global memory");
     389             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     390             :                  "local capacity before commit:",  gdmem.local_size());
     391             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     392             :                  "global capacity before commit:", gdmem.size());
     393             :   // Collectively commit changes of local memory allocation to global
     394             :   // memory space:
     395             :   // register newly allocated local memory and remove local memory marked
     396             :   // for deallocation.
     397           4 :   gdmem.commit();
     398             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility", "commit completed");
     399             : 
     400             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     401             :                  "local capacity after commit:",  gdmem.local_size());
     402             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     403             :                  "global capacity after commit:", gdmem.size());
     404             : 
     405             :   // Changes are globally visible now:
     406           4 :   auto expected_global_capacity = initial_global_capacity +
     407           4 :                                   unit_0_lsize_diff + unit_1_lsize_diff;
     408           4 :   EXPECT_EQ_U(expected_global_capacity, gdmem.size());
     409             : 
     410           4 :   if (dash::myid() == 0) {
     411             :     DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility", "grow(30)");
     412             :     LOG_MESSAGE("grow(30)");
     413           1 :     gdmem.grow(30);
     414             :   }
     415           4 :   if (dash::myid() == 1) {
     416             :     DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility", "grow(30)");
     417           1 :     gdmem.grow(30);
     418             :   }
     419             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     420             :                  "commit, balanced attach");
     421           4 :   gdmem.commit();
     422             :   // Capacity changes have been published globally:
     423           4 :   expected_global_capacity += (30 + 30);
     424           4 :   EXPECT_EQ(expected_global_capacity, gdmem.size());
     425             : 
     426           4 :   if (dash::myid() == 0) {
     427             :     // resizes attached bucket:
     428             :     DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility", "shrink(29)");
     429           1 :     gdmem.shrink(29);
     430             :   }
     431           4 :   if (dash::myid() == 1) {
     432             :     // marks bucket for detach:
     433             :     DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility", "shrink(30)");
     434           1 :     gdmem.shrink(30);
     435             :   }
     436             :   DASH_LOG_TRACE("GlobDynamicMemTest.LocalVisibility",
     437             :                  "commit, unbalanced detach");
     438           4 :   gdmem.commit();
     439             :   // Capacity changes have been published globally:
     440           4 :   expected_global_capacity -= (29 + 30);
     441           4 :   EXPECT_EQ(expected_global_capacity, gdmem.size());
     442             : }
     443             : 
     444          20 : TEST_F(GlobDynamicMemTest, RemoteAccess)
     445             : {
     446             :   typedef int value_t;
     447             : 
     448           4 :   if (dash::size() < 3) {
     449             :     LOG_MESSAGE(
     450             :       "GlobDynamicMemTest.RemoteAccess requires at least three units");
     451           0 :     return;
     452             :   }
     453             : 
     454             :   /* Illustration of the test case:
     455             :    *
     456             :    *  unit 0:
     457             :    *
     458             :    *  size: 10              size: 15                    size: 15
     459             :    * .-------------. grow  .-------------.----. init   .--------.----------.
     460             :    * |             | ----> |             |    | -----> | 0 1 .. | .. 13 14 |
     461             :    * '-------------`       '-------------'-/--'        '---/----'-----/----'
     462             :    *                                      /               /          /
     463             :    *                                  allocated,      attached,  unattached,
     464             :    *                                  locally         globally   locally
     465             :    *                                  visible         visible    visible
     466             :    *  unit 1:
     467             :    *
     468             :    *  size: 10              size: 10                    size: 8
     469             :    * .-------------. init  .-------------.   shrink    .---------.-----.
     470             :    * |             | ----> | 0 1 ... 8 9 | --------->  | 0 1 2 ..| 8 9 |
     471             :    * '-------------`       '-------------'             '--/------'--/--'
     472             :    *                                                     /         /
     473             :    *                                                attached,   attached,
     474             :    *                                                globally    visible to
     475             :    *                                   |            visible     remote units
     476             :    *                                   :
     477             :    *                                   '
     478             :    * =============================== COMMIT ==================================
     479             :    *                                   :
     480             :    *                                  \|/
     481             :    *  unit 0:                          V      unit 1:
     482             :    *
     483             :    *  size: 15                                size: 8
     484             :    * .----------------------------------.    .-----------------..-----.
     485             :    * | 0 1 2 3 4 5 6 ... 10 11 12 13 14 |    | 0 1 2 3 4 5 6 7 || x x |
     486             :    * '--------/-------------------------'    '--------/--------''---/-'
     487             :    *         /                                       /             /
     488             :    *     attached,                               attached,     detached,
     489             :    *     globally                                globally      deallocated
     490             :    *     visible                                 visible
     491             :    */
     492           4 :   size_t initial_local_capacity  = 10;
     493           4 :   size_t initial_global_capacity = dash::size() * initial_local_capacity;
     494           8 :   dash::GlobDynamicMem<value_t> gdmem(initial_local_capacity);
     495             : 
     496           4 :   int unit_0_num_grow   = 5;
     497           4 :   int unit_1_num_shrink = 2;
     498             : 
     499           4 :   if (dash::myid() == 0) {
     500           1 :     gdmem.resize(initial_global_capacity + unit_0_num_grow);
     501             :   }
     502             : 
     503           4 :   EXPECT_EQ_U(gdmem.local_size(),
     504           0 :               std::distance(gdmem.lbegin(), gdmem.lend()));
     505             : 
     506             :   // Initialize values in local memory:
     507           4 :   auto lbegin = gdmem.lbegin();
     508             :   DASH_LOG_TRACE("GlobDynamicMemTest.RemoteAccess",
     509             :                  "globmem.lbegin():", lbegin);
     510          49 :   for (size_t li = 0; li < gdmem.local_size(); ++li) {
     511          45 :     value_t value  = (100 * (dash::myid() + 1)) + li;
     512             :     DASH_LOG_TRACE("GlobDynamicMemTest.RemoteAccess",
     513             :                    "local[", li, "] =", value);
     514          45 :     *(lbegin + li) = value;
     515             :   }
     516             :   // Shrink after initialization of local values so elements in the locally
     517             :   // removed memory segment have meaningful values.
     518           4 :   if (dash::myid() == 1) {
     519           1 :     gdmem.resize(initial_global_capacity - unit_1_num_shrink);
     520             :   }
     521             : 
     522             :   // Wait for initialization of local values of all units:
     523           4 :   dash::barrier();
     524             : 
     525          20 :   for (int u = 0; u < dash::size(); ++u) {
     526          16 :     if (dash::myid() != u) {
     527          12 :       size_t  nlocal_expect = initial_local_capacity;
     528          12 :       size_t  nlocal_elem   = gdmem.local_size(u);
     529             : 
     530          12 :       EXPECT_EQ_U(nlocal_expect, nlocal_elem);
     531             :       DASH_LOG_DEBUG("GlobDynamicMemTest.RemoteAccess",
     532             :                      "requesting element from unit", u,
     533             :                      "before commit,", "local capacity:", nlocal_elem);
     534         132 :       for (size_t lidx = 0; lidx < nlocal_elem; ++lidx) {
     535             :         // Retreive global pointer from local-to-global address resolution
     536             :         // provided my global memory management:
     537         120 :         auto    u_last_elem = gdmem.at(u, lidx);
     538         120 :         value_t expected    = (100 * (u + 1)) + lidx;
     539             :         value_t actual;
     540             :         // Request value from unit u via dart_get on global pointer:
     541         120 :         dash::get_value(&actual, u_last_elem);
     542         120 :         EXPECT_EQ_U(expected, actual);
     543             :       }
     544             :     }
     545             :   }
     546             : 
     547           4 :   gdmem.commit();
     548             : 
     549             :   // Changed sizes of memory spaces are visible to all units after commit:
     550           4 :   EXPECT_EQ_U(initial_local_capacity + unit_0_num_grow,
     551           0 :               gdmem.local_size(0));
     552           4 :   EXPECT_EQ_U(initial_local_capacity - unit_1_num_shrink,
     553           0 :               gdmem.local_size(1));
     554             : 
     555             :   // Validate values after commit:
     556          20 :   for (int u = 0; u < dash::size(); ++u) {
     557          16 :     if (dash::myid() != u) {
     558          12 :       size_t  nlocal_elem   = gdmem.local_size(u);
     559          12 :       size_t  nlocal_expect = initial_local_capacity;
     560          12 :       if (u == 0) { nlocal_expect += unit_0_num_grow; }
     561          12 :       if (u == 1) { nlocal_expect -= unit_1_num_shrink; }
     562             : 
     563          12 :       EXPECT_EQ_U(nlocal_expect, nlocal_elem);
     564             :       DASH_LOG_DEBUG("GlobDynamicMemTest.RemoteAccess",
     565             :                      "requesting element from unit", u,
     566             :                      "after commit,", "local capacity:", nlocal_elem);
     567         141 :       for (size_t lidx = 0; lidx < nlocal_elem; ++lidx) {
     568             :         // Retreive global pointer from local-to-global address resolution
     569             :         // Retreive global pointer from local-to-global address resolution
     570             :         // provided my global memory management:
     571         129 :         auto    u_last_elem = gdmem.at(u, lidx);
     572         129 :         value_t expected    = (100 * (u + 1)) + lidx;
     573             :         value_t actual;
     574             :         // Request value from unit u via dart_get on global pointer:
     575         129 :         dash::get_value(&actual, u_last_elem);
     576         129 :         EXPECT_EQ_U(expected, actual);
     577             :       }
     578             :     }
     579             :   }
     580          12 : }

Generated by: LCOV version 1.12