Skip to content

Commit 3f9d890

Browse files
Merge pull request #2266 from KLayout/bugfix/issue-2262
Bugfix/issue 2262
2 parents f53c6b8 + 22a1971 commit 3f9d890

15 files changed

Lines changed: 894 additions & 110 deletions

src/buddies/src/bd/strmxor.cc

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@
2929
#include "dbSaveLayoutOptions.h"
3030
#include "dbRegion.h"
3131
#include "dbDeepShapeStore.h"
32+
#include "dbCellGraphUtils.h"
3233
#include "gsiExpression.h"
3334
#include "tlCommandLineParser.h"
3435
#include "tlThreads.h"
3536
#include "tlThreadedWorkers.h"
3637
#include "tlTimer.h"
38+
#include "tlOptional.h"
3739

3840
namespace {
3941

@@ -271,17 +273,19 @@ HealingTileLayoutOutputReceiver::output (const db::Box &box)
271273
struct ResultDescriptor
272274
{
273275
ResultDescriptor ()
274-
: shape_count (0), layer_a (-1), layer_b (-1), layer_output (-1), layout (0), top_cell (0)
276+
: shape_count (0), flat_shape_count (0), layer_a (-1), layer_b (-1), layer_output (-1), layout (0), top_cell (0)
275277
{
276278
// .. nothing yet ..
277279
}
278280

279281
size_t shape_count;
282+
size_t flat_shape_count;
280283
int layer_a;
281284
int layer_b;
282285
int layer_output;
283286
db::Layout *layout;
284287
db::cell_index_type top_cell;
288+
tl::optional<db::Region> results;
285289

286290
size_t count () const
287291
{
@@ -296,6 +300,20 @@ struct ResultDescriptor
296300
}
297301
}
298302

303+
size_t flat_count () const
304+
{
305+
if (layout && layer_output >= 0) {
306+
size_t res = 0;
307+
db::CellCounter counter (layout, top_cell);
308+
for (db::Layout::const_iterator c = layout->begin (); c != layout->end (); ++c) {
309+
res += c->shapes (layer_output).size () * counter.weight (c->cell_index ());
310+
}
311+
return res;
312+
} else {
313+
return flat_shape_count;
314+
}
315+
}
316+
299317
bool is_empty () const
300318
{
301319
if (layout && layer_output >= 0) {
@@ -586,12 +604,8 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
586604

587605
const char *line_format = " %-10s %-12s %s";
588606

589-
std::string headline;
590-
if (deep) {
591-
headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")), tl::to_string (tr ("Differences (hierarchical shape count)")));
592-
} else {
593-
headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")), tl::to_string (tr ("Differences (shape count)")));
594-
}
607+
std::string headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")),
608+
deep ? tl::to_string (tr ("Differences (hierarchical/flat count)")) : tl::to_string (tr ("Differences (shape count)")));
595609

596610
const char *sep = " ----------------------------------------------------------------";
597611

@@ -619,7 +633,11 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
619633
if (r->second.layer_output >= 0 && r->second.layout) {
620634
out = r->second.layout->get_properties (r->second.layer_output).to_string ();
621635
}
622-
value = tl::to_string (r->second.count ());
636+
if (deep) {
637+
value = tl::sprintf (tl::to_string (tr ("%-6lu / %-6lu")), r->second.count (), r->second.flat_count ());
638+
} else {
639+
value = tl::to_string (r->second.count ());
640+
}
623641
}
624642
if (! value.empty ()) {
625643
tl::info << tl::sprintf (line_format, r->first.second.to_string (), out, value);
@@ -767,8 +785,15 @@ bool run_tiled_xor (const XORData &xor_data)
767785
proc.execute ("Running XOR");
768786
}
769787

788+
// no stored results currently
789+
for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end (); ++r) {
790+
tl_assert (! r->second.results.has_value ());
791+
}
792+
770793
// Determines the output status
771794
for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end () && result; ++r) {
795+
// no stored results currently
796+
tl_assert (! r->second.results.has_value ());
772797
result = r->second.is_empty ();
773798
}
774799

@@ -846,29 +871,40 @@ class XORTask
846871

847872
tl::SelfTimer timer (tl::verbosity () >= 11, "XOR on layer " + m_layer_props.to_string ());
848873

849-
db::RecursiveShapeIterator ri_a, ri_b;
874+
db::Region xor_res;
850875

851-
if (m_la >= 0) {
852-
ri_a = db::RecursiveShapeIterator (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
853-
} else {
854-
ri_a = db::RecursiveShapeIterator (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), std::vector<unsigned int> ());
855-
}
856-
ri_a.set_for_merged_input (true);
876+
if (m_la < 0) {
877+
878+
tl_assert (m_lb >= 0);
879+
880+
db::RecursiveShapeIterator ri_b (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), m_lb);
881+
xor_res = db::Region (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));
882+
883+
} else if (m_lb < 0) {
884+
885+
db::RecursiveShapeIterator ri_a (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
886+
xor_res = db::Region (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));
857887

858-
if (m_lb >= 0) {
859-
ri_b = db::RecursiveShapeIterator (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), m_lb);
860888
} else {
861-
ri_b = db::RecursiveShapeIterator (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), std::vector<unsigned int> ());
862-
}
863-
ri_b.set_for_merged_input (true);
864889

865-
db::Region in_a (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));
866-
db::Region in_b (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));
890+
db::RecursiveShapeIterator ri_a (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
891+
db::RecursiveShapeIterator ri_b (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), m_lb);
892+
893+
db::Region in_a (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));
894+
db::Region in_b (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));
895+
896+
bool a_empty = in_a.empty ();
897+
bool b_empty = in_b.empty ();
898+
899+
if (a_empty && ! b_empty) {
900+
xor_res = in_b;
901+
} else if (! a_empty && b_empty) {
902+
xor_res = in_a;
903+
} else if (! a_empty && ! b_empty) {
904+
tl::SelfTimer timer (tl::verbosity () >= 21, "Basic XOR on layer " + m_layer_props.to_string ());
905+
xor_res = in_a ^ in_b;
906+
}
867907

868-
db::Region xor_res;
869-
{
870-
tl::SelfTimer timer (tl::verbosity () >= 21, "Basic XOR on layer " + m_layer_props.to_string ());
871-
xor_res = in_a ^ in_b;
872908
}
873909

874910
int tol_index = 0;
@@ -896,9 +932,12 @@ class XORTask
896932

897933
if (mp_xor_data->output_layout) {
898934
result.layer_output = result.layout->insert_layer (lp);
899-
xor_res.insert_into (mp_xor_data->output_layout, mp_xor_data->output_cell, result.layer_output);
935+
if (! xor_res.empty ()) {
936+
result.results = xor_res;
937+
}
900938
} else {
901939
result.shape_count = xor_res.hier_count ();
940+
result.flat_shape_count = xor_res.count ();
902941
}
903942
}
904943

@@ -964,6 +1003,22 @@ bool run_deep_xor (const XORData &xor_data)
9641003
job.start ();
9651004
job.wait ();
9661005

1006+
// Deliver the outputs
1007+
// NOTE: this is done single-threaded and in a delayed fashion as it is not efficient during
1008+
// computation and shifting hierarchy of the working layout
1009+
1010+
if (xor_data.output_layout) {
1011+
1012+
tl::SelfTimer timer (tl::verbosity () >= 11, "Result delivery");
1013+
1014+
for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end (); ++r) {
1015+
if (r->second.results.has_value ()) {
1016+
r->second.results.value ().insert_into (xor_data.output_layout, xor_data.output_cell, r->second.layer_output);
1017+
}
1018+
}
1019+
1020+
}
1021+
9671022
// Determine the output status
9681023

9691024
bool result = (xor_data.layers_missing == 0);

src/buddies/unit_tests/bdStrmxorTests.cc

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,11 @@ TEST(1A_Deep)
146146
"Layer 10/0 is not present in first layout, but in second\n"
147147
"Result summary (layers without differences are not shown):\n"
148148
"\n"
149-
" Layer Output Differences (hierarchical shape count)\n"
149+
" Layer Output Differences (hierarchical/flat count)\n"
150150
" ----------------------------------------------------------------\n"
151-
" 3/0 3/0 3\n"
152-
" 6/0 6/0 314\n"
153-
" 8/1 8/1 1\n"
151+
" 3/0 3/0 3 / 30 \n"
152+
" 6/0 6/0 314 / 314 \n"
153+
" 8/1 8/1 1 / 1 \n"
154154
" 10/0 - (no such layer in first layout)\n"
155155
"\n"
156156
);
@@ -188,11 +188,11 @@ TEST(1A_DeepNoEmptyCells)
188188
"Layer 10/0 is not present in first layout, but in second\n"
189189
"Result summary (layers without differences are not shown):\n"
190190
"\n"
191-
" Layer Output Differences (hierarchical shape count)\n"
191+
" Layer Output Differences (hierarchical/flat count)\n"
192192
" ----------------------------------------------------------------\n"
193-
" 3/0 3/0 3\n"
194-
" 6/0 6/0 314\n"
195-
" 8/1 8/1 1\n"
193+
" 3/0 3/0 3 / 30 \n"
194+
" 6/0 6/0 314 / 314 \n"
195+
" 8/1 8/1 1 / 1 \n"
196196
" 10/0 - (no such layer in first layout)\n"
197197
"\n"
198198
);
@@ -248,11 +248,11 @@ TEST(1B_Deep)
248248
"Layer 10/0 is not present in first layout, but in second\n"
249249
"Result summary (layers without differences are not shown):\n"
250250
"\n"
251-
" Layer Output Differences (hierarchical shape count)\n"
251+
" Layer Output Differences (hierarchical/flat count)\n"
252252
" ----------------------------------------------------------------\n"
253-
" 3/0 - 3\n"
254-
" 6/0 - 314\n"
255-
" 8/1 - 1\n"
253+
" 3/0 - 3 / 30 \n"
254+
" 6/0 - 314 / 314 \n"
255+
" 8/1 - 1 / 1 \n"
256256
" 10/0 - (no such layer in first layout)\n"
257257
"\n"
258258
);
@@ -830,10 +830,10 @@ TEST(7_OptimizeDeep)
830830
EXPECT_EQ (cap.captured_text (),
831831
"Result summary (layers without differences are not shown):\n"
832832
"\n"
833-
" Layer Output Differences (hierarchical shape count)\n"
833+
" Layer Output Differences (hierarchical/flat count)\n"
834834
" ----------------------------------------------------------------\n"
835-
" 2/0 2/0 1\n"
836-
" 3/0 3/0 8\n"
835+
" 2/0 2/0 1 / 12 \n"
836+
" 3/0 3/0 8 / 8 \n"
837837
"\n"
838838
);
839839
}

src/db/db/db.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ SOURCES = \
1515
dbCellGraphUtils.cc \
1616
dbCellHullGenerator.cc \
1717
dbCellInst.cc \
18+
dbCellInstanceSetHasher.cc \
1819
dbCellMapping.cc \
1920
dbClipboard.cc \
2021
dbClipboardData.cc \
@@ -253,6 +254,7 @@ HEADERS = \
253254
dbCell.h \
254255
dbCellHullGenerator.h \
255256
dbCellInst.h \
257+
dbCellInstanceSetHasher.h \
256258
dbCellMapping.h \
257259
dbClipboardData.h \
258260
dbClipboard.h \

src/db/db/dbBoxTree.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -981,9 +981,10 @@ class box_tree
981981
* Only after sorting the query iterators are available.
982982
* Sorting complexity is approx O(N*log(N)).
983983
*/
984-
void sort (const BoxConv &conv)
984+
template <class BC>
985+
void sort (const BC &conv)
985986
{
986-
typename BoxConv::complexity complexity_tag;
987+
typename BC::complexity complexity_tag;
987988
sort (conv, complexity_tag);
988989
}
989990

@@ -1192,7 +1193,8 @@ class box_tree
11921193
box_tree_node *mp_root;
11931194

11941195
/// Sort implementation for simple bboxes - no caching
1195-
void sort (const BoxConv &conv, const db::simple_bbox_tag &/*complexity*/)
1196+
template <class BC>
1197+
void sort (const BC &conv, const db::simple_bbox_tag &/*complexity*/)
11961198
{
11971199
m_elements.clear ();
11981200
m_elements.reserve (m_objects.size ());
@@ -1204,7 +1206,7 @@ class box_tree
12041206

12051207
if (! m_objects.empty ()) {
12061208

1207-
box_tree_picker_type picker (conv);
1209+
box_tree_picker<Box, Obj, BC, obj_vector_type> picker (conv);
12081210

12091211
box_type bbox;
12101212
for (typename obj_vector_type::const_iterator o = m_objects.begin (); o != m_objects.end (); ++o) {
@@ -1221,7 +1223,8 @@ class box_tree
12211223
}
12221224

12231225
/// Sort implementation for complex bboxes - with caching
1224-
void sort (const box_conv_type &conv, const db::complex_bbox_tag &/*complexity*/)
1226+
template <class BC>
1227+
void sort (const BC &conv, const db::complex_bbox_tag &/*complexity*/)
12251228
{
12261229
m_elements.clear ();
12271230
m_elements.reserve (m_objects.size ());
@@ -1233,7 +1236,7 @@ class box_tree
12331236

12341237
if (! m_objects.empty ()) {
12351238

1236-
box_tree_cached_picker<object_type, box_type, box_conv_type, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
1239+
box_tree_cached_picker<object_type, box_type, BC, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
12371240

12381241
for (typename obj_vector_type::const_iterator o = m_objects.begin (); o != m_objects.end (); ++o) {
12391242
m_elements.push_back (o.index ());
@@ -1997,9 +2000,10 @@ class unstable_box_tree
19972000
* Only after sorting the query iterators are available.
19982001
* Sorting complexity is approx O(N*log(N)).
19992002
*/
2000-
void sort (const BoxConv &conv)
2003+
template <class BC>
2004+
void sort (const BC &conv)
20012005
{
2002-
typename BoxConv::complexity complexity_tag;
2006+
typename BC::complexity complexity_tag;
20032007
sort (conv, complexity_tag);
20042008
}
20052009

@@ -2159,13 +2163,14 @@ class unstable_box_tree
21592163
box_tree_node *mp_root;
21602164

21612165
/// Sort implementation for simple bboxes - no caching
2162-
void sort (const BoxConv &conv, const db::simple_bbox_tag &/*complexity*/)
2166+
template <class BC>
2167+
void sort (const BC &conv, const db::simple_bbox_tag &/*complexity*/)
21632168
{
21642169
if (m_objects.empty ()) {
21652170
return;
21662171
}
21672172

2168-
box_tree_picker_type picker (conv);
2173+
box_tree_picker<box_type, object_type, BC, obj_vector_type> picker (conv);
21692174

21702175
if (mp_root) {
21712176
delete mp_root;
@@ -2184,13 +2189,14 @@ class unstable_box_tree
21842189
}
21852190

21862191
/// Sort implementation for complex bboxes - with caching
2187-
void sort (const box_conv_type &conv, const db::complex_bbox_tag &/*complexity*/)
2192+
template <class BC>
2193+
void sort (const BC &conv, const db::complex_bbox_tag &/*complexity*/)
21882194
{
21892195
if (m_objects.empty ()) {
21902196
return;
21912197
}
21922198

2193-
box_tree_cached_picker<object_type, box_type, box_conv_type, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
2199+
box_tree_cached_picker<object_type, box_type, BC, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
21942200

21952201
if (mp_root) {
21962202
delete mp_root;

0 commit comments

Comments
 (0)