Skip to content

Commit e82d214

Browse files
Merge pull request #2280 from KLayout/wip
Wip
2 parents 9b5c76f + 001deab commit e82d214

52 files changed

Lines changed: 1216 additions & 811 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ HAVE_CURL=0
4141
HAVE_EXPAT=0
4242
HAVE_GIT2=1
4343
HAVE_LSTREAM=1
44+
HAVE_CPP20=0
4445

4546
RUBYINCLUDE=""
4647
RUBYINCLUDE2=""
@@ -217,6 +218,9 @@ while [ "$*" != "" ]; do
217218
-nolstream)
218219
HAVE_LSTREAM=0
219220
;;
221+
-cpp20)
222+
HAVE_CPP20=1
223+
;;
220224
-qt5)
221225
echo "*** WARNING: -qt5 option is ignored - Qt version is auto-detected now."
222226
;;
@@ -275,6 +279,7 @@ while [ "$*" != "" ]; do
275279
echo " -libpng Use libpng instead of Qt for PNG generation"
276280
echo " -nolibgit2 Do not include libgit2 for Git package support"
277281
echo " -nolstream Do not include the LStream plugin"
282+
echo " -cpp20 Uses some C++20 features (e.g. atomics)"
278283
echo ""
279284
echo "Environment Variables:"
280285
echo ""
@@ -670,6 +675,7 @@ qmake_options=(
670675
HAVE_PNG="$HAVE_PNG"
671676
HAVE_GIT2="$HAVE_GIT2"
672677
HAVE_LSTREAM="$HAVE_LSTREAM"
678+
HAVE_CPP20="$HAVE_CPP20"
673679
PREFIX="$BIN"
674680
RPATH="$RPATH"
675681
KLAYOUT_VERSION="$KLAYOUT_VERSION"

src/buddies/src/bd/bdWriterOptions.cc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,20 @@ const std::string GenericWriterOptions::dxf_format_name = "DXF";
9898
const std::string GenericWriterOptions::cif_format_name = "CIF";
9999
const std::string GenericWriterOptions::mag_format_name = "MAG";
100100

101+
std::vector<std::string>
102+
GenericWriterOptions::all_format_names ()
103+
{
104+
std::vector<std::string> names;
105+
names.push_back (gds2_format_name);
106+
names.push_back (gds2text_format_name);
107+
names.push_back (oasis_format_name);
108+
names.push_back (lstream_format_name);
109+
names.push_back (dxf_format_name);
110+
names.push_back (cif_format_name);
111+
names.push_back (mag_format_name);
112+
return names;
113+
}
114+
101115
void
102116
GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::string &format)
103117
{
@@ -109,6 +123,15 @@ GenericWriterOptions::add_options (tl::CommandLineOptions &cmd, const std::strin
109123
"given factor."
110124
);
111125

126+
if (format.empty ()) {
127+
cmd << tl::arg (group +
128+
"-of|--format=format", &m_format, "Specifies the output format",
129+
"By default, the output format is derived from the file name suffix. "
130+
"You can also specify the format directly using this option. Allowed format names are: "
131+
+ tl::join (all_format_names (), ", ")
132+
);
133+
}
134+
112135
if (format.empty () || format == gds2_format_name || format == gds2text_format_name || format == oasis_format_name) {
113136
cmd << tl::arg (group +
114137
"-od|--dbu-out=dbu", &m_dbu, "Uses the specified database unit",
@@ -426,6 +449,22 @@ GenericWriterOptions::configure (db::SaveLayoutOptions &save_options, const db::
426449
save_options.set_keep_instances (m_keep_instances);
427450
save_options.set_write_context_info (m_write_context_info);
428451

452+
if (! m_format.empty ()) {
453+
454+
// check, if the format name is a valid one
455+
std::vector<std::string> af = all_format_names ();
456+
auto i = af.begin ();
457+
while (i != af.end () && *i != m_format) {
458+
++i;
459+
}
460+
if (i == af.end ()) {
461+
throw tl::Exception (tl::sprintf (tl::to_string (tr ("Invalid fornat name %s. Allowed names are: %s")), m_format, tl::join (af, ", ")));
462+
}
463+
464+
save_options.set_format (m_format);
465+
466+
}
467+
429468
save_options.set_option_by_name ("gds2_max_vertex_count", m_gds2_max_vertex_count);
430469
save_options.set_option_by_name ("gds2_no_zero_length_paths", m_gds2_no_zero_length_paths);
431470
save_options.set_option_by_name ("gds2_multi_xy_records", m_gds2_multi_xy_records);

src/buddies/src/bd/bdWriterOptions.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "bdCommon.h"
2727

2828
#include <string>
29+
#include <vector>
2930

3031
namespace tl
3132
{
@@ -60,6 +61,11 @@ class BD_PUBLIC GenericWriterOptions
6061
*/
6162
GenericWriterOptions (const db::SaveLayoutOptions &options);
6263

64+
/**
65+
* @brief Gets a list with all format names available
66+
*/
67+
static std::vector<std::string> all_format_names ();
68+
6369
/**
6470
* @brief Adds the generic options to the command line parser object
6571
* The format string gives a hint about the target format. Certain options will be
@@ -114,6 +120,7 @@ class BD_PUBLIC GenericWriterOptions
114120
static const std::string mag_format_name;
115121

116122
private:
123+
std::string m_format;
117124
double m_scale_factor;
118125
double m_dbu;
119126
bool m_dont_write_empty_cells;

src/db/db/dbCell.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,7 @@ std::string
945945
Cell::get_display_name () const
946946
{
947947
tl_assert (layout () != 0);
948-
if (is_ghost_cell () && empty ()) {
948+
if (is_real_ghost_cell ()) {
949949
return std::string ("(") + layout ()->cell_name (cell_index ()) + std::string (")");
950950
} else {
951951
return layout ()->cell_name (cell_index ());
@@ -959,6 +959,20 @@ Cell::set_name (const std::string &name)
959959
layout ()->rename_cell (cell_index (), name.c_str ());
960960
}
961961

962+
void
963+
Cell::set_ghost_cell (bool g)
964+
{
965+
// NOTE: this change is not undo managed
966+
if (m_ghost_cell != g) {
967+
968+
m_ghost_cell = g;
969+
tl_assert (layout () != 0);
970+
// To trigger a redraw and cell tree rebuild
971+
layout ()->cell_name_changed ();
972+
973+
}
974+
}
975+
962976
void
963977
Cell::check_locked () const
964978
{

src/db/db/dbCell.h

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -926,15 +926,26 @@ class DB_PUBLIC Cell
926926
}
927927

928928
/**
929-
* @brief Sets the "ghost cell" flag
929+
* @brief Gets a value indicating whether the cell is a "real" ghost cell
930930
*
931-
* See "is_ghost_cell" for a description of this property.
931+
* A ghost cell is a real ghost cell only if the ghost cell flag is set
932+
* and the cell is empty. Only in that case for example the cell is written
933+
* to GDS files as a ghost cell.
934+
*
935+
* Otherwise, the ghost cell flag is mostly ignored.
932936
*/
933-
void set_ghost_cell (bool g)
937+
bool is_real_ghost_cell () const
934938
{
935-
m_ghost_cell = g;
939+
return m_ghost_cell && empty ();
936940
}
937941

942+
/**
943+
* @brief Sets the "ghost cell" flag
944+
*
945+
* See "is_ghost_cell" for a description of this property.
946+
*/
947+
void set_ghost_cell (bool g);
948+
938949
/**
939950
* @brief Gets a value indicating whether the cell is locked
940951
*

src/db/db/dbCompoundOperation.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ namespace
859859
struct generic_result_adaptor
860860
{
861861
public:
862-
generic_result_adaptor<T> (std::vector<std::unordered_set<T> > *results)
862+
generic_result_adaptor (std::vector<std::unordered_set<T> > *results)
863863
: mp_results (results)
864864
{
865865
m_intermediate.reserve (results->size ());

src/db/db/dbCompoundOperation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ class DB_PUBLIC compound_local_operation
17581758
* Creates a local operation which utilizes the operation tree. "node" is the root of the operation tree.
17591759
* Ownership of the node is *not* transferred to the local operation.
17601760
*/
1761-
compound_local_operation<TS, TI, TR> (CompoundRegionOperationNode *node)
1761+
compound_local_operation (CompoundRegionOperationNode *node)
17621762
: mp_node (node)
17631763
{ }
17641764

@@ -1802,7 +1802,7 @@ class DB_PUBLIC compound_local_operation_with_properties
18021802
* Creates a local operation which utilizes the operation tree. "node" is the root of the operation tree.
18031803
* Ownership of the node is *not* transferred to the local operation.
18041804
*/
1805-
compound_local_operation_with_properties<TS, TI, TR> (CompoundRegionOperationNode *node, db::PropertyConstraint prop_constraint)
1805+
compound_local_operation_with_properties (CompoundRegionOperationNode *node, db::PropertyConstraint prop_constraint)
18061806
: mp_node (node), m_prop_constraint (prop_constraint)
18071807
{
18081808
// .. nothing yet ..

src/db/db/dbHierNetworkProcessor.cc

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1686,6 +1686,69 @@ connected_clusters<T>::join_cluster_with (typename local_cluster<T>::id_type id,
16861686
}
16871687
}
16881688

1689+
template <class T>
1690+
void
1691+
connected_clusters<T>::join_clusters_with (typename local_cluster<T>::id_type id, typename std::set<typename local_cluster<T>::id_type>::const_iterator with_from, typename std::set<typename local_cluster<T>::id_type>::const_iterator with_to)
1692+
{
1693+
if (with_from != with_to && *with_from == id) {
1694+
++with_from;
1695+
}
1696+
if (with_from == with_to) {
1697+
return;
1698+
}
1699+
1700+
connections_type &target = m_connections [id];
1701+
std::set<connections_type::value_type> target_set;
1702+
bool target_set_valid = false;
1703+
1704+
for (auto w = with_from; w != with_to; ++w) {
1705+
1706+
local_clusters<T>::join_cluster_with (id, *w);
1707+
1708+
// handle the connections by translating
1709+
1710+
typename std::map<typename local_cluster<T>::id_type, connections_type>::iterator tc = m_connections.find (*w);
1711+
if (tc != m_connections.end ()) {
1712+
1713+
connections_type &to_join = tc->second;
1714+
1715+
for (connections_type::const_iterator c = to_join.begin (); c != to_join.end (); ++c) {
1716+
m_rev_connections [*c] = id;
1717+
}
1718+
1719+
if (target.empty ()) {
1720+
1721+
target.swap (to_join);
1722+
1723+
} else if (! to_join.empty ()) {
1724+
1725+
// Join while removing duplicates
1726+
if (! target_set_valid) {
1727+
target_set.insert (target.begin (), target.end ());
1728+
target_set_valid = true;
1729+
}
1730+
1731+
for (auto j = to_join.begin (); j != to_join.end (); ++j) {
1732+
if (target_set.find (*j) == target_set.end ()) {
1733+
target.push_back (*j);
1734+
target_set.insert (*j);
1735+
}
1736+
}
1737+
1738+
}
1739+
1740+
m_connections.erase (tc);
1741+
1742+
}
1743+
1744+
if (m_connected_clusters.find (*w) != m_connected_clusters.end ()) {
1745+
m_connected_clusters.insert (id);
1746+
m_connected_clusters.erase (*w);
1747+
}
1748+
1749+
}
1750+
}
1751+
16891752
template <class T>
16901753
typename local_cluster<T>::id_type
16911754
connected_clusters<T>::find_cluster_with_connection (const ClusterInstance &inst) const
@@ -1995,8 +2058,9 @@ struct hc_receiver
19952058

19962059
typename std::set<id_type>::const_iterator c = sc->begin ();
19972060
typename std::set<id_type>::const_iterator cc = c;
1998-
for (++cc; cc != sc->end (); ++cc) {
1999-
mp_cell_clusters->join_cluster_with (*c, *cc);
2061+
++cc;
2062+
if (cc != sc->end ()) {
2063+
mp_cell_clusters->join_clusters_with (*c, cc, sc->end ());
20002064
}
20012065

20022066
}

src/db/db/dbHierNetworkProcessor.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,13 @@ class DB_PUBLIC_TEMPLATE connected_clusters
12741274
*/
12751275
void join_cluster_with (typename local_cluster<T>::id_type id, typename local_cluster<T>::id_type with_id);
12761276

1277+
/**
1278+
* @brief Joins a cluster id with the a set of clusters given by an iterator interval with_to .. with_from
1279+
*
1280+
* This function is equivalent to calling "join_cluster_with" multiple times, but more efficient.
1281+
*/
1282+
void join_clusters_with (typename local_cluster<T>::id_type id, typename std::set<typename local_cluster<T>::id_type>::const_iterator with_from, typename std::set<typename local_cluster<T>::id_type>::const_iterator with_to);
1283+
12771284
/**
12781285
* @brief An iterator delivering all clusters (even the connectors)
12791286
*

src/db/db/dbHierProcessor.cc

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,6 @@ local_processor_result_computation_task<TS, TI, TR>::perform ()
714714
{
715715
mp_cell_contexts->compute_results (*mp_contexts, mp_cell, mp_op, m_output_layers, mp_proc);
716716

717-
// erase the contexts we don't need any longer
718717
{
719718
tl::MutexLocker locker (& mp_contexts->lock ());
720719

@@ -734,7 +733,10 @@ local_processor_result_computation_task<TS, TI, TR>::perform ()
734733
}
735734
#endif
736735

737-
mp_contexts->context_map ().erase (mp_cell);
736+
// release some memory
737+
auto ctx = mp_contexts->context_map ().find (mp_cell);
738+
tl_assert (ctx != mp_contexts->context_map ().end ());
739+
ctx->second.cleanup ();
738740
}
739741
}
740742

@@ -881,15 +883,6 @@ void local_processor<TS, TI, TR>::run (local_operation<TS, TI, TR> *op, unsigned
881883
compute_results (contexts, op, output_layers);
882884
}
883885

884-
template <class TS, class TI, class TR>
885-
void local_processor<TS, TI, TR>::push_results (db::Cell *cell, unsigned int output_layer, const std::unordered_set<TR> &result) const
886-
{
887-
if (! result.empty ()) {
888-
tl::MutexLocker locker (&cell->layout ()->lock ());
889-
cell->shapes (output_layer).insert (result.begin (), result.end ());
890-
}
891-
}
892-
893886
template <class TS, class TI, class TR>
894887
void local_processor<TS, TI, TR>::compute_contexts (local_processor_contexts<TS, TI, TR> &contexts, const local_operation<TS, TI, TR> *op, unsigned int subject_layer, const std::vector<unsigned int> &intruder_layers) const
895888
{
@@ -1248,7 +1241,7 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
12481241
typename local_processor_contexts<TS, TI, TR>::iterator cpc = contexts.context_map ().find (&mp_subject_layout->cell (*bu));
12491242
if (cpc != contexts.context_map ().end ()) {
12501243
cpc->second.compute_results (contexts, cpc->first, op, output_layers, this);
1251-
contexts.context_map ().erase (cpc);
1244+
cpc->second.cleanup (); // release some memory
12521245
}
12531246

12541247
}
@@ -1261,6 +1254,24 @@ local_processor<TS, TI, TR>::compute_results (local_processor_contexts<TS, TI, T
12611254
}
12621255

12631256
}
1257+
1258+
// deliver the results
1259+
{
1260+
tl::MutexLocker locker (& mp_subject_layout->lock ());
1261+
for (auto c = contexts.begin (); c != contexts.end (); ++c) {
1262+
1263+
db::Cell *cell = c->first;
1264+
auto r = c->second.result ().begin ();
1265+
auto rend = c->second.result ().end ();
1266+
1267+
for (auto o = output_layers.begin (); r != rend && o != output_layers.end (); ++o, ++r) {
1268+
if (! r->empty ()) {
1269+
cell->shapes (*o).insert (r->begin (), r->end ());
1270+
}
1271+
}
1272+
1273+
}
1274+
}
12641275
}
12651276

12661277
namespace {

0 commit comments

Comments
 (0)