Merge pull request #1412 from KLayout/wip2

Wip2
This commit is contained in:
Matthias Köfferlein 2023-07-05 18:31:38 +02:00 committed by GitHub
commit 6b1aa882eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 80 additions and 14 deletions

View File

@ -754,6 +754,7 @@ bool run_deep_xor (const XORData &xor_data)
{
db::DeepShapeStore dss;
dss.set_threads (xor_data.threads);
dss.set_wants_all_cells (true); // saves time for less cell mapping operations
double dbu = std::min (xor_data.layout_a->dbu (), xor_data.layout_b->dbu ());

View File

@ -151,10 +151,6 @@ public:
}
std::set<db::cell_index_type> callers_b;
m_layout_b.cell (cell_b).collect_caller_cells (callers_b, selection_cone_b, -1);
callers_b.insert (cell_b);
m_repr_set = false;
std::map<db::cell_index_type, db::ICplxTrans>::const_iterator r = m_repr.find (cell_b);
@ -164,7 +160,11 @@ public:
return false;
}
}
std::set<db::cell_index_type> callers_b;
m_layout_b.cell (cell_b).collect_caller_cells (callers_b, selection_cone_b, -1);
callers_b.insert (cell_b);
trans_set_t trans (m_trans);
double mag = m_layout_b.dbu () / m_layout_a.dbu ();

View File

@ -1916,6 +1916,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons
// force different polygons in the different properties case to skip intra-polygon checks
if (pc_always_different (options.prop_constraint)) {
// TODO: this forces merged primaries, so maybe that is not a good optimization?
different_polygons = true;
}

View File

@ -487,13 +487,13 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter
}
DeepShapeStore::DeepShapeStore ()
: m_keep_layouts (true)
: m_keep_layouts (true), m_wants_all_cells (false)
{
++s_instance_count;
}
DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu)
: m_keep_layouts (true)
: m_keep_layouts (true), m_wants_all_cells (false)
{
++s_instance_count;
@ -765,6 +765,16 @@ double DeepShapeStore::max_area_ratio () const
return m_state.max_area_ratio ();
}
void DeepShapeStore::set_wants_all_cells (bool f)
{
m_wants_all_cells = f;
}
bool DeepShapeStore::wants_all_cells () const
{
return m_wants_all_cells;
}
void DeepShapeStore::set_reject_odd_polygons (bool f)
{
m_state.set_reject_odd_polygons (f);
@ -929,6 +939,8 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator
db::Layout &layout = m_layouts[layout_index]->layout;
db::HierarchyBuilder &builder = m_layouts[layout_index]->builder;
builder.set_wants_all_cells (m_wants_all_cells);
unsigned int layer_index = init_layer (layout, si);
builder.set_target_layer (layer_index);

View File

@ -727,6 +727,23 @@ public:
*/
int threads () const;
/**
* @brief Sets a flag indicating whether the working layouts will store the whole original hierarchy
*
* Setting this flag to true will make the deep shape store copy the
* hierarchy exactly from the origin layouts. This will take somewhat
* more memory but avoid future cell hierarchy mapping operations.
*
* If set to false, only the needed parts of the hierarchy are copied.
* This part may need to grow when further operations are triggered.
*/
void set_wants_all_cells (bool f);
/**
* @brief Gets a flag indicating whether the working layouts will store the whole original hierarchy
*/
bool wants_all_cells () const;
/**
* @brief Sets a flag indicating whether to reject odd polygons
*
@ -878,6 +895,7 @@ private:
DeepShapeStoreState m_state;
std::list<DeepShapeStoreState> m_state_stack;
bool m_keep_layouts;
bool m_wants_all_cells;
tl::Mutex m_lock;
struct DeliveryMappingCacheKey

View File

@ -152,13 +152,13 @@ static std::pair<bool, std::set<db::Box> > compute_clip_variant (const db::Box &
}
HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_wants_all_cells (false), m_trans (trans)
{
set_shape_receiver (pipe);
}
HierarchyBuilder::HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans)
: mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_wants_all_cells (false), m_trans (trans)
{
set_shape_receiver (pipe);
}

View File

@ -295,6 +295,7 @@ public:
*/
void set_shape_receiver (HierarchyBuilderShapeReceiver *pipe);
virtual bool wants_all_cells () const { return m_wants_all_cells; }
virtual void begin (const RecursiveShapeIterator *iter);
virtual void end (const RecursiveShapeIterator *iter);
virtual void enter_cell (const RecursiveShapeIterator *iter, const db::Cell *cell, const db::Box &region, const box_tree_type *complex_region);
@ -311,6 +312,14 @@ public:
m_target_layer = target_layer;
}
/**
* @brief Sets the target layer - shapes will be put there
*/
void set_wants_all_cells (bool f)
{
m_wants_all_cells = f;
}
/**
* @brief Reset the builder - performs a new initial pass
*/
@ -416,6 +425,7 @@ private:
cell_map_type::const_iterator m_cm_entry;
bool m_cm_new_entry;
unsigned int m_target_layer;
bool m_wants_all_cells;
std::vector<std::pair<bool, std::vector<db::Cell *> > > m_cell_stack;
db::Cell *mp_initial_cell;

View File

@ -693,7 +693,11 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const
// determine whether the cell is empty with respect to the layers specified
bool is_empty = false;
if (! m_has_layers) {
if (receiver && receiver->wants_all_cells ()) {
// don't skip empty cells in that case
} else if (! m_has_layers) {
is_empty = mp_layout->cell (m_inst->cell_index ()).bbox (m_layer).empty ();

View File

@ -913,6 +913,11 @@ public:
*/
virtual ~RecursiveShapeReceiver () { }
/**
* @brief Returns true, if the receivers wants the full hierarchy and not just non-empty cells
*/
virtual bool wants_all_cells () const { return false; }
/**
* @brief Called once when the iterator begins pushing
*/

View File

@ -111,6 +111,21 @@ Class<db::DeepShapeStore> decl_dbDeepShapeStore ("db", "DeepShapeStore",
gsi::method ("threads", &db::DeepShapeStore::threads,
"@brief Gets the number of threads.\n"
) +
gsi::method ("wants_all_cells=", &db::DeepShapeStore::set_wants_all_cells, gsi::arg ("flag"),
"@brief Sets a flag wether to copy the full hierarchy for the working layouts\n"
"\n"
"The DeepShapeStore object keeps a copy of the original hierarchy internally for the working layouts.\n"
"By default, this hierarchy is mapping only non-empty cells. While the operations proceed, more cells "
"may need to be added. This conservative approach saves some memory, but the update operations may "
"reduce overall performance. Setting this flag to 'true' switches to a mode where the full "
"hierarchy is copied always. This will take more memory but may save CPU time.\n"
"\n"
"This attribute has been introduced in version 0.28.10."
) +
gsi::method ("wants_all_cells", &db::DeepShapeStore::wants_all_cells,
"@brief Gets a flag wether to copy the full hierarchy for the working layouts\n"
"This attribute has been introduced in version 0.28.10."
) +
gsi::method ("reject_odd_polygons=", &db::DeepShapeStore::set_reject_odd_polygons, gsi::arg ("count"),
"@brief Sets a flag indicating whether to reject odd polygons\n"
"\n"

View File

@ -2630,7 +2630,7 @@ CODE
# @brief Returns the intersection points of intersecting edge segments for two edge collections
# @synopsis layer.intersections(edges)
# This operation is similar to the "&" operator, but it does also report intersection points
# between non-colinear, but intersection edges. Such points are reported as point-like,
# between non-colinear, but intersecting edges. Such points are reported as point-like,
# degenerated edge objects.
#
# This method is available for edge layers. The argument must be an edge layer.

View File

@ -472,15 +472,15 @@ Class<lay::MainWindow> decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M
"\n"
"This method has been added in version 0.24."
) +
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time"),
gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"),
"@brief Displays a message in the status bar\n"
"\n"
"@param message The message to display\n"
"@param time The time how long to display the message in ms\n"
"@param time The time how long to display the message in ms. A negative value means 'infinitely'.\n"
"\n"
"This given message is shown in the status bar for the given time.\n"
"\n"
"This method has been added in version 0.18."
"This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10."
) +
gsi::method ("resize", (void (lay::MainWindow::*)(int, int)) &lay::MainWindow::resize, gsi::arg ("width"), gsi::arg ("height"),
"@brief Resizes the window\n"