CGRA-ME
MRRG_reduction_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 <catch2/catch.hpp>
12 
13 #include <CGRA/MRRGProcedures.h>
14 #include <CGRA/Mapping.h>
15 
16 namespace {
17 
18 MRRG makeMRRG_4nodeLinear_latency1() {
19  MRRG mrrg(2);
20  // nodes are sorted by name, so add prefix to mess with that
21  const auto a = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "3aaa", 0)).first;
22  const auto b = mrrg.insert(a, MRRGNode::make_routing(nullptr, 32, 0, "2bbb", 0)).first;
23  const auto c = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "1ccc", 1)).first;
24  const auto d = mrrg.insert(c, MRRGNode::make_routing(nullptr, 32, 1, "4ddd", 0)).first;
25  (void)d;
26 
27  verifyAndPrintReport(mrrg, std::cout, true, true);
28  return mrrg;
29 }
30 
31 MRRG makeMRRG_2112DAG_latency1() {
32  MRRG mrrg(2);
33  // nodes are sorted by name, so add prefix to mess with that
34  const auto a1 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "4aaa1", 0)).first;
35  const auto a2 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "4aaa2", 0)).first;
36  const auto b = mrrg.insertMultiFanin({a1,a2}, MRRGNode::make_routing(nullptr, 32, 0, "3bbb", 0)).first;
37  const auto c = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc", 1)).first;
38  const auto d1 = mrrg.insert(c, MRRGNode::make_routing(nullptr, 32, 1, "1ddd1", 0)).first;
39  const auto d2 = mrrg.insert(c, MRRGNode::make_routing(nullptr, 32, 1, "0ddd2", 0)).first;
40  (void)d1;
41  (void)d2;
42 
43  verifyAndPrintReport(mrrg, std::cout, true, true);
44  return mrrg;
45 }
46 
47 MRRG makeMRRG_12221DAG_latency1() {
48  MRRG mrrg(2);
49  // nodes are sorted by name, so add prefix to mess with that
50  const auto b = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "3bbb", 0)).first;
51  const auto c1 = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc1", 1)).first;
52  const auto c2 = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc2", 1)).first;
53  const auto d1 = mrrg.insert(c1, MRRGNode::make_routing(nullptr, 32, 1, "1ddd1", 0)).first;
54  const auto d2 = mrrg.insert(c2, MRRGNode::make_routing(nullptr, 32, 1, "0ddd2", 0)).first;
55  const auto e1 = mrrg.insert(d1, MRRGNode::make_routing(nullptr, 32, 1, "1eee1", 0)).first;
56  const auto e2 = mrrg.insert(d2, MRRGNode::make_routing(nullptr, 32, 1, "0eee2", 0)).first;
57  const auto f = mrrg.insertMultiFanin({e1,e2}, MRRGNode::make_routing(nullptr, 32, 1, "3fff", 0)).first;
58  (void)f;
59 
60  verifyAndPrintReport(mrrg, std::cout, true, true);
61  return mrrg;
62 }
63 
64 MRRG makeMRRG_13331DAG_latency0() {
65  MRRG mrrg(2);
66  // nodes are sorted by name, so add prefix to mess with that
67  const auto b = mrrg.insert( MRRGNode::make_function(nullptr, 32, 0, "3bbb", 0, {})).first;
68  const auto c1 = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc1", 0)).first;
69  const auto c2 = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc2", 0)).first;
70  const auto c3 = mrrg.insert(b, MRRGNode::make_routing(nullptr, 32, 0, "2ccc3", 0)).first;
71 
72  const auto d1 = mrrg.insert(c1, MRRGNode::make_routing(nullptr, 32, 0, "1ddd1", 0)).first;
73  const auto d2 = mrrg.insert(c2, MRRGNode::make_routing(nullptr, 32, 0, "0ddd2", 0)).first;
74  const auto d3 = mrrg.insert(c3, MRRGNode::make_routing(nullptr, 32, 0, "0ddd3", 0)).first;
75 
76  const auto e1 = mrrg.insert(d1, MRRGNode::make_routing(nullptr, 32, 0, "1eee1", 0)).first;
77  const auto e2 = mrrg.insert(d2, MRRGNode::make_routing(nullptr, 32, 0, "0eee2", 0)).first;
78  const auto e3 = mrrg.insert(d3, MRRGNode::make_routing(nullptr, 32, 0, "0eee3", 0)).first;
79 
80  const auto f = mrrg.insertMultiFanin({e1,e2}, MRRGNode::make_function(nullptr, 32, 0, "3fff", 0, {})).first;
81  (void)f;
82 
83  verifyAndPrintReport(mrrg, std::cout, true, true);
84  return mrrg;
85 }
86 
87 MRRG makeMRRG_multiAdjacentFanin1() {
88  MRRG mrrg(1);
89 
90  const auto a1 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "a1", 0)).first;
91  const auto a2 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "a2", 0)).first;
92  const auto b1 = mrrg.insertMultiFanin({a1,a2}, MRRGNode::make_routing(nullptr, 32, 0, "b1", 0)).first;
93  const auto c1 = mrrg.insert(a2, MRRGNode::make_routing(nullptr, 32, 0, "c1", 0)).first;
94 
95  return mrrg;
96 }
97 
98 MRRG makeMRRG_multiAdjacentFanin2() {
99  MRRG mrrg(1);
100 
101  const auto a1 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "a1", 0)).first;
102  const auto a2 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "a2", 0)).first;
103  const auto b1 = mrrg.insertMultiFanin({a1,a2}, MRRGNode::make_routing(nullptr, 32, 0, "b1", 0)).first;
104  const auto b2 = mrrg.insert(a2, MRRGNode::make_routing(nullptr, 32, 0, "b2", 0)).first;
105  const auto b3 = mrrg.insert( MRRGNode::make_routing(nullptr, 32, 0, "b3", 0)).first;
106  const auto c1 = mrrg.insertMultiFanin({b1, b2}, MRRGNode::make_routing(nullptr, 32, 0, "c1", 0)).first;
107  const auto c2 = mrrg.insertMultiFanin({b2, b3}, MRRGNode::make_routing(nullptr, 32, 0, "c2", 0)).first;
108 
109 
110  return mrrg;
111 }
112 
113 MRRG::NodeDescriptor getNewNodeAssumingSingleMapping(
114  int cycle, const std::string& name,
115  const MRRG& old_mrrg,
116  const MRRGTransformationResult& transforme_result)
117 {
118  const auto& old_ndesc = old_mrrg.getNode(cycle, name);
119  const auto& new_nodes = transforme_result.mapping.newNodesForOldNode(old_ndesc);
120  CHECK(new_nodes.size() == 1);
121  return *new_nodes.begin();
122 }
123 
124 } // end anon namespace
125 
126 SCENARIO("MRRG Reduction Tests", "[mrrg-reduction]") {
127  GIVEN("a 4 node linear MRRG with latency on one node") {
128  const auto& old_mrrg = makeMRRG_4nodeLinear_latency1();
129 
130  WHEN("losslessly reducing") {
131  const auto& reduce_result = reduceLosslessly(old_mrrg, {});
132  const auto& new_mrrg = reduce_result.transformed_mrrg;
133 
134  THEN("Mapping should be as expcted") {
135  InterMRRGMap expected_mapping;
136  expected_mapping.addMappingMulti(
137  { old_mrrg.getNode(0, "3aaa"),
138  old_mrrg.getNode(0, "2bbb"),
139  old_mrrg.getNode(0, "1ccc"),
140  old_mrrg.getNode(1, "4ddd")
141  },
142  new_mrrg.getNode(0, "3aaa")
143  );
144  CHECK(reduce_result.mapping == expected_mapping);
145  CHECK(new_mrrg.size() == 1);
146 
147  AND_THEN("latency should be preserved") {
148  const auto& new_a_ndesc = getNewNodeAssumingSingleMapping(0, "3aaa", old_mrrg, reduce_result);
149  CHECK(new_mrrg.getNodeRef(new_a_ndesc).latency == 1);
150 
151  for (int cycle = 0; cycle < new_mrrg.initiationInterval(); ++cycle) {
152  for (auto& name_and_node : new_mrrg.allNodesByCycle().at(cycle)) {
153  if (name_and_node.second.get() != new_a_ndesc) {
154  CHECK(name_and_node.second->latency == 0);
155  }
156  }
157  }
158  }
159 
160  AND_THEN("mapping to an opgraph node and transforming back to original mrrg should give back original nodes") {
161  OpGraphOp op("add0", 32, OpCode::ADD);
162  Mapping mapping(nullptr, 1, nullptr);
163  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "3aaa"));
164  auto reversedMapping = transformToOriginalMRRG(mapping, reduce_result);
165 
166  const auto& mapping_list = reversedMapping.getMappingList(&op);
167  const auto actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
168  const auto expected = std::set<MRRG::NodeDescriptor> {
169  old_mrrg.getNode(0, "1ccc"),
170  old_mrrg.getNode(0, "2bbb"),
171  old_mrrg.getNode(0, "3aaa"),
172  old_mrrg.getNode(1, "4ddd"),
173  };
174 
175  CHECK(actual == expected);
176  }
177  }
178  }
179  }
180 
181  GIVEN("a 2112DAG MRRG with latency on one node") {
182  const auto& old_mrrg = makeMRRG_2112DAG_latency1();
183 
184  WHEN("losslessly reducing") {
185  const auto& reduce_result = reduceLosslessly(old_mrrg, {});
186  const auto& new_mrrg = reduce_result.transformed_mrrg;
187 
188  THEN("Mapping should be as expcted") {
189  InterMRRGMap expected_mapping;
190  expected_mapping.addMappingMulti(
191  { old_mrrg.getNode(0, "3bbb"), old_mrrg.getNode(0, "2ccc") }, new_mrrg.getNode(0, "3bbb")
192  );
193  expected_mapping.addMapping(old_mrrg.getNode(0, "4aaa1"), new_mrrg.getNode(0, "4aaa1"));
194  expected_mapping.addMapping(old_mrrg.getNode(0, "4aaa2"), new_mrrg.getNode(0, "4aaa2"));
195  expected_mapping.addMapping(old_mrrg.getNode(1, "1ddd1"), new_mrrg.getNode(1, "1ddd1"));
196  expected_mapping.addMapping(old_mrrg.getNode(1, "0ddd2"), new_mrrg.getNode(1, "0ddd2"));
197 
198  CHECK(reduce_result.mapping == expected_mapping);
199  CHECK(new_mrrg.size() == 5);
200 
201  AND_THEN("latency should be preserved") {
202  const auto& new_b_ndesc = getNewNodeAssumingSingleMapping(0, "3bbb", old_mrrg, reduce_result);
203  CHECK(new_mrrg.getNodeRef(new_b_ndesc).latency == 1);
204 
205  for (int cycle = 0; cycle < new_mrrg.initiationInterval(); ++cycle) {
206  for (auto& name_and_node : new_mrrg.allNodesByCycle().at(cycle)) {
207  if (name_and_node.second.get() != new_b_ndesc) {
208  CHECK(name_and_node.second->latency == 0);
209  }
210  }
211  }
212  }
213 
214  AND_THEN("mapping to an opgraph node and transforming back to original mrrg should give back original nodes") {
215  OpGraphOp op1("add0", 32, OpCode::ADD);
216  OpGraphOp op2("add1", 32, OpCode::ADD);
217 
218  Mapping mapping(nullptr, 1, nullptr);
219  mapping.mapMRRGNode(&op1, new_mrrg.getNode(0, "3bbb"));
220  mapping.mapMRRGNode(&op1, new_mrrg.getNode(0, "4aaa1"));
221  mapping.mapMRRGNode(&op1, new_mrrg.getNode(0, "4aaa2"));
222  mapping.mapMRRGNode(&op2, new_mrrg.getNode(1, "1ddd1"));
223  mapping.mapMRRGNode(&op2, new_mrrg.getNode(1, "0ddd2"));
224 
225  auto reversedMapping = transformToOriginalMRRG(mapping, reduce_result);
226 
227  auto mapping_list = reversedMapping.getMappingList(&op1);
228  auto actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
229  auto expected = std::set<MRRG::NodeDescriptor> {
230  old_mrrg.getNode(0, "3bbb"),
231  old_mrrg.getNode(0, "2ccc"),
232  old_mrrg.getNode(0, "4aaa1"),
233  old_mrrg.getNode(0, "4aaa2"),
234  };
235  CHECK(actual == expected);
236 
237  mapping_list = reversedMapping.getMappingList(&op2);
238  actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
239  expected = std::set<MRRG::NodeDescriptor> {
240  old_mrrg.getNode(1, "1ddd1"),
241  old_mrrg.getNode(1, "0ddd2"),
242  };
243 
244  CHECK(actual == expected);
245  }
246  }
247  }
248  }
249 
250  GIVEN("a 12221DAG MRRG with latency on one node") {
251  const auto& old_mrrg = makeMRRG_12221DAG_latency1();
252 
253  WHEN("losslessly reducing") {
254  const auto& reduce_result = reduceLosslessly(old_mrrg, {});
255  const auto& new_mrrg = reduce_result.transformed_mrrg;
256 
257  THEN("Mapping should be as expcted") {
258  InterMRRGMap expected_mapping;
259  expected_mapping.addMappingMulti(
260  { old_mrrg.getNode(0, "2ccc1"), old_mrrg.getNode(1, "1ddd1"), old_mrrg.getNode(1, "1eee1") },
261  new_mrrg.getNode(0, "2ccc1") );
262  expected_mapping.addMappingMulti(
263  { old_mrrg.getNode(0, "2ccc2"), old_mrrg.getNode(1, "0ddd2"), old_mrrg.getNode(1, "0eee2") },
264  new_mrrg.getNode(0, "2ccc2") );
265  expected_mapping.addMapping(old_mrrg.getNode(0, "3bbb"), new_mrrg.getNode(0, "3bbb"));
266  expected_mapping.addMapping(old_mrrg.getNode(1, "3fff"), new_mrrg.getNode(1, "3fff"));
267 
268  CHECK(reduce_result.mapping == expected_mapping);
269  CHECK(new_mrrg.size() == 4);
270 
271  AND_THEN("latency should be preserved") {
272  const auto new_c1_ndesc = getNewNodeAssumingSingleMapping(0, "2ccc1", old_mrrg, reduce_result);
273  CHECK(new_mrrg.getNodeRef(new_c1_ndesc).latency == 1);
274  const auto new_c2_ndesc = getNewNodeAssumingSingleMapping(0, "2ccc2", old_mrrg, reduce_result);
275  CHECK(new_mrrg.getNodeRef(new_c2_ndesc).latency == 1);
276 
277  for (int cycle = 0; cycle < new_mrrg.initiationInterval(); ++cycle) {
278  for (auto& name_and_node : new_mrrg.allNodesByCycle().at(cycle)) {
279  if (
280  name_and_node.second.get() != new_c1_ndesc
281  && name_and_node.second.get() != new_c2_ndesc
282  ) {
283  CHECK(name_and_node.second->latency == 0);
284  }
285  }
286  }
287  }
288 
289  AND_THEN("mapping all mrrg nodes to an opgraph node and transforming back to original mrrg should give back original nodes") {
290  OpGraphOp op1("add0", 32, OpCode::ADD);
291  OpGraphOp op2("add1", 32, OpCode::ADD);
292  OpGraphOp op3("add2", 32, OpCode::ADD);
293  OpGraphOp op4("mul3", 32, OpCode::MUL);
294 
295  Mapping mapping(nullptr, 1, nullptr);
296  mapping.mapMRRGNode(&op1, new_mrrg.getNode(0, "2ccc1"));
297  mapping.mapMRRGNode(&op2, new_mrrg.getNode(0, "2ccc2"));
298  mapping.mapMRRGNode(&op3, new_mrrg.getNode(0, "3bbb"));
299  mapping.mapMRRGNode(&op4, new_mrrg.getNode(1, "3fff"));
300 
301  auto reversedMapping = transformToOriginalMRRG(mapping, reduce_result);
302 
303  auto mapping_list = reversedMapping.getMappingList(&op1);
304  auto actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
305  auto expected = std::set<MRRG::NodeDescriptor> {
306  old_mrrg.getNode(1, "1ddd1"),
307  old_mrrg.getNode(0, "2ccc1"),
308  old_mrrg.getNode(1, "1eee1"),
309  };
310  CHECK(actual == expected);
311 
312  mapping_list = reversedMapping.getMappingList(&op2);
313  actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
314  expected = std::set<MRRG::NodeDescriptor> {
315  old_mrrg.getNode(1, "0ddd2"),
316  old_mrrg.getNode(0, "2ccc2"),
317  old_mrrg.getNode(1, "0eee2"),
318  };
319  CHECK(actual == expected);
320 
321  mapping_list = reversedMapping.getMappingList(&op3);
322  actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
323  expected = std::set<MRRG::NodeDescriptor> {
324  old_mrrg.getNode(0, "3bbb")
325  };
326  CHECK(actual == expected);
327 
328  mapping_list = reversedMapping.getMappingList(&op4);
329  actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
330  expected = std::set<MRRG::NodeDescriptor> {
331  old_mrrg.getNode(1, "3fff")
332  };
333  CHECK(actual == expected);
334  }
335  }
336  }
337  }
338 
339  GIVEN("a 13331DAG MRRG with 0 latency") {
340  const auto& old_mrrg = makeMRRG_13331DAG_latency0();
341 
342  WHEN("losslessly reducing") {
343  const auto& reduce_result = reduceLosslessly(old_mrrg, {});
344  const auto& new_mrrg = reduce_result.transformed_mrrg;
345  THEN("Mapping should be as expected") {
346  CHECK(new_mrrg.size() == 5);
347 
348  InterMRRGMap expected_mapping;
349  expected_mapping.addMappingMulti(
350  { old_mrrg.getNode(0, "2ccc1"), old_mrrg.getNode(0, "1ddd1"), old_mrrg.getNode(0, "1eee1") },
351  new_mrrg.getNode(0, "2ccc1") );
352  expected_mapping.addMappingMulti(
353  { old_mrrg.getNode(0, "2ccc2"), old_mrrg.getNode(0, "0ddd2"), old_mrrg.getNode(0, "0eee2") },
354  new_mrrg.getNode(0, "2ccc2") );
355  expected_mapping.addMappingMulti(
356  { old_mrrg.getNode(0, "2ccc3"), old_mrrg.getNode(0, "0ddd3"), old_mrrg.getNode(0, "0eee3") },
357  new_mrrg.getNode(0, "2ccc3") );
358  expected_mapping.addMapping(old_mrrg.getNode(0, "3bbb"), new_mrrg.getNode(0, "3bbb"));
359  expected_mapping.addMapping(old_mrrg.getNode(0, "3fff"), new_mrrg.getNode(0, "3fff"));
360 
361  CHECK(reduce_result.mapping == expected_mapping);
362 
363  AND_THEN("mapping some mrrg nodes to opgraph nodes and transforming back to original mrrg should give back original nodes") {
364  OpGraphOp op1("op1", 32, OpCode::ADD);
365  OpGraphOp op2("op2", 32, OpCode::ADD);
366  OpGraphOp op3("op3", 32, OpCode::ADD);
367  OpGraphOp op4("op4", 32, OpCode::ADD);
368 
369  Mapping mapping(nullptr, 1, nullptr);
370  mapping.mapMRRGNode(&op1, new_mrrg.getNode(0, "3bbb"));
371  mapping.mapMRRGNode(&op2, new_mrrg.getNode(0, "2ccc2"));
372  mapping.mapMRRGNode(&op3, new_mrrg.getNode(0, "2ccc3"));
373  mapping.mapMRRGNode(&op4, new_mrrg.getNode(0, "3fff"));
374 
375  auto reversedMapping = transformToOriginalMRRG(mapping, reduce_result);
376 
377  bool found1_1 = false, found1_2 = false, found1_3 = false;
378  for (auto mrrgNode : reversedMapping.getMappingList(&op2)) {
379  if (mrrgNode->getFullName() == "0:2ccc2") {
380  found1_1 = true;
381  }
382  else if (mrrgNode->getFullName() == "0:0ddd2") {
383  found1_2 = true;
384  }
385  else if (mrrgNode->getFullName() == "0:0eee2") {
386  found1_3 = true;
387  }
388  }
389 
390  int size = 0;
391  for (auto op : reversedMapping.getMapping()) {
392  size += op.second.size();
393  }
394 
395  CHECK(reversedMapping.getMappingList(&op1).size() == 1);
396  CHECK(reversedMapping.getMappingList(&op2).size() == 3);
397  CHECK(reversedMapping.getMappingList(&op3).size() == 3);
398  CHECK(reversedMapping.getMappingList(&op4).size() == 1);
399 
400  CHECK(size == 8);
401 
402  CHECK(found1_1);
403  CHECK(found1_2);
404  CHECK(found1_3);
405  }
406  }
407  }
408  }
409 }
410 
411 SCENARIO("Mux Exclusivity Insertion", "[mrrg-reduction2]") {
412  GIVEN("a MRRG with one pair of adjacent multi fanin nodes") {
413  const auto & old_mrrg = makeMRRG_multiAdjacentFanin1();
414 
415  WHEN("adding new nodes to satisfy mux ex constraint") {
416  const auto& muxExInsResult = muxExNodeInsertion(old_mrrg);
417  const auto& new_mrrg = muxExInsResult.transformed_mrrg;
418 
419  CHECK(new_mrrg.size() == 5);
420  bool linkedCorrectly = false;
421 
422  for (auto & fanout : new_mrrg.getNode(0, "a2")->fanout) {
423  if (fanout->getFullName() == "0:mux_ex_insert_0") {
424  if (fanout->fanout[0]->getFullName() == "0:b1") {
425  linkedCorrectly = true;
426  }
427  }
428  }
429 
430  CHECK(linkedCorrectly);
431 
432  THEN ("mapping to an opgraph node and transforming back to original mrrg should give back original nodes") {
433  OpGraphOp op("add0", 32, OpCode::ADD);
434 
435  Mapping mapping(nullptr, 1, nullptr);
436  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "a1"));
437  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "a2"));
438  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "b1"));
439  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "c1"));
440  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "mux_ex_insert_0"));
441 
442  auto reversedMapping = transformToOriginalMRRG(mapping, muxExInsResult);
443 
444  auto mapping_list = reversedMapping.getMappingList(&op);
445  auto actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
446  auto expected = std::set<MRRG::NodeDescriptor> {
447  old_mrrg.getNode(0, "a1"),
448  old_mrrg.getNode(0, "a2"),
449  old_mrrg.getNode(0, "b1"),
450  old_mrrg.getNode(0, "c1"),
451  };
452  CHECK(actual == expected);
453  }
454  }
455  }
456 
457  GIVEN("a MRRG with a series of adjacent multi fanin nodes") {
458  const auto & old_mrrg = makeMRRG_multiAdjacentFanin2();
459 
460  WHEN("adding new nodes to satisfy mux ex constraint") {
461  const auto& muxExInsResult = muxExNodeInsertion(old_mrrg);
462  const auto& new_mrrg = muxExInsResult.transformed_mrrg;
463 
464  CHECK(new_mrrg.size() == 10);
465 
466  THEN ("mapping to an opgraph node and transforming back to original mrrg should give back original nodes") {
467  OpGraphOp op("add0", 32, OpCode::ADD);
468 
469  Mapping mapping(nullptr, 1, nullptr);
470  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "a1"));
471  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "a2"));
472  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "b1"));
473  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "b2"));
474  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "b3"));
475  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "c1"));
476  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "c2"));
477  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "mux_ex_insert_0"));
478  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "mux_ex_insert_1"));
479  mapping.mapMRRGNode(&op, new_mrrg.getNode(0, "mux_ex_insert_2"));
480 
481  auto reversedMapping = transformToOriginalMRRG(mapping, muxExInsResult);
482 
483  auto mapping_list = reversedMapping.getMappingList(&op);
484  auto actual = std::set<MRRG::NodeDescriptor>(mapping_list.begin(), mapping_list.end());
485  auto expected = std::set<MRRG::NodeDescriptor> {
486  old_mrrg.getNode(0, "a1"),
487  old_mrrg.getNode(0, "a2"),
488  old_mrrg.getNode(0, "b1"),
489  old_mrrg.getNode(0, "b2"),
490  old_mrrg.getNode(0, "b3"),
491  old_mrrg.getNode(0, "c1"),
492  old_mrrg.getNode(0, "c2"),
493  };
494  CHECK(actual == expected);
495  }
496  }
497  }
498 }
MRRGTransformationResult::mapping
InterMRRGMap mapping
Definition: MRRGProcedures.h:280
verifyAndPrintReport
bool verifyAndPrintReport(const MRRG &mrrg, std::ostream &os, bool silent_on_no_errors, bool throw_if_errors, const ConfigStore &extra_opts)
Definition: MRRG.cpp:473
InterMRRGMap
Definition: MRRGProcedures.h:246
MRRG
Definition: MRRG.h:216
OpCode::ADD
@ ADD
MRRGTransformationResult::transformed_mrrg
MRRG transformed_mrrg
Definition: MRRGProcedures.h:279
Mapping::mapMRRGNode
void mapMRRGNode(OpGraph::NodeDescriptor, MRRG::NodeDescriptor node)
Definition: Mapping.cpp:58
Mapping
Definition: Mapping.h:31
muxExNodeInsertion
MRRGTransformationResult muxExNodeInsertion(const MRRG &src_mrrg)
Definition: MRRGProcedures.cpp:458
SCENARIO
SCENARIO("MRRG Reduction Tests", "[mrrg-reduction]")
Definition: MRRG_reduction_tests.cpp:126
InterMRRGMap::newNodesForOldNode
const NodeSet & newNodesForOldNode(MRRG::NodeDescriptor n) const
Definition: MRRGProcedures.h:252
MRRGNode::make_function
static MRRGNode make_function(Module *parent, int bitwidth, int cycle, STR &&name, int latency, SupportedOps supported_ops, int max_cap=1, bool is_const_unit=false)
Definition: MRRG.h:191
InterMRRGMap::addMapping
void addMapping(MRRG::NodeDescriptor old_node, MRRG::NodeDescriptor new_node)
Definition: MRRGProcedures.h:257
transformToOriginalMRRG
Mapping transformToOriginalMRRG(const Mapping &map, const MRRGTransformationResult &transformation)
Definition: MRRGProcedures.cpp:607
OpGraphOp
Definition: OpGraph.h:131
MRRGNode
Definition: MRRG.h:60
reduceLosslessly
MRRGTransformationResult reduceLosslessly(const MRRG &src_mrrg, const MRRGTransformFlags &flags)
Definition: MRRGProcedures.cpp:420
MRRG::getNode
NodeDescriptor getNode(int cycle, const std::string &name) const
Definition: MRRG.cpp:142
Mapping.h
OpCode::MUL
@ MUL
MRRGProcedures.h
InterMRRGMap::addMappingMulti
void addMappingMulti(MRRG::NodeDescriptor old_node, const NodeList &new_nodes)
Definition: MRRGProcedures.h:263
MRRGNode::make_routing
static MRRGNode make_routing(Module *parent, int bitwidth, int cycle, STR &&name, int latency=0, int max_cap=1)
Definition: MRRG.h:151
MRRGTransformationResult
Definition: MRRGProcedures.h:278