WIP: LStream samples+test, OASIS writer

Current version of LStream code, samples and reader tests.
OASIS Writer: now writing points (to degenerated edges)
and edge pairs without asserting.
This commit is contained in:
Matthias Koefferlein 2025-11-08 00:34:56 +01:00
parent 115b6d5716
commit e8d5499598
38 changed files with 138 additions and 91 deletions

View File

@ -354,7 +354,7 @@ make_regular_array (stream::repetition::Repetition::Reader repetition, db::regul
Reader::Reader (tl::InputStream &s)
: m_stream (&s), m_source (s.source ()),
m_progress (tl::to_string (tr ("Reading LStream file"))),
m_library_index (0), mp_layout (0), mp_cell (0), m_layout_view_id (0)
m_library_index (0), mp_cell (0), mp_layout (0), m_layout_view_id (0)
{
m_progress.set_format (tl::to_string (tr ("%.0f MB")));
m_progress.set_unit (1024 * 1024);
@ -423,6 +423,9 @@ Reader::do_read (db::Layout &layout)
} catch (lstr::CoordinateOverflowException &ex) {
// this adds source information
error (ex.msg ());
} catch (kj::Exception &ex) {
// this adds source information
error (ex.getDescription ().cStr ());
}
}

View File

@ -437,6 +437,21 @@ Writer::collect_property_ids (std::vector<db::properties_id_type> &prop_ids, std
}
}
namespace
{
struct ComparePropertyNameIdByValue
{
bool operator() (db::property_names_id_type a, db::property_names_id_type b) const
{
const tl::Variant &na = db::property_name (a);
const tl::Variant &nb = db::property_name (b);
return na.less (nb);
}
};
}
/**
* @brief Gets the LStream property set Id from a KLayout properties Id
*
@ -463,8 +478,13 @@ Writer::make_property_id (db::properties_id_type id, std::vector<db::properties_
prop_ids.push_back (id);
auto ps = db::properties (id);
std::set<db::property_names_id_type, ComparePropertyNameIdByValue> ps_sorted;
for (auto i = ps.begin (); i != ps.end (); ++i) {
make_property_name_id_from_id (i->first, prop_names);
ps_sorted.insert (i->first);
}
for (auto i = ps_sorted.begin (); i != ps_sorted.end (); ++i) {
make_property_name_id_from_id (*i, prop_names);
}
return ls_id;
@ -684,7 +704,6 @@ Writer::make_layer_table (stream::library::LayerTable::Builder layers)
for (auto l = m_layers_to_write.begin (); l != m_layers_to_write.end (); ++l) {
auto li = l->first;
auto lp = l->second;
// NOTE: currently, the purpose is always DRAWING
@ -876,11 +895,11 @@ Writer::write_cell (db::cell_index_type ci, kj::BufferedOutputStream &os)
int view_index = 0;
if (needs_layout_view) {
tl_assert (m_layout_view_id >= 0);
cell.getViewIds ().set (view_index++, m_layout_view_id);
cell.getViewIds ().set (view_index++, (unsigned int) m_layout_view_id);
}
if (needs_meta_data_view) {
tl_assert (m_meta_data_view_id >= 0);
cell.getViewIds ().set (view_index++, m_meta_data_view_id);
cell.getViewIds ().set (view_index++, (unsigned int) m_meta_data_view_id);
}
writePackedMessage (os, message);

View File

@ -78,8 +78,8 @@ private:
bool m_permissive;
db::Layout *mp_layout;
std::string m_cellname;
unsigned int m_layout_view_id;
unsigned int m_meta_data_view_id;
int m_layout_view_id;
int m_meta_data_view_id;
std::map<db::lib_id_type, uint64_t> m_ls_lib_ids;
std::vector<std::pair <unsigned int, db::LayerProperties> > m_layers_to_write;
std::set<db::cell_index_type> m_cells_to_write;

View File

@ -20,8 +20,7 @@
*/
#if 0 // @@@
#include "dbMALYReader.h"
#include "lstrReader.h"
#include "dbLayoutDiff.h"
#include "dbWriter.h"
#include "dbTestSupport.h"
@ -29,37 +28,16 @@
#include <stdlib.h>
static void run_test (tl::TestBase *_this, const std::string &base, const char *file, const char *file_au, const char *map = 0, double dbu = 0.001)
static void run_test (tl::TestBase *_this, const std::string &base, const char *file, const char *file_au)
{
db::MALYReaderOptions *opt = new db::MALYReaderOptions();
opt->dbu = dbu;
db::LayerMap lm;
if (map) {
unsigned int ln = 0;
tl::Extractor ex (map);
while (! ex.at_end ()) {
std::string n;
int l;
ex.read_word_or_quoted (n);
ex.test (":");
ex.read (l);
ex.test (",");
lm.map (n, ln++, db::LayerProperties (l, 0));
}
opt->layer_map = lm;
opt->create_other_layers = true;
}
db::LoadLayoutOptions options;
options.set_options (opt);
db::Manager m (false);
db::Layout layout (&m);
{
std::string fn (base);
fn += "/maly/";
fn += "/lstream/";
fn += file;
tl::InputStream stream (fn);
db::Reader reader (stream);
@ -67,82 +45,89 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char *
}
std::string fn_au (base);
fn_au += "/maly/";
fn_au += "/lstream/";
fn_au += file_au;
db::compare_layouts (_this, layout, fn_au, db::WriteOAS);
}
TEST(1_Basic)
TEST(basic)
{
std::string fn (tl::testdata ());
fn += "/maly/MALY_test1.maly";
tl::InputStream stream (fn);
db::MALYReader reader (stream);
db::MALYData data = reader.read_maly_file ();
EXPECT_EQ (data.to_string (),
"Mask A\n"
" Size 127000\n"
" Title \"<SERIAL>\" m90 0,-50 1,1,1 [Standard]\n"
" Title \"MaskA1\" m90 50,50 1,1,1 [Standard]\n"
" Title \"WITH \"QUOTES\"\" r270 -50,0 1,1,1 [Standard]\n"
" Ref A1.oas{CHIP_A}(1) (0,0;10,10) m90 *1 20,0\n"
" Ref A2.oas{CHIP_A}(2) ename(e001) dname(d001) (0,0;50,50) m90 *0.8 20,0 [2x5,1x2]\n"
" Ref B3.oas{CHIP_A}(2) (0,0;12,12) m90 *1 20,0"
)
run_test (_this, tl::testdata (), "basic.lstr", "basic_au.oas");
}
static std::string run_test_with_error (tl::TestBase * /*_this*/, const std::string &file)
TEST(boxes)
{
std::string fn (tl::testdata ());
fn += "/maly/";
fn += file;
tl::InputStream stream (fn);
db::MALYReader reader (stream);
try {
reader.read_maly_file ();
tl_assert (false);
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
return ex.msg ();
}
run_test (_this, tl::testdata (), "boxes.lstr", "boxes_au.oas");
}
TEST(2_Errors)
TEST(cells)
{
EXPECT_EQ (run_test_with_error (_this, "MALY_test2a.maly").find ("Line break inside quoted string (line=17,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2b.maly").find ("/*...*/ comment not closed (line=43,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2c.maly").find ("Expected value STANDARD or NATIVE for FONT (line=7,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2d.maly").find ("Unknown base specification: NOVALIDBASE (line=8,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2e.maly").find ("Expected end of text here: NOVALIDKEY .. (line=15,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2f.maly").find ("Expected 'Y' or 'NONE' for MIRROR spec (line=15,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2g.maly").find ("Expected end of text here: UNEXPECTED (line=20,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2h.maly").find ("Expected value Y or NONE for MASKMIRROR (line=23,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2i.maly").find ("Expected end of text here: UNEXPECTED (line=29,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2j.maly").find ("Expected end of text here: NOVALIDKEY .. (line=30,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2k.maly").find ("Expected a real number here: SCALE 0.80 .. (line=31,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2l.maly").find ("Expected 'PARAMETER' here: CMASK (line=19,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2m.maly").find ("Expected 'CMASK' here: TITLE (line=18,"), size_t (0));
EXPECT_EQ (run_test_with_error (_this, "MALY_test2n.maly").find ("Header expected ('BEGIN MALY') (line=2, "), size_t (0));
run_test (_this, tl::testdata (), "cells.lstr", "cells_au.oas");
}
TEST(10_BasicLayout)
TEST(cells_with_instances)
{
run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_au.oas");
run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_lm_au.oas", "A: 10, B: 11, C: 12, D: 13");
run_test (_this, tl::testdata (), "MALY_test10.maly", "maly_test10_dbu10nm_au.oas", 0, 0.01);
run_test (_this, tl::testdata (), "cells_with_instances.lstr", "cells_with_instances_au.oas");
}
TEST(11_Titles)
TEST(edge_pairs)
{
run_test (_this, tl::testdata (), "MALY_test11.maly", "maly_test11_au.oas");
run_test (_this, tl::testdata (), "edge_pairs.lstr", "edge_pairs_au.oas");
}
#endif
// @@@
TEST(edges)
{
run_test (_this, tl::testdata (), "edges.lstr", "edges_au.oas");
}
TEST(ghost_cells)
{
run_test (_this, tl::testdata (), "ghost_cells.lstr", "ghost_cells_au.oas");
}
TEST(meta_data)
{
run_test (_this, tl::testdata (), "meta_data.lstr", "meta_data_au.oas");
}
TEST(paths)
{
run_test (_this, tl::testdata (), "paths.lstr", "paths_au.oas");
}
TEST(pcells)
{
run_test (_this, tl::testdata (), "pcells.lstr", "pcells_au.oas");
}
TEST(points)
{
run_test (_this, tl::testdata (), "points.lstr", "points_au.oas");
}
TEST(polygons)
{
run_test (_this, tl::testdata (), "polygons.lstr", "polygons_au.oas");
}
TEST(properties)
{
run_test (_this, tl::testdata (), "properties.lstr", "properties_au.oas");
}
TEST(simple_polygons)
{
run_test (_this, tl::testdata (), "simple_polygons.lstr", "simple_polygons_au.oas");
}
TEST(texts)
{
run_test (_this, tl::testdata (), "texts.lstr", "texts_au.oas");
}
TEST(variants)
{
run_test (_this, tl::testdata (), "variants.lstr", "variants_au.oas");
}

View File

@ -9,7 +9,7 @@ include($$PWD/../../../../lib_ut.pri)
SOURCES = \
dbLStreamReaderTests.cc
INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common
INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common $$PWD/../db_plugin/capnp
DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common
LIBS += -L$$DESTDIR_UT -lklayout_db -lklayout_tl -lklayout_gsi

View File

@ -3309,6 +3309,46 @@ OASISWriter::write_shapes (const db::LayerProperties &lprops, const db::Shapes &
break;
case db::Shape::EdgePair:
if (shape->has_prop_id ()) {
db::EdgePairWithProperties edge_pair = *shape->basic_ptr (db::EdgePairWithProperties::tag ());
db::EdgeWithProperties e1 (edge_pair.first (), edge_pair.properties_id ());
db::EdgeWithProperties e2 (edge_pair.second (), edge_pair.properties_id ());
db::Disp tr;
e1.reduce (tr);
edge_with_properties_compressor.add (e1, tr.disp ());
e2.reduce (tr);
edge_with_properties_compressor.add (e2, tr.disp ());
} else {
db::EdgePair edge_pair = *shape->basic_ptr (db::EdgePair::tag ());
db::Disp tr;
edge_pair.first ().reduce (tr);
edge_compressor.add (edge_pair.first (), tr.disp ());
edge_pair.second ().reduce (tr);
edge_compressor.add (edge_pair.second (), tr.disp ());
}
break;
case db::Shape::Point:
if (shape->has_prop_id ()) {
db::PointWithProperties point = *shape->basic_ptr (db::PointWithProperties::tag ());
db::EdgeWithProperties e (db::Edge (point, point), point.properties_id ());
db::Disp tr;
e.reduce (tr);
edge_with_properties_compressor.add (e, tr.disp ());
} else {
db::Point point = *shape->basic_ptr (db::Point::tag ());
db::Disp tr;
db::Edge e (point, point);
e.reduce (tr);
edge_compressor.add (e, tr.disp ());
}
break;
case db::Shape::Path:
if (shape->has_prop_id ()) {

BIN
testdata/lstream/basic.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/basic_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/boxes.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/boxes_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/cells.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/cells_au.oas vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
testdata/lstream/edge_pairs.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/edge_pairs_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/edges.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/edges_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/ghost_cells.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/ghost_cells_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/meta_data.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/meta_data_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/paths.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/paths_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/pcells.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/pcells_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/points.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/points_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/polygons.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/polygons_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/properties.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/properties_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/simple_polygons.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/simple_polygons_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/texts.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/texts_au.oas vendored Normal file

Binary file not shown.

BIN
testdata/lstream/variants.lstr vendored Normal file

Binary file not shown.

BIN
testdata/lstream/variants_au.oas vendored Normal file

Binary file not shown.