Skip to content

Commit

Permalink
expose gate-level layout reader and writer
Browse files Browse the repository at this point in the history
  • Loading branch information
simon1hofmann committed Oct 9, 2023
1 parent 2d43a91 commit 256edb0
Show file tree
Hide file tree
Showing 6 changed files with 303 additions and 0 deletions.
46 changes: 46 additions & 0 deletions bindings/pyfiction/include/pyfiction/io/read_fgl_layout.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// Created by simon on 09.10.22.
//

#ifndef PYFICTION_READ_FGL_LAYOUT_HPP
#define PYFICTION_READ_FGL_LAYOUT_HPP

#include "pyfiction/documentation.hpp"
#include "pyfiction/types.hpp"

#include <fiction/io/read_fgl_layout.hpp>
#include <fiction/traits.hpp>

#include <pybind11/pybind11.h>

#include <string_view>

namespace pyfiction
{

namespace detail
{

template <typename Lyt>
void read_fgl_layout(pybind11::module& m)
{
using namespace pybind11::literals;

Lyt (*read_fgl_layout_function_pointer)(const std::string_view&, const std::string_view&) =
&fiction::read_fgl_layout<Lyt>;

m.def("read_fgl_layout", read_fgl_layout_function_pointer, "filename"_a, "layout_name"_a = "", DOC(fiction_read_fgl_layout_3));
}

} // namespace detail

inline void read_fgl_layout(pybind11::module& m)
{
detail::read_fgl_layout<py_cartesian_gate_layout>(m);
detail::read_fgl_layout<py_shifted_cartesian_gate_layout>(m);
detail::read_fgl_layout<py_hexagonal_gate_layout>(m);
}

} // namespace pyfiction

#endif // PYFICTION_READ_FGL_LAYOUT_HPP
49 changes: 49 additions & 0 deletions bindings/pyfiction/include/pyfiction/io/write_fgl_layout.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Created by simon on 09.10.22.
//

#ifndef PYFICTION_WRITE_FGL_LAYOUT_HPP
#define PYFICTION_WRITE_FGL_LAYOUT_HPP

#include "pyfiction/documentation.hpp"
#include "pyfiction/types.hpp"

#include <fiction/io/write_fgl_layout.hpp>
#include <fiction/traits.hpp>

#include <pybind11/pybind11.h>

#include <string_view>

namespace pyfiction
{

namespace detail
{

template <typename Lyt>
void write_fgl_layout(pybind11::module& m)
{
using namespace pybind11::literals;

m.def(
"write_fgl_layout",
[](const Lyt& lyt, const std::string_view& filename)
{
fiction::write_fgl_layout<Lyt>(lyt, filename);
},
"layout"_a, "filename"_a, DOC(fiction_write_fgl_layout_2));
}

} // namespace detail

inline void write_fgl_layout(pybind11::module& m)
{
detail::write_fgl_layout<py_cartesian_gate_layout>(m);
detail::write_fgl_layout<py_shifted_cartesian_gate_layout>(m);
detail::write_fgl_layout<py_hexagonal_gate_layout>(m);
}

} // namespace pyfiction

#endif // PYFICTION_WRITE_FGL_LAYOUT_HPP
157 changes: 157 additions & 0 deletions bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5532,6 +5532,48 @@ neutral).
Parameter ``charge_layout``:
Initialized charge layout.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage =
R"doc(@struct gate_storage

Represents a gate in a fcn layout, storing its unique ID, type, name,
location, and incoming connections.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_compare_by_id =
R"doc(Static member function to compare gate_storage objects by their IDs.

Parameter ``gate1``:
First gate to be compared.

Parameter ``gate2``:
Second gate to be compared.

Returns:
True if gate1's ID is less than gate2's ID, false otherwise.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_id = R"doc(Unique identifier for the gate.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_incoming = R"doc(List of incoming connections to the gate.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_loc = R"doc(Location of the gate represented its x-, y- and z-coordinate.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_name = R"doc(Name of the gate (for inputs and outputs).)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_gate_storage_type =
R"doc(Type of the gate, can be an alias (AND, OR, PI, ..) or the implemented
function in a binary or hexadecimal form.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_is = R"doc(The input stream from which the gate-level layout is read.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_lyt = R"doc(The layout which will be altered based on the parsed information.)doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_read_fgl_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_read_fgl_layout_impl_2 = R"doc()doc";

static const char *__doc_fiction_detail_read_fgl_layout_impl_run = R"doc()doc";

static const char *__doc_fiction_detail_read_fqca_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_read_fqca_layout_impl_cell_label_map = R"doc()doc";
Expand Down Expand Up @@ -5773,6 +5815,16 @@ static const char *__doc_fiction_detail_wire_east = R"doc()doc";

static const char *__doc_fiction_detail_wire_south = R"doc()doc";

static const char *__doc_fiction_detail_write_fgl_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_write_fgl_layout_impl_lyt = R"doc(The layout to be written.)doc";

static const char *__doc_fiction_detail_write_fgl_layout_impl_os = R"doc(The output stream to which the gate-level layout is written.)doc";

static const char *__doc_fiction_detail_write_fgl_layout_impl_run = R"doc()doc";

static const char *__doc_fiction_detail_write_fgl_layout_impl_write_fgl_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_write_fqca_layout_impl = R"doc()doc";

static const char *__doc_fiction_detail_write_fqca_layout_impl_alphabet_iterator = R"doc()doc";
Expand Down Expand Up @@ -7076,6 +7128,16 @@ Parameter ``g``:
Returns:
Transposed `fcn_gate`.)doc";

static const char *__doc_fiction_fgl_parsing_error =
R"doc(Exception thrown when an error occurs during parsing of a .fgl file
containing a gate-level layout.)doc";

static const char *__doc_fiction_fgl_parsing_error_fgl_parsing_error =
R"doc(Constructs a fgl_parsing_error object with the given error message.

Parameter ``msg``:
The error message describing the parsing error.)doc";

static const char *__doc_fiction_find_first_two_of =
R"doc(A derivative of `std::find_first_of` that uses the example
implementation given at
Expand Down Expand Up @@ -11776,6 +11838,72 @@ R"doc(Standard constructor with forward reference.
Parameter ``range``:
Begin and end iterator pair.)doc";

static const char *__doc_fiction_read_fgl_layout =
R"doc(Reads a gate-level layout from an FGL file provided as an input
stream.

May throw an `fgl_parsing_exception` if the FGL file is malformed.

Template parameter ``Lyt``:
The layout type to be created from an input.

Parameter ``is``:
The input stream to read from.

Parameter ``name``:
The name to give to the generated layout.)doc";

static const char *__doc_fiction_read_fgl_layout_2 =
R"doc(Reads a gate-level layout from an FGL file provided as an input
stream.

May throw an `fgl_parsing_exception` if the FGL file is malformed.

This is an in-place version of read_fgl_layout that utilizes the given
layout as a target to write to.

Template parameter ``Lyt``:
The layout type to be used as input.

Parameter ``lyt``:
The layout to write to.

Parameter ``is``:
The input stream to read from.)doc";

static const char *__doc_fiction_read_fgl_layout_3 =
R"doc(Reads a gate-level layout from an FGL file provided as an input
stream.

May throw an `fgl_parsing_exception` if the FGL file is malformed.

Template parameter ``Lyt``:
The layout type to be created from an input.

Parameter ``filename``:
The file name to open and read from.

Parameter ``name``:
The name to give to the generated layout.)doc";

static const char *__doc_fiction_read_fgl_layout_4 =
R"doc(Reads a gate-level layout from an FGL file provided as an input
stream.

May throw an `fgl_parsing_exception` if the FGL file is malformed.

This is an in-place version of `read_fgl_layout` that utilizes the
given layout as a target to write to.

Template parameter ``Lyt``:
The layout type to be used as input.

Parameter ``lyt``:
The layout to write to.

Parameter ``filename``:
The file name to open and read from.)doc";

static const char *__doc_fiction_read_fqca_layout =
R"doc(Reads a cell-level QCA layout from an fqca file provided as an input
stream. The format is used by QCA-STACK by Willem Lambooy
Expand Down Expand Up @@ -13806,6 +13934,35 @@ Parameter ``lyt``:
Parameter ``filename``:
Filename)doc";

static const char *__doc_fiction_write_fgl_layout =
R"doc(Writes an FGL layout to a file.

This overload uses an output stream to write into.

Template parameter ``Lyt``:
Layout.

Parameter ``lyt``:
The layout to be written.

Parameter ``os``:
The output stream to write into.)doc";

static const char *__doc_fiction_write_fgl_layout_2 =
R"doc(Writes an FGL layout to a file.

This overload uses a file name to create and write into.

Template parameter ``Lyt``:
Layout.

Parameter ``lyt``:
The layout to be written.

Parameter ``filename``:
The file name to create and write into. Should preferably use the
.fgl extension.)doc";

static const char *__doc_fiction_write_fqca_layout =
R"doc(Writes a cell-level QCA layout to an fqca file provided as an output
stream. The format is used by QCA-STACK by Willem Lambooy
Expand Down
4 changes: 4 additions & 0 deletions bindings/pyfiction/pyfiction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
// #include "pyfiction/algorithms/simulation/sidb/time_to_solution.hpp"
#include "pyfiction/algorithms/verification/design_rule_violations.hpp"
#include "pyfiction/algorithms/verification/equivalence_checking.hpp"
#include "pyfiction/io/read_fgl_layout.hpp"
#include "pyfiction/io/read_fqca_layout.hpp"
#include "pyfiction/io/read_sqd_layout.hpp"
#include "pyfiction/io/write_dot_layout.hpp"
#include "pyfiction/io/write_fgl_layout.hpp"
#include "pyfiction/io/write_fqca_layout.hpp"
#include "pyfiction/io/write_qca_layout.hpp"
#include "pyfiction/io/write_qcc_layout.hpp"
Expand Down Expand Up @@ -139,12 +141,14 @@ PYBIND11_MODULE(pyfiction, m)
* Input/Output
*/
pyfiction::write_dot_layout(m);
pyfiction::write_fgl_layout(m);
pyfiction::write_qca_layout(m);
pyfiction::write_svg_layout(m);
pyfiction::write_sqd_layout(m);
pyfiction::write_qcc_layout(m);
pyfiction::write_qll_layout(m);
pyfiction::write_fqca_layout(m);
pyfiction::read_fgl_layout(m);
pyfiction::read_fqca_layout(m);
pyfiction::read_sqd_layout(m);
/**
Expand Down
16 changes: 16 additions & 0 deletions bindings/pyfiction/test/io/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from os.path import dirname, basename, isfile, join
import glob
import os
import sys
from pathlib import Path

if sys.platform == "win32" and sys.version_info > (3, 8, 0) and "Z3_ROOT" in os.environ:
lib_path = Path(os.environ["Z3_ROOT"]) / "lib"
if lib_path.exists():
os.add_dll_directory(str(lib_path))
bin_path = Path(os.environ["Z3_ROOT"]) / "bin"
if bin_path.exists():
os.add_dll_directory(str(bin_path))

modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
31 changes: 31 additions & 0 deletions bindings/pyfiction/test/io/test_read_write_fgl_layout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from fiction.pyfiction import *
from dotenv import load_dotenv
import unittest
import os

dir_path = os.path.dirname(os.path.realpath(__file__))
load_dotenv()
z3 = os.environ.get("z3", "OFF")


class TestReadWriteFglLayout(unittest.TestCase):

def test_read_write_cartesian(self):
network = read_logic_network(dir_path + "/../resources/mux21.v")
layout = orthogonal(network)
write_fgl_layout(layout, "mux21.fgl")
read_layout = read_fgl_layout("mux21.fgl")
self.assertEqual(equivalence_checking(read_layout, layout), eq_type.STRONG)

@unittest.skipIf(z3 == "OFF", "Z3 not enabled")
def test_read_write_hexagonal(self):
network = read_logic_network(dir_path + "/../resources/mux21.v")
layout = exact_hexagonal(network)
write_fgl_layout(layout, "mux21_hex.fgl")
read_layout = read_fgl_layout("mux21_hex.fgl")
self.assertEqual(equivalence_checking(read_layout, layout), eq_type.STRONG)



if __name__ == '__main__':
unittest.main()

0 comments on commit 256edb0

Please sign in to comment.