14 #include <catch2/catch.hpp>
17 THEN(
"OpGraph::verify should pass") {
22 SCENARIO (
"removing nodes and links from OpGraphs",
"") {
23 GIVEN(
"A linear 3-node DFG") {
25 WHEN(
"Removing a link") {
26 const auto target_op = opgraph.getOp(
"op_b");
27 opgraph.unLink(opgraph.outputVal(target_op), opgraph.fanout(target_op).at(0));
30 WHEN(
"Removing an internal node") {
31 opgraph.erase(opgraph.getOp(
"op_b"));
34 WHEN(
"Removing a inpupt node") {
35 opgraph.erase(opgraph.getOp(
"op_a"));
38 WHEN(
"Removing a output node") {
39 opgraph.erase(opgraph.getOp(
"op_c"));
44 GIVEN(
"A self loop 3-node DFG") {
46 WHEN(
"Removing a link") {
47 const auto target_op = opgraph.getOp(
"op_l");
48 opgraph.unLink(opgraph.outputVal(target_op), opgraph.fanout(target_op).at(0));
51 WHEN(
"Removing an internal node") {
52 opgraph.erase(opgraph.getOp(
"op_l"));
55 WHEN(
"Removing a inpupt node") {
56 opgraph.erase(opgraph.getOp(
"op_a"));
59 WHEN(
"Removing a output node") {
60 opgraph.erase(opgraph.getOp(
"op_c"));
65 GIVEN(
"A loop 4-node DFG") {
67 WHEN(
"Removing a link") {
68 const auto target_op = opgraph.getOp(
"op_l");
69 opgraph.unLink(opgraph.outputVal(target_op), opgraph.fanout(target_op).at(0));
72 WHEN(
"Removing an internal node") {
73 opgraph.erase(opgraph.getOp(
"op_l"));
76 WHEN(
"Removing a inpupt node") {
77 opgraph.erase(opgraph.getOp(
"op_a"));
80 WHEN(
"Removing a output node") {
81 opgraph.erase(opgraph.getOp(
"op_d"));
86 GIVEN(
"A Tree 112 DFG") {
88 WHEN(
"Removing a link") {
89 const auto target_op = opgraph.getOp(
"op_b");
90 opgraph.unLink(opgraph.outputVal(target_op), opgraph.fanout(target_op).at(0));
93 WHEN(
"Removing an internal node") {
94 opgraph.erase(opgraph.getOp(
"op_b"));
97 WHEN(
"Removing a inpupt node") {
98 opgraph.erase(opgraph.getOp(
"op_a"));
101 WHEN(
"Removing a output node") {
102 opgraph.erase(opgraph.getOp(
"op_c"));
107 GIVEN(
"A Converging 121 DFG") {
109 WHEN(
"Removing a link") {
110 const auto target_op = opgraph.getOp(
"op_a");
111 opgraph.unLink(opgraph.outputVal(target_op), opgraph.fanout(target_op).at(0));
114 WHEN(
"Removing an internal node") {
115 opgraph.erase(opgraph.getOp(
"op_a"));
118 WHEN(
"Removing a inpupt node") {
119 opgraph.erase(opgraph.getOp(
"op_a"));
122 WHEN(
"Removing a output node") {
123 opgraph.erase(opgraph.getOp(
"op_c"));
131 const auto expected_opcode = GENERATE(values<OpGraphOpCode>({
157 THEN(
"Converting it to a string should work") {
158 const auto as_str =
to_string(expected_opcode);
159 AND_THEN(
"Converting back to an opcode should give the same thing") {
161 CHECK(actual_opcode == expected_opcode);
166 GIVEN(
"A bogus string") {
167 THEN(
"to_string should throw") {
189 og.
insert(a, {params.getString(
"name_b"), 32,
opcode_from_string(params.getStringOr(
"op_b",
"add"))}, params.getString(
"ab_oper"));
195 const auto b = og.
insert(a, {params.getString(
"name_b"), 32,
opcode_from_string(params.getStringOr(
"op_b",
"add"))}, params.getString(
"ab_oper")).newOp;
202 og.
insert(a, {params.getString(
"name_b"), 32,
opcode_from_string(params.getStringOr(
"op_b",
"add"))}, params.getString(
"ab_oper"));
203 og.
insert(a, {params.getString(
"name_c"), 32,
opcode_from_string(params.getStringOr(
"op_c",
"add"))}, params.getString(
"ac_oper"));
209 og.
insert(a, {params.getString(
"name_b"), 32,
opcode_from_string(params.getStringOr(
"op_b",
"add"))}, params.getString(
"ab_oper"));
210 const auto c = og.
insert(a, {params.getString(
"name_c"), 32,
opcode_from_string(params.getStringOr(
"op_c",
"add"))}, params.getString(
"ac_oper")).newOp;
216 og.
insert({params.getString(
"name_a"), 32,
opcode_from_string(params.getStringOr(
"op_const",
"const")), (unsigned)params.getInt(
"constVal")});
221 struct OpGraphEqualityTest {
222 std::string test_description;
223 bool expect_to_be_same;
228 const OpGraphEqualityTest tests[] {
229 {
"one op vs. one op -- same name",
true,
230 og_generators.at(
"a;")({{
"name_a",
"a"}}),
231 og_generators.at(
"a;")({{
"name_a",
"a"}}),
233 {
"one op vs. one op -- same name, different op",
false,
234 og_generators.at(
"a;")({{
"name_a",
"a"},{
"op_a",
"add"}}),
235 og_generators.at(
"a;")({{
"name_a",
"a"},{
"op_a",
"mul"}}),
237 {
"one op vs. one op -- different name",
false,
238 og_generators.at(
"a;")({{
"name_a",
"a"}}),
239 og_generators.at(
"a;")({{
"name_a",
"b"}}),
241 {
"two ops vs. two ops -- same names",
true,
242 og_generators.at(
"a;b")({{
"name_a",
"a"},{
"name_b",
"b"}}),
243 og_generators.at(
"a;b")({{
"name_a",
"a"},{
"name_b",
"b"}}),
245 {
"two ops vs. two ops -- 1 different name",
false,
246 og_generators.at(
"a;b")({{
"name_a",
"a"},{
"name_b",
"b"}}),
247 og_generators.at(
"a;b")({{
"name_a",
"a"},{
"name_b",
"c"}}),
249 {
"a->b vs. a;b",
false,
251 og_generators.at(
"a;b" )({{
"name_a",
"b"},{
"name_b",
"c"}}),
253 {
"a->b vs. a->b",
true,
257 {
"a->b vs. a->b, but operand tag is different",
false,
261 {
"a->{b c} vs. a->{b c}",
true,
262 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
263 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
265 {
"a->{b c} vs. a->{b d}",
false,
266 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
267 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"d"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
269 {
"a->{b c} vs. a->{b c}, but operand tag is different",
false,
270 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
271 og_generators.at(
"a->{b c}")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
Operands::BINARY_ANY},{
"ab_oper",
Operands::BINARY_LHS},{
"ac_oper",
Operands::BINARY_RHS}}),
273 {
"one const vs. one const -- same value",
true,
274 og_generators.at(
"const_a;")({{
"name_a",
"a"}, {
"constVal",
"4"}}),
275 og_generators.at(
"const_a;")({{
"name_a",
"a"}, {
"constVal",
"4"}}),
277 {
"one const vs. one const -- different value",
false,
278 og_generators.at(
"const_a;")({{
"name_a",
"a"}, {
"constVal",
"1"}}),
279 og_generators.at(
"const_a;")({{
"name_a",
"a"}, {
"constVal",
"4"}}),
281 {
"After erasing a node and a val",
true,
282 og_generators.at(
"a->b with b erased")({{
"name_a",
"a"},{
"name_b",
"b"},{
"ab_oper",
Operands::BINARY_ANY}}),
285 {
"After erasing just a node",
true,
286 og_generators.at(
"a->{b c} with c erased")({{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
287 og_generators.at(
"a->b")( {{
"name_a",
"a"},{
"name_b",
"b"},{
"name_c",
"c"},{
"ab_oper",
Operands::BINARY_ANY},{
"ac_oper",
Operands::BINARY_ANY}}),
292 const auto& test_it = GENERATE_REF(range((std::ptrdiff_t)0, std::distance(
begin(tests),
end(tests))));
293 const auto& test = tests[test_it];
295 GIVEN(
"A '" << test.test_description <<
"' test case") {
296 THEN(
"The OpGraphs should " << (test.expect_to_be_same?
"":
"not ") <<
"compare equal") {
297 if (test.expect_to_be_same) {
298 CHECK(test.graph1 == test.graph2);
299 CHECK_FALSE(test.graph1 != test.graph2);
301 CHECK(test.graph1 != test.graph2);
302 CHECK_FALSE(test.graph1 == test.graph2);
305 THEN(
"A copies should compare as expected") {
306 const auto graph1_copy = test.graph1;
307 CHECK(graph1_copy == test.graph1);
308 if (test.expect_to_be_same) {
309 CHECK(graph1_copy == test.graph2);
310 CHECK_FALSE(graph1_copy != test.graph2);
312 CHECK(graph1_copy != test.graph2);
313 CHECK_FALSE(graph1_copy == test.graph2);
316 const auto graph2_copy = test.graph2;
317 CHECK(graph2_copy == test.graph2);
318 if (test.expect_to_be_same) {
319 CHECK(test.graph1 == graph2_copy);
320 CHECK_FALSE(test.graph1 != graph2_copy);
322 CHECK(test.graph1 != graph2_copy);
323 CHECK_FALSE(test.graph1 == graph2_copy);