diff --git a/docs/io/visualization.rst b/docs/io/visualization.rst index 2e5a200e9..6b5c5b053 100644 --- a/docs/io/visualization.rst +++ b/docs/io/visualization.rst @@ -11,6 +11,7 @@ Layout Printing .. doxygenfunction:: fiction::print_gate_level_layout .. doxygenfunction:: fiction::print_cell_level_layout .. doxygenfunction:: fiction::print_charge_layout +.. doxygenfunction:: fiction::print_layout Graphviz (DOT) Drawers ###################### diff --git a/include/fiction/io/print_layout.hpp b/include/fiction/io/print_layout.hpp index 236a9939e..06d5ec51f 100644 --- a/include/fiction/io/print_layout.hpp +++ b/include/fiction/io/print_layout.hpp @@ -61,7 +61,7 @@ inline constexpr auto NO_COLOR = fmt::text_style{}; */ template void print_gate_level_layout(std::ostream& os, const Lyt& layout, const bool io_color = true, - const bool clk_color = false) noexcept + const bool clk_color = false) { static_assert(is_gate_level_layout_v, "Lyt is not a gate-level layout"); @@ -252,7 +252,7 @@ void print_gate_level_layout(std::ostream& os, const Lyt& layout, const bool io_ */ template void print_cell_level_layout(std::ostream& os, const Lyt& layout, const bool io_color = true, - const bool clk_color = false) noexcept + const bool clk_color = false) { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); @@ -327,31 +327,37 @@ void print_cell_level_layout(std::ostream& os, const Lyt& layout, const bool io_ /** * Writes a simplified 2D representation of an SiDB charge layout to an output stream. * - * @tparam Lyt Cell-level layout based on SiQAD coordinates. + * @tparam Lyt SiDB cell-level layout with charge-information based on SiQAD coordinates, e.g., a + * charge_distribution_surface object. * @param os Output stream to write into. - * @param cds The charge distribution surface of which the charge layout is to be printed. + * @param lyt The layout of which the charge distribution is to be printed. * @param cs_color Flag to utilize color escapes for charge states. * @param crop_layout Flag to print the 2D bounding box of the layout, while leaving a maximum padding of one dimer row * and two columns. * @param draw_lattice Flag to enable lattice background drawing. */ template -void print_charge_layout(std::ostream& os, const charge_distribution_surface& cds, const bool cs_color = true, - const bool crop_layout = false, const bool draw_lattice = true) noexcept +void print_charge_layout(std::ostream& os, const Lyt& lyt, const bool cs_color = true, const bool crop_layout = false, + const bool draw_lattice = true) { + static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); + static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); + static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + static_assert(has_get_charge_state_v, "Lyt does not implement the get_charge_state function"); + // empty layout - if (cds.is_empty()) + if (lyt.is_empty()) { os << "[i] empty layout" << std::endl; return; } coordinate min{}; - coordinate max{cds.x(), cds.y(), 1}; + coordinate max{lyt.x(), lyt.y(), 1}; if (crop_layout) { - const auto bb = bounding_box_2d{cds}; + const auto bb = bounding_box_2d{lyt}; // apply padding of maximally one dimer row and two columns min = bb.get_min() - coordinate{2, 1}; @@ -363,7 +369,7 @@ void print_charge_layout(std::ostream& os, const charge_distribution_surface& c) { if (crop_layout && (c.x < min.x || c.x > max.x)) // apply horizontal crop @@ -371,7 +377,7 @@ void print_charge_layout(std::ostream& os, const charge_distribution_surface empty cell { - os << (draw_lattice || !cds.is_empty_cell(c) ? + os << (draw_lattice || !lyt.is_empty_cell(c) ? fmt::format(cs_color ? detail::SIDB_LAT_COLOR : detail::NO_COLOR, " ยท ") : " "); } @@ -406,6 +412,41 @@ void print_charge_layout(std::ostream& os, const charge_distribution_surface +void print_layout(const Lyt& lyt, std::ostream& os = std::cout) +{ + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); + + if constexpr (is_gate_level_layout_v) + { + print_gate_level_layout(os, lyt); + } + else if constexpr (is_cell_level_layout_v) + { + if constexpr (has_sidb_technology_v && has_siqad_coord_v && has_get_charge_state_v) + { + print_charge_layout(os, lyt); + } + else + { + print_cell_level_layout(os, lyt); + } + } + else + { + os << "[e] unknown layout type" << std::endl; + } +} } // namespace fiction diff --git a/test/io/print_layout.cpp b/test/io/print_layout.cpp index 1bc252b01..328d2d453 100644 --- a/test/io/print_layout.cpp +++ b/test/io/print_layout.cpp @@ -33,6 +33,12 @@ TEST_CASE("Print empty gate-level layout", "[print-gate-level-layout]") print_gate_level_layout(print_stream, layout, false, false); CHECK(print_stream.str() == layout_print); + + print_stream = {}; + + print_layout(layout, print_stream); + + CHECK(print_stream.str() == layout_print); } TEST_CASE("Print simple gate-level layout", "[print-gate-level-layout]") @@ -121,6 +127,12 @@ TEST_CASE("Print empty cell-level layout", "[print-cell-level-layout]") print_cell_level_layout(print_stream, layout, false, false); CHECK(print_stream.str() == layout_print); + + print_stream = {}; + + print_layout(layout, print_stream); + + CHECK(print_stream.str() == layout_print); } TEST_CASE("Print AND gate cell-level layout", "[print-cell-level-layout]") @@ -203,11 +215,19 @@ TEST_CASE("Print empty charge layout", "[print-charge-layout]") { using sqd_lyt = sidb_cell_clk_lyt_siqad; + const charge_distribution_surface layout{sqd_lyt{{2, 2}, "Empty"}}; + constexpr const char* layout_print = "[i] empty layout\n"; std::stringstream print_stream{}; - print_charge_layout(print_stream, charge_distribution_surface{sqd_lyt{{2, 2}, "Empty"}}, false); + print_charge_layout(print_stream, layout, false); + + CHECK(print_stream.str() == layout_print); + + print_stream = {}; + + print_layout(layout, print_stream); CHECK(print_stream.str() == layout_print); }