Bug fixes, RBA tests for meta info

This commit is contained in:
Matthias Koefferlein 2023-04-21 23:33:42 +02:00
parent d1f962a228
commit d9e0d107b1
6 changed files with 144 additions and 26 deletions

View File

@ -1799,7 +1799,7 @@ Layout::meta_info_iterator
Layout::begin_meta (db::cell_index_type ci) const Layout::begin_meta (db::cell_index_type ci) const
{ {
auto m = m_meta_info_by_cell.find (ci); auto m = m_meta_info_by_cell.find (ci);
if (m != m_meta_info_by_cell.find (ci)) { if (m != m_meta_info_by_cell.end ()) {
return m->second.begin (); return m->second.begin ();
} else { } else {
return s_empty_meta.begin (); return s_empty_meta.begin ();
@ -1810,7 +1810,7 @@ Layout::meta_info_iterator
Layout::end_meta (db::cell_index_type ci) const Layout::end_meta (db::cell_index_type ci) const
{ {
auto m = m_meta_info_by_cell.find (ci); auto m = m_meta_info_by_cell.find (ci);
if (m != m_meta_info_by_cell.find (ci)) { if (m != m_meta_info_by_cell.end ()) {
return m->second.end (); return m->second.end ();
} else { } else {
return s_empty_meta.end (); return s_empty_meta.end ();
@ -1871,6 +1871,12 @@ Layout::meta_info (meta_info_name_id_type name_id) const
return n != m_meta_info.end () ? n->second : null_value; return n != m_meta_info.end () ? n->second : null_value;
} }
bool
Layout::has_meta_info (meta_info_name_id_type name_id) const
{
return m_meta_info.find (name_id) != m_meta_info.end ();
}
void void
Layout::clear_meta (db::cell_index_type ci) Layout::clear_meta (db::cell_index_type ci)
{ {
@ -1907,7 +1913,18 @@ Layout::meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const
return null_value; return null_value;
} }
void bool
Layout::has_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const
{
auto c = m_meta_info_by_cell.find (ci);
if (c != m_meta_info_by_cell.end ()) {
return c->second.find (name_id) != c->second.end ();
} else {
return false;
}
}
void
Layout::swap_layers (unsigned int a, unsigned int b) Layout::swap_layers (unsigned int a, unsigned int b)
{ {
tl_assert (m_layers.layer_state (a) != LayoutLayers::Free); tl_assert (m_layers.layer_state (a) != LayoutLayers::Free);

View File

@ -1932,6 +1932,19 @@ public:
*/ */
const MetaInfo &meta_info (meta_info_name_id_type name_id) const; const MetaInfo &meta_info (meta_info_name_id_type name_id) const;
/**
* @brief Gets a value indicating whether a meta info with the given name is present
*/
bool has_meta_info (const std::string &name) const
{
return has_meta_info (meta_info_name_id (name));
}
/**
* @brief Gets a value indicating whether a meta info with the given name is present
*/
bool has_meta_info (meta_info_name_id_type name_id) const;
/** /**
* @brief Clears the meta information for a specific cell * @brief Clears the meta information for a specific cell
*/ */
@ -1954,6 +1967,19 @@ public:
*/ */
void add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i); void add_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id, const MetaInfo &i);
/**
* @brief Gets a value indicating whether a meta info with the given name is present for the given cell
*/
bool has_meta_info (db::cell_index_type ci, const std::string &name) const
{
return has_meta_info (ci, meta_info_name_id (name));
}
/**
* @brief Gets a value indicating whether a meta info with the given name is present for the given cell
*/
bool has_meta_info (db::cell_index_type ci, meta_info_name_id_type name_id) const;
/** /**
* @brief Removes the meta information object with the given name from the given cell * @brief Removes the meta information object with the given name from the given cell
* The method will do nothing if no object with that name exists. * The method will do nothing if no object with that name exists.

View File

@ -1014,14 +1014,15 @@ static const tl::Variant &cell_meta_info_value (db::Cell *cell, const std::strin
} }
} }
static MetaInfo cell_meta_info (db::Cell *cell, const std::string &name) static MetaInfo *cell_meta_info (db::Cell *cell, const std::string &name)
{ {
if (! cell->layout ()) { if (! cell->layout ()) {
static MetaInfo null_value; return 0;
return null_value; } else if (cell->layout ()->has_meta_info (cell->cell_index (), name)) {
} else {
const db::MetaInfo &value = cell->layout ()->meta_info (cell->cell_index (), name); const db::MetaInfo &value = cell->layout ()->meta_info (cell->cell_index (), name);
return MetaInfo (name, value); return new MetaInfo (name, value);
} else {
return 0;
} }
} }
@ -1857,7 +1858,7 @@ Class<db::Cell> decl_Cell ("db", "Cell",
"\n" "\n"
"This method has been introduced in version 0.28.8." "This method has been introduced in version 0.28.8."
) + ) +
gsi::method_ext ("meta_info", &cell_meta_info, gsi::arg ("name"), gsi::factory_ext ("meta_info", &cell_meta_info, gsi::arg ("name"),
"@brief Gets the meta information for a given name\n" "@brief Gets the meta information for a given name\n"
"See \\LayoutMetaInfo for details about cells and meta information.\n" "See \\LayoutMetaInfo for details about cells and meta information.\n"
"\n" "\n"

View File

@ -908,10 +908,14 @@ static void layout_add_meta_info (db::Layout *layout, const MetaInfo &mi)
layout->add_meta_info (mi.name, db::MetaInfo (mi.description, mi.value)); layout->add_meta_info (mi.name, db::MetaInfo (mi.description, mi.value));
} }
static MetaInfo layout_get_meta_info (db::Layout *layout, const std::string &name) static MetaInfo *layout_get_meta_info (db::Layout *layout, const std::string &name)
{ {
const db::MetaInfo &value = layout->meta_info (name); if (layout->has_meta_info (name)) {
return MetaInfo (name, value); const db::MetaInfo &value = layout->meta_info (name);
return new MetaInfo (name, value);
} else {
return 0;
}
} }
static const tl::Variant &layout_get_meta_info_value (db::Layout *layout, const std::string &name) static const tl::Variant &layout_get_meta_info_value (db::Layout *layout, const std::string &name)
@ -1073,11 +1077,11 @@ Class<db::Layout> decl_Layout ("db", "Layout",
"\n" "\n"
"This method has been introduced in version 0.25. Starting with version 0.28.8, the value is of variant type instead of string only.\n" "This method has been introduced in version 0.25. Starting with version 0.28.8, the value is of variant type instead of string only.\n"
) + ) +
gsi::method_ext ("meta_info", &layout_get_meta_info, gsi::arg ("name"), gsi::factory_ext ("meta_info", &layout_get_meta_info, gsi::arg ("name"),
"@brief Gets the meta information for a given name\n" "@brief Gets the meta information for a given name\n"
"See \\LayoutMetaInfo for details about layouts and meta information.\n" "See \\LayoutMetaInfo for details about layouts and meta information.\n"
"\n" "\n"
"If no meta information with the given name exists, a default object with empty fields will be returned.\n" "If no meta information with the given name exists, nil is returned.\n"
"\n" "\n"
"This method has been introduced in version 0.28.8.\n" "This method has been introduced in version 0.28.8.\n"
) + ) +

View File

@ -27,7 +27,7 @@
namespace gsi namespace gsi
{ {
static MetaInfo *layout_meta_info_ctor (const std::string &name, const std::string &value, const std::string &description, bool persisted) static MetaInfo *layout_meta_info_ctor (const std::string &name, const tl::Variant &value, const std::string &description, bool persisted)
{ {
return new MetaInfo (name, description, value, persisted); return new MetaInfo (name, description, value, persisted);
} }
@ -101,7 +101,7 @@ Class<MetaInfo> decl_LayoutMetaInfo ("db", "LayoutMetaInfo",
gsi::method_ext ("description=", &layout_meta_set_description, gsi::method_ext ("description=", &layout_meta_set_description,
"@brief Sets the description of the layout meta info object\n" "@brief Sets the description of the layout meta info object\n"
) + ) +
gsi::method_ext ("persisted", &layout_meta_get_persisted, gsi::method_ext ("is_persisted?", &layout_meta_get_persisted,
"@brief Gets a value indicating whether the meta information will be persisted\n" "@brief Gets a value indicating whether the meta information will be persisted\n"
"This predicate was introduced in version 0.28.8.\n" "This predicate was introduced in version 0.28.8.\n"
) + ) +
@ -118,6 +118,22 @@ Class<MetaInfo> decl_LayoutMetaInfo ("db", "LayoutMetaInfo",
"Meta information is identified by a unique name and carries a string value plus an optional description string. " "Meta information is identified by a unique name and carries a string value plus an optional description string. "
"The description string is for information only and is not evaluated by code.\n" "The description string is for information only and is not evaluated by code.\n"
"\n" "\n"
"Meta information can be attached to the layout object and to cells. It is similar to "
"user properties. The differences are:\n"
"\n"
"@ul\n"
"@li Meta information is stored differently in GDS and OASIS files using the context information added "
" by KLayout to annotated PCell or library cells too. Hence meta information does not pollute "
" the standard user properties space. @/li\n"
"@li The value of meta information can be complex serializable types such as lists, hashes and elementary "
" objects such as \\Box or \\DBox. Scalar types include floats and booleans. @/li\n"
"@li Meta information keys are strings and are supported also for GDS which only accepts integer number "
" keys for user properties. @/li\n"
"@/ul\n"
"\n"
"Note that only meta information marked with \\is_persisted? == true are stored in GDS or OASIS files. "
"This is not the default setting, so you need to explicitly set that flag.\n"
"\n"
"See also \\Layout#each_meta_info, \\Layout#meta_info_value, \\Layout#meta_info and \\Layout#remove_meta_info as " "See also \\Layout#each_meta_info, \\Layout#meta_info_value, \\Layout#meta_info and \\Layout#remove_meta_info as "
"well as the corresponding \\Cell methods.\n" "well as the corresponding \\Cell methods.\n"
"\n" "\n"

View File

@ -1044,36 +1044,39 @@ class DBLayoutTests2_TestClass < TestBase
end end
# Meta information # Meta information
def test_12 def test_12a
mi = RBA::LayoutMetaInfo::new("myinfo", "a") mi = RBA::LayoutMetaInfo::new("myinfo", "a")
assert_equal(mi.name, "myinfo") assert_equal(mi.name, "myinfo")
assert_equal(mi.description, "") assert_equal(mi.description, "")
assert_equal(mi.value, "a") assert_equal(mi.value, "a")
assert_equal(mi.is_persisted?, false)
mi.name = "x" mi.name = "x"
mi.description = "y" mi.description = "y"
mi.value = "z" mi.value = "z"
mi.persisted = true
assert_equal(mi.name, "x") assert_equal(mi.name, "x")
assert_equal(mi.description, "y") assert_equal(mi.description, "y")
assert_equal(mi.value, "z") assert_equal(mi.value, "z")
assert_equal(mi.is_persisted?, true)
ly = RBA::Layout::new ly = RBA::Layout::new
ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "a")) ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "a"))
ly.add_meta_info(RBA::LayoutMetaInfo::new("another", "42", "description")) ly.add_meta_info(RBA::LayoutMetaInfo::new("another", 42, "description"))
assert_equal(ly.meta_info_value("myinfo"), "a") assert_equal(ly.meta_info_value("myinfo"), "a")
assert_equal(ly.meta_info_value("doesnotexist"), "") assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), "42") assert_equal(ly.meta_info_value("another"), 42)
a = [] a = []
ly.each_meta_info { |mi| a << mi.name } ly.each_meta_info { |mi| a << mi.name }
assert_equal(a.join(","), "myinfo,another") assert_equal(a.join(","), "myinfo,another")
a = [] a = []
ly.each_meta_info { |mi| a << mi.value } ly.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "a,42") assert_equal(a.join(","), "a,42")
a = [] a = []
ly.each_meta_info { |mi| a << mi.description } ly.each_meta_info { |mi| a << mi.description }
@ -1081,13 +1084,64 @@ class DBLayoutTests2_TestClass < TestBase
ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "b")) ly.add_meta_info(RBA::LayoutMetaInfo::new("myinfo", "b"))
assert_equal(ly.meta_info_value("myinfo"), "b") assert_equal(ly.meta_info_value("myinfo"), "b")
assert_equal(ly.meta_info_value("doesnotexist"), "") assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), "42") assert_equal(ly.meta_info_value("another"), 42)
ly.remove_meta_info("doesnotexist") # should not fail
ly.remove_meta_info("myinfo") ly.remove_meta_info("myinfo")
assert_equal(ly.meta_info_value("myinfo"), "") assert_equal(ly.meta_info_value("myinfo"), nil)
assert_equal(ly.meta_info_value("doesnotexist"), "") assert_equal(ly.meta_info_value("doesnotexist"), nil)
assert_equal(ly.meta_info_value("another"), "42") assert_equal(ly.meta_info_value("another"), 42)
assert_equal(ly.meta_info("doesnotexist"), nil)
assert_equal(ly.meta_info("another").value, 42)
assert_equal(ly.meta_info("another").description, "description")
ly.clear_meta_info
assert_equal(ly.meta_info_value("another"), nil)
assert_equal(ly.meta_info("another"), nil)
# cellwise
c1 = ly.create_cell("X")
c2 = ly.create_cell("U")
c1.add_meta_info(RBA::LayoutMetaInfo::new("a", true))
c1.add_meta_info(RBA::LayoutMetaInfo::new("b", [ 1, 17, 42 ]))
assert_equal(c2.meta_info("a"), nil)
assert_equal(c2.meta_info_value("a"), nil)
a = []
c2.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "")
assert_equal(c1.meta_info("a").value, true)
assert_equal(c1.meta_info("b").value, [ 1, 17, 42 ])
assert_equal(c1.meta_info_value("b"), [ 1, 17, 42 ])
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true,[1, 17, 42]")
c1.remove_meta_info("doesnotexist") # should not fail
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true,[1, 17, 42]")
c1.remove_meta_info("b")
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "true")
c1.clear_meta_info
a = []
c1.each_meta_info { |mi| a << mi.value.to_s }
assert_equal(a.join(","), "")
end end