Allowing the polygon neighborhood visitor to specify a variant type for deep mode

This commit is contained in:
Matthias Koefferlein 2025-05-27 21:07:28 +02:00
parent 010fa2d5ba
commit 0cb5f35659
8 changed files with 184 additions and 19 deletions

View File

@ -712,6 +712,28 @@ VariantsCollectorBase::create_var_instances_tl_invariant (db::Cell &in_cell, std
// ------------------------------------------------------------------------------------------
TransformationReducer *
make_reducer (ReducerType type)
{
switch (type) {
case Orientation:
return new OrientationReducer ();
case Orthogonal:
return new OrthogonalTransformationReducer ();
case Magnification:
return new MagnificationReducer ();
case XYAnisotropyAndMagnification:
return new XYAnisotropyAndMagnificationReducer ();
case MagnificationAndOrientation:
return new MagnificationAndOrientationReducer ();
default:
return 0;
}
}
// ------------------------------------------------------------------------------------------
VariantStatistics::VariantStatistics ()
: mp_red ()
{

View File

@ -166,6 +166,51 @@ private:
int64_t m_grid;
};
/**
* @brief An enum describing a reducer type
*
* This enum is used to create a generic reducer (parameterless) from the code.
*/
enum ReducerType
{
/**
* @brief No specific reducer
*/
NoReducer = 0,
/**
* @brief Rotation/mirror variants
*/
Orientation = 1,
/**
* @brief Orthogonal transformations (rotations of multiple of 90 degree) variants
*/
Orthogonal = 2,
/**
* @brief Scaling variants
*/
Magnification = 3,
/**
* @brief Scaling and x/y assymmetry variants (i.e. anisotropic size)
*/
XYAnisotropyAndMagnification = 4,
/**
* @brief Scaling and orientation variants
*/
MagnificationAndOrientation = 5
};
/**
* @brief Creates a TransformationReducer from the type enum
*
* This function returns 0 if the type is NoReducer or invalid.
*/
DB_PUBLIC TransformationReducer *make_reducer (ReducerType type);
/**
* @brief A class computing variants for cells according to a given criterion
*

View File

@ -302,7 +302,7 @@ CompoundTransformationReducer::is_translation_invariant () const
// ---------------------------------------------------------------------------------------------
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children)
CompoundRegionMultiInputOperationNode::CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children, bool no_init)
{
for (std::vector<CompoundRegionOperationNode *>::const_iterator c = children.begin (); c != children.end (); ++c) {
(*c)->keep ();
@ -362,6 +362,11 @@ CompoundRegionMultiInputOperationNode::init ()
for (tl::shared_collection<CompoundRegionOperationNode>::iterator i = m_children.begin (); i != m_children.end (); ++i) {
m_vars.add (i->vars ());
}
// add the local variant reducer
if (local_vars ()) {
m_vars.add (local_vars ());
}
}
CompoundRegionMultiInputOperationNode::~CompoundRegionMultiInputOperationNode ()

View File

@ -453,7 +453,7 @@ class DB_PUBLIC CompoundRegionMultiInputOperationNode
: public CompoundRegionOperationNode
{
public:
CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children);
CompoundRegionMultiInputOperationNode (const std::vector<CompoundRegionOperationNode *> &children, bool no_init = false);
CompoundRegionMultiInputOperationNode ();
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *child);
CompoundRegionMultiInputOperationNode (CompoundRegionOperationNode *a, CompoundRegionOperationNode *b);
@ -521,14 +521,16 @@ protected:
CompoundRegionOperationNode *child (unsigned int index);
const CompoundRegionOperationNode *child (unsigned int index) const;
virtual const TransformationReducer *local_vars () const { return 0; }
void init ();
private:
tl::shared_collection<CompoundRegionOperationNode> m_children;
// maps child#,layer# to layer# of child:
std::map<std::pair<unsigned int, unsigned int>, unsigned int> m_map_layer_to_child;
std::vector<db::Region *> m_inputs;
CompoundTransformationReducer m_vars;
void init ();
};

View File

@ -28,38 +28,42 @@ namespace db
{
PolygonNeighborhoodVisitor::PolygonNeighborhoodVisitor ()
: m_result_type (db::CompoundRegionOperationNode::ResultType::Edges)
: m_result_type (db::CompoundRegionOperationNode::ResultType::Edges), m_variant_type (db::NoReducer)
{
disconnect_outputs ();
}
void
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons) const
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons, const db::ICplxTrans &trans) const
{
disconnect_outputs ();
mp_polygons = polygons;
m_trans = trans;
}
void
PolygonNeighborhoodVisitor::connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons) const
PolygonNeighborhoodVisitor::connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons, const db::ICplxTrans &trans) const
{
disconnect_outputs ();
mp_layout = layout;
mp_polygon_refs = polygons;
m_trans = trans;
}
void
PolygonNeighborhoodVisitor::connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges) const
PolygonNeighborhoodVisitor::connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges, const db::ICplxTrans &trans) const
{
disconnect_outputs ();
mp_edges = edges;
m_trans = trans;
}
void
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs) const
PolygonNeighborhoodVisitor::connect_output (Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs, const db::ICplxTrans &trans) const
{
disconnect_outputs ();
mp_edge_pairs = edge_pairs;
m_trans = trans;
}
void
@ -76,10 +80,10 @@ void
PolygonNeighborhoodVisitor::output_polygon (const db::PolygonWithProperties &poly)
{
if (mp_polygons) {
mp_polygons->insert (poly);
mp_polygons->insert (poly.transformed (m_trans));
} else if (mp_polygon_refs) {
tl_assert (mp_layout != 0);
mp_polygon_refs->insert (db::PolygonRefWithProperties (db::PolygonRef (poly, mp_layout->shape_repository ()), poly.properties_id ()));
mp_polygon_refs->insert (db::PolygonRefWithProperties (db::PolygonRef (poly.transformed (m_trans), mp_layout->shape_repository ()), poly.properties_id ()));
} else {
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge output (use 'result_type=Edges')")));
}
@ -91,7 +95,7 @@ PolygonNeighborhoodVisitor::output_edge (const db::EdgeWithProperties &edge)
if (mp_edges == 0) {
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge output (use 'result_type=Edges')")));
}
mp_edges->insert (edge);
mp_edges->insert (edge.transformed (m_trans));
}
void
@ -100,16 +104,22 @@ PolygonNeighborhoodVisitor::output_edge_pair (const db::EdgePairWithProperties &
if (mp_edge_pairs == 0) {
throw tl::Exception (tl::to_string (tr ("PolygonNeighborhoodVisitor is not configured for edge pair output (use 'result_type=EdgePairs')")));
}
mp_edge_pairs->insert (edge_pair);
mp_edge_pairs->insert (edge_pair.transformed (m_trans));
}
// --------------------------------------------------------------------------------------------------
PolygonNeighborhoodCompoundOperationNode::PolygonNeighborhoodCompoundOperationNode (const std::vector<CompoundRegionOperationNode *> &children, PolygonNeighborhoodVisitor *visitor, db::Coord dist)
: CompoundRegionMultiInputOperationNode (children), m_dist (dist), mp_visitor (visitor)
: CompoundRegionMultiInputOperationNode (children, true /*no implicit init()*/),
m_dist (dist), mp_visitor (visitor)
{
tl_assert (visitor != 0);
visitor->keep ();
m_vars.reset (db::make_reducer (visitor->variant_type ()));
// must be called after local_vars() is available
init ();
}
db::Coord
@ -170,12 +180,19 @@ PolygonNeighborhoodCompoundOperationNode::compute_local_impl (CompoundRegionOper
tl_assert (interactions.num_subjects () == 1);
tl_assert (! results.empty ());
db::ICplxTrans var_trans, var_trans_inv;
if (proc->vars ()) {
var_trans_inv = proc->vars ()->single_variant_transformation (cell->cell_index ());
var_trans = var_trans_inv.inverted ();
}
try {
mp_visitor->connect_output (layout, &results.front ());
mp_visitor->connect_output (layout, &results.front (), var_trans_inv);
const T &pr = interactions.begin_subjects ()->second;
db::PolygonWithProperties subject (pr.instantiate (), pr.properties_id ());
subject.transform (var_trans);
PolygonNeighborhoodVisitor::neighbors_type neighbors;
@ -191,6 +208,7 @@ PolygonNeighborhoodCompoundOperationNode::compute_local_impl (CompoundRegionOper
for (auto p = others.front ().begin (); p != others.front ().end (); ++p) {
n.push_back (db::PolygonWithProperties (p->instantiate (), p->properties_id ()));
n.back ().transform (var_trans);
}
}

View File

@ -58,22 +58,22 @@ public:
/**
* @brief Configure the polygon output
*/
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons) const;
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::PolygonWithProperties> *polygons, const db::ICplxTrans &trans) const;
/**
* @brief Configure the polygon ref output
*/
void connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons) const;
void connect_output (db::Layout *layout, std::unordered_set<db::PolygonRefWithProperties> *polygons, const db::ICplxTrans &trans) const;
/**
* @brief Configure the edge output
*/
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges) const;
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgeWithProperties> *edges, const db::ICplxTrans &trans) const;
/**
* @brief Configure the edge pair output
*/
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs) const;
void connect_output (db::Layout * /*layout*/, std::unordered_set<db::EdgePairWithProperties> *edge_pairs, const db::ICplxTrans &trans) const;
/**
* @brief Disconnects output
@ -102,6 +102,22 @@ public:
return m_result_type;
}
/**
* @brief Sets the variant type
*/
void set_variant_type (db::ReducerType variant_type)
{
m_variant_type = variant_type;
}
/**
* @brief Gets the variant type
*/
db::ReducerType variant_type () const
{
return m_variant_type;
}
/**
* @brief Delivers a polygon
* This function is only permitted if the result type is Region.
@ -122,11 +138,13 @@ public:
private:
db::CompoundRegionOperationNode::ResultType m_result_type;
db::ReducerType m_variant_type;
mutable std::unordered_set<db::PolygonWithProperties> *mp_polygons;
mutable std::unordered_set<db::PolygonRefWithProperties> *mp_polygon_refs;
mutable std::unordered_set<db::EdgeWithProperties> *mp_edges;
mutable std::unordered_set<db::EdgePairWithProperties> *mp_edge_pairs;
mutable db::Layout *mp_layout;
mutable db::ICplxTrans m_trans;
};
/**
@ -148,6 +166,11 @@ public:
return false;
}
virtual const TransformationReducer *local_vars () const
{
return m_vars.get ();
}
protected:
virtual db::Coord computed_dist () const;
virtual std::string generated_description () const;
@ -162,6 +185,7 @@ protected:
private:
db::Coord m_dist;
tl::weak_ptr<PolygonNeighborhoodVisitor> mp_visitor;
std::unique_ptr<db::TransformationReducer> m_vars;
template <class T, class TR>
void compute_local_impl (CompoundRegionOperationCache * /*cache*/, db::Layout * /*layout*/, db::Cell * /*cell*/, const shape_interactions<T, T> & /*interactions*/, std::vector<std::unordered_set<TR> > & /*results*/, const db::LocalProcessorBase * /*proc*/) const;

View File

@ -22,6 +22,7 @@
#include "gsiDecl.h"
#include "gsiDeclDbMetaInfo.h"
#include "gsiEnums.h"
#include "gsiDeclDbHelpers.h"
#include "dbLayout.h"
@ -4655,5 +4656,39 @@ Class<db::DCellInstArray> decl_DCellInstArray ("db", "DCellInstArray",
"This class has been introduced in version 0.25."
);
gsi::Enum<db::ReducerType> decl_VariantType ("db", "VariantType",
gsi::enum_const ("NoVariants", db::NoReducer,
"@brief No variants needed."
) +
gsi::enum_const ("Orientation", db::Orientation,
"@brief Orientation variants needed.\n"
"For example, the edge orientation selection operation needs this variant type."
) +
gsi::enum_const ("Orthogonal", db::Orthogonal,
"@brief Orthogonal transformations (rotations by multiples of 90 degree) need variants.\n"
"For example, the diagonal edge selection operation needs this variant type."
) +
gsi::enum_const ("Magnification", db::Magnification,
"@brief Scaling variants needed.\n"
"For example, distance measurements or the isotropic sizing operations needs this variant type."
) +
gsi::enum_const ("XYAnisotropyAndMagnification", db::XYAnisotropyAndMagnification,
"@brief Scaling and anisotropy variants needed.\n"
"For example, the anisotropic sizing operation needs this variant type."
) +
gsi::enum_const ("MagnificationAndOrientation", db::MagnificationAndOrientation,
"@brief Scaling and orientation variants needed.\n"
"For example, the 'move' operation needs this variant type."
),
"@brief This class represents the cell variant type for various methods.\n"
"\n"
"Cell variants are needed in hierarchical applications, when operations are to be "
"performed on cell level, but the operations are not transformation invariant.\n"
"In that case, a variant type needs to be specified in order to make the algorithm "
"separate the cells by their absolute orientation or by their accumulated magnification.\n"
"\n"
"This enum has been introduced in version 0.30.2."
);
}

View File

@ -109,6 +109,20 @@ Class<gsi::PolygonNeighborhoodVisitorImpl> decl_PolygonNeighborhoodVisitorImpl (
) +
gsi::method ("result_type", &PolygonNeighborhoodVisitorImpl::result_type,
"@brief Gets the result type\n"
) +
gsi::method ("variant_type=", &PolygonNeighborhoodVisitorImpl::set_variant_type, gsi::arg ("variant_type"),
"@brief Configures the variant type\n"
"The variant type configures transformation variant formation. The polygons presented to the visitor are "
"normalized to the given variant type. For example, specify \\VariantType#Orientation to force orientation variants "
"in the cell tree. Polygons presented to the visitor are normalized to 'as if top' orientation with this variant type.\n"
"\n"
"This property was introduced in version 0.30.2."
) +
gsi::method ("variant_type", &PolygonNeighborhoodVisitorImpl::variant_type,
"@brief Gets the variant type\n"
"See \\variant_type= for a description of this property.\n"
"\n"
"This property was introduced in version 0.30.2."
),
"@brief A visitor for the neighborhood of polygons in the input\n"
"\n"