mirror of https://github.com/KLayout/klayout.git
WIP: reduced space runtimes (OpenRAM sample) by selective edge processing
This commit is contained in:
parent
05b1023fd5
commit
58afc47071
|
|
@ -56,7 +56,6 @@ void local_operation<TS, TI, TR>::compute_local (db::Layout *layout, const shape
|
||||||
}
|
}
|
||||||
|
|
||||||
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
for (typename shape_interactions<TS, TI>::iterator i = interactions.begin (); i != interactions.end (); ++i) {
|
||||||
|
|
||||||
const TS &subject_shape = interactions.subject_shape (i->first);
|
const TS &subject_shape = interactions.subject_shape (i->first);
|
||||||
|
|
||||||
shape_interactions<TS, TI> single_interactions;
|
shape_interactions<TS, TI> single_interactions;
|
||||||
|
|
|
||||||
|
|
@ -154,13 +154,16 @@ Edge2EdgeCheckBase::finish (const Edge *o, const size_t &p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
Edge2EdgeCheckBase::feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanner)
|
Edge2EdgeCheckBase::feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanner)
|
||||||
{
|
{
|
||||||
if (m_pass == 1) {
|
if (m_pass == 1) {
|
||||||
for (std::set<std::pair<db::Edge, size_t> >::const_iterator e = m_pseudo_edges.begin (); e != m_pseudo_edges.end (); ++e) {
|
for (std::set<std::pair<db::Edge, size_t> >::const_iterator e = m_pseudo_edges.begin (); e != m_pseudo_edges.end (); ++e) {
|
||||||
scanner.insert (&e->first, e->second);
|
scanner.insert (&e->first, e->second);
|
||||||
}
|
}
|
||||||
|
return ! m_pseudo_edges.empty ();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,11 +445,33 @@ poly2poly_check<PolygonType>::add (const PolygonType *o1, size_t p1, const Polyg
|
||||||
enter (*o1, p1, *o2, p2);
|
enter (*o1, p1, *o2, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool interact (const db::Box &box, const db::Edge &e)
|
||||||
|
{
|
||||||
|
if (! e.bbox ().touches (box)) {
|
||||||
|
return false;
|
||||||
|
} else if (e.is_ortho ()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return e.clipped (box).first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class PolygonType>
|
template <class PolygonType>
|
||||||
void
|
void
|
||||||
poly2poly_check<PolygonType>::enter (const PolygonType &o1, size_t p1, const PolygonType &o2, size_t p2)
|
poly2poly_check<PolygonType>::enter (const PolygonType &o1, size_t p1, const PolygonType &o2, size_t p2)
|
||||||
{
|
{
|
||||||
if ((! mp_output->different_polygons () || p1 != p2) && (! mp_output->requires_different_layers () || ((p1 ^ p2) & 1) != 0)) {
|
if (p1 != p2 && (! mp_output->requires_different_layers () || ((p1 ^ p2) & 1) != 0)) {
|
||||||
|
|
||||||
|
bool take_all = mp_output->has_negative_edge_output ();
|
||||||
|
|
||||||
|
db::Box common_box;
|
||||||
|
if (! take_all) {
|
||||||
|
db::Vector e (mp_output->distance (), mp_output->distance ());
|
||||||
|
common_box = o1.box ().enlarged (e) & o2.box ().enlarged (e);
|
||||||
|
if (common_box.empty ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_scanner.clear ();
|
m_scanner.clear ();
|
||||||
m_scanner.reserve (vertices (o1) + vertices (o2));
|
m_scanner.reserve (vertices (o1) + vertices (o2));
|
||||||
|
|
@ -454,20 +479,30 @@ poly2poly_check<PolygonType>::enter (const PolygonType &o1, size_t p1, const Pol
|
||||||
m_edges.clear ();
|
m_edges.clear ();
|
||||||
m_edges.reserve (vertices (o1) + vertices (o2));
|
m_edges.reserve (vertices (o1) + vertices (o2));
|
||||||
|
|
||||||
|
bool any_o1 = false, any_o2 = false;
|
||||||
|
|
||||||
for (typename PolygonType::polygon_edge_iterator e = o1.begin_edge (); ! e.at_end (); ++e) {
|
for (typename PolygonType::polygon_edge_iterator e = o1.begin_edge (); ! e.at_end (); ++e) {
|
||||||
m_edges.push_back (*e);
|
if (take_all || interact (common_box, *e)) {
|
||||||
m_scanner.insert (& m_edges.back (), p1);
|
m_edges.push_back (*e);
|
||||||
|
m_scanner.insert (& m_edges.back (), p1);
|
||||||
|
any_o1 = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (typename PolygonType::polygon_edge_iterator e = o2.begin_edge (); ! e.at_end (); ++e) {
|
for (typename PolygonType::polygon_edge_iterator e = o2.begin_edge (); ! e.at_end (); ++e) {
|
||||||
m_edges.push_back (*e);
|
if (take_all || interact (common_box, *e)) {
|
||||||
m_scanner.insert (& m_edges.back (), p2);
|
m_edges.push_back (*e);
|
||||||
|
m_scanner.insert (& m_edges.back (), p2);
|
||||||
|
any_o2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! take_all && (! any_o1 || ! any_o2)) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_output->feed_pseudo_edges (m_scanner);
|
mp_output->feed_pseudo_edges (m_scanner);
|
||||||
|
|
||||||
tl_assert (m_edges.size () == vertices (o1) + vertices (o2));
|
|
||||||
|
|
||||||
// temporarily disable intra-polygon check in that step .. we do that later in finish()
|
// temporarily disable intra-polygon check in that step .. we do that later in finish()
|
||||||
// if required (#650).
|
// if required (#650).
|
||||||
bool no_intra = mp_output->different_polygons ();
|
bool no_intra = mp_output->different_polygons ();
|
||||||
|
|
|
||||||
|
|
@ -601,7 +601,7 @@ public:
|
||||||
* @brief Before the scanner is run, this method must be called to feed additional edges into the scanner
|
* @brief Before the scanner is run, this method must be called to feed additional edges into the scanner
|
||||||
* (required for negative edge output - cancellation of perpendicular edges)
|
* (required for negative edge output - cancellation of perpendicular edges)
|
||||||
*/
|
*/
|
||||||
void feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanner);
|
bool feed_pseudo_edges (db::box_scanner<db::Edge, size_t> &scanner);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reimplementation of the box_scanner_receiver interface
|
* @brief Reimplementation of the box_scanner_receiver interface
|
||||||
|
|
@ -641,6 +641,14 @@ public:
|
||||||
m_has_negative_edge_output = f;
|
m_has_negative_edge_output = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a flag indicating that this class wants negative edge output
|
||||||
|
*/
|
||||||
|
bool has_negative_edge_output () const
|
||||||
|
{
|
||||||
|
return m_has_negative_edge_output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets a flag indicating that this class wants normal edge pair output
|
* @brief Sets a flag indicating that this class wants normal edge pair output
|
||||||
*/
|
*/
|
||||||
|
|
@ -649,6 +657,14 @@ public:
|
||||||
m_has_edge_pair_output = f;
|
m_has_edge_pair_output = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets a flag indicating that this class wants normal edge pair output
|
||||||
|
*/
|
||||||
|
bool has_edge_pair_output () const
|
||||||
|
{
|
||||||
|
return m_has_edge_pair_output;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the distance value
|
* @brief Gets the distance value
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue