WIP: tests for local processor flat mode

This commit is contained in:
Matthias Koefferlein 2020-09-26 17:11:13 +02:00
parent 00ae88a5d4
commit ec01c9b72b
4 changed files with 224 additions and 5 deletions

View File

@ -1655,6 +1655,13 @@ struct scan_shape2shape_same_layer
scanner.process (rec, dist, db::box_convert<TS> (), db::box_convert<TI> ()); scanner.process (rec, dist, db::box_convert<TS> (), db::box_convert<TI> ());
} }
void
operator () (const db::Shapes *, unsigned int, unsigned int, shape_interactions<TS, TI> &, db::Coord) const
{
// cannot have different types on the same layer
tl_assert (false);
}
}; };
template <class T> template <class T>
@ -1679,13 +1686,28 @@ struct scan_shape2shape_same_layer<T, T>
scanner.process (rec, dist, db::box_convert<T> ()); scanner.process (rec, dist, db::box_convert<T> ());
} }
void
operator () (const db::Shapes *shapes, unsigned int subject_id0, unsigned int intruder_layer, shape_interactions<T, T> &interactions, db::Coord dist) const
{
db::box_scanner<T, int> scanner;
interaction_registration_shape1<T, T> rec (&interactions, intruder_layer);
unsigned int id = subject_id0;
for (db::Shapes::shape_iterator i = shapes->begin (shape_flags<T> ()); !i.at_end (); ++i) {
const T *ref = i->basic_ptr (typename T::tag ());
scanner.insert (ref, id++);
}
scanner.process (rec, dist, db::box_convert<T> ());
}
}; };
template <class TS, class TI> template <class TS, class TI>
struct scan_shape2shape_different_layers struct scan_shape2shape_different_layers
{ {
void void
operator () (db::Layout *layout, const db::Shapes *subject_shapes, const db::Shapes *intruder_shapes, unsigned int subject_id0, const std::set<TI> &intruders, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) operator () (db::Layout *layout, const db::Shapes *subject_shapes, const db::Shapes *intruder_shapes, unsigned int subject_id0, const std::set<TI> *intruders, unsigned int intruder_layer, shape_interactions<TS, TI> &interactions, db::Coord dist) const
{ {
db::box_scanner2<TS, int, TI, int> scanner; db::box_scanner2<TS, int, TI, int> scanner;
interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer); interaction_registration_shape2shape<TS, TI> rec (layout, &interactions, intruder_layer);
@ -1697,8 +1719,10 @@ struct scan_shape2shape_different_layers
} }
// TODO: can we confine this search to the subject's (sized) bounding box? // TODO: can we confine this search to the subject's (sized) bounding box?
for (typename std::set<TI>::const_iterator i = intruders.begin (); i != intruders.end (); ++i) { if (intruders) {
scanner.insert2 (i.operator-> (), interactions.next_id ()); for (typename std::set<TI>::const_iterator i = intruders->begin (); i != intruders->end (); ++i) {
scanner.insert2 (i.operator-> (), interactions.next_id ());
}
} }
if (intruder_shapes) { if (intruder_shapes) {
@ -1763,7 +1787,7 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
} else { } else {
db::Layout *target_layout = (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout); db::Layout *target_layout = (mp_subject_layout == mp_intruder_layout ? 0 : mp_subject_layout);
scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, ipl == intruders.second.end () ? empty_intruders : ipl->second, *il, interactions, op->dist ()); scan_shape2shape_different_layers<TS, TI> () (target_layout, subject_shapes, intruder_shapes, subject_id0, &(ipl == intruders.second.end () ? empty_intruders : ipl->second), *il, interactions, op->dist ());
} }
@ -1825,6 +1849,88 @@ local_processor<TS, TI, TR>::compute_local_cell (const db::local_processor_conte
} }
} }
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const
{
std::vector<const db::Shapes *> is;
is.push_back (intruders);
std::vector<db::Shapes *> os;
os.push_back (result_shapes);
run_flat (subject_shapes, is, op, os);
}
template <class TS, class TI, class TR>
void
local_processor<TS, TI, TR>::run_flat (const db::Shapes *subject_shapes, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const
{
tl_assert (mp_subject_top == 0);
tl_assert (mp_intruder_top == 0);
shape_interactions<TS, TI> interactions;
for (std::vector<const db::Shapes *>::const_iterator il = intruders.begin (); il != intruders.end (); ++il) {
const db::Shapes *intruder_shapes = *il;
// insert dummy interactions to accommodate subject vs. nothing and assign an ID
// range for the subject shapes.
unsigned int subject_id0 = 0;
for (db::Shapes::shape_iterator i = subject_shapes->begin (shape_flags<TS> ()); !i.at_end (); ++i) {
unsigned int id = interactions.next_id ();
if (subject_id0 == 0) {
subject_id0 = id;
}
if (op->on_empty_intruder_hint () != local_operation<TS, TI, TR>::Drop) {
const TS *ref = i->basic_ptr (typename TS::tag ());
interactions.add_subject (id, *ref);
}
}
static std::set<TI> empty_intruders;
if (! subject_shapes->empty () && intruder_shapes) {
if (intruder_shapes == subject_shapes) {
scan_shape2shape_same_layer<TS, TI> () (subject_shapes, subject_id0, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
} else {
scan_shape2shape_different_layers<TS, TI> () (0 /*layout*/, subject_shapes, intruder_shapes, subject_id0, 0 /*ext. intruders*/, (unsigned int) (il - intruders.begin ()), interactions, op->dist ());
}
}
}
if (interactions.begin () != interactions.end ()) {
if (interactions.begin_intruders () == interactions.end_intruders ()) {
typename local_operation<TS, TI, TR>::on_empty_intruder_mode eh = op->on_empty_intruder_hint ();
if (eh == local_operation<TS, TI, TR>::Drop) {
return;
}
}
std::vector<std::unordered_set<TR> > result;
result.resize (result_shapes.size ());
op->compute_local (mp_subject_layout, interactions, result, m_max_vertex_count, m_area_ratio);
for (std::vector<db::Shapes *>::const_iterator r = result_shapes.begin (); r != result_shapes.end (); ++r) {
if (*r) {
const std::unordered_set<TR> rs = result [r - result_shapes.begin ()];
(*r)->insert (rs.begin (), rs.end ());
}
}
}
}
template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>; template class DB_PUBLIC local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>; template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::PolygonRef>;
template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::Edge>; template class DB_PUBLIC local_processor<db::PolygonRef, db::Edge, db::Edge>;

View File

@ -375,7 +375,7 @@ template <class TS, class TI, class TR>
class DB_PUBLIC local_processor class DB_PUBLIC local_processor
{ {
public: public:
local_processor (db::Layout *layout, db::Cell *top, const std::set<db::cell_index_type> *breakout_cells = 0); local_processor (db::Layout *layout = 0, db::Cell *top = 0, const std::set<db::cell_index_type> *breakout_cells = 0);
local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0); local_processor (db::Layout *subject_layout, db::Cell *subject_top, const db::Layout *intruder_layout, const db::Cell *intruder_cell, const std::set<db::cell_index_type> *subject_breakout_cells = 0, const std::set<db::cell_index_type> *intruder_breakout_cells = 0);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers); void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, unsigned int intruder_layer, unsigned int output_layers);
void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers); void run (local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers, const std::vector<unsigned int> &output_layers);
@ -383,6 +383,9 @@ public:
void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const; void compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const;
void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const; void compute_results (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, const std::vector<unsigned int> &output_layers) const;
void run_flat (const db::Shapes *subject_shapes, const db::Shapes *intruders, const local_operation<TS, TI, TR> *op, db::Shapes *result_shapes) const;
void run_flat (const db::Shapes *subjects, const std::vector<const db::Shapes *> &intruders, const local_operation<TS, TI, TR> *op, const std::vector<db::Shapes *> &result_shapes) const;
void set_description (const std::string &d) void set_description (const std::string &d)
{ {
m_description = d; m_description = d;

View File

@ -323,6 +323,110 @@ static void run_test_bool22 (tl::TestBase *_this, const char *file, TestMode mod
run_test_bool_gen (_this, file, mode, out_layer_num1, out_layer_num2, context_doc, false, 0, nthreads); run_test_bool_gen (_this, file, mode, out_layer_num1, out_layer_num2, context_doc, false, 0, nthreads);
} }
static void run_test_bool_gen_flat (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num1, int out_layer_num2, db::Coord dist)
{
db::Layout layout_org;
unsigned int l1 = 0, l2 = 0, lout1 = 0, lout2 = 0;
db::LayerMap lmap;
bool swap = (mode == TMAndSwapped || mode == TMNotSwapped);
{
tl::InputStream stream (testdata (file));
db::Reader reader (stream);
db::LayerProperties p;
p.layer = swap ? 2 : 1;
p.datatype = 0;
lmap.map (db::LDPair (p.layer, p.datatype), l1 = layout_org.insert_layer ());
layout_org.set_properties (l1, p);
p.layer = swap ? 1 : 2;
p.datatype = 0;
if (mode == TMSelfOverlap) {
lmap.map (db::LDPair (p.layer, p.datatype), l2 = l1);
} else {
lmap.map (db::LDPair (p.layer, p.datatype), l2 = layout_org.insert_layer ());
layout_org.set_properties (l2, p);
}
p.layer = out_layer_num1;
p.datatype = 0;
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<db::CommonReaderOptions> ().layer_map = lmap;
options.get_options<db::CommonReaderOptions> ().create_other_layers = false;
reader.read (layout_org, options);
}
db::Cell &top_cell = layout_org.cell (*layout_org.begin_top_down ());
layout_org.flatten (top_cell, -1, true);
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);
}
db::local_operation<db::PolygonRef, db::PolygonRef, db::PolygonRef> *lop = 0;
db::BoolAndOrNotLocalOperation bool_op (mode == TMAnd || mode == TMAndSwapped);
db::SelfOverlapMergeLocalOperation self_intersect_op (2);
BoolAndOrNotWithSizedLocalOperation sized_bool_op (mode == TMAnd || mode == TMAndSwapped, dist);
SelfOverlapWithSizedLocalOperation sized_self_intersect_op (2, dist);
db::TwoBoolAndNotLocalOperation andnot;
if (mode == TMAndNot) {
lop = &andnot;
} else if (mode == TMSelfOverlap) {
if (dist > 0) {
lop = &sized_self_intersect_op;
} else {
lop = &self_intersect_op;
}
} else {
if (dist > 0) {
lop = &sized_bool_op;
} else {
lop = &bool_op;
}
}
std::vector<const db::Shapes *> ilv;
std::vector<db::Shapes *> olv;
ilv.push_back (&top_cell.shapes (l2));
olv.push_back (&top_cell.shapes (lout1));
if (out_layer_num2 >= 0) {
olv.push_back (&top_cell.shapes (lout2));
}
db::local_processor<db::PolygonRef, db::PolygonRef, db::PolygonRef> proc (&layout_org);
proc.set_area_ratio (3.0);
proc.set_max_vertex_count (16);
proc.run_flat (&top_cell.shapes (l1), ilv, lop, olv);
db::compare_layouts (_this, layout_org, testdata (file), lmap, false /*skip other layers*/, db::AsPolygons);
}
static void run_test_bool22_flat (tl::TestBase *_this, const char *file, TestMode mode, int out_layer_num1, int out_layer_num2)
{
run_test_bool_gen_flat (_this, file, mode, out_layer_num1, out_layer_num2, 0);
}
TEST(BasicAnd1) TEST(BasicAnd1)
{ {
// Simple flat AND // Simple flat AND
@ -1167,3 +1271,9 @@ TEST(MultipleOutputs)
run_test_bool22 (_this, "hlp17.oas", TMAndNot, 100, 101); run_test_bool22 (_this, "hlp17.oas", TMAndNot, 100, 101);
} }
TEST(FlatOperation)
{
// Redundant hierarchy, NOT
run_test_bool22_flat (_this, "hlp17_flat.oas", TMAndNot, 100, 101);
}

BIN
testdata/algo/hlp17_flat.oas vendored Normal file

Binary file not shown.