DASH  0.3.0
main.cpp
1 #include <libdash.h>
2 
3 #include <sstream>
4 #include <iostream>
5 #include <iomanip>
6 #include <ctime>
7 #include <cstdlib>
8 #include <cassert>
9 
10 using std::cout;
11 using std::endl;
12 
13 #define COUT(expr) { \
14  std::ostringstream os; \
15  os << expr; \
16  std::cout << os.str(); \
17  } do { } while(0)
18 
22 template<typename Key>
23 class MyHash
24 {
25 private:
26  typedef dash::default_size_t size_type;
27 
28 public:
29  typedef Key argument_type;
30  typedef dash::team_unit_t result_type;
31 
32 public:
37  : _team(nullptr),
38  _nunits(0),
40  { }
41 
46  dash::Team & team)
47  : _team(&team),
48  _nunits(team.size()),
49  _myid(team.myid())
50  { }
51 
52  result_type operator()(
53  const argument_type & key) const
54  {
55  if (_nunits == 0) {
56  return result_type{0};
57  }
58  return result_type((key ^ 0xAA) % _nunits);
59  }
60 
61 private:
62  dash::Team * _team = nullptr;
63  size_type _nunits = 0;
64  dash::team_unit_t _myid;
65 
66 }; // class HashLocal
67 
68 typedef int key_t;
69 typedef double mapped_t;
70 typedef MyHash<key_t> hash_t;
72 typedef typename map_t::iterator map_iterator;
73 typedef typename map_t::value_type value_t;
74 typedef typename map_t::size_type size_type;
75 
76 
77 template<typename InputIt>
78 void print_map(InputIt first, InputIt last)
79 {
80  int idx = 0;
81  for (auto mit = first; mit != last; ++mit) {
82  value_t elem = *mit;
83  auto lpos = mit.lpos();
84  COUT(std::setw(3) << idx << ": "
85  << "unit:" << std::setw(2) << lpos.unit << ", "
86  << "lidx:" << std::setw(3) << lpos.index << " "
87  << "value:"
88  << std::setw(5)
89  << elem.first
90  << " -> "
91  << std::setprecision(3) << std::fixed
92  << static_cast<mapped_t>(elem.second)
93  << endl);
94  idx++;
95  }
96 }
97 
98 int main(int argc, char* argv[])
99 {
100  dash::init(&argc, &argv);
101 
103  size_t num_units = dash::Team::All().size();
104 
105  // Number of preallocated elements:
106  size_type init_global_size = 0;
107  // Local buffer size determines initial local capacity and size of
108  // new buckets that are allocated when local capacity is reached.
109  // In effect, larger buffer sizes reduce allocation calls but may lead
110  // to unused allocated memory.
111  // Local buffer sizes may differ between units.
112  size_type bucket_size = (myid % 2 == 0) ? 5 : 7;
113 
114  size_type min_elem_per_unit = 5;
115  size_type max_elem_per_unit = 12;
116  if (argc >= 3) {
117  min_elem_per_unit = static_cast<size_type>(atoi(argv[1]));
118  max_elem_per_unit = static_cast<size_type>(atoi(argv[2]));
119  }
120 
121  dash::UnorderedMap<key_t, mapped_t, hash_t> map(init_global_size,
122  bucket_size);
123 
124  if (myid == 0) {
125  COUT(endl
126  << "ex.02.unordered_map <min inserts> <max inserts>" << endl
127  << " min. number of elements inserted per unit: "
128  << min_elem_per_unit << endl
129  << " max. number of elements inserted per unit: "
130  << max_elem_per_unit << endl
131  << endl
132  << "Initial map size: " << map.size()
133  << endl);
134  }
135 
136  dash::barrier();
137 
138  COUT("Initial local map size (unit " << myid << "): " << map.lsize());
139 
140  dash::barrier();
141 
142  // fresh random numbers for every run and unit:
143  std::srand(std::time(0) + myid);
144  size_type num_add_elem = min_elem_per_unit + (
145  std::rand() %
146  (max_elem_per_unit - min_elem_per_unit));
147 
148  for (auto i = 0; i < num_add_elem; i++) {
149  key_t key = 100 * (myid+1) + i;
150  mapped_t mapped = 1.000 * (myid+1) + ((i+1) * 0.001);
151  value_t value = std::make_pair(key, mapped);
152 
153  // Satisfies map concept as specified in STL
154  auto insertion = map.insert(value);
155  bool key_existed = !insertion.second;
156  auto inserted_it = insertion.first;
157  assert(!key_existed);
158  assert(map.count(key) == 1);
159 
160  mapped_t new_mapped_val = mapped + 400;
161  // Access and modify mapped value directly:
162  map[key] = new_mapped_val;
163 
164  // Read inserted value back:
165  auto read_it = map.find(key);
166  value_t read_value = *read_it;
167  assert(read_it != map.end());
168 
169  assert(read_value.second == new_mapped_val);
170  }
171  // Wait for initialization of local values:
172  dash::barrier();
173 
174  COUT("Local map size after inserts (unit " << myid << "): " << map.lsize());
175 
176  dash::barrier();
177 
178  if (myid == 0) {
179  COUT(endl
180  << "Map size before commit: " << map.size() << endl
181  << "Elements accessible to unit 0 before commit: " << endl);
182  print_map(map.begin(), map.end());
183  }
184 
185  // Commit elements in local buffer and synchronize local memory spaces:
186  map.barrier();
187 
188  if (myid == 0) {
189  COUT(endl
190  << "Size of map after commit: " << map.size() << endl
191  << "Elements accessible to unit 0 after commit: ");
192  print_map(map.begin(), map.end());
193  }
194 }
MyHash(dash::Team &team)
Constructor.
Definition: main.cpp:45
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
internal::default_unsigned_index default_size_t
Unsigned integer type used as default for size values.
Definition: Types.h:69
size_type size() const noexcept
The size of the map.
size_t size()
Return the number of units in the global team.
Hash functor for mapping element keys to units.
Definition: main.cpp:23
int32_t dart_unit_t
Data type for storing a unit ID.
Definition: dart_types.h:154
size_type lsize() const noexcept
The number of elements in the local part of the map.
MyHash()
Default constructor.
Definition: main.cpp:36
size_t size() const
The number of units in this team.
Definition: Team.h:498
A Team instance specifies a subset of all available units.
Definition: Team.h:41
iterator & begin() noexcept
Global iterator to the beginning of the map.
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
Definition: Types.h:319
iterator & end() noexcept
Global iterator to the end of the map.
#define DART_UNDEFINED_UNIT_ID
Undefined unit ID.
Definition: dart_types.h:160
void barrier()
A global barrier involving all units.
void barrier()
Synchronize changes on local and global memory space of the map since initialization or the last call...
static Team & All()
The invariant Team instance containing all available units.
Definition: Team.h:213
void init(int *argc, char ***argv)
Initialize the DASH library and the underlying runtime system.
iterator find(const key_type &key)
Get iterator to element with specified key.
std::pair< iterator, bool > insert(const value_type &value)
Insert a new element as key-value pair, increasing the container size by 1.
size_type count(const key_type &key) const
Count elements with a specific key.