CGRA-ME
mapper_interface_tests.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * The software programs comprising "CGRA-ME" and the documentation provided
3  * with them are copyright by its authors and the University of Toronto. Only
4  * non-commercial, not-for-profit use of this software is permitted without ex-
5  * plicit permission. This software is provided "as is" with no warranties or
6  * guarantees of support. See the LICENCE for more details. You should have re-
7  * ceived a copy of the full licence along with this software. If not, see
8  * <http://cgra-me.ece.utoronto.ca/license/>.
9  ******************************************************************************/
10 
11 #include <CGRA/Mapper.h>
12 
13 #include <catch2/catch.hpp>
14 
15 namespace {
16  struct DummyMapper : Mapper {
17  int II = 0;
18  DummyMapper(std::shared_ptr<CGRA> cgra, int timelimit) : Mapper(cgra, timelimit) {}
19  Mapping mapOpGraph(std::shared_ptr<OpGraph> opgraph, int II, const MRRG& mrrg, std::unordered_map<std::string, std::string> fix_port) {
20  this->II = II;
21  return Mapping(cgra, II, opgraph);
22  }
23  };
24 
25  void runArgsTest(ConfigStore in_args, ConfigStore expcected_out_args, bool expect_pass, bool is_composite);
26  void runArgsTest_Success(ConfigStore in_args, ConfigStore expcected_out_args) { return runArgsTest(in_args, expcected_out_args, true, false); }
27  void runArgsTest_Failure(ConfigStore in_args, ConfigStore expcected_out_args) { return runArgsTest(in_args, expcected_out_args, false, false); }
28  void runArgsTest_Composite_Success(ConfigStore in_args, ConfigStore expcected_out_args) { return runArgsTest(in_args, expcected_out_args, true, true); }
29  void runArgsTest_Composite_Failure(ConfigStore in_args, ConfigStore expcected_out_args) { return runArgsTest(in_args, expcected_out_args, false, true); }
30 
31  void runArgsFilterTest(std::vector<std::string> in_args, std::vector<std::string> required_args, std::vector<std::string> optional_regexes, bool expect_pass);
32  void runArgsFilterTest_Success(std::vector<std::string> in_args, std::vector<std::string> required_args, std::vector<std::string> optional_regexes) { return runArgsFilterTest(in_args, required_args, optional_regexes, true); }
33  void runArgsFilterTest_Failure(std::vector<std::string> in_args, std::vector<std::string> required_args, std::vector<std::string> optional_regexes) { return runArgsFilterTest(in_args, required_args, optional_regexes, false); }
34 };
35 
36 SCENARIO ("MapperRegistry Test -- Direct args, success", "[mapper registry]") {
37  runArgsTest_Success(
38  { // in
39  {"checker.arg1", 1},
40  {"checker.arg2", 2},
41  }, { // expected
42  {"arg1", 1},
43  {"arg2", 2},
44  }
45  );
46 }
47 
48 SCENARIO ("MapperRegistry Test -- Direct args, failure", "[mapper registry]") {
49  runArgsTest_Failure(
50  { // in
51  {"checker.arg1", 1},
52  {"checker.arg2", 3},
53  }, { // expected
54  {"arg1", 1},
55  {"arg2", 2},
56  }
57  );
58 }
59 
60 SCENARIO ("MapperRegistry Test -- Direct args to another mapper", "[mapper registry]") {
61  runArgsTest_Success(
62  { // in
63  {"not_the_checker.arg1", 1},
64  {"not_the_checker.arg2", 2},
65  }, { // expected
66  }
67  );
68 }
69 
70 SCENARIO ("MapperRegistry Test -- AllMappers args", "[mapper registry]") {
71  runArgsTest_Success(
72  { // in
73  {"AllMappers.arg1", 1},
74  {"AllMappers.arg2", 2},
75  }, { // expected
76  {"arg1", 1},
77  {"arg2", 2},
78  }
79  );
80 }
81 
82 SCENARIO ("MapperRegistry Test -- AllMappers + Direct args", "[mapper registry]") {
83  runArgsTest_Success(
84  { // in
85  {"AllMappers.arg1", 1},
86  {"checker.arg2", 2},
87  }, { // expected
88  {"arg1", 1},
89  {"arg2", 2},
90  }
91  );
92 }
93 
94 SCENARIO ("MapperRegistry Test -- AllMappers + Direct args to wrong mapper", "[mapper registry]") {
95  runArgsTest_Success(
96  { // in
97  {"AllMappers.arg1", 1},
98  {"not_the_checker.arg2", 2},
99  }, { // expected
100  {"arg1", 1}
101  }
102  );
103 }
104 
105 SCENARIO ("MapperRegistry Test -- Composite -- Direct args, success", "[mapper registry]") {
106  runArgsTest_Composite_Success(
107  { // in
108  {"checker.arg1", 1},
109  {"checker.arg2", 2},
110  }, { // expected
111  {"checker.arg1", 1},
112  {"checker.arg2", 2},
113  }
114  );
115 }
116 
117 SCENARIO ("MapperRegistry Test -- Composite -- Direct args, failure", "[mapper registry]") {
118  runArgsTest_Composite_Failure(
119  { // in
120  {"checker.arg1", 1},
121  {"checker.arg2", 3},
122  }, { // expected
123  {"checker.arg1", 1},
124  {"checker.arg2", 2},
125  }
126  );
127 }
128 
129 SCENARIO ("MapperRegistry Test -- Composite -- Direct args to another mapper", "[mapper registry]") {
130  runArgsTest_Composite_Success(
131  { // in
132  {"not_the_checker.arg1", 1},
133  {"not_the_checker.arg2", 2},
134  }, { // expected
135  {"not_the_checker.arg1", 1},
136  {"not_the_checker.arg2", 2},
137  }
138  );
139 }
140 
141 SCENARIO ("MapperRegistry Test -- Composite -- AllMappers args", "[mapper registry]") {
142  runArgsTest_Composite_Success(
143  { // in
144  {"AllMappers.arg1", 1},
145  {"AllMappers.arg2", 2},
146  }, { // expected
147  {"AllMappers.arg1", 1},
148  {"AllMappers.arg2", 2},
149  {"checker.arg1", 1},
150  {"checker.arg2", 2},
151  }
152  );
153 }
154 
155 SCENARIO ("MapperRegistry Test -- Composite -- nested args", "[mapper registry]") {
156  runArgsTest_Composite_Success(
157  { // in
158  {"checker.nested.arg1", 1},
159  }, { // expected
160  {"checker.nested.arg1", 1},
161  {"nested.arg1", 1},
162  }
163  );
164 }
165 
166 SCENARIO ("MapperRegistry Test -- Composite -- doubly nested arg overwrites", "[mapper registry]") {
167  runArgsTest_Composite_Success(
168  { // in
169  {"checker.nested.arg1", 1},
170  {"checker.checker.nested.arg1", 1},
171  }, { // expected
172  {"nested.arg1", 1},
173  {"checker.nested.arg1", 1},
174  {"checker.checker.nested.arg1", 1},
175  }
176  );
177 }
178 
179 SCENARIO ("MapperRegistry Test -- Composite -- AllMappers + Direct args", "[mapper registry]") {
180  runArgsTest_Composite_Success(
181  { // in
182  {"AllMappers.arg1", 1},
183  {"checker.arg2", 2},
184  }, { // expected
185  {"AllMappers.arg1", 1},
186  {"checker.arg1", 1},
187  {"checker.arg2", 2},
188  }
189  );
190 }
191 
192 SCENARIO ("MapperRegistry Test -- Composite -- AllMappers + Direct arg override", "[mapper registry]") {
193  runArgsTest_Composite_Success(
194  { // in
195  {"AllMappers.arg1", 1},
196  {"checker.arg1", 7},
197  {"checker.arg2", 2},
198  }, { // expected
199  {"AllMappers.arg1", 1},
200  {"checker.arg1", 7},
201  {"checker.arg2", 2},
202  }
203  );
204 }
205 
206 SCENARIO ("MapperRegistry Test -- Composite -- AllMappers + Direct args to wrong mapper", "[mapper registry]") {
207  runArgsTest_Composite_Success(
208  { // in
209  {"AllMappers.arg1", 1},
210  {"not_the_checker.arg2", 2},
211  }, { // expected
212  {"AllMappers.arg1", 1},
213  {"not_the_checker.arg2", 2},
214  {"checker.arg1", 1}
215  }
216  );
217 }
218 
219 SCENARIO ("MapperRegistry Test -- Arg Checking -- no args & none given", "[mapper registry]") {
220  runArgsFilterTest_Success(
221  { // in
222  }, { // required
223  }, { // optional regexes
224  }
225  );
226 }
227 
228 SCENARIO ("MapperRegistry Test -- Arg Checking -- one required arg expected & given", "[mapper registry]") {
229  runArgsFilterTest_Success(
230  { // in
231  {"arg1"},
232  }, { // required
233  {"arg1"},
234  }, { // optional regexes
235  }
236  );
237 }
238 
239 SCENARIO ("MapperRegistry Test -- Arg Checking -- two required args expected & given", "[mapper registry]") {
240  runArgsFilterTest_Success(
241  { // in
242  {"arg1"},
243  {"arg2"},
244  }, { // required
245  {"arg1"},
246  {"arg2"},
247  }, { // optional regexes
248  }
249  );
250 }
251 
252 SCENARIO ("MapperRegistry Test -- Arg Checking -- one required arg expected & none given", "[mapper registry]") {
253  runArgsFilterTest_Failure(
254  { // in
255  }, { // required
256  {"arg1"},
257  }, { // optional regexes
258  }
259  );
260 }
261 
262 SCENARIO ("MapperRegistry Test -- Arg Checking -- two required args expected & one given", "[mapper registry]") {
263  runArgsFilterTest_Failure(
264  { // in
265  {"arg1"},
266  }, { // required
267  {"arg1"},
268  {"arg2"},
269  }, { // optional regexes
270  }
271  );
272 }
273 
274 SCENARIO ("MapperRegistry Test -- Arg Checking -- one optional arg allowed & none given", "[mapper registry]") {
275  runArgsFilterTest_Success(
276  { // in
277  }, { // required
278  }, { // optional regexes
279  {"arg1"},
280  }
281  );
282 }
283 
284 SCENARIO ("MapperRegistry Test -- Arg Checking -- one optional arg allowed & given -- non-regex", "[mapper registry]") {
285  runArgsFilterTest_Success(
286  { // in
287  {"arg1"},
288  }, { // required
289  }, { // optional regexes
290  {"arg1"},
291  }
292  );
293 }
294 
295 SCENARIO ("MapperRegistry Test -- Arg Checking -- one optional arg allowed & given", "[mapper registry]") {
296  runArgsFilterTest_Success(
297  { // in
298  {"arg1"},
299  }, { // required
300  }, { // optional regexes
301  {"arg.*"},
302  }
303  );
304 }
305 
306 SCENARIO ("MapperRegistry Test -- Arg Checking -- two optional args allowed & given", "[mapper registry]") {
307  runArgsFilterTest_Success(
308  { // in
309  {"arg1"},
310  {"barg1"},
311  }, { // required
312  }, { // optional regexes
313  {"arg.*"},
314  {"barg.*"},
315  }
316  );
317 }
318 
319 SCENARIO ("MapperRegistry Test -- Arg Checking -- one optional arg allowed & non-matching given", "[mapper registry]") {
320  runArgsFilterTest_Failure(
321  { // in
322  {"barg1"},
323  }, { // required
324  }, { // optional regexes
325  {"arg.*"},
326  }
327  );
328 }
329 
330 SCENARIO ("MapperRegistry Test -- INI printing", "[mapper registry]") {
331  MapperRegistry mr({
332  {"common1", 1, "a common1 arg\n\ntesting common1"},
333  {"common2", 2, "a common2 arg\n\ntesting common2"},
334  });
335 
336  mr.registerMapper("checker", nullptr, false, "a checker", {
337  {"arg1", 11, "the arg1\n\narg1 long description"},
338  {"arg2", 22, "the arg2"},
339  {"common1", 1, ""},
340  }, {
341  {"regex.*", "a regex"},
342  });
343 
344  mr.registerMapper("checker2", nullptr, false, "a checker", {
345  {"arg2", 22, "the arg2"},
346  {"arg3", 33, ""},
347  {"common1", 1, ""},
348  }, {
349  {"regex.*", "a regex"},
350  });
351 
352  mr.registerMapper("checker3", nullptr, false, "a checker", {
353  {"common1", 2, ""},
354  {"common2", 2, "means something special"},
355  }, {
356  {"regex.*", "a regex"},
357  });
358 
359  std::stringstream ini_dump_ss;
360  mr.printDefaultsAsINI(ini_dump_ss);
361 
362  const auto expected = std::string(
363  "#\n"
364  "# Gobal settings & defaults\n"
365  "#\n"
366  "\n"
367  "[AllMappers]\n"
368  "# a common1 arg\n"
369  "common1 = 1\n"
370  "# a common2 arg\n"
371  "common2 = 2\n"
372  "\n"
373  "#\n"
374  "# The rest are mapper-specific & overrides\n"
375  "#\n"
376  "\n"
377  "[checker]\n"
378  "# the arg1\n"
379  "arg1 = 11\n"
380  "# the arg2\n"
381  "arg2 = 22\n"
382  "\n"
383  "[checker2]\n"
384  "# the arg2\n"
385  "arg2 = 22\n"
386  "arg3 = 33\n"
387  "\n"
388  "[checker3]\n"
389  "common1 = 2\n"
390  "# means something special\n"
391  "common2 = 2\n"
392  );
393 
394  CHECK(ini_dump_ss.str() == expected);
395 }
396 
397 namespace {
398 
399 void runArgsTest(ConfigStore in_args, ConfigStore expcected_out_args, bool expect_pass, bool is_composite) {
400  MapperRegistry mr({});
401  ConfigStore out_args;
402 
403  mr.registerMapper("checker", [&](auto&& cgra, int timeout, const ConfigStore& args) {
404  out_args = args;
405  return std::unique_ptr<Mapper>(std::make_unique<DummyMapper>(cgra, timeout));
406  }, is_composite, "a checker", {}, { {"arg.*", ""} });
407 
408  auto cgra = std::make_shared<CGRA>();
409  mr.createMapper("checker", cgra, 0, in_args);
410 
411  if (expect_pass) {
412  CHECK(out_args == expcected_out_args);
413  } else {
414  CHECK(out_args != expcected_out_args);
415  }
416 }
417 
418 void runArgsFilterTest(std::vector<std::string> in_args, std::vector<std::string> required_args, std::vector<std::string> optional_regexes, bool expect_pass) {
419  std::vector<ImplicitTuple<std::string, ImplicitlyToString, std::string>> required_arg_names_defaults_and_descriptions;
420  for (const auto& arg : required_args) {
421  required_arg_names_defaults_and_descriptions.push_back({arg, "dflt", ""});
422  }
423 
424  std::vector<std::pair<std::string, std::string>> optional_arg_regexes_and_descriptions;
425  for (const auto& regex : optional_regexes) {
426  optional_arg_regexes_and_descriptions.push_back({regex, ""});
427  }
428 
429  ConfigStore in_args_cs;
430  for (const auto& arg : in_args) {
431  in_args_cs.setString("checker." + arg, "in");
432  }
433 
434  auto do_test = [&](bool is_composite) {
435  WHEN ("Testing a " << (is_composite ? "" : "non-") << "composite mapper") {
436  MapperRegistry mr({});
437  mr.registerMapper("checker", [&](auto&& cgra, int timeout, const ConfigStore& args) {
438  return std::unique_ptr<Mapper>(std::make_unique<DummyMapper>(cgra, timeout));
439  }, is_composite, "a checker", required_arg_names_defaults_and_descriptions, optional_arg_regexes_and_descriptions);
440 
441  auto cgra = std::make_shared<CGRA>();
442  if (expect_pass) {
443  mr.createMapper("checker", cgra, 0, in_args_cs);
444  } else {
445  CHECK_THROWS(mr.createMapper("checker", cgra, 0, in_args_cs));
446  }
447  }
448  };
449 
450  do_test(false);
451  do_test(true);
452 }
453 
454 } // end anon namespace
ConfigStore::setString
void setString(std::string key, std::string value)
Definition: ConfigStore.h:128
MRRG
Definition: MRRG.h:216
Mapper::mapOpGraph
virtual Mapping mapOpGraph(std::shared_ptr< OpGraph > opgraph, int II, const MRRG &mrrg, std::unordered_map< std::string, std::string > fix_port)=0
MapperRegistry
Holds instances of mapper makers and creates mappers by ID, while resolving arguments.
Definition: Mapper.h:66
ConfigStore
Definition: ConfigStore.h:76
Mapper
Common interface for mappers.
Definition: Mapper.h:28
Mapping
Definition: Mapping.h:31
Mapper.h
SCENARIO
SCENARIO("MapperRegistry Test -- Direct args, success", "[mapper registry]")
Definition: mapper_interface_tests.cpp:36
MapperRegistry::registerMapper
void registerMapper(std::string mapper_id, MapperMaker maker, bool is_composite, std::string mapper_description, std::vector< ImplicitTuple< std::string, ImplicitlyToString, std::string >> required_arg_names_defaults_and_descriptions, std::vector< std::pair< std::string, std::string >> optional_arg_regexes_and_descriptions)
Register a new mapper under the name mapper_id.
Definition: Mapper.cpp:66