diff --git a/src/buddies/src/bd/strmxor.cc b/src/buddies/src/bd/strmxor.cc index da2092718..bc592af0b 100644 --- a/src/buddies/src/bd/strmxor.cc +++ b/src/buddies/src/bd/strmxor.cc @@ -94,9 +94,11 @@ struct ResultDescriptor size_t count () const { if (layout && layer_output >= 0) { - // NOTE: this assumes the output is flat - tl_assert (layout->cells () == 1); - return layout->cell (top_cell).shapes (layer_output).size (); + size_t res = 0; + for (db::Layout::const_iterator c = layout->begin (); c != layout->end (); ++c) { + res += c->shapes (layer_output).size (); + } + return res; } else { return shape_count; } @@ -105,9 +107,12 @@ struct ResultDescriptor bool is_empty () const { if (layout && layer_output >= 0) { - // NOTE: this assumes the output is flat - tl_assert (layout->cells () == 1); - return layout->cell (top_cell).shapes (layer_output).empty (); + for (db::Layout::const_iterator c = layout->begin (); c != layout->end (); ++c) { + if (! c->shapes (layer_output).empty ()) { + return false; + } + } + return true; } else { return shape_count == 0; } @@ -185,7 +190,7 @@ BD_PUBLIC int strmxor (int argc, char *argv[]) << tl::arg ("-tb|--top-b=name", &top_b, "Specifies the top cell for the second layout", "See --top-a for details." ) - << tl::arg ("-d|--deep", &deep, "Deep (hierarchical mode)", + << tl::arg ("-u|--deep", &deep, "Deep (hierarchical mode)", "Enables hierarchical XOR (experimental). In this mode, tiling is not supported " "and the tiling arguments are ignored." ) @@ -593,7 +598,7 @@ bool run_deep_xor (const XORData &xor_data) ri_a = db::RecursiveShapeIterator (*xor_data.layout_a, xor_data.layout_a->cell (xor_data.cell_a), ll->second.first); } - if (ll->second.second < 0) { + if (ll->second.second >= 0) { ri_b = db::RecursiveShapeIterator (*xor_data.layout_b, xor_data.layout_b->cell (xor_data.cell_b), ll->second.second); } diff --git a/src/buddies/unit_tests/bdStrmxorTests.cc b/src/buddies/unit_tests/bdStrmxorTests.cc index 27871f521..2ccf0a4d1 100644 --- a/src/buddies/unit_tests/bdStrmxorTests.cc +++ b/src/buddies/unit_tests/bdStrmxorTests.cc @@ -30,7 +30,7 @@ BD_PUBLIC int strmxor (int argc, char *argv[]); -TEST(0) +TEST(0_Basic_Flat) { tl::CaptureChannel cap; @@ -51,7 +51,28 @@ TEST(0) ); } -TEST(1A) +TEST(0_Basic_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in1.gds"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", input_a.c_str (), input_b.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 0); + + EXPECT_EQ (cap.captured_text (), + "No differences found\n" + ); +} + +TEST(1A_Flat) { tl::CaptureChannel cap; @@ -93,7 +114,49 @@ TEST(1A) ); } -TEST(1B) +TEST(1A_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au1d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "--deep", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + "Result summary (layers without differences are not shown):\n" + "\n" + " Layer Output Differences (shape count)\n" + " -------------------------------------------------------\n" + " 3/0 3/0 3\n" + " 6/0 6/0 314\n" + " 8/1 8/1 1\n" + " 10/0 - (no such layer in first layout)\n" + "\n" + ); +} + +TEST(1B_Flat) { tl::CaptureChannel cap; @@ -123,7 +186,37 @@ TEST(1B) ); } -TEST(1C) +TEST(1B_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", input_a.c_str (), input_b.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + "Result summary (layers without differences are not shown):\n" + "\n" + " Layer Output Differences (shape count)\n" + " -------------------------------------------------------\n" + " 3/0 - 30\n" + " 6/0 - 314\n" + " 8/1 - 1\n" + " 10/0 - (no such layer in first layout)\n" + "\n" + ); +} + +TEST(1C_Flat) { tl::CaptureChannel cap; @@ -144,7 +237,28 @@ TEST(1C) ); } -TEST(1D) +TEST(1C_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "--no-summary", input_a.c_str (), input_b.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + ); +} + +TEST(1D_Flat) { tl::CaptureChannel cap; @@ -162,7 +276,25 @@ TEST(1D) EXPECT_EQ (cap.captured_text (), ""); } -TEST(2) +TEST(1D_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "-s", input_a.c_str (), input_b.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + EXPECT_EQ (cap.captured_text (), ""); +} + +TEST(2_Flat) { tl::CaptureChannel cap; @@ -195,7 +327,40 @@ TEST(2) ); } -TEST(3) +TEST(2_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au2d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "--no-summary", "-l", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "" + ); +} + +TEST(3_Flat) { tl::CaptureChannel cap; @@ -228,7 +393,41 @@ TEST(3) ); } -TEST(4) +TEST(3_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au3d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + // NOTE: -p is ignored in deep mode + const char *argv[] = { "x", "-u", "--no-summary", "-p=1.0", "-n=4", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + ); +} + +TEST(4_Flat) { tl::CaptureChannel cap; @@ -261,7 +460,40 @@ TEST(4) ); } -TEST(5) +TEST(4_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au4d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "--no-summary", "-p=1.0", "-n=4", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + ); +} + +TEST(5_Flat) { tl::CaptureChannel cap; @@ -294,7 +526,40 @@ TEST(5) ); } -TEST(6) +TEST(5_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au5d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "--no-summary", "-b=1000", "-t=0.0,0.005,0.01,0.02,0.09,0.1", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + ); +} + +TEST(6_Flat) { tl::CaptureChannel cap; @@ -326,3 +591,36 @@ TEST(6) "Layer 10/0 is not present in first layout, but in second\n" ); } + +TEST(6_Deep) +{ + tl::CaptureChannel cap; + + std::string input_a = tl::testsrc (); + input_a += "/testdata/bd/strmxor_in1.gds"; + + std::string input_b = tl::testsrc (); + input_b += "/testdata/bd/strmxor_in2.gds"; + + std::string au = tl::testsrc (); + au += "/testdata/bd/strmxor_au6d.oas"; + + std::string output = this->tmp_file ("tmp.oas"); + + const char *argv[] = { "x", "-u", "--no-summary", "-ta=INV2", "-tb=2VNI", input_a.c_str (), input_b.c_str (), output.c_str () }; + + EXPECT_EQ (strmxor (sizeof (argv) / sizeof (argv[0]), (char **) argv), 1); + + db::Layout layout; + + { + tl::InputStream stream (output); + db::Reader reader (stream); + reader.read (layout); + } + + db::compare_layouts (this, layout, au, db::NoNormalization); + EXPECT_EQ (cap.captured_text (), + "Layer 10/0 is not present in first layout, but in second\n" + ); +} diff --git a/testdata/bd/strmxor_au1d.oas b/testdata/bd/strmxor_au1d.oas new file mode 100644 index 000000000..012da7843 Binary files /dev/null and b/testdata/bd/strmxor_au1d.oas differ diff --git a/testdata/bd/strmxor_au2d.oas b/testdata/bd/strmxor_au2d.oas new file mode 100644 index 000000000..fcef4685e Binary files /dev/null and b/testdata/bd/strmxor_au2d.oas differ diff --git a/testdata/bd/strmxor_au3d.oas b/testdata/bd/strmxor_au3d.oas new file mode 100644 index 000000000..012da7843 Binary files /dev/null and b/testdata/bd/strmxor_au3d.oas differ diff --git a/testdata/bd/strmxor_au4d.oas b/testdata/bd/strmxor_au4d.oas new file mode 100644 index 000000000..996d58443 Binary files /dev/null and b/testdata/bd/strmxor_au4d.oas differ diff --git a/testdata/bd/strmxor_au5d.oas b/testdata/bd/strmxor_au5d.oas new file mode 100644 index 000000000..fed55a713 Binary files /dev/null and b/testdata/bd/strmxor_au5d.oas differ diff --git a/testdata/bd/strmxor_au6d.oas b/testdata/bd/strmxor_au6d.oas new file mode 100644 index 000000000..2b90eba60 Binary files /dev/null and b/testdata/bd/strmxor_au6d.oas differ