DASH  0.3.0
main.cpp
1 
7 #include <unistd.h>
8 #include <iostream>
9 #include <iomanip>
10 #include <sstream>
11 #include <fstream>
12 #include <cstddef>
13 #include <cmath>
14 
15 #include <libdash.h>
16 
17 #include <dash/tools/PatternVisualizer.h>
18 
19 #include <dash/util/PatternMetrics.h>
20 
21 #include <dash/pattern/internal/PatternLogging.h>
22 
23 // needed for basename()
24 #include <libgen.h>
25 
26 
27 using std::cout;
28 using std::cerr;
29 using std::endl;
30 
31 using namespace dash;
32 
33 typedef dash::default_index_t index_t;
34 typedef dash::default_extent_t extent_t;
35 
36 typedef struct cli_params_t {
37  cli_params_t()
38  { }
39  std::string type = "summa";
40  extent_t size_x = 110;
41  extent_t size_y = 110;
42  extent_t units_x = 10;
43  extent_t units_y = 10;
44  int tile_x = -1;
45  int tile_y = -1;
46  bool blocked_display = false;
47  bool balance_extents = false;
48  bool cout = false;
49 } cli_params;
50 
51 static const
52 cli_params default_params;
53 
54 template<typename PatternType>
55 static
56 std::string pattern_to_string(
57  const PatternType & pattern);
58 
59 template<typename PatternType>
60 static
61 std::string pattern_to_filename(
62  const PatternType & pattern);
63 
64 static
65 void print_usage(char **argv);
66 
67 static
68 cli_params parse_args(int argc, char * argv[]);
69 static
70 void print_params(const cli_params & params);
71 
72 template<typename PatternT>
73 static
74 void print_pattern_metrics(const PatternT & pattern);
75 
76 template<typename PatternT>
77 static
78 void print_example(
79  const PatternT & pattern,
80  const cli_params & params)
81 {
82  typedef typename PatternT::index_type index_t;
83 
84  auto pattern_file = pattern_to_filename(pattern);
85  auto pattern_desc = pattern_to_string(pattern);
86  print_pattern_metrics(pattern);
87 
89  pv.set_title(pattern_desc);
90 
91  cerr << "Generating visualization of "
92  << endl
93  << " " << pattern_desc
94  << endl;
95 
96  if (params.cout) {
97  pv.draw_pattern(std::cout, params.blocked_display);
98  } else {
99  cerr << "Image file:"
100  << endl
101  << " " << pattern_file
102  << endl;
103  std::ofstream out(pattern_file);
104  pv.draw_pattern(out, params.blocked_display);
105  out.close();
106  }
107 }
108 
109 static
111 make_summa_pattern(
112  const cli_params & params,
113  const dash::SizeSpec<2, extent_t> & sizespec,
114  const dash::TeamSpec<2, index_t> & teamspec)
115 {
116  auto pattern = dash::make_pattern<
120  sizespec,
121  teamspec);
122 
123  if (params.tile_x >= 0 || params.tile_y >= 0) {
124  // change tile sizes of deduced pattern:
125  typedef decltype(pattern) pattern_t;
126  pattern_t custom_pattern(sizespec,
128  params.tile_x > 0
129  ? dash::TILE(params.tile_x)
130  : dash::NONE,
131  params.tile_y > 0
132  ? dash::TILE(params.tile_y)
133  : dash::NONE),
134  teamspec);
135  pattern = custom_pattern;
136  }
137  return pattern;
138 }
139 
140 static
142 make_shift_tile_pattern(
143  const cli_params & params,
144  const dash::SizeSpec<2, extent_t> & sizespec,
145  const dash::TeamSpec<2, index_t> & teamspec)
146 {
147  // Example: -n 1680 1680 -u 28 1 -t 60 60
148  typedef dash::ShiftTilePattern<2> pattern_t;
149  pattern_t pattern(sizespec,
151  dash::TILE(params.tile_y),
152  dash::TILE(params.tile_x)),
153  teamspec);
154  return pattern;
155 }
156 
157 static
159 make_seq_tile_pattern(
160  const cli_params & params,
161  const dash::SizeSpec<2, extent_t> & sizespec,
162  const dash::TeamSpec<2, index_t> & teamspec)
163 {
164  // Example: -n 30 30 -u 4 1 -t 10 10
165  typedef dash::SeqTilePattern<2> pattern_t;
166  pattern_t pattern(sizespec,
168  dash::TILE(params.tile_y),
169  dash::TILE(params.tile_x)),
170  teamspec);
171  return pattern;
172 }
173 
174 static
176 make_tile_pattern(
177  const cli_params & params,
178  const dash::SizeSpec<2, extent_t> & sizespec,
179  const dash::TeamSpec<2, index_t> & teamspec)
180 {
181  // Example: -n 30 30 -u 4 1 -t 10 10
182  typedef dash::TilePattern<2> pattern_t;
183  pattern_t pattern(sizespec,
185  dash::TILE(params.tile_y),
186  dash::TILE(params.tile_x)),
187  teamspec);
188  return pattern;
189 }
190 
191 static
193 make_block_pattern(
194  const cli_params & params,
195  const dash::SizeSpec<2, extent_t> & sizespec,
196  const dash::TeamSpec<2, index_t> & teamspec)
197 {
198  // Example: -n 30 30 -u 4 1 -t 10 10
199  typedef dash::Pattern<2> pattern_t;
200  pattern_t pattern(sizespec,
202  (params.tile_y > 0
203  ? dash::BLOCKCYCLIC(params.tile_y)
204  : dash::NONE),
205  (params.tile_x > 0
206  ? dash::BLOCKCYCLIC(params.tile_x)
207  : dash::NONE)),
208  teamspec);
209  return pattern;
210 }
211 
212 int main(int argc, char* argv[])
213 {
214  dash::init(&argc, &argv);
215 
216  auto params = parse_args(argc, argv);
217  print_params(params);
218 
219  if (dash::myid() == 0) {
220  try {
221  dash::SizeSpec<2, extent_t> sizespec(params.size_y, params.size_x);
222  dash::TeamSpec<2, index_t> teamspec(params.units_y, params.units_x);
223 
224  if(params.balance_extents) {
225  teamspec.balance_extents();
226  }
227  if (params.tile_x < 0 && params.tile_y < 0) {
228  auto max_team_extent = std::max(teamspec.extent(0),
229  teamspec.extent(1));
230  params.tile_y = sizespec.extent(0) / max_team_extent;
231  params.tile_x = sizespec.extent(1) / max_team_extent;
232  }
233 
234  if (params.type == "summa") {
235  auto pattern = make_summa_pattern(params, sizespec, teamspec);
236  print_example(pattern, params);
237  } else if (params.type == "block") {
238  auto pattern = make_block_pattern(params, sizespec, teamspec);
239  print_example(pattern, params);
240  } else if (params.type == "tile") {
241  auto pattern = make_tile_pattern(params, sizespec, teamspec);
242  print_example(pattern, params);
243  } else if (params.type == "shift") {
244  auto pattern = make_shift_tile_pattern(params, sizespec, teamspec);
245  print_example(pattern, params);
246  } else if (params.type == "seq") {
247  auto pattern = make_seq_tile_pattern(params, sizespec, teamspec);
248  print_example(pattern, params);
249  } else {
250  print_usage(argv);
251  exit(EXIT_FAILURE);
252  }
253 
254  } catch (std::exception & excep) {
255  cerr << excep.what() << endl;
256  }
257  }
258 
259  dash::finalize();
260 
261  return EXIT_SUCCESS;
262 }
263 
264 static
265 void print_usage(char **argv)
266 {
267  if (dash::myid() == 0) {
268  cerr << "Usage: \n"
269  << basename(argv[0]) << " "
270  << "-h | "
271  << "[-s pattern] "
272  << "[-n size_spec] "
273  << "[-u unit_spec] "
274  << "[-t tile_spec] "
275  << "[-p] "
276  << "\n\n";
277  cerr << "-s pattern: [summa|block|tile|seq|shift]\n"
278  << "-n size_spec: <size_y> <size_x> [ "
279  << default_params.size_y << " " << default_params.size_x << " ]\n"
280  << "-u unit_spec: <units_y> <units_x> [ "
281  << default_params.units_x << " " << default_params.units_x << " ]\n"
282  << "-t tile_spec: <tile_y> <tile_x> [ automatically determined ]\n"
283  << "-p : print to stdout instead of stderr\n"
284  << "-h : print help and exit"
285  << std::endl;
286  }
287 }
288 
289 static
290 cli_params parse_args(int argc, char * argv[])
291 {
292  cli_params params = default_params;
293 
294  for (auto i = 1; i < argc; i += 3) {
295  std::string flag = argv[i];
296  if (flag == "-h") {
297  print_usage(argv);
298  exit(EXIT_SUCCESS);
299  }
300  if (flag == "-s") {
301  params.type = argv[i+1];
302  i -= 1;
303  } else if (flag == "-n") {
304  params.size_y = static_cast<extent_t>(atoi(argv[i+1]));
305  params.size_x = static_cast<extent_t>(atoi(argv[i+2]));
306  } else if (flag == "-u") {
307  params.units_y = static_cast<extent_t>(atoi(argv[i+1]));
308  params.units_x = static_cast<extent_t>(atoi(argv[i+2]));
309  } else if (flag == "-t") {
310  params.tile_y = static_cast<extent_t>(atoi(argv[i+1]));
311  params.tile_x = static_cast<extent_t>(atoi(argv[i+2]));
312  } else if (flag == "-p") {
313  params.cout = true;
314  i -= 2;
315  } else if (flag == "-e") {
316  params.balance_extents = true;
317  i -= 2;
318  } else if (flag == "-b") {
319  params.blocked_display = true;
320  i -= 2;
321  } else {
322  print_usage(argv);
323  exit(EXIT_FAILURE);
324  }
325  }
326 
327  return params;
328 }
329 
330 static
331 void print_params(const cli_params & params)
332 {
333  int w_size = std::log10(std::max(params.size_x, params.size_y));
334  int w_units = std::log10(std::max(params.units_x, params.units_y));
335  int w_tile = std::log10(std::max(params.tile_x, params.tile_y));
336  int w = std::max({ w_size, w_units, w_tile }) + 1;
337 
338  cerr << "Parameters:"
339  << endl
340  << " type (-s): " << params.type
341  << endl
342  << " size (-n <rows> <cols>): ( "
343  << std::fixed << std::setw(w) << params.size_y << ", "
344  << std::fixed << std::setw(w) << params.size_x << " )"
345  << endl
346  << " team (-u <rows> <cols>): ( "
347  << std::fixed << std::setw(w) << params.units_y << ", "
348  << std::fixed << std::setw(w) << params.units_x << " )"
349  << endl
350  << " balance extents (-e): "
351  << (params.balance_extents ? "yes" : "no")
352  << endl
353  << " tile (-t <rows> <cols>): ( "
354  << std::fixed << std::setw(w) << params.tile_y << ", "
355  << std::fixed << std::setw(w) << params.tile_x << " )"
356  << endl
357  << " blocked display (-b): "
358  << (params.blocked_display ? "yes" : "no")
359  << endl
360  << endl;
361 }
362 
366 template<typename PatternType>
367 static
368 std::string pattern_to_string(
369  const PatternType & pattern)
370 {
371  typedef typename PatternType::index_type index_t;
372 
373  dim_t ndim = pattern.ndim();
374 
375  std::string storage_order = pattern.memory_order() == ROW_MAJOR
376  ? "ROW_MAJOR"
377  : "COL_MAJOR";
378 
379  std::array<index_t, 2> blocksize;
380  blocksize[0] = pattern.blocksize(0);
381  blocksize[1] = pattern.blocksize(1);
382 
383  std::ostringstream ss;
384  ss << "dash::"
385  << PatternType::PatternName
386  << "<"
387  << ndim << ","
388  << storage_order << ","
389  << typeid(index_t).name()
390  << ">(" << endl
391  << " SizeSpec: " << pattern.sizespec().extents() << "," << endl
392  << " TeamSpec: " << pattern.teamspec().extents() << "," << endl
393  << " BlockSpec: " << pattern.blockspec().extents() << "," << endl
394  << " BlockSize: " << blocksize << " )";
395 
396  return ss.str();
397 }
398 
402 template<typename PatternType>
403 static
404 std::string pattern_to_filename(
405  const PatternType & pattern)
406 {
407  typedef typename PatternType::index_type index_t;
408 
409  dim_t ndim = pattern.ndim();
410 
411  std::string storage_order = pattern.memory_order() == ROW_MAJOR
412  ? "ROW_MAJOR"
413  : "COL_MAJOR";
414 
415  auto sspc = pattern.sizespec();
416  auto tspc = pattern.teamspec();
417  auto bspc = pattern.blockspec();
418 
419  std::ostringstream ss;
420  ss << PatternType::PatternName
421  << "--"
422  << ndim << "-"
423  << storage_order << "-"
424  << typeid(index_t).name()
425  << "--"
426  << "size-" << sspc.extent(0) << "x" << sspc.extent(1) << "--"
427  << "team-" << tspc.extent(0) << "x" << tspc.extent(1) << "--"
428  << "blocks-" << bspc.extent(0) << "x" << bspc.extent(1)
429  << ".svg";
430 
431  return ss.str();
432 }
433 
434 template<typename PatternT>
435 static
436 void print_pattern_metrics(const PatternT & pattern)
437 {
439 
440  size_t block_kbytes = pattern.blocksize(0) * pattern.blocksize(1) *
441  sizeof(double) /
442  1024;
443 
444  cerr << "Pattern Metrics:"
445  << endl
446  << " Partitioning:"
447  << endl
448  << " block size: " << block_kbytes << " KB"
449  << endl
450  << " number of blocks: " << pm.num_blocks()
451  << endl
452  << " Mapping imbalance:"
453  << endl
454  << " min. blocks/unit: " << pm.min_blocks_per_unit()
455  << " = " << pm.min_elements_per_unit() << " elements"
456  << endl
457  << " max. blocks/unit: " << pm.max_blocks_per_unit()
458  << " = " << pm.max_elements_per_unit() << " elements"
459  << endl
460  << " imbalance factor: " << std::setprecision(4)
461  << pm.imbalance_factor()
462  << endl
463  << " balanced units: " << pm.num_balanced_units()
464  << endl
465  << " imbalanced units: " << pm.num_imbalanced_units()
466  << endl
467  << endl;
468 }
469 
470 template<typename PatternT>
471 static
472 void log_pattern_mapping(const PatternT & pattern)
473 {
474  typedef PatternT pattern_t;
475 
476  dash::internal::print_pattern_mapping(
477  "pattern.unit_at", pattern, 3,
478  [](const pattern_t & _pattern, int _x, int _y) -> dart_unit_t {
479  return _pattern.unit_at(std::array<index_t, 2> {{_x, _y}});
480  });
481  dash::internal::print_pattern_mapping(
482  "pattern.global_at", pattern, 3,
483  [](const pattern_t & _pattern, int _x, int _y) -> index_t {
484  return _pattern.global_at(std::array<index_t, 2> {{_x, _y}});
485  });
486  dash::internal::print_pattern_mapping(
487  "pattern.local", pattern, 10,
488  [](const pattern_t & _pattern, int _x, int _y) -> std::string {
489  auto lpos = _pattern.local(std::array<index_t, 2> {{_x, _y}});
490  std::ostringstream ss;
491  ss << lpos.unit << ":" << lpos.coords;
492  return ss.str();
493  });
494  dash::internal::print_pattern_mapping(
495  "pattern.at", pattern, 3,
496  [](const pattern_t & _pattern, int _x, int _y) -> index_t {
497  return _pattern.at(std::array<index_t, 2> {{_x, _y}});
498  });
499  dash::internal::print_pattern_mapping(
500  "pattern.block_at", pattern, 3,
501  [](const pattern_t & _pattern, int _x, int _y) -> index_t {
502  return _pattern.block_at(std::array<index_t, 2> {{_x, _y}});
503  });
504  dash::internal::print_pattern_mapping(
505  "pattern.block.offset", pattern, 5,
506  [](const pattern_t & _pattern, int _x, int _y) -> std::string {
507  auto block_idx = _pattern.block_at(std::array<index_t, 2> {{_x, _y}});
508  auto block_vs = _pattern.block(block_idx);
509  std::ostringstream ss;
510  ss << block_vs.offset(0) << "," << block_vs.offset(1);
511  return ss.str();
512  });
513  dash::internal::print_pattern_mapping(
514  "pattern.local_index", pattern, 3,
515  [](const pattern_t & _pattern, int _x, int _y) -> index_t {
516  return _pattern.local_index(std::array<index_t, 2> {{_x, _y}}).index;
517  });
518 }
519 
internal::default_unsigned_index default_extent_t
Unsigned integer type used as default for extent values.
Definition: Types.h:64
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
constexpr std::enable_if< std::is_integral< IndexType >::value, IndexType >::type index(IndexType idx)
Definition: Iterator.h:60
Defines how a list of global indices is mapped to single units within a Team.
Definition: BlockPattern.h:42
This class is a simple memory pool which holds allocates elements of size ValueType.
Definition: AllOf.h:8
Specifies cartesian extents in a specific number of dimensions.
Definition: Cartesian.h:197
dash::pattern_partitioning_properties< dash::pattern_partitioning_tag::rectangular, dash::pattern_partitioning_tag::balanced, dash::pattern_partitioning_tag::ndimensional > summa_pattern_partitioning_constraints
Constraints on pattern partitioning properties of matrix operands passed to dash::summa.
Definition: SUMMA.h:103
int32_t dart_unit_t
Data type for storing a unit ID.
Definition: dart_types.h:154
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
Definition: Types.h:39
constexpr double imbalance_factor() const noexcept
Relation of (max.
void balance_extents()
Tries to equally distribute the units across the dimensions.
Definition: TeamSpec.h:234
void finalize()
Finalize the DASH library and the underlying runtime system.
std::enable_if< !MappingTags::diagonal &&PartitioningTags::rectangular &&PartitioningTags::balanced &&!PartitioningTags::unbalanced &&LayoutTags::blocked, TilePattern< SizeSpecType::ndim::value, dash::ROW_MAJOR, typename SizeSpecType::index_type >>::type make_pattern(const SizeSpecType &sizespec, const TeamSpecType &teamspec)
Generic Abstract Factory for models of the Pattern concept.
Definition: MakePattern.h:373
Defines how a list of global indices is mapped to single units within a Team.
Definition: TilePattern.h:47
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
Definition: Types.h:59
void draw_pattern(std::ostream &os, bool blocked_display=false, std::array< index_t, PatternT::ndim()> coords={}, int dimx=1, int dimy=0)
Outputs the pattern as a svg over the given output stream.
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:412
Defines how a list of global indices is mapped to single units within a Team.
Take a generic pattern instance and visualize it as an SVG image.
Defines how a list of global indices is mapped to single units within a Team.
constexpr dim_t ndim(const DimensionalType &d)
Definition: Dimensional.h:56
Specifies the arrangement of team units in a specified number of dimensions.
Definition: TeamSpec.h:33
dash::pattern_mapping_properties< dash::pattern_mapping_tag::multiple, dash::pattern_mapping_tag::unbalanced > summa_pattern_mapping_constraints
Constraints on pattern mapping properties of matrix operands passed to dash::summa.
Definition: SUMMA.h:112
void set_title(const std::string &str)
Sets the title displayed above the pattern.
constexpr int num_imbalanced_units() const noexcept
Number of units mapped to maximum number of blocks per unit.
constexpr int max_blocks_per_unit() const noexcept
Maximum number of blocks mapped to any unit.
constexpr int max_elements_per_unit() const noexcept
Maximum number of elements mapped to any unit.
SizeType extent(dim_t dim) const
The extent of the cartesian space in the given dimension.
Definition: Cartesian.h:181
constexpr int min_elements_per_unit() const noexcept
Minimum number of elements mapped to any unit.
constexpr int num_balanced_units() const noexcept
Number of units mapped to minimum number of blocks per unit.
constexpr int min_blocks_per_unit() const noexcept
Minimum number of blocks mapped to any unit.
void init(int *argc, char ***argv)
Initialize the DASH library and the underlying runtime system.
DistributionSpec describes distribution patterns of all dimensions,.
Definition: Dimensional.h:222