From 4390a80dda1b9521c4aa32aa4f750e6304ca3280 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 13 Jun 2020 23:57:40 +0200 Subject: [PATCH] Added test cases for multiple-outputs local processors. --- src/db/db/dbLocalOperationUtils.h | 8 +- src/db/unit_tests/dbHierProcessorTests.cc | 153 +++++++++++++++++++--- testdata/algo/hlp17.oas | Bin 0 -> 475 bytes 3 files changed, 137 insertions(+), 24 deletions(-) create mode 100644 testdata/algo/hlp17.oas diff --git a/src/db/db/dbLocalOperationUtils.h b/src/db/db/dbLocalOperationUtils.h index 51e5c5ada..d20f50043 100644 --- a/src/db/db/dbLocalOperationUtils.h +++ b/src/db/db/dbLocalOperationUtils.h @@ -63,7 +63,7 @@ private: const Trans m_trans; }; -class PolygonRefGenerator +class DB_PUBLIC PolygonRefGenerator : public PolygonSink { public: @@ -82,7 +82,7 @@ private: std::unordered_set *mp_polyrefs; }; -class EdgeToEdgeSetGenerator +class DB_PUBLIC EdgeToEdgeSetGenerator : public EdgeSink { public: @@ -100,7 +100,7 @@ private: std::unordered_set *mp_edges; }; -class PolygonRefToShapesGenerator +class DB_PUBLIC PolygonRefToShapesGenerator : public PolygonSink { public: @@ -119,7 +119,7 @@ private: db::Shapes *mp_shapes; }; -class PolygonSplitter +class DB_PUBLIC PolygonSplitter : public PolygonSink { public: diff --git a/src/db/unit_tests/dbHierProcessorTests.cc b/src/db/unit_tests/dbHierProcessorTests.cc index 4d589411c..16d102c1a 100644 --- a/src/db/unit_tests/dbHierProcessorTests.cc +++ b/src/db/unit_tests/dbHierProcessorTests.cc @@ -27,6 +27,10 @@ #include "dbTestSupport.h" #include "dbReader.h" #include "dbCommonReader.h" +#include "dbEdgeProcessor.h" +#include "dbPolygonGenerators.h" +#include "dbLocalOperationUtils.h" +#include "dbPolygon.h" static std::string testdata (const std::string &fn) { @@ -39,7 +43,8 @@ enum TestMode TMNot = 1, TMAndSwapped = 2, TMNotSwapped = 3, - TMSelfOverlap = 4 + TMSelfOverlap = 4, + TMAndNot = 5 }; /** @@ -79,6 +84,88 @@ private: db::Coord m_dist; }; +/** + * @brief A new processor class providing two outputs for two inputs: one for AND and one for NOT + */ +class BoolAndPlusNotLocalOperation + : public db::local_operation +{ +public: + BoolAndPlusNotLocalOperation () + : db::local_operation () + { + // .. nothing yet .. + } + + virtual std::string description () const + { + return std::string (); + } + + void compute_local (db::Layout *layout, const db::shape_interactions &interactions, std::vector > &results, size_t max_vertex_count, double area_ratio) const + { + tl_assert (results.size () == 2); + + db::EdgeProcessor ep; + + // 0: and, 1: not + for (unsigned int gen = 0; gen < 2; ++gen) { + + std::unordered_set &result = results [gen]; + ep.clear (); + + size_t p1 = 0, p2 = 1; + + std::set others; + for (db::shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + for (db::shape_interactions::iterator2 j = i->second.begin (); j != i->second.end (); ++j) { + others.insert (interactions.intruder_shape (*j).second); + } + } + + for (db::shape_interactions::iterator i = interactions.begin (); i != interactions.end (); ++i) { + + const db::PolygonRef &subject = interactions.subject_shape (i->first); + if (others.find (subject) != others.end ()) { + if (gen == 0) { + result.insert (subject); + } + } else if (i->second.empty ()) { + // shortcut (not: keep, and: drop) + if (gen != 0) { + result.insert (subject); + } + } else { + for (db::PolygonRef::polygon_edge_iterator e = subject.begin_edge (); ! e.at_end(); ++e) { + ep.insert (*e, p1); + } + p1 += 2; + } + + } + + if (! others.empty () || p1 > 0) { + + for (std::set::const_iterator o = others.begin (); o != others.end (); ++o) { + for (db::PolygonRef::polygon_edge_iterator e = o->begin_edge (); ! e.at_end(); ++e) { + ep.insert (*e, p2); + } + p2 += 2; + } + + db::BooleanOp op (gen == 0 ? db::BooleanOp::And : db::BooleanOp::ANotB); + db::PolygonRefGenerator pr (layout, result); + db::PolygonSplitter splitter (pr, area_ratio, max_vertex_count); + db::PolygonGenerator pg (splitter, true, true); + ep.set_base_verbosity (50); + ep.process (pg, op); + + } + + } + } +}; + /** * @brief A new processor class which and/nots with a sized version of the intruder */ @@ -169,11 +256,11 @@ static std::string contexts_to_s (db::Layout *layout, db::local_processor_contex return res; } -static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc, bool single, db::Coord dist, unsigned int nthreads = 0) +static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num1, int out_layer_num2, std::string *context_doc, bool single, db::Coord dist, unsigned int nthreads = 0) { db::Layout layout_org; - unsigned int l1 = 0, l2 = 0, lout = 0; + unsigned int l1 = 0, l2 = 0, lout1 = 0, lout2 = 0; db::LayerMap lmap; bool swap = (mode == TMAndSwapped || mode == TMNotSwapped); @@ -197,10 +284,17 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m layout_org.set_properties (l2, p); } - p.layer = out_layer_num; + p.layer = out_layer_num1; p.datatype = 0; - lmap.map (db::LDPair (out_layer_num, 0), lout = layout_org.insert_layer ()); - layout_org.set_properties (lout, p); + lmap.map (db::LDPair (out_layer_num1, 0), lout1 = layout_org.insert_layer ()); + layout_org.set_properties (lout1, p); + + if (out_layer_num2 >= 0) { + p.layer = out_layer_num2; + p.datatype = 0; + lmap.map (db::LDPair (out_layer_num2, 0), lout2 = layout_org.insert_layer ()); + layout_org.set_properties (lout2, p); + } db::LoadLayoutOptions options; options.get_options ().layer_map = lmap; @@ -208,7 +302,10 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m reader.read (layout_org, options); } - layout_org.clear_layer (lout); + layout_org.clear_layer (lout1); + if (out_layer_num2 >= 0) { + layout_org.clear_layer (lout2); + } normalize_layer (layout_org, l1); if (l1 != l2) { normalize_layer (layout_org, l2); @@ -219,7 +316,11 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m db::SelfOverlapMergeLocalOperation self_intersect_op (2); BoolAndOrNotWithSizedLocalOperation sized_bool_op (mode == TMAnd || mode == TMAndSwapped, dist); SelfOverlapWithSizedLocalOperation sized_self_intersect_op (2, dist); - if (mode == TMSelfOverlap) { + BoolAndPlusNotLocalOperation andnot; + + if (mode == TMAndNot) { + lop = &andnot; + } else if (mode == TMSelfOverlap) { if (dist > 0) { lop = &sized_self_intersect_op; } else { @@ -233,6 +334,13 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m } } + std::vector ilv, olv; + ilv.push_back (l2); + olv.push_back (lout1); + if (out_layer_num2 >= 0) { + olv.push_back (lout2); + } + if (single) { db::local_processor proc (&layout_org, &layout_org.cell (*layout_org.begin_top_down ())); @@ -241,12 +349,9 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m proc.set_max_vertex_count (16); if (! context_doc) { - proc.run (lop, l1, l2, lout); + proc.run (lop, l1, ilv, olv); } else { db::local_processor_contexts contexts; - std::vector ilv, olv; - ilv.push_back (l2); - olv.push_back (lout); proc.compute_contexts (contexts, lop, l1, ilv); *context_doc = contexts_to_s (&layout_org, contexts); proc.compute_results (contexts, lop, olv); @@ -262,12 +367,9 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m proc.set_max_vertex_count (16); if (! context_doc) { - proc.run (lop, l1, l2, lout); + proc.run (lop, l1, ilv, olv); } else { db::local_processor_contexts contexts; - std::vector ilv, olv; - ilv.push_back (l2); - olv.push_back (lout); proc.compute_contexts (contexts, lop, l1, ilv); *context_doc = contexts_to_s (&layout_org, contexts); proc.compute_results (contexts, lop, olv); @@ -280,22 +382,27 @@ static void run_test_bool_gen (tl::TestBase *_this, const char *file, TestMode m static void run_test_bool (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc = 0, unsigned int nthreads = 0) { - run_test_bool_gen (_this, file, mode, out_layer_num, context_doc, true, 0, nthreads); + run_test_bool_gen (_this, file, mode, out_layer_num, -1, context_doc, true, 0, nthreads); } static void run_test_bool2 (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num, std::string *context_doc = 0, unsigned int nthreads = 0) { - run_test_bool_gen (_this, file, mode, out_layer_num, context_doc, false, 0, nthreads); + run_test_bool_gen (_this, file, mode, out_layer_num, -1, context_doc, false, 0, nthreads); } static void run_test_bool_with_size (tl::TestBase *_this, const char *file, TestMode mode, db::Coord dist, int out_layer_num, std::string *context_doc = 0, unsigned int nthreads = 0) { - run_test_bool_gen (_this, file, mode, out_layer_num, context_doc, true, dist, nthreads); + run_test_bool_gen (_this, file, mode, out_layer_num, -1, context_doc, true, dist, nthreads); } static void run_test_bool2_with_size (tl::TestBase *_this, const char *file, TestMode mode, db::Coord dist, int out_layer_num, std::string *context_doc = 0, unsigned int nthreads = 0) { - run_test_bool_gen (_this, file, mode, out_layer_num, context_doc, false, dist, nthreads); + run_test_bool_gen (_this, file, mode, out_layer_num, -1, context_doc, false, dist, nthreads); +} + +static void run_test_bool22 (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num1, int out_layer_num2, std::string *context_doc = 0, unsigned int nthreads = 0) +{ + run_test_bool_gen (_this, file, mode, out_layer_num1, out_layer_num2, context_doc, false, 0, nthreads); } TEST(BasicAnd1) @@ -1136,3 +1243,9 @@ TEST(RedundantHierarchyNot2) run_test_bool2 (_this, "hlp16.gds", TMNot, 101); } +TEST(MultipleOutputs) +{ + // Redundant hierarchy, NOT + run_test_bool22 (_this, "hlp17.oas", TMAndNot, 100, 101); +} + diff --git a/testdata/algo/hlp17.oas b/testdata/algo/hlp17.oas new file mode 100644 index 0000000000000000000000000000000000000000..a40ff47668825b00c9ab8bc78d5d27a3c10e7cbf GIT binary patch literal 475 zcmY!lcJ=kt^>+;R4CduxWH!_@V0gjKfDB|rrGn#q9V6m{J>C6WUE)3cLR{TlgW|(I zT|zuKSY&u*Akv|J*c8Z!as|hS_y@#0yZZR>Fauf4tj->uJ}%54HZOyyF(U&bQ-}H= zv9HXcmQ0LHFZ4gKU0~hFBC44J692%)AS#%;kWthC#5=)ufQOe+@F&BDXDllwGBPoK jU=y`Z0UL0IY0d|h1zFq-AJ_zdI`%wbVQLu3fPn!3yc)F| literal 0 HcmV?d00001