Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 82 additions & 27 deletions src/buddies/src/bd/strmxor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@
#include "dbSaveLayoutOptions.h"
#include "dbRegion.h"
#include "dbDeepShapeStore.h"
#include "dbCellGraphUtils.h"
#include "gsiExpression.h"
#include "tlCommandLineParser.h"
#include "tlThreads.h"
#include "tlThreadedWorkers.h"
#include "tlTimer.h"
#include "tlOptional.h"

namespace {

Expand Down Expand Up @@ -271,17 +273,19 @@ HealingTileLayoutOutputReceiver::output (const db::Box &box)
struct ResultDescriptor
{
ResultDescriptor ()
: shape_count (0), layer_a (-1), layer_b (-1), layer_output (-1), layout (0), top_cell (0)
: shape_count (0), flat_shape_count (0), layer_a (-1), layer_b (-1), layer_output (-1), layout (0), top_cell (0)
{
// .. nothing yet ..
}

size_t shape_count;
size_t flat_shape_count;
int layer_a;
int layer_b;
int layer_output;
db::Layout *layout;
db::cell_index_type top_cell;
tl::optional<db::Region> results;

size_t count () const
{
Expand All @@ -296,6 +300,20 @@ struct ResultDescriptor
}
}

size_t flat_count () const
{
if (layout && layer_output >= 0) {
size_t res = 0;
db::CellCounter counter (layout, top_cell);
for (db::Layout::const_iterator c = layout->begin (); c != layout->end (); ++c) {
res += c->shapes (layer_output).size () * counter.weight (c->cell_index ());
}
return res;
} else {
return flat_shape_count;
}
}

bool is_empty () const
{
if (layout && layer_output >= 0) {
Expand Down Expand Up @@ -586,12 +604,8 @@ BD_PUBLIC int strmxor (int argc, char *argv[])

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

std::string headline;
if (deep) {
headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")), tl::to_string (tr ("Differences (hierarchical shape count)")));
} else {
headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")), tl::to_string (tr ("Differences (shape count)")));
}
std::string headline = tl::sprintf (line_format, tl::to_string (tr ("Layer")), tl::to_string (tr ("Output")),
deep ? tl::to_string (tr ("Differences (hierarchical/flat count)")) : tl::to_string (tr ("Differences (shape count)")));

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

Expand Down Expand Up @@ -619,7 +633,11 @@ BD_PUBLIC int strmxor (int argc, char *argv[])
if (r->second.layer_output >= 0 && r->second.layout) {
out = r->second.layout->get_properties (r->second.layer_output).to_string ();
}
value = tl::to_string (r->second.count ());
if (deep) {
value = tl::sprintf (tl::to_string (tr ("%-6lu / %-6lu")), r->second.count (), r->second.flat_count ());
} else {
value = tl::to_string (r->second.count ());
}
}
if (! value.empty ()) {
tl::info << tl::sprintf (line_format, r->first.second.to_string (), out, value);
Expand Down Expand Up @@ -767,8 +785,15 @@ bool run_tiled_xor (const XORData &xor_data)
proc.execute ("Running XOR");
}

// no stored results currently
for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end (); ++r) {
tl_assert (! r->second.results.has_value ());
}

// Determines the output status
for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end () && result; ++r) {
// no stored results currently
tl_assert (! r->second.results.has_value ());
result = r->second.is_empty ();
}

Expand Down Expand Up @@ -846,29 +871,40 @@ class XORTask

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

db::RecursiveShapeIterator ri_a, ri_b;
db::Region xor_res;

if (m_la >= 0) {
ri_a = db::RecursiveShapeIterator (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
} else {
ri_a = db::RecursiveShapeIterator (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), std::vector<unsigned int> ());
}
ri_a.set_for_merged_input (true);
if (m_la < 0) {

tl_assert (m_lb >= 0);

db::RecursiveShapeIterator ri_b (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), m_lb);
xor_res = db::Region (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));

} else if (m_lb < 0) {

db::RecursiveShapeIterator ri_a (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
xor_res = db::Region (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));

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

db::Region in_a (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));
db::Region in_b (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));
db::RecursiveShapeIterator ri_a (*mp_xor_data->layout_a, mp_xor_data->layout_a->cell (mp_xor_data->cell_a), m_la);
db::RecursiveShapeIterator ri_b (*mp_xor_data->layout_b, mp_xor_data->layout_b->cell (mp_xor_data->cell_b), m_lb);

db::Region in_a (ri_a, worker->dss (), db::ICplxTrans (mp_xor_data->layout_a->dbu () / m_dbu));
db::Region in_b (ri_b, worker->dss (), db::ICplxTrans (mp_xor_data->layout_b->dbu () / m_dbu));

bool a_empty = in_a.empty ();
bool b_empty = in_b.empty ();

if (a_empty && ! b_empty) {
xor_res = in_b;
} else if (! a_empty && b_empty) {
xor_res = in_a;
} else if (! a_empty && ! b_empty) {
tl::SelfTimer timer (tl::verbosity () >= 21, "Basic XOR on layer " + m_layer_props.to_string ());
xor_res = in_a ^ in_b;
}

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

int tol_index = 0;
Expand Down Expand Up @@ -896,9 +932,12 @@ class XORTask

if (mp_xor_data->output_layout) {
result.layer_output = result.layout->insert_layer (lp);
xor_res.insert_into (mp_xor_data->output_layout, mp_xor_data->output_cell, result.layer_output);
if (! xor_res.empty ()) {
result.results = xor_res;
}
} else {
result.shape_count = xor_res.hier_count ();
result.flat_shape_count = xor_res.count ();
}
}

Expand Down Expand Up @@ -964,6 +1003,22 @@ bool run_deep_xor (const XORData &xor_data)
job.start ();
job.wait ();

// Deliver the outputs
// NOTE: this is done single-threaded and in a delayed fashion as it is not efficient during
// computation and shifting hierarchy of the working layout

if (xor_data.output_layout) {

tl::SelfTimer timer (tl::verbosity () >= 11, "Result delivery");

for (std::map<std::pair<int, db::LayerProperties>, ResultDescriptor>::const_iterator r = xor_data.results->begin (); r != xor_data.results->end (); ++r) {
if (r->second.results.has_value ()) {
r->second.results.value ().insert_into (xor_data.output_layout, xor_data.output_cell, r->second.layer_output);
}
}

}

// Determine the output status

bool result = (xor_data.layers_missing == 0);
Expand Down
30 changes: 15 additions & 15 deletions src/buddies/unit_tests/bdStrmxorTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ TEST(1A_Deep)
"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 (hierarchical shape count)\n"
" Layer Output Differences (hierarchical/flat count)\n"
" ----------------------------------------------------------------\n"
" 3/0 3/0 3\n"
" 6/0 6/0 314\n"
" 8/1 8/1 1\n"
" 3/0 3/0 3 / 30 \n"
" 6/0 6/0 314 / 314 \n"
" 8/1 8/1 1 / 1 \n"
" 10/0 - (no such layer in first layout)\n"
"\n"
);
Expand Down Expand Up @@ -188,11 +188,11 @@ TEST(1A_DeepNoEmptyCells)
"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 (hierarchical shape count)\n"
" Layer Output Differences (hierarchical/flat count)\n"
" ----------------------------------------------------------------\n"
" 3/0 3/0 3\n"
" 6/0 6/0 314\n"
" 8/1 8/1 1\n"
" 3/0 3/0 3 / 30 \n"
" 6/0 6/0 314 / 314 \n"
" 8/1 8/1 1 / 1 \n"
" 10/0 - (no such layer in first layout)\n"
"\n"
);
Expand Down Expand Up @@ -248,11 +248,11 @@ TEST(1B_Deep)
"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 (hierarchical shape count)\n"
" Layer Output Differences (hierarchical/flat count)\n"
" ----------------------------------------------------------------\n"
" 3/0 - 3\n"
" 6/0 - 314\n"
" 8/1 - 1\n"
" 3/0 - 3 / 30 \n"
" 6/0 - 314 / 314 \n"
" 8/1 - 1 / 1 \n"
" 10/0 - (no such layer in first layout)\n"
"\n"
);
Expand Down Expand Up @@ -830,10 +830,10 @@ TEST(7_OptimizeDeep)
EXPECT_EQ (cap.captured_text (),
"Result summary (layers without differences are not shown):\n"
"\n"
" Layer Output Differences (hierarchical shape count)\n"
" Layer Output Differences (hierarchical/flat count)\n"
" ----------------------------------------------------------------\n"
" 2/0 2/0 1\n"
" 3/0 3/0 8\n"
" 2/0 2/0 1 / 12 \n"
" 3/0 3/0 8 / 8 \n"
"\n"
);
}
2 changes: 2 additions & 0 deletions src/db/db/db.pro
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ SOURCES = \
dbCellGraphUtils.cc \
dbCellHullGenerator.cc \
dbCellInst.cc \
dbCellInstanceSetHasher.cc \
dbCellMapping.cc \
dbClipboard.cc \
dbClipboardData.cc \
Expand Down Expand Up @@ -253,6 +254,7 @@ HEADERS = \
dbCell.h \
dbCellHullGenerator.h \
dbCellInst.h \
dbCellInstanceSetHasher.h \
dbCellMapping.h \
dbClipboardData.h \
dbClipboard.h \
Expand Down
30 changes: 18 additions & 12 deletions src/db/db/dbBoxTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -981,9 +981,10 @@ class box_tree
* Only after sorting the query iterators are available.
* Sorting complexity is approx O(N*log(N)).
*/
void sort (const BoxConv &conv)
template <class BC>
void sort (const BC &conv)
{
typename BoxConv::complexity complexity_tag;
typename BC::complexity complexity_tag;
sort (conv, complexity_tag);
}

Expand Down Expand Up @@ -1192,7 +1193,8 @@ class box_tree
box_tree_node *mp_root;

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

if (! m_objects.empty ()) {

box_tree_picker_type picker (conv);
box_tree_picker<Box, Obj, BC, obj_vector_type> picker (conv);

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

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

if (! m_objects.empty ()) {

box_tree_cached_picker<object_type, box_type, box_conv_type, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
box_tree_cached_picker<object_type, box_type, BC, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());

for (typename obj_vector_type::const_iterator o = m_objects.begin (); o != m_objects.end (); ++o) {
m_elements.push_back (o.index ());
Expand Down Expand Up @@ -1997,9 +2000,10 @@ class unstable_box_tree
* Only after sorting the query iterators are available.
* Sorting complexity is approx O(N*log(N)).
*/
void sort (const BoxConv &conv)
template <class BC>
void sort (const BC &conv)
{
typename BoxConv::complexity complexity_tag;
typename BC::complexity complexity_tag;
sort (conv, complexity_tag);
}

Expand Down Expand Up @@ -2159,13 +2163,14 @@ class unstable_box_tree
box_tree_node *mp_root;

/// Sort implementation for simple bboxes - no caching
void sort (const BoxConv &conv, const db::simple_bbox_tag &/*complexity*/)
template <class BC>
void sort (const BC &conv, const db::simple_bbox_tag &/*complexity*/)
{
if (m_objects.empty ()) {
return;
}

box_tree_picker_type picker (conv);
box_tree_picker<box_type, object_type, BC, obj_vector_type> picker (conv);

if (mp_root) {
delete mp_root;
Expand All @@ -2184,13 +2189,14 @@ class unstable_box_tree
}

/// Sort implementation for complex bboxes - with caching
void sort (const box_conv_type &conv, const db::complex_bbox_tag &/*complexity*/)
template <class BC>
void sort (const BC &conv, const db::complex_bbox_tag &/*complexity*/)
{
if (m_objects.empty ()) {
return;
}

box_tree_cached_picker<object_type, box_type, box_conv_type, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());
box_tree_cached_picker<object_type, box_type, BC, obj_vector_type> picker (conv, m_objects.begin (), m_objects.end ());

if (mp_root) {
delete mp_root;
Expand Down
Loading
Loading