DASH  0.3.0
main.cpp
1 
9 #ifdef DASH_ENABLE_IPM
10 #include <mpi.h>
11 #endif
12 
13 #include <math.h>
14 #include <stdio.h>
15 #include <assert.h>
16 #include <stdint.h>
17 
18 #include <iostream>
19 
20 #include <libdash.h>
21 
22 #ifndef N
23 #define N (25)
24 #endif
25 
26 #define TableSize (1ULL<<N)
27 #define NUPDATE (4ULL * TableSize)
28 
29 #define POLY 0x0000000000000007ULL
30 #define PERIOD 1317624576693539401LL
31 
32 typedef uint64_t
33  value_t;
34 typedef int64_t
35  index_t;
36 typedef dash::CSRPattern<1, dash::ROW_MAJOR, index_t>
37  pattern_t;
38 typedef typename pattern_t::size_type
39  extent_t;
41  Timer;
42 
43 typedef struct benchmark_params_t {
44  size_t size_base;
45  size_t num_updates;
46  size_t rep_base;
47  bool verify;
49 
50 using std::cout;
51 using std::endl;
52 using std::setw;
53 
55 
56 
57 template<typename T>
58 void print(dash::Array<T>& arr)
59 {
60  for (auto el: arr) {
61  std::cout << el << " ";
62  }
63  std::cout << std::endl;
64 }
65 
66 uint64_t starts(int64_t n)
67 {
68  int i;
69  uint64_t m2[64];
70  uint64_t temp, ran;
71 
72  while (n < 0) n += PERIOD;
73  while (n > PERIOD) n -= PERIOD;
74 
75  if (n == 0)
76  return 0x1;
77 
78  temp = 0x1;
79  for (i=0; i<64; i++) {
80  m2[i] = temp;
81  temp = (temp << 1) ^ ((int64_t) temp < 0 ? POLY : 0);
82  temp = (temp << 1) ^ ((int64_t) temp < 0 ? POLY : 0);
83  }
84 
85  for (i=62; i>=0; i--) if ((n >> i) & 1) break;
86 
87  ran = 0x2;
88  while (i > 0) {
89  temp = 0;
90  for (int j=0; j<64; j++) if ((ran >> j) & 1) temp ^= m2[j];
91  ran = temp;
92  i -= 1;
93  if ((n >> i) & 1) ran = (ran << 1) ^ ((int64_t) ran < 0 ? POLY : 0);
94  }
95 
96  return ran;
97 }
98 
99 void RandomAccessUpdate(const benchmark_params & params)
100 {
101  uint64_t i;
102  uint64_t ran = starts(params.num_updates / dash::size() * dash::myid());
103  auto table_size = params.size_base;
104 
105  for (i = dash::myid(); i < params.num_updates; i += dash::size()) {
106  ran = (ran << 1) ^ (((int64_t) ran < 0) ? POLY : 0);
107  int64_t g_idx = static_cast<int64_t>(ran & (table_size-1));
108  Table[g_idx] ^= ran;
109  }
110 }
111 
112 uint64_t RandomAccessVerify(const benchmark_params & params)
113 {
114  uint64_t i, localerrors, errors;
115  auto table_size = params.size_base;
116  localerrors = 0;
117  for (i = dash::myid(); i < table_size; i += dash::size()) {
118  if (Table[i] != i) {
119  localerrors++;
120  }
121  }
122  errors = localerrors;
123  return errors;
124 }
125 
126 void perform_test(const benchmark_params & params);
127 
128 benchmark_params parse_args(int argc, char * argv[]);
129 
130 void print_params(
131  const dash::util::BenchmarkParams & bench_cfg,
132  const benchmark_params & params);
133 
134 
135 int main(int argc, char **argv)
136 {
137  DASH_LOG_DEBUG("bench.gups", "main()");
138 
139  dash::init(&argc, &argv);
140 #ifdef DASH_ENABLE_IPM
141  MPI_Pcontrol(0, "off");
142 #endif
143 
144  Timer::Calibrate(0);
145 
146  dash::util::BenchmarkParams bench_cfg("bench.03.gups");
147 
148  bench_cfg.set_output_width(72);
149  bench_cfg.print_header();
150  bench_cfg.print_pinning();
151 
152  benchmark_params params = parse_args(argc, argv);
153  print_params(bench_cfg, params);
154 
155  perform_test(params);
156 
157  dash::finalize();
158 
159  return 0;
160 }
161 
162 void perform_test(const benchmark_params & params)
163 {
164  Timer::timestamp_t ts_start;
165  double duration_us;
166  auto array_size = params.size_base;
167  auto num_updates = params.num_updates;
168  auto ts_init_start = Timer::Now();
169 
170  DASH_LOG_DEBUG("bench.gups", "Table.allocate()");
171  Table.allocate(params.size_base, dash::BLOCKED);
172 
173  if(dash::myid() == 0) {
174  auto nunits = dash::size();
175  double bytes_total = (double)(array_size * sizeof(value_t));
176  double mb_total = bytes_total / 1024 / 1024;
177  double mb_unit = mb_total / nunits;
178  double updates_m = (double)(num_updates * 1.0e-9);
179 #ifdef DASH_MPI_IMPL_ID
180  std::string mpi_impl = dash__toxstr(DASH_MPI_IMPL_ID);
181 #else
182  std::string mpi_impl = "-";
183 #endif
184  cout << setw(6) << "units" << ","
185  << setw(12) << "size" << ","
186  << setw(9) << "mpi.impl" << ","
187  << setw(12) << "mb.total" << ","
188  << setw(12) << "mb.unit" << ","
189  << setw(12) << "updates.m" << ","
190  << setw(9) << "init.s" << ","
191  << setw(9) << "time.s" << ","
192  << setw(9) << "lat.us" << ","
193  << setw(9) << "gups" << ","
194  << setw(9) << "verified" << ","
195  << setw(9) << "errors"
196  << endl;
197  cout << setw(6) << nunits << ","
198  << setw(12) << params.size_base << ","
199  << setw(9) << mpi_impl << ","
200  << setw(12) << std::fixed << std::setprecision(2) << mb_total << ","
201  << setw(12) << std::fixed << std::setprecision(2) << mb_unit << ","
202  << setw(12) << std::fixed << std::setprecision(2) << updates_m << ","
203  << std::flush;
204  }
205 
206  // Initialize array values:
207 #if 0
208  if(dash::myid() == 0) {
209  for (uint64_t i = dash::myid(); i < TableSize; ++i) {
210  Table[i] = i;
211  }
212  }
213 #else
214  // Global offset of local array region:
215  auto l_begin_glob_offset = Table.pattern().global(0);
216  for (uint64_t i = 0; i < Table.local.size(); ++i) {
217  Table.local[i] = l_begin_glob_offset + i;
218  }
219 #endif
220  dash::barrier();
221 
222  if(dash::myid() == 0) {
223  double time_init_s = Timer::ElapsedSince(ts_init_start) * 1.0e-6;
224 
225  cout << setw(9) << std::fixed << std::setprecision(4) << time_init_s << ","
226  << std::flush;
227  }
228 
229  // Perform random access test:
230 #ifdef DASH_ENABLE_IPM
231  MPI_Pcontrol(0, "on");
232  MPI_Pcontrol(0, "clear");
233 #endif
234  ts_start = Timer::Now();
235  RandomAccessUpdate(params);
236  dash::barrier();
237  duration_us = Timer::ElapsedSince(ts_start);
238 #ifdef DASH_ENABLE_IPM
239  MPI_Pcontrol(0, "off");
240 #endif
241 
242  if(dash::myid() == 0) {
243  double gups = (static_cast<double>(params.num_updates) / 1000.0f)
244  / duration_us;
245  double latency = duration_us * dash::size() / num_updates;
246  double duration_s = (duration_us * 1.0e-6);
247  cout << setw(9) << std::fixed << std::setprecision(4) << duration_s << ","
248  << setw(9) << std::fixed << std::setprecision(4) << latency << ","
249  << setw(9) << std::fixed << std::setprecision(5) << gups << ","
250  << std::flush;
251  }
252 
253  // Verification:
254  if (params.verify) {
255  // do it again
256  RandomAccessUpdate(params);
257  dash::barrier();
258  uint64_t errors = RandomAccessVerify(params);
259  if (dash::myid() == 0) {
260  if ((double)errors/num_updates < 0.01) {
261  cout << setw(9) << "passed" << ","
262  << setw(9) << errors
263  << endl;
264  } else {
265  cout << setw(9) << "failed" << ","
266  << setw(9) << errors
267  << endl;
268  }
269  }
270  } else {
271  if (dash::myid() == 0) {
272  cout << setw(9) << "no" << ","
273  << setw(9) << 0
274  << endl;
275  }
276  }
277 }
278 
279 benchmark_params parse_args(int argc, char * argv[])
280 {
281  benchmark_params params;
282  params.size_base = TableSize;
283  params.num_updates = NUPDATE;
284  params.rep_base = 1;
285  params.verify = false;
286 
287  for (auto i = 1; i < argc; i += 2) {
288  std::string flag = argv[i];
289  if (flag == "-sb") {
290  params.size_base = atoi(argv[i+1]);
291  } else if (flag == "-rb") {
292  params.rep_base = atoi(argv[i+1]);
293  } else if (flag == "-verify") {
294  params.verify = true;
295  --i;
296  }
297  }
298  return params;
299 }
300 
301 void print_params(
302  const dash::util::BenchmarkParams & bench_cfg,
303  const benchmark_params & params)
304 {
305  if (dash::myid() != 0) {
306  return;
307  }
308 
309  bench_cfg.print_section_start("Runtime arguments");
310  bench_cfg.print_param("-sb", "size base", params.size_base);
311  bench_cfg.print_param("-rb", "rep. base", params.rep_base);
312  bench_cfg.print_param("-verify", "verification", params.verify);
313  bench_cfg.print_section_end();
314 }
315 
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
size_t size()
Return the number of units in the global team.
void finalize()
Finalize the DASH library and the underlying runtime system.
constexpr const PatternType & pattern() const noexcept
The pattern used to distribute array elements to units.
Definition: Array.h:1310
A distributed array.
Definition: Array.h:89
void barrier()
A global barrier involving all units.
void init(int *argc, char ***argv)
Initialize the DASH library and the underlying runtime system.
bool allocate(size_type nelem, dash::DistributionSpec< 1 > distribution, dash::Team &team=dash::Team::All())
Delayed allocation of global memory using a one-dimensional distribution spec.
Definition: Array.h:1319
local_type local
Local proxy object, allows use in range-based for loops.
Definition: Array.h:732