From f76860ba7f4dc2b6304d44874bba672c5478b1fa Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 12 Feb 2023 14:02:05 +0100 Subject: [PATCH 01/21] :sparkles: functions to convert layouts to a new layout based on a new coordinate type (fiction to siqad and vs.). --- .../layout_fiction_coordinates_to_siqad.hpp | 34 +++++++++++++++ .../layout_siqad_coordinates_to_fiction.hpp | 35 ++++++++++++++++ .../layout_fiction_coordinates_to_siqad.cpp | 42 +++++++++++++++++++ .../layout_siqad_coordinates_to_fiction.cpp | 42 +++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp create mode 100644 include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp create mode 100644 test/layouts/layout_fiction_coordinates_to_siqad.cpp create mode 100644 test/layouts/layout_siqad_coordinates_to_fiction.cpp diff --git a/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp b/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp new file mode 100644 index 000000000..8b6457ca0 --- /dev/null +++ b/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp @@ -0,0 +1,34 @@ +// +// Created by Jan Drewniok on 11.02.23. +// + +#ifndef FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP +#define FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP + +#include "fiction/layouts/cell_level_layout.hpp" +#include "fiction/layouts/coordinates.hpp" +#include "fiction/traits.hpp" +#include "fiction/types.hpp" + +namespace fiction +{ +/** + * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is + * returned. + * + * @tparam Lyt Cell-level layout based on Fiction coordinates (Cube, Offset). + * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. + * @return new layout based on SiQAD coordinates. + */ +template +sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) +{ + sidb_cell_clk_lyt_siqad lyt_new{}; + lyt.foreach_cell([&lyt_new, &lyt](const auto& c) + { lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); }); + return lyt_new; +} + +} // namespace fiction + +#endif // FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP diff --git a/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp b/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp new file mode 100644 index 000000000..77a2e5a53 --- /dev/null +++ b/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp @@ -0,0 +1,35 @@ +// +// Created by Jan Drewniok on 11.02.23. +// + +#ifndef FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP +#define FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP + +#include "fiction/layouts/cell_level_layout.hpp" +#include "fiction/layouts/coordinates.hpp" +#include "fiction/traits.hpp" +#include "fiction/types.hpp" + +namespace fiction +{ +/** + * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is + * returned. + * + * @tparam Lyt Cell-level layout based on SiQAD coordinates. + * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. + * @return New layout based on Fiction coordinates. + */ +template +sidb_cell_clk_lyt lyt_coordinates_to_fiction(const Lyt& lyt) +{ + sidb_cell_clk_lyt lyt_new{}; + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { lyt_new.assign_cell_type(siqad::to_fiction_coord(c), lyt.get_cell_type(c)); }); + return lyt_new; +} + +} // namespace fiction + +#endif // FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP diff --git a/test/layouts/layout_fiction_coordinates_to_siqad.cpp b/test/layouts/layout_fiction_coordinates_to_siqad.cpp new file mode 100644 index 000000000..fffa38928 --- /dev/null +++ b/test/layouts/layout_fiction_coordinates_to_siqad.cpp @@ -0,0 +1,42 @@ +// +// Created by Jan Drewniok on 12.02.23. +// + +#include + +#include +#include +#include +#include + +using namespace fiction; + +TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_clk_lyt) +{ + SECTION("empty layout") + { + TestType lyt{{10, 10}}; + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.is_empty()); + } + + SECTION("layout with one cell") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.num_cells() == 1); + CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); + } + + SECTION("layout with two cells") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::NORMAL); + } +} \ No newline at end of file diff --git a/test/layouts/layout_siqad_coordinates_to_fiction.cpp b/test/layouts/layout_siqad_coordinates_to_fiction.cpp new file mode 100644 index 000000000..397f02546 --- /dev/null +++ b/test/layouts/layout_siqad_coordinates_to_fiction.cpp @@ -0,0 +1,42 @@ +// +// Created by Jan Drewniok on 12.02.23. +// + +#include + +#include +#include +#include +#include + +using namespace fiction; + +TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_clk_lyt_siqad) +{ + SECTION("empty layout") + { + TestType lyt{{10, 10}}; + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.is_empty()); + } + + SECTION("layout with one cell") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 1); + CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); + } + + SECTION("layout with two cells") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::NORMAL); + } +} \ No newline at end of file From e40fbc1e64e79c34fabd119e7e5af4f482a61f12 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 12 Feb 2023 18:33:52 +0100 Subject: [PATCH 02/21] :sparkles: functions to convert layouts to a new layout based on a new coordinate type (fiction to siqad and vs.). --- test/layouts/layout_fiction_coordinates_to_siqad.cpp | 8 +++++--- test/layouts/layout_siqad_coordinates_to_fiction.cpp | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/test/layouts/layout_fiction_coordinates_to_siqad.cpp b/test/layouts/layout_fiction_coordinates_to_siqad.cpp index fffa38928..6a4d82d7f 100644 --- a/test/layouts/layout_fiction_coordinates_to_siqad.cpp +++ b/test/layouts/layout_fiction_coordinates_to_siqad.cpp @@ -11,7 +11,7 @@ using namespace fiction; -TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) { SECTION("empty layout") { @@ -29,13 +29,15 @@ TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_ CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); } - SECTION("layout with two cells") + SECTION("layout with three cells") { TestType lyt{}; + lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); auto lyt_transformed = lyt_coordinates_to_siqad(lyt); - CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::NORMAL); } diff --git a/test/layouts/layout_siqad_coordinates_to_fiction.cpp b/test/layouts/layout_siqad_coordinates_to_fiction.cpp index 397f02546..84ea25c3f 100644 --- a/test/layouts/layout_siqad_coordinates_to_fiction.cpp +++ b/test/layouts/layout_siqad_coordinates_to_fiction.cpp @@ -11,11 +11,11 @@ using namespace fiction; -TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_clk_lyt_siqad) +TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt_siqad) { SECTION("empty layout") { - TestType lyt{{10, 10}}; + TestType lyt{}; auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); } @@ -29,14 +29,16 @@ TEMPLATE_TEST_CASE("Cell-level layout traits", "[cell-level-layout]", sidb_cell_ CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); } - SECTION("layout with two cells") + SECTION("layout with three cells") { TestType lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); auto lyt_transformed = lyt_coordinates_to_fiction(lyt); - CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::NORMAL); } } \ No newline at end of file From d7de6c3414ab0f4ff7bcb28320edcedb6165e965 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 10:47:24 +0100 Subject: [PATCH 03/21] :art: put functions in different header, added missing attributes, updated tests. --- .../layout_fiction_coordinates_to_siqad.hpp | 34 -------- .../layout_siqad_coordinates_to_fiction.hpp | 35 -------- include/fiction/utils/layout_utils.hpp | 58 +++++++++++++ .../layout_fiction_coordinates_to_siqad.cpp | 44 ---------- .../layout_siqad_coordinates_to_fiction.cpp | 44 ---------- test/utils/layout_utils.cpp | 82 +++++++++++++++++++ 6 files changed, 140 insertions(+), 157 deletions(-) delete mode 100644 include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp delete mode 100644 include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp delete mode 100644 test/layouts/layout_fiction_coordinates_to_siqad.cpp delete mode 100644 test/layouts/layout_siqad_coordinates_to_fiction.cpp diff --git a/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp b/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp deleted file mode 100644 index 8b6457ca0..000000000 --- a/include/fiction/layouts/layout_fiction_coordinates_to_siqad.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// Created by Jan Drewniok on 11.02.23. -// - -#ifndef FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP -#define FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP - -#include "fiction/layouts/cell_level_layout.hpp" -#include "fiction/layouts/coordinates.hpp" -#include "fiction/traits.hpp" -#include "fiction/types.hpp" - -namespace fiction -{ -/** - * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is - * returned. - * - * @tparam Lyt Cell-level layout based on Fiction coordinates (Cube, Offset). - * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. - * @return new layout based on SiQAD coordinates. - */ -template -sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) -{ - sidb_cell_clk_lyt_siqad lyt_new{}; - lyt.foreach_cell([&lyt_new, &lyt](const auto& c) - { lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); }); - return lyt_new; -} - -} // namespace fiction - -#endif // FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP diff --git a/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp b/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp deleted file mode 100644 index 77a2e5a53..000000000 --- a/include/fiction/layouts/layout_siqad_coordinates_to_fiction.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Created by Jan Drewniok on 11.02.23. -// - -#ifndef FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP -#define FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP - -#include "fiction/layouts/cell_level_layout.hpp" -#include "fiction/layouts/coordinates.hpp" -#include "fiction/traits.hpp" -#include "fiction/types.hpp" - -namespace fiction -{ -/** - * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is - * returned. - * - * @tparam Lyt Cell-level layout based on SiQAD coordinates. - * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. - * @return New layout based on Fiction coordinates. - */ -template -sidb_cell_clk_lyt lyt_coordinates_to_fiction(const Lyt& lyt) -{ - sidb_cell_clk_lyt lyt_new{}; - lyt.foreach_cell( - [&lyt_new, &lyt](const auto& c) - { lyt_new.assign_cell_type(siqad::to_fiction_coord(c), lyt.get_cell_type(c)); }); - return lyt_new; -} - -} // namespace fiction - -#endif // FICTION_LAYOUT_SIQAD_COORDINATES_TO_FICTION_HPP diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 7fd7518ea..8a70de9c8 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -5,8 +5,11 @@ #ifndef FICTION_LAYOUT_UTILS_HPP #define FICTION_LAYOUT_UTILS_HPP +#include "fiction/layouts/cell_level_layout.hpp" +#include "fiction/layouts/coordinates.hpp" #include "fiction/technology/cell_ports.hpp" #include "fiction/traits.hpp" +#include "fiction/types.hpp" #include #include @@ -224,6 +227,61 @@ template return {}; } +/** + * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is + * returned. + * + * @tparam Lyt Cell-level layout based on Fiction coordinates (Cube, Offset). + * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. + * @return new layout based on SiQAD coordinates. + */ +template +sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) +{ + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + 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"); + + sidb_cell_clk_lyt_siqad lyt_new{}; + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)), + lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)), + lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; +} + +/** + * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is + * returned. + * + * @tparam Lyt Cell-level layout based on SiQAD coordinates. + * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. + * @return New layout based on Fiction coordinates. + */ +template +sidb_cell_clk_lyt lyt_coordinates_to_fiction(const Lyt& lyt) +{ + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + 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"); + + sidb_cell_clk_lyt lyt_new{}; + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord(c), lyt.get_cell_type(c)), + lyt_new.assign_cell_mode(siqad::to_fiction_coord(c), lyt.get_cell_mode(c)), + lyt_new.assign_cell_name(siqad::to_fiction_coord(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; +} + } // namespace fiction #endif // FICTION_LAYOUT_UTILS_HPP diff --git a/test/layouts/layout_fiction_coordinates_to_siqad.cpp b/test/layouts/layout_fiction_coordinates_to_siqad.cpp deleted file mode 100644 index 6a4d82d7f..000000000 --- a/test/layouts/layout_fiction_coordinates_to_siqad.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Created by Jan Drewniok on 12.02.23. -// - -#include - -#include -#include -#include -#include - -using namespace fiction; - -TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) -{ - SECTION("empty layout") - { - TestType lyt{{10, 10}}; - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); - CHECK(lyt_transformed.is_empty()); - } - - SECTION("layout with one cell") - { - TestType lyt{}; - lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); - CHECK(lyt_transformed.num_cells() == 1); - CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); - } - - SECTION("layout with three cells") - { - TestType lyt{}; - lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); - CHECK(lyt_transformed.num_cells() == 3); - CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::NORMAL); - } -} \ No newline at end of file diff --git a/test/layouts/layout_siqad_coordinates_to_fiction.cpp b/test/layouts/layout_siqad_coordinates_to_fiction.cpp deleted file mode 100644 index 84ea25c3f..000000000 --- a/test/layouts/layout_siqad_coordinates_to_fiction.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// Created by Jan Drewniok on 12.02.23. -// - -#include - -#include -#include -#include -#include - -using namespace fiction; - -TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt_siqad) -{ - SECTION("empty layout") - { - TestType lyt{}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); - CHECK(lyt_transformed.is_empty()); - } - - SECTION("layout with one cell") - { - TestType lyt{}; - lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); - CHECK(lyt_transformed.num_cells() == 1); - CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); - } - - SECTION("layout with three cells") - { - TestType lyt{}; - lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); - CHECK(lyt_transformed.num_cells() == 3); - CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::NORMAL); - } -} \ No newline at end of file diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 8f740902a..f8775a3e0 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -38,3 +38,85 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia lyt.north_west(c)); }); } + +TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) +{ + SECTION("empty layout") + { + TestType lyt{{10, 10}, "test"}; + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.is_empty()); + CHECK(lyt_transformed.get_layout_name() == "test"); + } + // + SECTION("layout with one normal and one input cell") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::INPUT); + } + + SECTION("layout with three cells") + { + TestType lyt{}; + lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 3}, TestType::cell_type::INPUT); + lyt.assign_cell_type({5, 1}, TestType::cell_type::OUTPUT); + lyt.assign_cell_name({0, 0}, "normal cell"); + lyt.assign_cell_name({5, 3}, "input cell"); + lyt.assign_cell_name({5, 1}, "output cell"); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::OUTPUT); + CHECK(lyt_transformed.get_cell_name({0, 0, 0}) == "normal cell"); + CHECK(lyt_transformed.get_cell_name({5, 1, 1}) == "input cell"); + CHECK(lyt_transformed.get_cell_name({5, 0, 1}) == "output cell"); + } +} + +TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt_siqad) +{ + SECTION("empty layout") + { + TestType lyt{{}, "layout based on siqad coordinates"}; + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.is_empty()); + CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + } + + SECTION("layout with one normal and one input cell") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::INPUT); + } + + SECTION("layout with three cells") + { + TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); + lyt.assign_cell_type({5, 1}, TestType::cell_type::OUTPUT); + lyt.assign_cell_name({5, 3}, "normal cell"); + lyt.assign_cell_name({0, 0}, "input cell"); + lyt.assign_cell_name({5, 1}, "output cell"); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::OUTPUT); + CHECK(lyt_transformed.get_cell_name({5, 6}) == "normal cell"); + CHECK(lyt_transformed.get_cell_name({0, 0}) == "input cell"); + CHECK(lyt_transformed.get_cell_name({5, 2}) == "output cell"); + } +} From 514b9906f401e5dcc3e7d6348cc2a3f8f3b91885 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 10:50:18 +0100 Subject: [PATCH 04/21] :memo: docu updated --- docs/utils/utils.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index 29001f724..e58c1c21a 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -54,6 +54,8 @@ Layout Utils .. doxygenfunction:: fiction::num_adjacent_coordinates .. doxygenfunction:: fiction::relative_to_absolute_cell_position .. doxygenfunction:: fiction::port_direction_to_coordinate +.. doxygenfunction:: fiction::lyt_coordinates_to_siqad +.. doxygenfunction:: fiction::lyt_coordinates_to_fiction Placement Utils From 2a058a3a415696d8129888d2078f9a3588347812 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 15:18:05 +0100 Subject: [PATCH 05/21] :art: new function to shift layout to positive coordinates --- docs/utils/utils.rst | 1 + include/fiction/traits.hpp | 2 + include/fiction/utils/layout_utils.hpp | 86 ++++++++++++++++++++++---- test/utils/layout_utils.cpp | 73 +++++++++++++++++++--- 4 files changed, 142 insertions(+), 20 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index e58c1c21a..c3da42050 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -56,6 +56,7 @@ Layout Utils .. doxygenfunction:: fiction::port_direction_to_coordinate .. doxygenfunction:: fiction::lyt_coordinates_to_siqad .. doxygenfunction:: fiction::lyt_coordinates_to_fiction +.. doxygenfunction:: fiction::normalize_layout_coordinates Placement Utils diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index c6e5cc97e..de4446cff 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -575,6 +575,8 @@ template inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; template inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; +template +inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; #pragma region is_cell_level_layout template diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 8a70de9c8..5c4dff283 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -227,6 +227,52 @@ template return {}; } +/** + * The layout is shifted by x_min and y_min such that the cells' coordinates are positive. + * + * @tparam Lyt Cell-level layout. + * @param lyt The given layout which is shifted. + * @return shifted layout. + */ +template +Lyt normalize_layout_coordinates(const Lyt& lyt) +{ + if (lyt.num_cells() == 0) + { + return lyt; + } + Lyt lyt_new{}; + auto x_min = INT32_MAX; + auto y_min = INT32_MAX; + lyt.foreach_cell( + [&lyt, &x_min, &y_min](const auto& c) + { + if (c.y <= y_min && c.x <= x_min) + { + y_min = c.y; + x_min = c.x; + } + else if (c.y <= y_min && c.x > x_min) + { + y_min = c.y; + } + else if (c.y > y_min && (c.x <= x_min)) + { + x_min = c.x; + } + }); + + lyt.foreach_cell( + [&lyt_new, &lyt, &x_min, &y_min](const auto& c) + { + lyt_new.assign_cell_type({c.x - x_min, c.y - y_min}, lyt.get_cell_type(c)), + lyt_new.assign_cell_mode({c.x - x_min, c.y - y_min}, lyt.get_cell_mode(c)), + lyt_new.assign_cell_name({c.x - x_min, c.y - y_min}, lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; +} + /** * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is * returned. @@ -251,6 +297,7 @@ sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); }); lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; } @@ -258,27 +305,42 @@ sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is * returned. * - * @tparam Lyt Cell-level layout based on SiQAD coordinates. + * @tparam Lyt Cell-level layout based on Fiction coordinates. * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. * @return New layout based on Fiction coordinates. */ template -sidb_cell_clk_lyt lyt_coordinates_to_fiction(const Lyt& lyt) +Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) { static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); 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"); - sidb_cell_clk_lyt lyt_new{}; - lyt.foreach_cell( - [&lyt_new, &lyt](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_fiction_coord(c), lyt.get_cell_type(c)), - lyt_new.assign_cell_mode(siqad::to_fiction_coord(c), lyt.get_cell_mode(c)), - lyt_new.assign_cell_name(siqad::to_fiction_coord(c), lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); + Lyt lyt_new{}; + + if constexpr (has_offset_ucoord_v) + { + auto lyt_normalized = normalize_layout_coordinates(lyt); + lyt_normalized.foreach_cell( + [&lyt_new, &lyt_normalized](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)), + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)), + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt_normalized.get_layout_name()); + } + else + { + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)), + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)), + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + } return lyt_new; } diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index f8775a3e0..8057e0301 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,7 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia }); } -TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) { SECTION("empty layout") { @@ -48,7 +49,7 @@ TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_si CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } - // + SECTION("layout with one normal and one input cell") { TestType lyt{}; @@ -80,11 +81,26 @@ TEMPLATE_TEST_CASE("Cell-level layout trait", "[layout_fiction_coordinates_to_si } } -TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt_siqad) +TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates", "[normalize_layout_coordinates]", sidb_cell_clk_lyt_siqad) { SECTION("empty layout") { TestType lyt{{}, "layout based on siqad coordinates"}; + lyt.assign_cell_type({-5,-1}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5,1}, TestType::cell_type::NORMAL); + auto lyt_transformed = normalize_layout_coordinates(lyt); + CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + CHECK(lyt_transformed.get_cell_type({0,0}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({10,2}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({-5,-1}) == TestType::cell_type::EMPTY); + } +} + +TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt) +{ + SECTION("empty layout") + { + sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); @@ -92,18 +108,18 @@ TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fic SECTION("layout with one normal and one input cell") { - TestType lyt{}; + sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); + lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 2); - CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); } SECTION("layout with three cells") { - TestType lyt{}; + sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); lyt.assign_cell_type({5, 1}, TestType::cell_type::OUTPUT); @@ -120,3 +136,44 @@ TEMPLATE_TEST_CASE("Cell-level layout traits", "[layout_siqad_coordinates_to_fic CHECK(lyt_transformed.get_cell_name({5, 2}) == "output cell"); } } + +TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordinates_to_fiction]", (cell_level_layout>>)) +{ + SECTION("empty layout") + { + sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.is_empty()); + CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + } + + SECTION("layout with one normal and one input cell") + { + sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5,-1,1}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 2,0}) == TestType::cell_type::INPUT); + } + + SECTION("layout with three cells") + { + sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5, -3}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); + lyt.assign_cell_type({5, 3}, TestType::cell_type::OUTPUT); + lyt.assign_cell_name({5, -3}, "normal cell"); + lyt.assign_cell_name({0, 0}, "input cell"); + lyt.assign_cell_name({5, 3}, "output cell"); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.get_cell_type({5, -6}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::OUTPUT); + CHECK(lyt_transformed.get_cell_name({5, -6}) == "normal cell"); + CHECK(lyt_transformed.get_cell_name({0, 0}) == "input cell"); + CHECK(lyt_transformed.get_cell_name({5, 6}) == "output cell"); + } +} From 35e3728d117f15fc081977638d86b471c274acaf Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 15:22:24 +0100 Subject: [PATCH 06/21] :art: new function to shift layout to positive coordinates --- include/fiction/utils/layout_utils.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 5c4dff283..13e7b3f47 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -252,11 +252,11 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) y_min = c.y; x_min = c.x; } - else if (c.y <= y_min && c.x > x_min) + else if (c.y <= y_min) { y_min = c.y; } - else if (c.y > y_min && (c.x <= x_min)) + else if (c.x <= x_min) { x_min = c.x; } From f46f4e35496355d0d24564e1c9d6bc156eee0a4a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 18:18:08 +0100 Subject: [PATCH 07/21] :art: updated Marcel's suggestions --- docs/utils/utils.rst | 3 +- include/fiction/traits.hpp | 7 ++- include/fiction/utils/layout_utils.hpp | 65 ++++++++++++-------------- 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index c3da42050..557fc4e5f 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -54,9 +54,10 @@ Layout Utils .. doxygenfunction:: fiction::num_adjacent_coordinates .. doxygenfunction:: fiction::relative_to_absolute_cell_position .. doxygenfunction:: fiction::port_direction_to_coordinate +.. doxygenfunction:: fiction::normalize_layout_coordinates .. doxygenfunction:: fiction::lyt_coordinates_to_siqad .. doxygenfunction:: fiction::lyt_coordinates_to_fiction -.. doxygenfunction:: fiction::normalize_layout_coordinates + Placement Utils diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index de4446cff..23907fc47 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -574,9 +574,12 @@ inline constexpr const bool has_inml_technology_v = std::is_same_v inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; template -inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; -template inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; +template +inline constexpr const bool has_cube_coord_v = std::is_same_v, cube::coord_t>; +template +inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; + #pragma region is_cell_level_layout template diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 13e7b3f47..d9461836c 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -13,6 +13,7 @@ #include #include +#include namespace fiction { @@ -235,39 +236,33 @@ template * @return shifted layout. */ template -Lyt normalize_layout_coordinates(const Lyt& lyt) +Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept { - if (lyt.num_cells() == 0) - { - return lyt; - } - Lyt lyt_new{}; - auto x_min = INT32_MAX; - auto y_min = INT32_MAX; + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); + + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + auto x_offset = std::numeric_limits::max(); + auto y_offset = std::numeric_limits::max(); lyt.foreach_cell( - [&lyt, &x_min, &y_min](const auto& c) + [&x_offset, &y_offset](const auto& c) { - if (c.y <= y_min && c.x <= x_min) - { - y_min = c.y; - x_min = c.x; - } - else if (c.y <= y_min) + if (c.y <= y_offset) { - y_min = c.y; + y_offset = c.y; } - else if (c.x <= x_min) + if (c.x <= x_offset) { - x_min = c.x; + x_offset = c.x; } }); lyt.foreach_cell( - [&lyt_new, &lyt, &x_min, &y_min](const auto& c) + [&lyt_new, &lyt, &x_offset, &y_offset](const auto& c) { - lyt_new.assign_cell_type({c.x - x_min, c.y - y_min}, lyt.get_cell_type(c)), - lyt_new.assign_cell_mode({c.x - x_min, c.y - y_min}, lyt.get_cell_mode(c)), - lyt_new.assign_cell_name({c.x - x_min, c.y - y_min}, lyt.get_cell_name(c)); + lyt_new.assign_cell_type({c.x - x_offset, c.y - y_offset}, lyt.get_cell_type(c)); + lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); + lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); }); lyt_new.set_layout_name(lyt.get_layout_name()); return lyt_new; @@ -282,19 +277,19 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) * @return new layout based on SiQAD coordinates. */ template -sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) +sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept { static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); 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"); - sidb_cell_clk_lyt_siqad lyt_new{}; + sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; lyt.foreach_cell( [&lyt_new, &lyt](const auto& c) { - lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)), - lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)), - lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); + lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); }); lyt_new.set_layout_name(lyt.get_layout_name()); @@ -310,13 +305,13 @@ sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) * @return New layout based on Fiction coordinates. */ template -Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) +Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept { static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); 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"); - Lyt lyt_new{}; + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; if constexpr (has_offset_ucoord_v) { @@ -324,9 +319,9 @@ Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) lyt_normalized.foreach_cell( [&lyt_new, &lyt_normalized](const auto& c) { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)), - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)), - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); }); lyt_new.set_layout_name(lyt_normalized.get_layout_name()); } @@ -335,9 +330,9 @@ Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) lyt.foreach_cell( [&lyt_new, &lyt](const auto& c) { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)), - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)), - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); }); lyt_new.set_layout_name(lyt.get_layout_name()); } From c258e70117a2ef9a4c4c51eb444403d51e2ecc2f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 18:24:47 +0100 Subject: [PATCH 08/21] :art: reformat code --- .../technology/sidb_surface_analysis.hpp | 14 ++++----- include/fiction/traits.hpp | 1 - test/utils/layout_utils.cpp | 29 ++++++++++--------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index d90465b0d..91db9f05a 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -120,14 +120,12 @@ template }; // for each tile in the layout - gate_lyt.foreach_tile( - [&](const auto& t) constexpr - { - // for each gate in the library - std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), - // analyze the defect impact - std::bind(analyze_gate, std::placeholders::_1, t)); - }); + gate_lyt.foreach_tile([&](const auto& t) constexpr { + // for each gate in the library + std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), + // analyze the defect impact + std::bind(analyze_gate, std::placeholders::_1, t)); + }); return black_list; } diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index 23907fc47..6e80f54cb 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -580,7 +580,6 @@ inline constexpr const bool has_cube_coord_v = std::is_same_v, c template inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; - #pragma region is_cell_level_layout template struct is_cell_level_layout : std::false_type diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 8057e0301..6d149768e 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -81,27 +81,29 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordina } } -TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates", "[normalize_layout_coordinates]", sidb_cell_clk_lyt_siqad) +TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates", "[normalize_layout_coordinates]", + sidb_cell_clk_lyt_siqad) { SECTION("empty layout") { TestType lyt{{}, "layout based on siqad coordinates"}; - lyt.assign_cell_type({-5,-1}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5,1}, TestType::cell_type::NORMAL); - auto lyt_transformed = normalize_layout_coordinates(lyt); + lyt.assign_cell_type({-5, -1}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); + auto lyt_transformed = normalize_layout_coordinates(lyt); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); - CHECK(lyt_transformed.get_cell_type({0,0}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({10,2}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({-5,-1}) == TestType::cell_type::EMPTY); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({10, 2}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({-5, -1}) == TestType::cell_type::EMPTY); } } -TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coordinates_to_fiction]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coordinates_to_fiction]", + sidb_cell_clk_lyt) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -137,12 +139,13 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo } } -TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordinates_to_fiction]", (cell_level_layout>>)) +TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordinates_to_fiction]", + (cell_level_layout>>)) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -150,12 +153,12 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordi SECTION("layout with one normal and one input cell") { sidb_cell_clk_lyt_siqad lyt{}; - lyt.assign_cell_type({5,-1,1}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, -1, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({5, 2,0}) == TestType::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({5, 2, 0}) == TestType::cell_type::INPUT); } SECTION("layout with three cells") From 8ea6c248cc962c24156ca50b4dad0278fb168f32 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 19:09:17 +0100 Subject: [PATCH 09/21] :art: reformat code --- .../technology/sidb_surface_analysis.hpp | 146 +- include/fiction/traits.hpp | 1508 +++++++++-------- include/fiction/utils/layout_utils.hpp | 420 ++--- test/utils/layout_utils.cpp | 41 +- 4 files changed, 1034 insertions(+), 1081 deletions(-) diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index 91db9f05a..e39ccccc8 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -21,8 +21,7 @@ #include #include -namespace fiction -{ +namespace fiction { /** * This alias represents a black list of gates that cannot be placed on certain positions on a (layout) surface in @@ -34,10 +33,11 @@ namespace fiction * to be used preferably as it, e.g., helps the exact physical design algorithm to convert these assertions into unit * clauses which significantly helps runtime. */ -template -using surface_black_list = - std::unordered_map, std::unordered_map>, - kitty::hash>>; + template + using surface_black_list = + std::unordered_map, std::unordered_map>, + kitty::hash>>; + /** * Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library. Any gate type that * cannot be realized on a certain tile due to disturbances caused by defects gets blacklisted on said tile. The black @@ -53,82 +53,74 @@ using surface_black_list = * @param surface SiDB surface that instantiates the defects. * @return A black list of gate functions associated with tiles. */ -template -[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface) noexcept -{ - static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); - - static_assert(has_get_functional_implementations_v, - "GateLibrary does not implement the get_functional_implementations function"); - static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); - static_assert(std::is_same_v, technology>, - "CellLyt and GateLibrary must implement the same technology"); - - // fetch the port type used by the gate library - using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; - - surface_black_list black_list{}; - - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); - const auto gate_implementations = GateLibrary::get_functional_implementations(); - const auto gate_ports = GateLibrary::get_gate_ports(); - - // a lambda that analyzes defect impact on a gate at a given layout tile - // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error - // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() - // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it - const auto analyze_gate = [&](const auto& it, const auto& t) noexcept - { - const auto& [fun, impls] = it; - - // for each gate in the list of possible implementations - for (const auto& gate : impls) - { - // for each cell position in the gate - for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) - { - for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) - { - // if the cell type at position (x, y) in the gate is non-empty - if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) - { - // cell position within the gate - const cell relative_cell_pos{x, y, t.z}; - - const auto sidb_pos = - relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); - - // if any SiDB position of the current gate is compromised - if (sidbs_affected_by_defects.count(sidb_pos) > 0) - { - // add this gate's function to the black list of tile t using the ports - // specified by get_gate_ports in GateLibrary - for (const auto& port : gate_ports.at(gate)) - { - black_list[t][fun].push_back(port); + template + [[nodiscard]] auto sidb_surface_analysis(const GateLyt &gate_lyt, const sidb_surface &surface) noexcept { + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); + + static_assert(has_get_functional_implementations_v, + "GateLibrary does not implement the get_functional_implementations function"); + static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); + static_assert(std::is_same_v, technology>, + "CellLyt and GateLibrary must implement the same technology"); + + // fetch the port type used by the gate library + using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; + + surface_black_list black_list{}; + + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); + const auto gate_implementations = GateLibrary::get_functional_implementations(); + const auto gate_ports = GateLibrary::get_gate_ports(); + + // a lambda that analyzes defect impact on a gate at a given layout tile + // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error + // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() + // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it + const auto analyze_gate = [&](const auto &it, const auto &t) noexcept { + const auto &[fun, impls] = it; + + // for each gate in the list of possible implementations + for (const auto &gate: impls) { + // for each cell position in the gate + for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) { + for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) { + // if the cell type at position (x, y) in the gate is non-empty + if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) { + // cell position within the gate + const cell relative_cell_pos{x, y, t.z}; + + const auto sidb_pos = + relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); + + // if any SiDB position of the current gate is compromised + if (sidbs_affected_by_defects.count(sidb_pos) > 0) { + // add this gate's function to the black list of tile t using the ports + // specified by get_gate_ports in GateLibrary + for (const auto &port: gate_ports.at(gate)) { + black_list[t][fun].push_back(port); + } + + return; // skip to next gate } - - return; // skip to next gate } } } } - } - }; - - // for each tile in the layout - gate_lyt.foreach_tile([&](const auto& t) constexpr { - // for each gate in the library - std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), - // analyze the defect impact - std::bind(analyze_gate, std::placeholders::_1, t)); - }); - - return black_list; -} + }; + + // for each tile in the layout + gate_lyt.foreach_tile([&](const auto &t) constexpr { + // for each gate in the library + std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), + // analyze the defect impact + std::bind(analyze_gate, std::placeholders::_1, t)); + }); + + return black_list; + } } // namespace fiction diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index 6e80f54cb..dcea4ec97 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -19,8 +19,7 @@ #include #include -namespace fiction -{ +namespace fiction { /** * This file includes fiction's trait system that is modeled after mockturtle/traits.hpp. It allows to check at compile @@ -31,722 +30,731 @@ namespace fiction * Coordinate layouts */ -template -using aspect_ratio = typename Lyt::aspect_ratio; + template + using aspect_ratio = typename Lyt::aspect_ratio; -template -using coordinate = typename Lyt::coordinate; + template + using coordinate = typename Lyt::coordinate; #pragma region has_north -template -struct has_north : std::false_type -{}; + template + struct has_north : std::false_type { + }; -template -struct has_north().north(std::declval>()))>> - : std::true_type -{}; + template + struct has_north().north(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_north_v = has_north::value; + template + inline constexpr bool has_north_v = has_north::value; #pragma endregion #pragma region has_east -template -struct has_east : std::false_type -{}; + template + struct has_east : std::false_type { + }; -template -struct has_east().east(std::declval>()))>> : std::true_type -{}; + template + struct has_east().east(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_east_v = has_east::value; + template + inline constexpr bool has_east_v = has_east::value; #pragma endregion #pragma region has_south -template -struct has_south : std::false_type -{}; + template + struct has_south : std::false_type { + }; -template -struct has_south().south(std::declval>()))>> - : std::true_type -{}; + template + struct has_south().south(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_south_v = has_south::value; + template + inline constexpr bool has_south_v = has_south::value; #pragma endregion #pragma region has_west -template -struct has_west : std::false_type -{}; + template + struct has_west : std::false_type { + }; -template -struct has_west().west(std::declval>()))>> : std::true_type -{}; + template + struct has_west().west(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_west_v = has_west::value; + template + inline constexpr bool has_west_v = has_west::value; #pragma endregion #pragma region has_cardinal_operations -template -struct has_cardinal_operations : std::false_type -{}; + template + struct has_cardinal_operations : std::false_type { + }; -template -struct has_cardinal_operations< - Lyt, std::enable_if_t, has_east, has_south, has_west>>> - : std::true_type -{}; + template + struct has_cardinal_operations< + Lyt, std::enable_if_t, has_east, has_south, has_west>>> + : std::true_type { + }; -template -inline constexpr bool has_cardinal_operations_v = has_cardinal_operations::value; + template + inline constexpr bool has_cardinal_operations_v = has_cardinal_operations::value; #pragma endregion #pragma region has_above -template -struct has_above : std::false_type -{}; + template + struct has_above : std::false_type { + }; -template -struct has_above().above(std::declval>()))>> - : std::true_type -{}; + template + struct has_above().above(std::declval>()))>> + : std::true_type { + }; #pragma region has_north_east -template -struct has_north_east : std::false_type -{}; + template + struct has_north_east : std::false_type { + }; -template -struct has_north_east().north_east(std::declval>()))>> - : std::true_type -{}; + template + struct has_north_east().north_east(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_north_east_v = has_north_east::value; + template + inline constexpr bool has_north_east_v = has_north_east::value; #pragma endregion #pragma region has_south_east -template -struct has_south_east : std::false_type -{}; + template + struct has_south_east : std::false_type { + }; -template -struct has_south_east().south_east(std::declval>()))>> - : std::true_type -{}; + template + struct has_south_east().south_east(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_south_east_v = has_south_east::value; + template + inline constexpr bool has_south_east_v = has_south_east::value; #pragma endregion #pragma region has_south_west -template -struct has_south_west : std::false_type -{}; + template + struct has_south_west : std::false_type { + }; -template -struct has_south_west().south_west(std::declval>()))>> - : std::true_type -{}; + template + struct has_south_west().south_west(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_south_west_v = has_south_west::value; + template + inline constexpr bool has_south_west_v = has_south_west::value; #pragma endregion #pragma region has_north_west -template -struct has_north_west : std::false_type -{}; + template + struct has_north_west : std::false_type { + }; -template -struct has_north_west().north_west(std::declval>()))>> - : std::true_type -{}; + template + struct has_north_west().north_west(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_north_west_v = has_north_west::value; + template + inline constexpr bool has_north_west_v = has_north_west::value; #pragma endregion #pragma region has_ordinal_operations -template -struct has_ordinal_operations : std::false_type -{}; + template + struct has_ordinal_operations : std::false_type { + }; -template -struct has_ordinal_operations, has_south_east, - has_south_west, has_north_west>>> - : std::true_type -{}; + template + struct has_ordinal_operations, has_south_east, + has_south_west, has_north_west>>> + : std::true_type { + }; -template -inline constexpr bool has_ordinal_operations_v = has_ordinal_operations::value; + template + inline constexpr bool has_ordinal_operations_v = has_ordinal_operations::value; #pragma endregion -template -inline constexpr bool has_above_v = has_above::value; + template + inline constexpr bool has_above_v = has_above::value; #pragma endregion #pragma region has_below -template -struct has_below : std::false_type -{}; + template + struct has_below : std::false_type { + }; -template -struct has_below().below(std::declval>()))>> - : std::true_type -{}; + template + struct has_below().below(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_below_v = has_below::value; + template + inline constexpr bool has_below_v = has_below::value; #pragma endregion #pragma region has_elevation_operations -template -struct has_elevation_operations : std::false_type -{}; + template + struct has_elevation_operations : std::false_type { + }; -template -struct has_elevation_operations, has_below>>> - : std::true_type -{}; + template + struct has_elevation_operations, has_below>>> + : std::true_type { + }; -template -inline constexpr bool has_elevation_operations_v = has_elevation_operations::value; + template + inline constexpr bool has_elevation_operations_v = has_elevation_operations::value; #pragma endregion #pragma region is_coordinate_layout -template -struct is_coordinate_layout : std::false_type -{}; - -template -struct is_coordinate_layout< - Lyt, - std::enable_if_t< - std::conjunction_v, coordinate>, has_cardinal_operations, - has_elevation_operations>, - std::void_t, coordinate, typename Lyt::storage, - decltype(Lyt::max_fanin_size), decltype(Lyt::min_fanin_size), decltype(std::declval().x()), - decltype(std::declval().y()), decltype(std::declval().z()), - decltype(std::declval().area()), decltype(std::declval().resize(aspect_ratio()))>>> - : std::true_type -{}; - -template -inline constexpr bool is_coordinate_layout_v = is_coordinate_layout::value; + template + struct is_coordinate_layout : std::false_type { + }; + + template + struct is_coordinate_layout< + Lyt, + std::enable_if_t< + std::conjunction_v, coordinate>, has_cardinal_operations, + has_elevation_operations>, + std::void_t, coordinate, typename Lyt::storage, + decltype(Lyt::max_fanin_size), decltype(Lyt::min_fanin_size), decltype(std::declval().x()), + decltype(std::declval().y()), decltype(std::declval().z()), + decltype(std::declval().area()), decltype(std::declval().resize( + aspect_ratio()))>>> + : std::true_type { + }; + + template + inline constexpr bool is_coordinate_layout_v = is_coordinate_layout::value; #pragma endregion #pragma region has_foreach_coordinate -template -struct has_foreach_coordinate : std::false_type -{}; + template + struct has_foreach_coordinate : std::false_type { + }; -template -struct has_foreach_coordinate< - Lyt, std::void_t().foreach_coordinate(std::declval, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_coordinate< + Lyt, std::void_t().foreach_coordinate( + std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_coordinate_v = has_foreach_coordinate::value; + template + inline constexpr bool has_foreach_coordinate_v = has_foreach_coordinate::value; #pragma endregion #pragma region has_foreach_adjacent_coordinate -template -struct has_foreach_adjacent_coordinate : std::false_type -{}; + template + struct has_foreach_adjacent_coordinate : std::false_type { + }; -template -struct has_foreach_adjacent_coordinate< - Lyt, std::void_t().foreach_adjacent_coordinate( - std::declval>(), std::declval, uint32_t)>()))>> : std::true_type -{}; + template + struct has_foreach_adjacent_coordinate< + Lyt, std::void_t().foreach_adjacent_coordinate( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_adjacent_coordinate_v = has_foreach_adjacent_coordinate::value; + template + inline constexpr bool has_foreach_adjacent_coordinate_v = has_foreach_adjacent_coordinate::value; #pragma endregion #pragma region has_foreach_adjacent_opposite_coordinates -template -struct has_foreach_adjacent_opposite_coordinates : std::false_type -{}; + template + struct has_foreach_adjacent_opposite_coordinates : std::false_type { + }; -template -struct has_foreach_adjacent_opposite_coordinates< - Lyt, std::void_t().foreach_adjacent_opposite_coordinates( - std::declval>(), std::declval, uint32_t)>()))>> : std::true_type -{}; + template + struct has_foreach_adjacent_opposite_coordinates< + Lyt, std::void_t().foreach_adjacent_opposite_coordinates( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_adjacent_opposite_coordinates_v = - has_foreach_adjacent_opposite_coordinates::value; + template + inline constexpr bool has_foreach_adjacent_opposite_coordinates_v = + has_foreach_adjacent_opposite_coordinates::value; #pragma endregion #pragma region is_cartesian_layout -template -struct is_cartesian_layout : std::false_type -{}; + template + struct is_cartesian_layout : std::false_type { + }; -template -struct is_cartesian_layout< - Lyt, - std::enable_if_t && Lyt::max_fanin_size == 3u, - std::void_t, coordinate, typename Lyt::storage>>> - : std::true_type -{}; + template + struct is_cartesian_layout< + Lyt, + std::enable_if_t && Lyt::max_fanin_size == 3u, + std::void_t, coordinate, typename Lyt::storage>>> + : std::true_type { + }; -template -inline constexpr bool is_cartesian_layout_v = is_cartesian_layout::value; + template + inline constexpr bool is_cartesian_layout_v = is_cartesian_layout::value; #pragma endregion #pragma region is_shifted_cartesian_layout -template -struct is_shifted_cartesian_layout : std::false_type -{}; + template + struct is_shifted_cartesian_layout : std::false_type { + }; -template -struct is_shifted_cartesian_layout< - Lyt, std::enable_if_t && has_ordinal_operations_v && Lyt::max_fanin_size == 5u, - std::void_t, - coordinate, typename Lyt::storage>>> : std::true_type -{}; + template + struct is_shifted_cartesian_layout< + Lyt, std::enable_if_t< + is_coordinate_layout_v && has_ordinal_operations_v && Lyt::max_fanin_size == 5u, + std::void_t, + coordinate, typename Lyt::storage>>> : std::true_type { + }; -template -inline constexpr bool is_shifted_cartesian_layout_v = is_shifted_cartesian_layout::value; + template + inline constexpr bool is_shifted_cartesian_layout_v = is_shifted_cartesian_layout::value; #pragma endregion #pragma region shifted cartesian orientation and arrangement -template -constexpr bool has_horizontally_shifted_cartesian_orientation_v = - std::is_same_v; -template -constexpr bool has_vertically_shifted_cartesian_orientation_v = - std::is_same_v; -template -constexpr bool has_odd_row_cartesian_arrangement_v = - std::is_same_v; -template -constexpr bool has_even_row_cartesian_arrangement_v = - std::is_same_v; -template -constexpr bool has_odd_column_cartesian_arrangement_v = - std::is_same_v; -template -constexpr bool has_even_column_cartesian_arrangement_v = - std::is_same_v; + template + constexpr bool has_horizontally_shifted_cartesian_orientation_v = + std::is_same_v; + template + constexpr bool has_vertically_shifted_cartesian_orientation_v = + std::is_same_v; + template + constexpr bool has_odd_row_cartesian_arrangement_v = + std::is_same_v; + template + constexpr bool has_even_row_cartesian_arrangement_v = + std::is_same_v; + template + constexpr bool has_odd_column_cartesian_arrangement_v = + std::is_same_v; + template + constexpr bool has_even_column_cartesian_arrangement_v = + std::is_same_v; #pragma endregion #pragma region is_hexagonal_layout -template -struct is_hexagonal_layout : std::false_type -{}; + template + struct is_hexagonal_layout : std::false_type { + }; -template -struct is_hexagonal_layout && is_coordinate_layout_v && - has_ordinal_operations_v && Lyt::max_fanin_size == 5u, - std::void_t, coordinate, typename Lyt::storage>>> - : std::true_type -{}; + template + struct is_hexagonal_layout && is_coordinate_layout_v && + has_ordinal_operations_v && Lyt::max_fanin_size == 5u, + std::void_t, coordinate, typename Lyt::storage>>> + : std::true_type { + }; -template -inline constexpr bool is_hexagonal_layout_v = is_hexagonal_layout::value; + template + inline constexpr bool is_hexagonal_layout_v = is_hexagonal_layout::value; #pragma endregion #pragma region hexagonal orientation and arrangement -template -inline constexpr const bool has_pointy_top_hex_orientation_v = - std::is_same_v; -template -inline constexpr const bool has_flat_top_hex_orientation_v = - std::is_same_v; -template -inline constexpr const bool has_odd_row_hex_arrangement_v = std::is_same_v; -template -inline constexpr const bool has_even_row_hex_arrangement_v = - std::is_same_v; -template -inline constexpr const bool has_odd_column_hex_arrangement_v = - std::is_same_v; -template -inline constexpr const bool has_even_column_hex_arrangement_v = - std::is_same_v; + template + inline constexpr const bool has_pointy_top_hex_orientation_v = + std::is_same_v; + template + inline constexpr const bool has_flat_top_hex_orientation_v = + std::is_same_v; + template + inline constexpr const bool has_odd_row_hex_arrangement_v = std::is_same_v; + template + inline constexpr const bool has_even_row_hex_arrangement_v = + std::is_same_v; + template + inline constexpr const bool has_odd_column_hex_arrangement_v = + std::is_same_v; + template + inline constexpr const bool has_even_column_hex_arrangement_v = + std::is_same_v; #pragma endregion /** * Tile-based layouts */ -template -using tile = typename Lyt::tile; + template + using tile = typename Lyt::tile; #pragma region is_tile_based_layout -template -struct is_tile_based_layout : std::false_type -{}; + template + struct is_tile_based_layout : std::false_type { + }; -template -struct is_tile_based_layout, - std::void_t, typename Lyt::storage>>> - : std::true_type -{}; + template + struct is_tile_based_layout, + std::void_t, typename Lyt::storage>>> + : std::true_type { + }; -template -inline constexpr bool is_tile_based_layout_v = is_tile_based_layout::value; + template + inline constexpr bool is_tile_based_layout_v = is_tile_based_layout::value; #pragma endregion #pragma region has_foreach_tile -template -struct has_foreach_tile : std::false_type -{}; + template + struct has_foreach_tile : std::false_type { + }; -template -struct has_foreach_tile< - Lyt, std::void_t().foreach_tile(std::declval, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_tile< + Lyt, std::void_t().foreach_tile(std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_tile_v = has_foreach_tile::value; + template + inline constexpr bool has_foreach_tile_v = has_foreach_tile::value; #pragma endregion #pragma region has_foreach_adjacent_tile -template -struct has_foreach_adjacent_tile : std::false_type -{}; + template + struct has_foreach_adjacent_tile : std::false_type { + }; -template -struct has_foreach_adjacent_tile().foreach_adjacent_tile( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_adjacent_tile().foreach_adjacent_tile( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_adjacent_tile_v = has_foreach_adjacent_tile::value; + template + inline constexpr bool has_foreach_adjacent_tile_v = has_foreach_adjacent_tile::value; #pragma endregion #pragma region has_foreach_adjacent_opposite_tiles -template -struct has_foreach_adjacent_opposite_tiles : std::false_type -{}; + template + struct has_foreach_adjacent_opposite_tiles : std::false_type { + }; -template -struct has_foreach_adjacent_opposite_tiles().foreach_adjacent_opposite_tiles( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_adjacent_opposite_tiles().foreach_adjacent_opposite_tiles( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_adjacent_opposite_tiles_v = has_foreach_adjacent_opposite_tiles::value; + template + inline constexpr bool has_foreach_adjacent_opposite_tiles_v = has_foreach_adjacent_opposite_tiles::value; #pragma endregion /** * Clocked layouts */ -template -using clock_zone = typename Lyt::clock_zone; + template + using clock_zone = typename Lyt::clock_zone; #pragma region is_clocked_layout -template -struct is_clocked_layout : std::false_type -{}; - -template -struct is_clocked_layout< - Lyt, std::enable_if_t, - std::void_t, typename Lyt::clocking_scheme_t, - typename Lyt::clock_number_t, typename Lyt::degree_t, typename Lyt::storage, - decltype(std::declval().get_clock_number(clock_zone())), - decltype(std::declval().num_clocks()), - decltype(std::declval().is_regularly_clocked()), - decltype(std::declval().is_clocking_scheme(std::string()))>>> - : std::true_type -{}; - -template -inline constexpr bool is_clocked_layout_v = is_clocked_layout::value; + template + struct is_clocked_layout : std::false_type { + }; + + template + struct is_clocked_layout< + Lyt, std::enable_if_t, + std::void_t, typename Lyt::clocking_scheme_t, + typename Lyt::clock_number_t, typename Lyt::degree_t, typename Lyt::storage, + decltype(std::declval().get_clock_number(clock_zone())), + decltype(std::declval().num_clocks()), + decltype(std::declval().is_regularly_clocked()), + decltype(std::declval().is_clocking_scheme(std::string()))>>> + : std::true_type { + }; + + template + inline constexpr bool is_clocked_layout_v = is_clocked_layout::value; #pragma endregion #pragma region has_is_incoming_clocked -template -struct has_is_incoming_clocked : std::false_type -{}; + template + struct has_is_incoming_clocked : std::false_type { + }; -template -struct has_is_incoming_clocked().is_incoming_clocked( - std::declval>(), std::declval>()))>> - : std::true_type -{}; + template + struct has_is_incoming_clocked().is_incoming_clocked( + std::declval>(), std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_incoming_clocked_v = has_is_incoming_clocked::value; + template + inline constexpr bool has_is_incoming_clocked_v = has_is_incoming_clocked::value; #pragma endregion #pragma region has_foreach_incoming_clocked_zone -template -struct has_foreach_incoming_clocked_zone : std::false_type -{}; + template + struct has_foreach_incoming_clocked_zone : std::false_type { + }; -template -struct has_foreach_incoming_clocked_zone< - Lyt, std::void_t().foreach_incoming_clocked_zone( - std::declval>(), std::declval, uint32_t)>()))>> : std::true_type -{}; + template + struct has_foreach_incoming_clocked_zone< + Lyt, std::void_t().foreach_incoming_clocked_zone( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_incoming_clocked_zone_v = has_foreach_incoming_clocked_zone::value; + template + inline constexpr bool has_foreach_incoming_clocked_zone_v = has_foreach_incoming_clocked_zone::value; #pragma endregion #pragma region has_is_outgoing_clocked -template -struct has_is_outgoing_clocked : std::false_type -{}; + template + struct has_is_outgoing_clocked : std::false_type { + }; -template -struct has_is_outgoing_clocked().is_outgoing_clocked( - std::declval>(), std::declval>()))>> - : std::true_type -{}; + template + struct has_is_outgoing_clocked().is_outgoing_clocked( + std::declval>(), std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_outgoing_clocked_v = has_is_outgoing_clocked::value; + template + inline constexpr bool has_is_outgoing_clocked_v = has_is_outgoing_clocked::value; #pragma endregion #pragma region has_foreach_outgoing_clocked_zone -template -struct has_foreach_outgoing_clocked_zone : std::false_type -{}; + template + struct has_foreach_outgoing_clocked_zone : std::false_type { + }; -template -struct has_foreach_outgoing_clocked_zone< - Lyt, std::void_t().foreach_outgoing_clocked_zone( - std::declval>(), std::declval, uint32_t)>()))>> : std::true_type -{}; + template + struct has_foreach_outgoing_clocked_zone< + Lyt, std::void_t().foreach_outgoing_clocked_zone( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_outgoing_clocked_zone_v = has_foreach_outgoing_clocked_zone::value; + template + inline constexpr bool has_foreach_outgoing_clocked_zone_v = has_foreach_outgoing_clocked_zone::value; #pragma endregion #pragma region has_synchronization_elements -template -struct has_synchronization_elements : std::false_type -{}; - -template -struct has_synchronization_elements< - Lyt, std::enable_if_t< - is_clocked_layout_v, - std::void_t().assign_synchronization_element( - std::declval>(), std::declval())), - decltype(std::declval().is_synchronization_element(std::declval>())), - decltype(std::declval().get_synchronization_element(std::declval>())), - decltype(std::declval().num_se())>>> : std::true_type -{}; - -template -inline constexpr bool has_synchronization_elements_v = has_synchronization_elements::value; + template + struct has_synchronization_elements : std::false_type { + }; + + template + struct has_synchronization_elements< + Lyt, std::enable_if_t< + is_clocked_layout_v, + std::void_t().assign_synchronization_element( + std::declval>(), std::declval())), + decltype(std::declval().is_synchronization_element(std::declval>())), + decltype(std::declval().get_synchronization_element(std::declval>())), + decltype(std::declval().num_se())>>> : std::true_type { + }; + + template + inline constexpr bool has_synchronization_elements_v = has_synchronization_elements::value; #pragma endregion /** * Cell-level layouts */ -template -using cell = typename Lyt::cell; - -template -using technology = typename Lyt::technology; - -template -inline constexpr const bool has_qca_technology_v = std::is_same_v, qca_technology>; -template -inline constexpr const bool has_inml_technology_v = std::is_same_v, inml_technology>; -template -inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; -template -inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; -template -inline constexpr const bool has_cube_coord_v = std::is_same_v, cube::coord_t>; -template -inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; + template + using cell = typename Lyt::cell; + + template + using technology = typename Lyt::technology; + + template + inline constexpr const bool has_qca_technology_v = std::is_same_v, qca_technology>; + template + inline constexpr const bool has_inml_technology_v = std::is_same_v, inml_technology>; + template + inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; + template + inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; + template + inline constexpr const bool has_cube_coord_v = std::is_same_v, cube::coord_t>; + template + inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; #pragma region is_cell_level_layout -template -struct is_cell_level_layout : std::false_type -{}; - -template -struct is_cell_level_layout< - Lyt, - std::enable_if_t, - std::void_t, typename Lyt::cell_type, typename Lyt::cell_mode, - technology, typename Lyt::storage, - decltype(std::declval().assign_cell_type(cell(), typename Lyt::cell_type())), - decltype(std::declval().get_cell_type(cell())), - decltype(std::declval().is_empty_cell(cell())), - decltype(std::declval().assign_cell_mode(cell(), typename Lyt::cell_mode())), - decltype(std::declval().get_cell_mode(cell())), - decltype(std::declval().assign_cell_name(cell(), std::string())), - decltype(std::declval().get_cell_name(cell()))>>> : std::true_type -{}; - -template -inline constexpr bool is_cell_level_layout_v = is_cell_level_layout::value; + template + struct is_cell_level_layout : std::false_type { + }; + + template + struct is_cell_level_layout< + Lyt, + std::enable_if_t, + std::void_t, typename Lyt::cell_type, typename Lyt::cell_mode, + technology, typename Lyt::storage, + decltype(std::declval().assign_cell_type(cell(), typename Lyt::cell_type())), + decltype(std::declval().get_cell_type(cell())), + decltype(std::declval().is_empty_cell(cell())), + decltype(std::declval().assign_cell_mode(cell(), typename Lyt::cell_mode())), + decltype(std::declval().get_cell_mode(cell())), + decltype(std::declval().assign_cell_name(cell(), std::string())), + decltype(std::declval().get_cell_name(cell()))>>> : std::true_type { + }; + + template + inline constexpr bool is_cell_level_layout_v = is_cell_level_layout::value; #pragma endregion #pragma region has_is_empty_cell -template -struct has_is_empty_cell : std::false_type -{}; + template + struct has_is_empty_cell : std::false_type { + }; -template -struct has_is_empty_cell().is_empty_cell(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_empty_cell().is_empty_cell(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_empty_cell_v = has_is_empty_cell::value; + template + inline constexpr bool has_is_empty_cell_v = has_is_empty_cell::value; #pragma endregion #pragma region has_foreach_cell -template -struct has_foreach_cell : std::false_type -{}; + template + struct has_foreach_cell : std::false_type { + }; -template -struct has_foreach_cell< - Lyt, std::void_t().foreach_cell(std::declval, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_cell< + Lyt, std::void_t().foreach_cell(std::declval, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_cell_v = has_foreach_cell::value; + template + inline constexpr bool has_foreach_cell_v = has_foreach_cell::value; #pragma endregion #pragma region has_set_layout_name -template -struct has_set_layout_name : std::false_type -{}; + template + struct has_set_layout_name : std::false_type { + }; -template -struct has_set_layout_name().set_layout_name(std::string()))>> - : std::true_type -{}; + template + struct has_set_layout_name().set_layout_name(std::string()))>> + : std::true_type { + }; -template -inline constexpr bool has_set_layout_name_v = has_set_layout_name::value; + template + inline constexpr bool has_set_layout_name_v = has_set_layout_name::value; #pragma endregion #pragma region has_get_layout_name -template -struct has_get_layout_name : std::false_type -{}; + template + struct has_get_layout_name : std::false_type { + }; -template -struct has_get_layout_name().get_layout_name())>> : std::true_type -{}; + template + struct has_get_layout_name().get_layout_name())>> : std::true_type { + }; -template -inline constexpr bool has_get_layout_name_v = has_get_layout_name::value; + template + inline constexpr bool has_get_layout_name_v = has_get_layout_name::value; #pragma endregion #pragma region has_assign_sidb_defect -template -struct has_assign_sidb_defect : std::false_type -{}; + template + struct has_assign_sidb_defect : std::false_type { + }; -template -struct has_assign_sidb_defect< - Lyt, std::void_t().assign_sidb_defect(coordinate(), sidb_defect()))>> - : std::true_type -{}; + template + struct has_assign_sidb_defect< + Lyt, std::void_t().assign_sidb_defect(coordinate(), sidb_defect()))>> + : std::true_type { + }; -template -inline constexpr bool has_assign_sidb_defect_v = has_assign_sidb_defect::value; + template + inline constexpr bool has_assign_sidb_defect_v = has_assign_sidb_defect::value; #pragma endregion #pragma region has_get_sidb_defect -template -struct has_get_sidb_defect : std::false_type -{}; + template + struct has_get_sidb_defect : std::false_type { + }; -template -struct has_get_sidb_defect().get_sidb_defect(coordinate()))>> - : std::true_type -{}; + template + struct has_get_sidb_defect().get_sidb_defect(coordinate()))>> + : std::true_type { + }; -template -inline constexpr bool has_get_sidb_defect_v = has_get_sidb_defect::value; + template + inline constexpr bool has_get_sidb_defect_v = has_get_sidb_defect::value; #pragma endregion #pragma region has_foreach_sidb_defect -template -struct has_foreach_sidb_defect : std::false_type -{}; + template + struct has_foreach_sidb_defect : std::false_type { + }; -template -struct has_foreach_sidb_defect().foreach_sidb_defect( - std::declval, sidb_defect>, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_sidb_defect().foreach_sidb_defect( + std::declval, sidb_defect>, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_sidb_defect_v = has_foreach_sidb_defect::value; + template + inline constexpr bool has_foreach_sidb_defect_v = has_foreach_sidb_defect::value; #pragma endregion #pragma region has_assign_charge_state -template -struct has_assign_charge_state : std::false_type -{}; + template + struct has_assign_charge_state : std::false_type { + }; -template -struct has_assign_charge_state< - Lyt, std::void_t().assign_charge_state(coordinate(), sidb_charge_state()))>> - : std::true_type -{}; + template + struct has_assign_charge_state< + Lyt, std::void_t().assign_charge_state(coordinate(), sidb_charge_state()))>> + : std::true_type { + }; -template -inline constexpr bool has_assign_charge_state_v = has_assign_charge_state::value; + template + inline constexpr bool has_assign_charge_state_v = has_assign_charge_state::value; #pragma endregion #pragma region has_get_charge_state -template -struct has_get_charge_state : std::false_type -{}; + template + struct has_get_charge_state : std::false_type { + }; -template -struct has_get_charge_state().get_charge_state(coordinate()))>> - : std::true_type -{}; + template + struct has_get_charge_state().get_charge_state(coordinate()))>> + : std::true_type { + }; -template -inline constexpr bool has_get_charge_state_v = has_get_charge_state::value; + template + inline constexpr bool has_get_charge_state_v = has_get_charge_state::value; #pragma endregion #pragma region has_foreach_charge_state -template -struct has_foreach_charge_state : std::false_type -{}; + template + struct has_foreach_charge_state : std::false_type { + }; -template -struct has_foreach_charge_state().foreach_charge_state( - std::declval, sidb_charge_state>, uint32_t)>()))>> - : std::true_type -{}; + template + struct has_foreach_charge_state().foreach_charge_state( + std::declval, sidb_charge_state>, uint32_t)>()))>> + : std::true_type { + }; -template -inline constexpr bool has_foreach_charge_state_v = has_foreach_charge_state::value; + template + inline constexpr bool has_foreach_charge_state_v = has_foreach_charge_state::value; #pragma endregion /** @@ -754,73 +762,73 @@ inline constexpr bool has_foreach_charge_state_v = has_foreach_charge_state */ #pragma region is_gate_level_layout -template -struct is_gate_level_layout : std::false_type -{}; + template + struct is_gate_level_layout : std::false_type { + }; -template -struct is_gate_level_layout< - Lyt, std::enable_if_t, mockturtle::is_network_type>, - std::void_t, typename Lyt::storage>>> : std::true_type -{}; + template + struct is_gate_level_layout< + Lyt, std::enable_if_t, mockturtle::is_network_type>, + std::void_t, typename Lyt::storage>>> : std::true_type { + }; -template -inline constexpr bool is_gate_level_layout_v = is_gate_level_layout::value; + template + inline constexpr bool is_gate_level_layout_v = is_gate_level_layout::value; #pragma endregion #pragma region has_is_gate_tile -template -struct has_is_gate_tile : std::false_type -{}; + template + struct has_is_gate_tile : std::false_type { + }; -template -struct has_is_gate_tile().is_gate_tile(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_gate_tile().is_gate_tile(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_gate_tile_v = has_is_gate_tile::value; + template + inline constexpr bool has_is_gate_tile_v = has_is_gate_tile::value; #pragma endregion #pragma region has_is_wire_tile -template -struct has_is_wire_tile : std::false_type -{}; + template + struct has_is_wire_tile : std::false_type { + }; -template -struct has_is_wire_tile().is_wire_tile(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_wire_tile().is_wire_tile(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_wire_tile_v = has_is_wire_tile::value; + template + inline constexpr bool has_is_wire_tile_v = has_is_wire_tile::value; #pragma endregion #pragma region has_is_empty_tile -template -struct has_is_empty_tile : std::false_type -{}; + template + struct has_is_empty_tile : std::false_type { + }; -template -struct has_is_empty_tile().is_empty_tile(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_empty_tile().is_empty_tile(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_empty_tile_v = has_is_empty_tile::value; + template + inline constexpr bool has_is_empty_tile_v = has_is_empty_tile::value; #pragma endregion #pragma region has_is_empty -template -struct has_is_empty : std::false_type -{}; + template + struct has_is_empty : std::false_type { + }; -template -struct has_is_empty().is_empty())>> : std::true_type -{}; + template + struct has_is_empty().is_empty())>> : std::true_type { + }; -template -inline constexpr bool has_is_empty_v = has_is_empty::value; + template + inline constexpr bool has_is_empty_v = has_is_empty::value; #pragma endregion /** @@ -828,33 +836,33 @@ inline constexpr bool has_is_empty_v = has_is_empty::value; */ #pragma region has_is_obstructed_coordinate -template -struct has_is_obstructed_coordinate : std::false_type -{}; + template + struct has_is_obstructed_coordinate : std::false_type { + }; -template -struct has_is_obstructed_coordinate< - Lyt, std::void_t().is_obstructed_coordinate(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_obstructed_coordinate< + Lyt, std::void_t().is_obstructed_coordinate(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_obstructed_coordinate_v = has_is_obstructed_coordinate::value; + template + inline constexpr bool has_is_obstructed_coordinate_v = has_is_obstructed_coordinate::value; #pragma endregion #pragma region has_is_obstructed_connection -template -struct has_is_obstructed_connection : std::false_type -{}; + template + struct has_is_obstructed_connection : std::false_type { + }; -template -struct has_is_obstructed_connection().is_obstructed_connection( - std::declval>(), std::declval>()))>> - : std::true_type -{}; + template + struct has_is_obstructed_connection().is_obstructed_connection( + std::declval>(), std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_obstructed_connection_v = has_is_obstructed_connection::value; + template + inline constexpr bool has_is_obstructed_connection_v = has_is_obstructed_connection::value; #pragma endregion /** @@ -862,53 +870,53 @@ inline constexpr bool has_is_obstructed_connection_v = has_is_obstructed_connect */ #pragma region has_get_functional_implementations -template -struct has_get_functional_implementations : std::false_type -{}; + template + struct has_get_functional_implementations : std::false_type { + }; -template -struct has_get_functional_implementations< - Lib, std::enable_if_t().get_functional_implementations()), - typename Lib::gate_functions>>> : std::true_type -{}; + template + struct has_get_functional_implementations< + Lib, std::enable_if_t().get_functional_implementations()), + typename Lib::gate_functions>>> : std::true_type { + }; -template -inline constexpr bool has_get_functional_implementations_v = has_get_functional_implementations::value; + template + inline constexpr bool has_get_functional_implementations_v = has_get_functional_implementations::value; #pragma endregion #pragma region has_get_gate_ports -template -struct has_get_gate_ports : std::false_type -{}; + template + struct has_get_gate_ports : std::false_type { + }; -template -struct has_get_gate_ports().get_gate_ports()), - typename Lib::template gate_ports> || - std::is_same_v().get_gate_ports()), - typename Lib::template gate_ports>>> - : std::true_type -{}; + template + struct has_get_gate_ports().get_gate_ports()), + typename Lib::template gate_ports> || + std::is_same_v().get_gate_ports()), + typename Lib::template gate_ports>>> + : std::true_type { + }; -template -inline constexpr bool has_get_gate_ports_v = has_get_gate_ports::value; + template + inline constexpr bool has_get_gate_ports_v = has_get_gate_ports::value; #pragma endregion #pragma region has_post_layout_optimization -template -struct has_post_layout_optimization : std::false_type -{}; + template + struct has_post_layout_optimization : std::false_type { + }; -template -struct has_post_layout_optimization< - Lib, Lyt, - std::enable_if_t, std::is_same, technology>>, - std::void_t().post_layout_optimization(std::declval))>>> - : std::true_type -{}; + template + struct has_post_layout_optimization< + Lib, Lyt, + std::enable_if_t, std::is_same, technology>>, + std::void_t().post_layout_optimization(std::declval))>>> + : std::true_type { + }; -template -inline constexpr bool has_post_layout_optimization_v = has_post_layout_optimization::value; + template + inline constexpr bool has_post_layout_optimization_v = has_post_layout_optimization::value; #pragma endregion /** @@ -916,228 +924,234 @@ inline constexpr bool has_post_layout_optimization_v = has_post_layout_optimizat */ #pragma region has_is_po -template -struct has_is_po : std::false_type -{}; + template + struct has_is_po : std::false_type { + }; -template -struct has_is_po().is_po(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_po().is_po(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_po_v = has_is_po::value; + template + inline constexpr bool has_is_po_v = has_is_po::value; #pragma endregion #pragma region has_is_buf -template -struct has_is_buf : std::false_type -{}; + template + struct has_is_buf : std::false_type { + }; -template -struct has_is_buf().is_buf(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_buf().is_buf(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_buf_v = has_is_buf::value; + template + inline constexpr bool has_is_buf_v = has_is_buf::value; #pragma endregion #pragma region has_is_inv -template -struct has_is_inv : std::false_type -{}; + template + struct has_is_inv : std::false_type { + }; -template -struct has_is_inv().is_inv(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_inv().is_inv(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_inv_v = has_is_inv::value; + template + inline constexpr bool has_is_inv_v = has_is_inv::value; #pragma endregion #pragma region has_is_fanout -template -struct has_is_fanout : std::false_type -{}; + template + struct has_is_fanout : std::false_type { + }; -template -struct has_is_fanout().is_fanout(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_fanout().is_fanout( + std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_fanout_v = has_is_fanout::value; + template + inline constexpr bool has_is_fanout_v = has_is_fanout::value; #pragma endregion #pragma region has_is_nand -template -struct has_is_nand : std::false_type -{}; + template + struct has_is_nand : std::false_type { + }; -template -struct has_is_nand().is_nand(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_nand().is_nand(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_nand_v = has_is_nand::value; + template + inline constexpr bool has_is_nand_v = has_is_nand::value; #pragma endregion #pragma region has_is_nor -template -struct has_is_nor : std::false_type -{}; + template + struct has_is_nor : std::false_type { + }; -template -struct has_is_nor().is_nor(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_nor().is_nor(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_nor_v = has_is_nor::value; + template + inline constexpr bool has_is_nor_v = has_is_nor::value; #pragma endregion #pragma region has_is_xnor -template -struct has_is_xnor : std::false_type -{}; + template + struct has_is_xnor : std::false_type { + }; -template -struct has_is_xnor().is_xnor(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_xnor().is_xnor(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_xnor_v = has_is_xnor::value; + template + inline constexpr bool has_is_xnor_v = has_is_xnor::value; #pragma endregion #pragma region has_is_and3 -template -struct has_is_and3 : std::false_type -{}; + template + struct has_is_and3 : std::false_type { + }; -template -struct has_is_and3().is_and3(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_and3().is_and3(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_and3_v = has_is_and3::value; + template + inline constexpr bool has_is_and3_v = has_is_and3::value; #pragma endregion #pragma region has_is_xor_and -template -struct has_is_xor_and : std::false_type -{}; + template + struct has_is_xor_and : std::false_type { + }; -template -struct has_is_xor_and().is_xor_and(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_xor_and().is_xor_and( + std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_xor_and_v = has_is_xor_and::value; + template + inline constexpr bool has_is_xor_and_v = has_is_xor_and::value; #pragma endregion #pragma region has_is_or_and -template -struct has_is_or_and : std::false_type -{}; + template + struct has_is_or_and : std::false_type { + }; -template -struct has_is_or_and().is_or_and(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_or_and().is_or_and( + std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_or_and_v = has_is_or_and::value; + template + inline constexpr bool has_is_or_and_v = has_is_or_and::value; #pragma endregion #pragma region has_is_onehot -template -struct has_is_onehot : std::false_type -{}; + template + struct has_is_onehot : std::false_type { + }; -template -struct has_is_onehot().is_onehot(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_onehot().is_onehot( + std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_onehot_v = has_is_onehot::value; + template + inline constexpr bool has_is_onehot_v = has_is_onehot::value; #pragma endregion #pragma region has_is_gamble -template -struct has_is_gamble : std::false_type -{}; + template + struct has_is_gamble : std::false_type { + }; -template -struct has_is_gamble().is_gamble(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_gamble().is_gamble( + std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_gamble_v = has_is_gamble::value; + template + inline constexpr bool has_is_gamble_v = has_is_gamble::value; #pragma endregion #pragma region has_create_dot -template -struct has_create_dot : std::false_type -{}; + template + struct has_create_dot : std::false_type { + }; -template -struct has_create_dot().create_dot( - std::declval>(), std::declval>(), - std::declval>()))>> : std::true_type -{}; + template + struct has_create_dot().create_dot( + std::declval>(), std::declval>(), + std::declval>()))>> : std::true_type { + }; -template -inline constexpr bool has_create_dot_v = has_create_dot::value; + template + inline constexpr bool has_create_dot_v = has_create_dot::value; #pragma endregion #pragma region has_is_dot -template -struct has_is_dot : std::false_type -{}; + template + struct has_is_dot : std::false_type { + }; -template -struct has_is_dot().is_dot(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_dot().is_dot(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_dot_v = has_is_dot::value; + template + inline constexpr bool has_is_dot_v = has_is_dot::value; #pragma endregion #pragma region has_is_mux -template -struct has_is_mux : std::false_type -{}; + template + struct has_is_mux : std::false_type { + }; -template -struct has_is_mux().is_mux(std::declval>()))>> - : std::true_type -{}; + template + struct has_is_mux().is_mux(std::declval>()))>> + : std::true_type { + }; -template -inline constexpr bool has_is_mux_v = has_is_mux::value; + template + inline constexpr bool has_is_mux_v = has_is_mux::value; #pragma endregion #pragma region has_is_and_xor -template -struct has_is_and_xor : std::false_type -{}; - -template -struct has_is_and_xor().is_and_xor(std::declval>()))>> - : std::true_type -{}; - -template -inline constexpr bool has_is_and_xor_v = has_is_and_xor::value; + template + struct has_is_and_xor : std::false_type { + }; + + template + struct has_is_and_xor().is_and_xor( + std::declval>()))>> + : std::true_type { + }; + + template + inline constexpr bool has_is_and_xor_v = has_is_and_xor::value; #pragma endregion } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index d9461836c..975e6e594 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -15,8 +15,7 @@ #include #include -namespace fiction -{ +namespace fiction { /** * Returns the number of adjacent coordinates of a given one. This is not a constant value because `c` could be located @@ -27,13 +26,13 @@ namespace fiction * @param c Coordinate whose number of adjacencies are required. * @return Number of `c`'s adjacent coordinates. */ -template -[[nodiscard]] uint8_t num_adjacent_coordinates(const Lyt& lyt, const coordinate& c) noexcept -{ - static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); + template + [[nodiscard]] uint8_t num_adjacent_coordinates(const Lyt &lyt, const coordinate &c) noexcept { + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); + + return static_cast(lyt.adjacent_coordinates(c).size()); + } - return static_cast(lyt.adjacent_coordinates(c).size()); -} /** * Converts a relative cell position within a tile to an absolute cell position within a layout. To compute the absolute * position, the layout topology is taken into account. @@ -47,126 +46,94 @@ template * @param relative_c Relative cell position within t. * @return Absolute cell position in a layout. */ -template -[[nodiscard]] cell relative_to_absolute_cell_position(const GateLyt& gate_lyt, const tile& t, - const cell& relative_c) noexcept -{ - static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + template + [[nodiscard]] cell relative_to_absolute_cell_position(const GateLyt &gate_lyt, const tile &t, + const cell &relative_c) noexcept { + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - assert(relative_c.x < GateSizeX && relative_c.y < GateSizeY && - "relative_c must be within the bounds of a single tile"); + assert(relative_c.x < GateSizeX && relative_c.y < GateSizeY && + "relative_c must be within the bounds of a single tile"); - cell absolute_c{}; + cell absolute_c{}; - // Cartesian layouts - if constexpr (is_cartesian_layout_v) - { - absolute_c = {t.x * GateSizeX, t.y * GateSizeY, t.z}; - } - // shifted Cartesian layouts - else if constexpr (is_shifted_cartesian_layout_v) - { - if constexpr (has_horizontally_shifted_cartesian_orientation_v) - { - absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY)), t.z}; - } - else if constexpr (has_vertically_shifted_cartesian_orientation_v) - { - absolute_c = {static_cast(t.x * (GateSizeX)), t.y * (GateSizeY), t.z}; - } - - if constexpr (has_odd_row_cartesian_arrangement_v) - { - if (gate_lyt.is_in_odd_row(t)) - { - // odd rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); - } + // Cartesian layouts + if constexpr (is_cartesian_layout_v) { + absolute_c = {t.x * GateSizeX, t.y * GateSizeY, t.z}; } - else if constexpr (has_even_row_cartesian_arrangement_v) - { - if (gate_lyt.is_in_even_row(t)) - { - // even rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + // shifted Cartesian layouts + else if constexpr (is_shifted_cartesian_layout_v) { + if constexpr (has_horizontally_shifted_cartesian_orientation_v) { + absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY)), t.z}; + } else if constexpr (has_vertically_shifted_cartesian_orientation_v) { + absolute_c = {static_cast(t.x * (GateSizeX)), t.y * (GateSizeY), t.z}; } - } - else if constexpr (has_odd_column_cartesian_arrangement_v) - { - if (gate_lyt.is_in_odd_column(t)) - { - // odd columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } - } - else if constexpr (has_even_column_cartesian_arrangement_v) - { - if (gate_lyt.is_in_even_column(t)) - { - // even columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } - } - } - // hexagonal layouts - else if constexpr (is_hexagonal_layout_v) - { - if constexpr (has_pointy_top_hex_orientation_v) - { - // vertical distance between pointy top hexagons is height * 3/4 - absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY * 3 / 4)), t.z}; - } - else if constexpr (has_flat_top_hex_orientation_v) - { - // horizontal distance between flat top hexagons is width * 3/4 - absolute_c = {static_cast(t.x * (GateSizeX * 3 / 4)), t.y * (GateSizeY), t.z}; - } - if constexpr (has_odd_row_hex_arrangement_v) - { - if (gate_lyt.is_in_odd_row(t)) - { - // odd rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + if constexpr (has_odd_row_cartesian_arrangement_v) { + if (gate_lyt.is_in_odd_row(t)) { + // odd rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } else if constexpr (has_even_row_cartesian_arrangement_v) { + if (gate_lyt.is_in_even_row(t)) { + // even rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } else if constexpr (has_odd_column_cartesian_arrangement_v) { + if (gate_lyt.is_in_odd_column(t)) { + // odd columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } + } else if constexpr (has_even_column_cartesian_arrangement_v) { + if (gate_lyt.is_in_even_column(t)) { + // even columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } } } - else if constexpr (has_even_row_hex_arrangement_v) - { - if (gate_lyt.is_in_even_row(t)) - { - // even rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + // hexagonal layouts + else if constexpr (is_hexagonal_layout_v) { + if constexpr (has_pointy_top_hex_orientation_v) { + // vertical distance between pointy top hexagons is height * 3/4 + absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY * 3 / 4)), t.z}; + } else if constexpr (has_flat_top_hex_orientation_v) { + // horizontal distance between flat top hexagons is width * 3/4 + absolute_c = {static_cast(t.x * (GateSizeX * 3 / 4)), t.y * (GateSizeY), t.z}; } - } - else if constexpr (has_odd_column_hex_arrangement_v) - { - if (gate_lyt.is_in_odd_column(t)) - { - // odd columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + + if constexpr (has_odd_row_hex_arrangement_v) { + if (gate_lyt.is_in_odd_row(t)) { + // odd rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } else if constexpr (has_even_row_hex_arrangement_v) { + if (gate_lyt.is_in_even_row(t)) { + // even rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } else if constexpr (has_odd_column_hex_arrangement_v) { + if (gate_lyt.is_in_odd_column(t)) { + // odd columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } + } else if constexpr (has_even_column_hex_arrangement_v) { + if (gate_lyt.is_in_even_column(t)) { + // even columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } } } - else if constexpr (has_even_column_hex_arrangement_v) - { - if (gate_lyt.is_in_even_column(t)) - { - // even columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } + // more gate-level layout types go here + else { + assert(false && "unknown gate-level layout type"); } - } - // more gate-level layout types go here - else - { - assert(false && "unknown gate-level layout type"); - } - absolute_c.x += relative_c.x; - absolute_c.y += relative_c.y; + absolute_c.x += relative_c.x; + absolute_c.y += relative_c.y; + + return absolute_c; + } - return absolute_c; -} /** * Port directions address coordinates relative to each other by specifying cardinal directions. This function converts * such a relative direction to an absolute coordinate when given a layout and a coordinate therein to consider. That @@ -179,54 +146,43 @@ template -[[nodiscard]] coordinate port_direction_to_coordinate(const Lyt& lyt, const coordinate& c, - const port_direction& port) noexcept -{ - static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); + template + [[nodiscard]] coordinate port_direction_to_coordinate(const Lyt &lyt, const coordinate &c, + const port_direction &port) noexcept { + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); - switch (port.dir) - { - case port_direction::cardinal::NORTH: - { - return lyt.north(c); - } - case port_direction::cardinal::NORTH_EAST: - { - return lyt.north_east(c); - } - case port_direction::cardinal::EAST: - { - return lyt.east(c); - } - case port_direction::cardinal::SOUTH_EAST: - { - return lyt.south_east(c); - } - case port_direction::cardinal::SOUTH: - { - return lyt.south(c); - } - case port_direction::cardinal::SOUTH_WEST: - { - return lyt.south_west(c); - } - case port_direction::cardinal::WEST: - { - return lyt.west(c); - } - case port_direction::cardinal::NORTH_WEST: - { - return lyt.north_west(c); - } - default: - { - assert(false && "Given port does not specify a cardinal direction"); + switch (port.dir) { + case port_direction::cardinal::NORTH: { + return lyt.north(c); + } + case port_direction::cardinal::NORTH_EAST: { + return lyt.north_east(c); + } + case port_direction::cardinal::EAST: { + return lyt.east(c); + } + case port_direction::cardinal::SOUTH_EAST: { + return lyt.south_east(c); + } + case port_direction::cardinal::SOUTH: { + return lyt.south(c); + } + case port_direction::cardinal::SOUTH_WEST: { + return lyt.south_west(c); + } + case port_direction::cardinal::WEST: { + return lyt.west(c); + } + case port_direction::cardinal::NORTH_WEST: { + return lyt.north_west(c); + } + default: { + assert(false && "Given port does not specify a cardinal direction"); + } } - } - return {}; -} + return {}; + } /** * The layout is shifted by x_min and y_min such that the cells' coordinates are positive. @@ -235,38 +191,33 @@ template * @param lyt The given layout which is shifted. * @return shifted layout. */ -template -Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept -{ - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); + template + Lyt normalize_layout_coordinates(const Lyt &lyt) noexcept { + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - auto x_offset = std::numeric_limits::max(); - auto y_offset = std::numeric_limits::max(); - lyt.foreach_cell( - [&x_offset, &y_offset](const auto& c) - { - if (c.y <= y_offset) - { - y_offset = c.y; - } - if (c.x <= x_offset) - { - x_offset = c.x; - } - }); + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + auto x_offset = std::numeric_limits::max(); + auto y_offset = std::numeric_limits::max(); + lyt.foreach_cell( + [&x_offset, &y_offset](const auto &c) { + if (c.y <= y_offset) { + y_offset = c.y; + } + if (c.x <= x_offset) { + x_offset = c.x; + } + }); - lyt.foreach_cell( - [&lyt_new, &lyt, &x_offset, &y_offset](const auto& c) - { - lyt_new.assign_cell_type({c.x - x_offset, c.y - y_offset}, lyt.get_cell_type(c)); - lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); - lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); - return lyt_new; -} + lyt.foreach_cell( + [&lyt_new, &lyt, &x_offset, &y_offset](const auto &c) { + lyt_new.assign_cell_type({c.x - x_offset, c.y - y_offset}, lyt.get_cell_type(c)); + lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); + lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; + } /** * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is @@ -276,25 +227,23 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. * @return new layout based on SiQAD coordinates. */ -template -sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept -{ - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - 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"); + template + sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt &lyt) noexcept { + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + 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"); - sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - lyt.foreach_cell( - [&lyt_new, &lyt](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); + sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + lyt.foreach_cell( + [&lyt_new, &lyt](const auto &c) { + lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); - return lyt_new; -} + return lyt_new; + } /** * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is @@ -304,40 +253,37 @@ sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. * @return New layout based on Fiction coordinates. */ -template -Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept -{ - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - 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"); + template + Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad &lyt) noexcept { + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + 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"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - if constexpr (has_offset_ucoord_v) - { - auto lyt_normalized = normalize_layout_coordinates(lyt); - lyt_normalized.foreach_cell( - [&lyt_new, &lyt_normalized](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt_normalized.get_layout_name()); - } - else - { - lyt.foreach_cell( - [&lyt_new, &lyt](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); + if constexpr (has_offset_ucoord_v) { + auto lyt_normalized = normalize_layout_coordinates(lyt); + lyt_normalized.foreach_cell( + [&lyt_new, &lyt_normalized](const auto &c) { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), + lyt_normalized.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), + lyt_normalized.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), + lyt_normalized.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt_normalized.get_layout_name()); + } else { + lyt.foreach_cell( + [&lyt_new, &lyt](const auto &c) { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + } + return lyt_new; } - return lyt_new; -} } // namespace fiction diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 6d149768e..a554c7046 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -21,23 +21,24 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia TestType lyt{{4, 4}}; lyt.foreach_coordinate( - [&lyt](const auto& c) - { - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH}) == - lyt.north(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_EAST}) == - lyt.north_east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::EAST}) == lyt.east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_EAST}) == - lyt.south_east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH}) == - lyt.south(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_WEST}) == - lyt.south_west(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::WEST}) == lyt.west(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_WEST}) == - lyt.north_west(c)); - }); + [&lyt](const auto &c) { + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH}) == + lyt.north(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_EAST}) == + lyt.north_east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::EAST}) == + lyt.east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_EAST}) == + lyt.south_east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH}) == + lyt.south(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_WEST}) == + lyt.south_west(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::WEST}) == + lyt.west(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_WEST}) == + lyt.north_west(c)); + }); } TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) @@ -45,7 +46,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordina SECTION("empty layout") { TestType lyt{{10, 10}, "test"}; - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } @@ -103,7 +104,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -145,7 +146,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordi SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } From 1e04450f10baa1e750c6283f62de5de194e5857c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Feb 2023 19:14:02 +0100 Subject: [PATCH 10/21] :art: reformat code --- .../technology/sidb_surface_analysis.hpp | 145 +- include/fiction/traits.hpp | 1508 ++++++++--------- include/fiction/utils/layout_utils.hpp | 418 +++-- test/utils/layout_utils.cpp | 41 +- 4 files changed, 1081 insertions(+), 1031 deletions(-) diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index e39ccccc8..5d4ffa33f 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -21,7 +21,8 @@ #include #include -namespace fiction { +namespace fiction +{ /** * This alias represents a black list of gates that cannot be placed on certain positions on a (layout) surface in @@ -33,10 +34,10 @@ namespace fiction { * to be used preferably as it, e.g., helps the exact physical design algorithm to convert these assertions into unit * clauses which significantly helps runtime. */ - template - using surface_black_list = - std::unordered_map, std::unordered_map>, - kitty::hash>>; +template +using surface_black_list = + std::unordered_map, std::unordered_map>, + kitty::hash>>; /** * Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library. Any gate type that @@ -53,74 +54,82 @@ namespace fiction { * @param surface SiDB surface that instantiates the defects. * @return A black list of gate functions associated with tiles. */ - template - [[nodiscard]] auto sidb_surface_analysis(const GateLyt &gate_lyt, const sidb_surface &surface) noexcept { - static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); - - static_assert(has_get_functional_implementations_v, - "GateLibrary does not implement the get_functional_implementations function"); - static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); - static_assert(std::is_same_v, technology>, - "CellLyt and GateLibrary must implement the same technology"); - - // fetch the port type used by the gate library - using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; - - surface_black_list black_list{}; - - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); - const auto gate_implementations = GateLibrary::get_functional_implementations(); - const auto gate_ports = GateLibrary::get_gate_ports(); - - // a lambda that analyzes defect impact on a gate at a given layout tile - // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error - // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() - // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it - const auto analyze_gate = [&](const auto &it, const auto &t) noexcept { - const auto &[fun, impls] = it; - - // for each gate in the list of possible implementations - for (const auto &gate: impls) { - // for each cell position in the gate - for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) { - for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) { - // if the cell type at position (x, y) in the gate is non-empty - if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) { - // cell position within the gate - const cell relative_cell_pos{x, y, t.z}; - - const auto sidb_pos = - relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); - - // if any SiDB position of the current gate is compromised - if (sidbs_affected_by_defects.count(sidb_pos) > 0) { - // add this gate's function to the black list of tile t using the ports - // specified by get_gate_ports in GateLibrary - for (const auto &port: gate_ports.at(gate)) { - black_list[t][fun].push_back(port); - } - - return; // skip to next gate +template +[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface) noexcept +{ + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); + + static_assert(has_get_functional_implementations_v, + "GateLibrary does not implement the get_functional_implementations function"); + static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); + static_assert(std::is_same_v, technology>, + "CellLyt and GateLibrary must implement the same technology"); + + // fetch the port type used by the gate library + using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; + + surface_black_list black_list{}; + + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); + const auto gate_implementations = GateLibrary::get_functional_implementations(); + const auto gate_ports = GateLibrary::get_gate_ports(); + + // a lambda that analyzes defect impact on a gate at a given layout tile + // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error + // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() + // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it + const auto analyze_gate = [&](const auto& it, const auto& t) noexcept + { + const auto& [fun, impls] = it; + + // for each gate in the list of possible implementations + for (const auto& gate : impls) + { + // for each cell position in the gate + for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) + { + for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) + { + // if the cell type at position (x, y) in the gate is non-empty + if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) + { + // cell position within the gate + const cell relative_cell_pos{x, y, t.z}; + + const auto sidb_pos = + relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); + + // if any SiDB position of the current gate is compromised + if (sidbs_affected_by_defects.count(sidb_pos) > 0) + { + // add this gate's function to the black list of tile t using the ports + // specified by get_gate_ports in GateLibrary + for (const auto& port : gate_ports.at(gate)) + { + black_list[t][fun].push_back(port); } + + return; // skip to next gate } } } } - }; - - // for each tile in the layout - gate_lyt.foreach_tile([&](const auto &t) constexpr { - // for each gate in the library - std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), - // analyze the defect impact - std::bind(analyze_gate, std::placeholders::_1, t)); - }); - - return black_list; - } + } + }; + + // for each tile in the layout + gate_lyt.foreach_tile([&](const auto& t) constexpr { + // for each gate in the library + std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), + // analyze the defect impact + std::bind(analyze_gate, std::placeholders::_1, t)); + }); + + return black_list; +} } // namespace fiction diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index dcea4ec97..6e80f54cb 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -19,7 +19,8 @@ #include #include -namespace fiction { +namespace fiction +{ /** * This file includes fiction's trait system that is modeled after mockturtle/traits.hpp. It allows to check at compile @@ -30,731 +31,722 @@ namespace fiction { * Coordinate layouts */ - template - using aspect_ratio = typename Lyt::aspect_ratio; +template +using aspect_ratio = typename Lyt::aspect_ratio; - template - using coordinate = typename Lyt::coordinate; +template +using coordinate = typename Lyt::coordinate; #pragma region has_north - template - struct has_north : std::false_type { - }; +template +struct has_north : std::false_type +{}; - template - struct has_north().north(std::declval>()))>> - : std::true_type { - }; +template +struct has_north().north(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_north_v = has_north::value; +template +inline constexpr bool has_north_v = has_north::value; #pragma endregion #pragma region has_east - template - struct has_east : std::false_type { - }; +template +struct has_east : std::false_type +{}; - template - struct has_east().east(std::declval>()))>> - : std::true_type { - }; +template +struct has_east().east(std::declval>()))>> : std::true_type +{}; - template - inline constexpr bool has_east_v = has_east::value; +template +inline constexpr bool has_east_v = has_east::value; #pragma endregion #pragma region has_south - template - struct has_south : std::false_type { - }; +template +struct has_south : std::false_type +{}; - template - struct has_south().south(std::declval>()))>> - : std::true_type { - }; +template +struct has_south().south(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_south_v = has_south::value; +template +inline constexpr bool has_south_v = has_south::value; #pragma endregion #pragma region has_west - template - struct has_west : std::false_type { - }; +template +struct has_west : std::false_type +{}; - template - struct has_west().west(std::declval>()))>> - : std::true_type { - }; +template +struct has_west().west(std::declval>()))>> : std::true_type +{}; - template - inline constexpr bool has_west_v = has_west::value; +template +inline constexpr bool has_west_v = has_west::value; #pragma endregion #pragma region has_cardinal_operations - template - struct has_cardinal_operations : std::false_type { - }; +template +struct has_cardinal_operations : std::false_type +{}; - template - struct has_cardinal_operations< - Lyt, std::enable_if_t, has_east, has_south, has_west>>> - : std::true_type { - }; +template +struct has_cardinal_operations< + Lyt, std::enable_if_t, has_east, has_south, has_west>>> + : std::true_type +{}; - template - inline constexpr bool has_cardinal_operations_v = has_cardinal_operations::value; +template +inline constexpr bool has_cardinal_operations_v = has_cardinal_operations::value; #pragma endregion #pragma region has_above - template - struct has_above : std::false_type { - }; +template +struct has_above : std::false_type +{}; - template - struct has_above().above(std::declval>()))>> - : std::true_type { - }; +template +struct has_above().above(std::declval>()))>> + : std::true_type +{}; #pragma region has_north_east - template - struct has_north_east : std::false_type { - }; +template +struct has_north_east : std::false_type +{}; - template - struct has_north_east().north_east(std::declval>()))>> - : std::true_type { - }; +template +struct has_north_east().north_east(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_north_east_v = has_north_east::value; +template +inline constexpr bool has_north_east_v = has_north_east::value; #pragma endregion #pragma region has_south_east - template - struct has_south_east : std::false_type { - }; +template +struct has_south_east : std::false_type +{}; - template - struct has_south_east().south_east(std::declval>()))>> - : std::true_type { - }; +template +struct has_south_east().south_east(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_south_east_v = has_south_east::value; +template +inline constexpr bool has_south_east_v = has_south_east::value; #pragma endregion #pragma region has_south_west - template - struct has_south_west : std::false_type { - }; +template +struct has_south_west : std::false_type +{}; - template - struct has_south_west().south_west(std::declval>()))>> - : std::true_type { - }; +template +struct has_south_west().south_west(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_south_west_v = has_south_west::value; +template +inline constexpr bool has_south_west_v = has_south_west::value; #pragma endregion #pragma region has_north_west - template - struct has_north_west : std::false_type { - }; +template +struct has_north_west : std::false_type +{}; - template - struct has_north_west().north_west(std::declval>()))>> - : std::true_type { - }; +template +struct has_north_west().north_west(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_north_west_v = has_north_west::value; +template +inline constexpr bool has_north_west_v = has_north_west::value; #pragma endregion #pragma region has_ordinal_operations - template - struct has_ordinal_operations : std::false_type { - }; +template +struct has_ordinal_operations : std::false_type +{}; - template - struct has_ordinal_operations, has_south_east, - has_south_west, has_north_west>>> - : std::true_type { - }; +template +struct has_ordinal_operations, has_south_east, + has_south_west, has_north_west>>> + : std::true_type +{}; - template - inline constexpr bool has_ordinal_operations_v = has_ordinal_operations::value; +template +inline constexpr bool has_ordinal_operations_v = has_ordinal_operations::value; #pragma endregion - template - inline constexpr bool has_above_v = has_above::value; +template +inline constexpr bool has_above_v = has_above::value; #pragma endregion #pragma region has_below - template - struct has_below : std::false_type { - }; +template +struct has_below : std::false_type +{}; - template - struct has_below().below(std::declval>()))>> - : std::true_type { - }; +template +struct has_below().below(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_below_v = has_below::value; +template +inline constexpr bool has_below_v = has_below::value; #pragma endregion #pragma region has_elevation_operations - template - struct has_elevation_operations : std::false_type { - }; +template +struct has_elevation_operations : std::false_type +{}; - template - struct has_elevation_operations, has_below>>> - : std::true_type { - }; +template +struct has_elevation_operations, has_below>>> + : std::true_type +{}; - template - inline constexpr bool has_elevation_operations_v = has_elevation_operations::value; +template +inline constexpr bool has_elevation_operations_v = has_elevation_operations::value; #pragma endregion #pragma region is_coordinate_layout - template - struct is_coordinate_layout : std::false_type { - }; - - template - struct is_coordinate_layout< - Lyt, - std::enable_if_t< - std::conjunction_v, coordinate>, has_cardinal_operations, - has_elevation_operations>, - std::void_t, coordinate, typename Lyt::storage, - decltype(Lyt::max_fanin_size), decltype(Lyt::min_fanin_size), decltype(std::declval().x()), - decltype(std::declval().y()), decltype(std::declval().z()), - decltype(std::declval().area()), decltype(std::declval().resize( - aspect_ratio()))>>> - : std::true_type { - }; - - template - inline constexpr bool is_coordinate_layout_v = is_coordinate_layout::value; +template +struct is_coordinate_layout : std::false_type +{}; + +template +struct is_coordinate_layout< + Lyt, + std::enable_if_t< + std::conjunction_v, coordinate>, has_cardinal_operations, + has_elevation_operations>, + std::void_t, coordinate, typename Lyt::storage, + decltype(Lyt::max_fanin_size), decltype(Lyt::min_fanin_size), decltype(std::declval().x()), + decltype(std::declval().y()), decltype(std::declval().z()), + decltype(std::declval().area()), decltype(std::declval().resize(aspect_ratio()))>>> + : std::true_type +{}; + +template +inline constexpr bool is_coordinate_layout_v = is_coordinate_layout::value; #pragma endregion #pragma region has_foreach_coordinate - template - struct has_foreach_coordinate : std::false_type { - }; +template +struct has_foreach_coordinate : std::false_type +{}; - template - struct has_foreach_coordinate< - Lyt, std::void_t().foreach_coordinate( - std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_coordinate< + Lyt, std::void_t().foreach_coordinate(std::declval, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_coordinate_v = has_foreach_coordinate::value; +template +inline constexpr bool has_foreach_coordinate_v = has_foreach_coordinate::value; #pragma endregion #pragma region has_foreach_adjacent_coordinate - template - struct has_foreach_adjacent_coordinate : std::false_type { - }; +template +struct has_foreach_adjacent_coordinate : std::false_type +{}; - template - struct has_foreach_adjacent_coordinate< - Lyt, std::void_t().foreach_adjacent_coordinate( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_adjacent_coordinate< + Lyt, std::void_t().foreach_adjacent_coordinate( + std::declval>(), std::declval, uint32_t)>()))>> : std::true_type +{}; - template - inline constexpr bool has_foreach_adjacent_coordinate_v = has_foreach_adjacent_coordinate::value; +template +inline constexpr bool has_foreach_adjacent_coordinate_v = has_foreach_adjacent_coordinate::value; #pragma endregion #pragma region has_foreach_adjacent_opposite_coordinates - template - struct has_foreach_adjacent_opposite_coordinates : std::false_type { - }; +template +struct has_foreach_adjacent_opposite_coordinates : std::false_type +{}; - template - struct has_foreach_adjacent_opposite_coordinates< - Lyt, std::void_t().foreach_adjacent_opposite_coordinates( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_adjacent_opposite_coordinates< + Lyt, std::void_t().foreach_adjacent_opposite_coordinates( + std::declval>(), std::declval, uint32_t)>()))>> : std::true_type +{}; - template - inline constexpr bool has_foreach_adjacent_opposite_coordinates_v = - has_foreach_adjacent_opposite_coordinates::value; +template +inline constexpr bool has_foreach_adjacent_opposite_coordinates_v = + has_foreach_adjacent_opposite_coordinates::value; #pragma endregion #pragma region is_cartesian_layout - template - struct is_cartesian_layout : std::false_type { - }; +template +struct is_cartesian_layout : std::false_type +{}; - template - struct is_cartesian_layout< - Lyt, - std::enable_if_t && Lyt::max_fanin_size == 3u, - std::void_t, coordinate, typename Lyt::storage>>> - : std::true_type { - }; +template +struct is_cartesian_layout< + Lyt, + std::enable_if_t && Lyt::max_fanin_size == 3u, + std::void_t, coordinate, typename Lyt::storage>>> + : std::true_type +{}; - template - inline constexpr bool is_cartesian_layout_v = is_cartesian_layout::value; +template +inline constexpr bool is_cartesian_layout_v = is_cartesian_layout::value; #pragma endregion #pragma region is_shifted_cartesian_layout - template - struct is_shifted_cartesian_layout : std::false_type { - }; +template +struct is_shifted_cartesian_layout : std::false_type +{}; - template - struct is_shifted_cartesian_layout< - Lyt, std::enable_if_t< - is_coordinate_layout_v && has_ordinal_operations_v && Lyt::max_fanin_size == 5u, - std::void_t, - coordinate, typename Lyt::storage>>> : std::true_type { - }; +template +struct is_shifted_cartesian_layout< + Lyt, std::enable_if_t && has_ordinal_operations_v && Lyt::max_fanin_size == 5u, + std::void_t, + coordinate, typename Lyt::storage>>> : std::true_type +{}; - template - inline constexpr bool is_shifted_cartesian_layout_v = is_shifted_cartesian_layout::value; +template +inline constexpr bool is_shifted_cartesian_layout_v = is_shifted_cartesian_layout::value; #pragma endregion #pragma region shifted cartesian orientation and arrangement - template - constexpr bool has_horizontally_shifted_cartesian_orientation_v = - std::is_same_v; - template - constexpr bool has_vertically_shifted_cartesian_orientation_v = - std::is_same_v; - template - constexpr bool has_odd_row_cartesian_arrangement_v = - std::is_same_v; - template - constexpr bool has_even_row_cartesian_arrangement_v = - std::is_same_v; - template - constexpr bool has_odd_column_cartesian_arrangement_v = - std::is_same_v; - template - constexpr bool has_even_column_cartesian_arrangement_v = - std::is_same_v; +template +constexpr bool has_horizontally_shifted_cartesian_orientation_v = + std::is_same_v; +template +constexpr bool has_vertically_shifted_cartesian_orientation_v = + std::is_same_v; +template +constexpr bool has_odd_row_cartesian_arrangement_v = + std::is_same_v; +template +constexpr bool has_even_row_cartesian_arrangement_v = + std::is_same_v; +template +constexpr bool has_odd_column_cartesian_arrangement_v = + std::is_same_v; +template +constexpr bool has_even_column_cartesian_arrangement_v = + std::is_same_v; #pragma endregion #pragma region is_hexagonal_layout - template - struct is_hexagonal_layout : std::false_type { - }; +template +struct is_hexagonal_layout : std::false_type +{}; - template - struct is_hexagonal_layout && is_coordinate_layout_v && - has_ordinal_operations_v && Lyt::max_fanin_size == 5u, - std::void_t, coordinate, typename Lyt::storage>>> - : std::true_type { - }; +template +struct is_hexagonal_layout && is_coordinate_layout_v && + has_ordinal_operations_v && Lyt::max_fanin_size == 5u, + std::void_t, coordinate, typename Lyt::storage>>> + : std::true_type +{}; - template - inline constexpr bool is_hexagonal_layout_v = is_hexagonal_layout::value; +template +inline constexpr bool is_hexagonal_layout_v = is_hexagonal_layout::value; #pragma endregion #pragma region hexagonal orientation and arrangement - template - inline constexpr const bool has_pointy_top_hex_orientation_v = - std::is_same_v; - template - inline constexpr const bool has_flat_top_hex_orientation_v = - std::is_same_v; - template - inline constexpr const bool has_odd_row_hex_arrangement_v = std::is_same_v; - template - inline constexpr const bool has_even_row_hex_arrangement_v = - std::is_same_v; - template - inline constexpr const bool has_odd_column_hex_arrangement_v = - std::is_same_v; - template - inline constexpr const bool has_even_column_hex_arrangement_v = - std::is_same_v; +template +inline constexpr const bool has_pointy_top_hex_orientation_v = + std::is_same_v; +template +inline constexpr const bool has_flat_top_hex_orientation_v = + std::is_same_v; +template +inline constexpr const bool has_odd_row_hex_arrangement_v = std::is_same_v; +template +inline constexpr const bool has_even_row_hex_arrangement_v = + std::is_same_v; +template +inline constexpr const bool has_odd_column_hex_arrangement_v = + std::is_same_v; +template +inline constexpr const bool has_even_column_hex_arrangement_v = + std::is_same_v; #pragma endregion /** * Tile-based layouts */ - template - using tile = typename Lyt::tile; +template +using tile = typename Lyt::tile; #pragma region is_tile_based_layout - template - struct is_tile_based_layout : std::false_type { - }; +template +struct is_tile_based_layout : std::false_type +{}; - template - struct is_tile_based_layout, - std::void_t, typename Lyt::storage>>> - : std::true_type { - }; +template +struct is_tile_based_layout, + std::void_t, typename Lyt::storage>>> + : std::true_type +{}; - template - inline constexpr bool is_tile_based_layout_v = is_tile_based_layout::value; +template +inline constexpr bool is_tile_based_layout_v = is_tile_based_layout::value; #pragma endregion #pragma region has_foreach_tile - template - struct has_foreach_tile : std::false_type { - }; +template +struct has_foreach_tile : std::false_type +{}; - template - struct has_foreach_tile< - Lyt, std::void_t().foreach_tile(std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_tile< + Lyt, std::void_t().foreach_tile(std::declval, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_tile_v = has_foreach_tile::value; +template +inline constexpr bool has_foreach_tile_v = has_foreach_tile::value; #pragma endregion #pragma region has_foreach_adjacent_tile - template - struct has_foreach_adjacent_tile : std::false_type { - }; +template +struct has_foreach_adjacent_tile : std::false_type +{}; - template - struct has_foreach_adjacent_tile().foreach_adjacent_tile( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_adjacent_tile().foreach_adjacent_tile( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_adjacent_tile_v = has_foreach_adjacent_tile::value; +template +inline constexpr bool has_foreach_adjacent_tile_v = has_foreach_adjacent_tile::value; #pragma endregion #pragma region has_foreach_adjacent_opposite_tiles - template - struct has_foreach_adjacent_opposite_tiles : std::false_type { - }; +template +struct has_foreach_adjacent_opposite_tiles : std::false_type +{}; - template - struct has_foreach_adjacent_opposite_tiles().foreach_adjacent_opposite_tiles( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_adjacent_opposite_tiles().foreach_adjacent_opposite_tiles( + std::declval>(), std::declval, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_adjacent_opposite_tiles_v = has_foreach_adjacent_opposite_tiles::value; +template +inline constexpr bool has_foreach_adjacent_opposite_tiles_v = has_foreach_adjacent_opposite_tiles::value; #pragma endregion /** * Clocked layouts */ - template - using clock_zone = typename Lyt::clock_zone; +template +using clock_zone = typename Lyt::clock_zone; #pragma region is_clocked_layout - template - struct is_clocked_layout : std::false_type { - }; - - template - struct is_clocked_layout< - Lyt, std::enable_if_t, - std::void_t, typename Lyt::clocking_scheme_t, - typename Lyt::clock_number_t, typename Lyt::degree_t, typename Lyt::storage, - decltype(std::declval().get_clock_number(clock_zone())), - decltype(std::declval().num_clocks()), - decltype(std::declval().is_regularly_clocked()), - decltype(std::declval().is_clocking_scheme(std::string()))>>> - : std::true_type { - }; - - template - inline constexpr bool is_clocked_layout_v = is_clocked_layout::value; +template +struct is_clocked_layout : std::false_type +{}; + +template +struct is_clocked_layout< + Lyt, std::enable_if_t, + std::void_t, typename Lyt::clocking_scheme_t, + typename Lyt::clock_number_t, typename Lyt::degree_t, typename Lyt::storage, + decltype(std::declval().get_clock_number(clock_zone())), + decltype(std::declval().num_clocks()), + decltype(std::declval().is_regularly_clocked()), + decltype(std::declval().is_clocking_scheme(std::string()))>>> + : std::true_type +{}; + +template +inline constexpr bool is_clocked_layout_v = is_clocked_layout::value; #pragma endregion #pragma region has_is_incoming_clocked - template - struct has_is_incoming_clocked : std::false_type { - }; +template +struct has_is_incoming_clocked : std::false_type +{}; - template - struct has_is_incoming_clocked().is_incoming_clocked( - std::declval>(), std::declval>()))>> - : std::true_type { - }; +template +struct has_is_incoming_clocked().is_incoming_clocked( + std::declval>(), std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_incoming_clocked_v = has_is_incoming_clocked::value; +template +inline constexpr bool has_is_incoming_clocked_v = has_is_incoming_clocked::value; #pragma endregion #pragma region has_foreach_incoming_clocked_zone - template - struct has_foreach_incoming_clocked_zone : std::false_type { - }; +template +struct has_foreach_incoming_clocked_zone : std::false_type +{}; - template - struct has_foreach_incoming_clocked_zone< - Lyt, std::void_t().foreach_incoming_clocked_zone( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_incoming_clocked_zone< + Lyt, std::void_t().foreach_incoming_clocked_zone( + std::declval>(), std::declval, uint32_t)>()))>> : std::true_type +{}; - template - inline constexpr bool has_foreach_incoming_clocked_zone_v = has_foreach_incoming_clocked_zone::value; +template +inline constexpr bool has_foreach_incoming_clocked_zone_v = has_foreach_incoming_clocked_zone::value; #pragma endregion #pragma region has_is_outgoing_clocked - template - struct has_is_outgoing_clocked : std::false_type { - }; +template +struct has_is_outgoing_clocked : std::false_type +{}; - template - struct has_is_outgoing_clocked().is_outgoing_clocked( - std::declval>(), std::declval>()))>> - : std::true_type { - }; +template +struct has_is_outgoing_clocked().is_outgoing_clocked( + std::declval>(), std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_outgoing_clocked_v = has_is_outgoing_clocked::value; +template +inline constexpr bool has_is_outgoing_clocked_v = has_is_outgoing_clocked::value; #pragma endregion #pragma region has_foreach_outgoing_clocked_zone - template - struct has_foreach_outgoing_clocked_zone : std::false_type { - }; +template +struct has_foreach_outgoing_clocked_zone : std::false_type +{}; - template - struct has_foreach_outgoing_clocked_zone< - Lyt, std::void_t().foreach_outgoing_clocked_zone( - std::declval>(), std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_outgoing_clocked_zone< + Lyt, std::void_t().foreach_outgoing_clocked_zone( + std::declval>(), std::declval, uint32_t)>()))>> : std::true_type +{}; - template - inline constexpr bool has_foreach_outgoing_clocked_zone_v = has_foreach_outgoing_clocked_zone::value; +template +inline constexpr bool has_foreach_outgoing_clocked_zone_v = has_foreach_outgoing_clocked_zone::value; #pragma endregion #pragma region has_synchronization_elements - template - struct has_synchronization_elements : std::false_type { - }; - - template - struct has_synchronization_elements< - Lyt, std::enable_if_t< - is_clocked_layout_v, - std::void_t().assign_synchronization_element( - std::declval>(), std::declval())), - decltype(std::declval().is_synchronization_element(std::declval>())), - decltype(std::declval().get_synchronization_element(std::declval>())), - decltype(std::declval().num_se())>>> : std::true_type { - }; - - template - inline constexpr bool has_synchronization_elements_v = has_synchronization_elements::value; +template +struct has_synchronization_elements : std::false_type +{}; + +template +struct has_synchronization_elements< + Lyt, std::enable_if_t< + is_clocked_layout_v, + std::void_t().assign_synchronization_element( + std::declval>(), std::declval())), + decltype(std::declval().is_synchronization_element(std::declval>())), + decltype(std::declval().get_synchronization_element(std::declval>())), + decltype(std::declval().num_se())>>> : std::true_type +{}; + +template +inline constexpr bool has_synchronization_elements_v = has_synchronization_elements::value; #pragma endregion /** * Cell-level layouts */ - template - using cell = typename Lyt::cell; - - template - using technology = typename Lyt::technology; - - template - inline constexpr const bool has_qca_technology_v = std::is_same_v, qca_technology>; - template - inline constexpr const bool has_inml_technology_v = std::is_same_v, inml_technology>; - template - inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; - template - inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; - template - inline constexpr const bool has_cube_coord_v = std::is_same_v, cube::coord_t>; - template - inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; +template +using cell = typename Lyt::cell; + +template +using technology = typename Lyt::technology; + +template +inline constexpr const bool has_qca_technology_v = std::is_same_v, qca_technology>; +template +inline constexpr const bool has_inml_technology_v = std::is_same_v, inml_technology>; +template +inline constexpr const bool has_sidb_technology_v = std::is_same_v, sidb_technology>; +template +inline constexpr const bool has_offset_ucoord_v = std::is_same_v, offset::ucoord_t>; +template +inline constexpr const bool has_cube_coord_v = std::is_same_v, cube::coord_t>; +template +inline constexpr const bool has_siqad_coord_v = std::is_same_v, siqad::coord_t>; #pragma region is_cell_level_layout - template - struct is_cell_level_layout : std::false_type { - }; - - template - struct is_cell_level_layout< - Lyt, - std::enable_if_t, - std::void_t, typename Lyt::cell_type, typename Lyt::cell_mode, - technology, typename Lyt::storage, - decltype(std::declval().assign_cell_type(cell(), typename Lyt::cell_type())), - decltype(std::declval().get_cell_type(cell())), - decltype(std::declval().is_empty_cell(cell())), - decltype(std::declval().assign_cell_mode(cell(), typename Lyt::cell_mode())), - decltype(std::declval().get_cell_mode(cell())), - decltype(std::declval().assign_cell_name(cell(), std::string())), - decltype(std::declval().get_cell_name(cell()))>>> : std::true_type { - }; - - template - inline constexpr bool is_cell_level_layout_v = is_cell_level_layout::value; +template +struct is_cell_level_layout : std::false_type +{}; + +template +struct is_cell_level_layout< + Lyt, + std::enable_if_t, + std::void_t, typename Lyt::cell_type, typename Lyt::cell_mode, + technology, typename Lyt::storage, + decltype(std::declval().assign_cell_type(cell(), typename Lyt::cell_type())), + decltype(std::declval().get_cell_type(cell())), + decltype(std::declval().is_empty_cell(cell())), + decltype(std::declval().assign_cell_mode(cell(), typename Lyt::cell_mode())), + decltype(std::declval().get_cell_mode(cell())), + decltype(std::declval().assign_cell_name(cell(), std::string())), + decltype(std::declval().get_cell_name(cell()))>>> : std::true_type +{}; + +template +inline constexpr bool is_cell_level_layout_v = is_cell_level_layout::value; #pragma endregion #pragma region has_is_empty_cell - template - struct has_is_empty_cell : std::false_type { - }; +template +struct has_is_empty_cell : std::false_type +{}; - template - struct has_is_empty_cell().is_empty_cell(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_empty_cell().is_empty_cell(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_empty_cell_v = has_is_empty_cell::value; +template +inline constexpr bool has_is_empty_cell_v = has_is_empty_cell::value; #pragma endregion #pragma region has_foreach_cell - template - struct has_foreach_cell : std::false_type { - }; +template +struct has_foreach_cell : std::false_type +{}; - template - struct has_foreach_cell< - Lyt, std::void_t().foreach_cell(std::declval, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_cell< + Lyt, std::void_t().foreach_cell(std::declval, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_cell_v = has_foreach_cell::value; +template +inline constexpr bool has_foreach_cell_v = has_foreach_cell::value; #pragma endregion #pragma region has_set_layout_name - template - struct has_set_layout_name : std::false_type { - }; +template +struct has_set_layout_name : std::false_type +{}; - template - struct has_set_layout_name().set_layout_name(std::string()))>> - : std::true_type { - }; +template +struct has_set_layout_name().set_layout_name(std::string()))>> + : std::true_type +{}; - template - inline constexpr bool has_set_layout_name_v = has_set_layout_name::value; +template +inline constexpr bool has_set_layout_name_v = has_set_layout_name::value; #pragma endregion #pragma region has_get_layout_name - template - struct has_get_layout_name : std::false_type { - }; +template +struct has_get_layout_name : std::false_type +{}; - template - struct has_get_layout_name().get_layout_name())>> : std::true_type { - }; +template +struct has_get_layout_name().get_layout_name())>> : std::true_type +{}; - template - inline constexpr bool has_get_layout_name_v = has_get_layout_name::value; +template +inline constexpr bool has_get_layout_name_v = has_get_layout_name::value; #pragma endregion #pragma region has_assign_sidb_defect - template - struct has_assign_sidb_defect : std::false_type { - }; +template +struct has_assign_sidb_defect : std::false_type +{}; - template - struct has_assign_sidb_defect< - Lyt, std::void_t().assign_sidb_defect(coordinate(), sidb_defect()))>> - : std::true_type { - }; +template +struct has_assign_sidb_defect< + Lyt, std::void_t().assign_sidb_defect(coordinate(), sidb_defect()))>> + : std::true_type +{}; - template - inline constexpr bool has_assign_sidb_defect_v = has_assign_sidb_defect::value; +template +inline constexpr bool has_assign_sidb_defect_v = has_assign_sidb_defect::value; #pragma endregion #pragma region has_get_sidb_defect - template - struct has_get_sidb_defect : std::false_type { - }; +template +struct has_get_sidb_defect : std::false_type +{}; - template - struct has_get_sidb_defect().get_sidb_defect(coordinate()))>> - : std::true_type { - }; +template +struct has_get_sidb_defect().get_sidb_defect(coordinate()))>> + : std::true_type +{}; - template - inline constexpr bool has_get_sidb_defect_v = has_get_sidb_defect::value; +template +inline constexpr bool has_get_sidb_defect_v = has_get_sidb_defect::value; #pragma endregion #pragma region has_foreach_sidb_defect - template - struct has_foreach_sidb_defect : std::false_type { - }; +template +struct has_foreach_sidb_defect : std::false_type +{}; - template - struct has_foreach_sidb_defect().foreach_sidb_defect( - std::declval, sidb_defect>, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_sidb_defect().foreach_sidb_defect( + std::declval, sidb_defect>, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_sidb_defect_v = has_foreach_sidb_defect::value; +template +inline constexpr bool has_foreach_sidb_defect_v = has_foreach_sidb_defect::value; #pragma endregion #pragma region has_assign_charge_state - template - struct has_assign_charge_state : std::false_type { - }; +template +struct has_assign_charge_state : std::false_type +{}; - template - struct has_assign_charge_state< - Lyt, std::void_t().assign_charge_state(coordinate(), sidb_charge_state()))>> - : std::true_type { - }; +template +struct has_assign_charge_state< + Lyt, std::void_t().assign_charge_state(coordinate(), sidb_charge_state()))>> + : std::true_type +{}; - template - inline constexpr bool has_assign_charge_state_v = has_assign_charge_state::value; +template +inline constexpr bool has_assign_charge_state_v = has_assign_charge_state::value; #pragma endregion #pragma region has_get_charge_state - template - struct has_get_charge_state : std::false_type { - }; +template +struct has_get_charge_state : std::false_type +{}; - template - struct has_get_charge_state().get_charge_state(coordinate()))>> - : std::true_type { - }; +template +struct has_get_charge_state().get_charge_state(coordinate()))>> + : std::true_type +{}; - template - inline constexpr bool has_get_charge_state_v = has_get_charge_state::value; +template +inline constexpr bool has_get_charge_state_v = has_get_charge_state::value; #pragma endregion #pragma region has_foreach_charge_state - template - struct has_foreach_charge_state : std::false_type { - }; +template +struct has_foreach_charge_state : std::false_type +{}; - template - struct has_foreach_charge_state().foreach_charge_state( - std::declval, sidb_charge_state>, uint32_t)>()))>> - : std::true_type { - }; +template +struct has_foreach_charge_state().foreach_charge_state( + std::declval, sidb_charge_state>, uint32_t)>()))>> + : std::true_type +{}; - template - inline constexpr bool has_foreach_charge_state_v = has_foreach_charge_state::value; +template +inline constexpr bool has_foreach_charge_state_v = has_foreach_charge_state::value; #pragma endregion /** @@ -762,73 +754,73 @@ namespace fiction { */ #pragma region is_gate_level_layout - template - struct is_gate_level_layout : std::false_type { - }; +template +struct is_gate_level_layout : std::false_type +{}; - template - struct is_gate_level_layout< - Lyt, std::enable_if_t, mockturtle::is_network_type>, - std::void_t, typename Lyt::storage>>> : std::true_type { - }; +template +struct is_gate_level_layout< + Lyt, std::enable_if_t, mockturtle::is_network_type>, + std::void_t, typename Lyt::storage>>> : std::true_type +{}; - template - inline constexpr bool is_gate_level_layout_v = is_gate_level_layout::value; +template +inline constexpr bool is_gate_level_layout_v = is_gate_level_layout::value; #pragma endregion #pragma region has_is_gate_tile - template - struct has_is_gate_tile : std::false_type { - }; +template +struct has_is_gate_tile : std::false_type +{}; - template - struct has_is_gate_tile().is_gate_tile(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_gate_tile().is_gate_tile(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_gate_tile_v = has_is_gate_tile::value; +template +inline constexpr bool has_is_gate_tile_v = has_is_gate_tile::value; #pragma endregion #pragma region has_is_wire_tile - template - struct has_is_wire_tile : std::false_type { - }; +template +struct has_is_wire_tile : std::false_type +{}; - template - struct has_is_wire_tile().is_wire_tile(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_wire_tile().is_wire_tile(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_wire_tile_v = has_is_wire_tile::value; +template +inline constexpr bool has_is_wire_tile_v = has_is_wire_tile::value; #pragma endregion #pragma region has_is_empty_tile - template - struct has_is_empty_tile : std::false_type { - }; +template +struct has_is_empty_tile : std::false_type +{}; - template - struct has_is_empty_tile().is_empty_tile(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_empty_tile().is_empty_tile(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_empty_tile_v = has_is_empty_tile::value; +template +inline constexpr bool has_is_empty_tile_v = has_is_empty_tile::value; #pragma endregion #pragma region has_is_empty - template - struct has_is_empty : std::false_type { - }; +template +struct has_is_empty : std::false_type +{}; - template - struct has_is_empty().is_empty())>> : std::true_type { - }; +template +struct has_is_empty().is_empty())>> : std::true_type +{}; - template - inline constexpr bool has_is_empty_v = has_is_empty::value; +template +inline constexpr bool has_is_empty_v = has_is_empty::value; #pragma endregion /** @@ -836,33 +828,33 @@ namespace fiction { */ #pragma region has_is_obstructed_coordinate - template - struct has_is_obstructed_coordinate : std::false_type { - }; +template +struct has_is_obstructed_coordinate : std::false_type +{}; - template - struct has_is_obstructed_coordinate< - Lyt, std::void_t().is_obstructed_coordinate(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_obstructed_coordinate< + Lyt, std::void_t().is_obstructed_coordinate(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_obstructed_coordinate_v = has_is_obstructed_coordinate::value; +template +inline constexpr bool has_is_obstructed_coordinate_v = has_is_obstructed_coordinate::value; #pragma endregion #pragma region has_is_obstructed_connection - template - struct has_is_obstructed_connection : std::false_type { - }; +template +struct has_is_obstructed_connection : std::false_type +{}; - template - struct has_is_obstructed_connection().is_obstructed_connection( - std::declval>(), std::declval>()))>> - : std::true_type { - }; +template +struct has_is_obstructed_connection().is_obstructed_connection( + std::declval>(), std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_obstructed_connection_v = has_is_obstructed_connection::value; +template +inline constexpr bool has_is_obstructed_connection_v = has_is_obstructed_connection::value; #pragma endregion /** @@ -870,53 +862,53 @@ namespace fiction { */ #pragma region has_get_functional_implementations - template - struct has_get_functional_implementations : std::false_type { - }; +template +struct has_get_functional_implementations : std::false_type +{}; - template - struct has_get_functional_implementations< - Lib, std::enable_if_t().get_functional_implementations()), - typename Lib::gate_functions>>> : std::true_type { - }; +template +struct has_get_functional_implementations< + Lib, std::enable_if_t().get_functional_implementations()), + typename Lib::gate_functions>>> : std::true_type +{}; - template - inline constexpr bool has_get_functional_implementations_v = has_get_functional_implementations::value; +template +inline constexpr bool has_get_functional_implementations_v = has_get_functional_implementations::value; #pragma endregion #pragma region has_get_gate_ports - template - struct has_get_gate_ports : std::false_type { - }; +template +struct has_get_gate_ports : std::false_type +{}; - template - struct has_get_gate_ports().get_gate_ports()), - typename Lib::template gate_ports> || - std::is_same_v().get_gate_ports()), - typename Lib::template gate_ports>>> - : std::true_type { - }; +template +struct has_get_gate_ports().get_gate_ports()), + typename Lib::template gate_ports> || + std::is_same_v().get_gate_ports()), + typename Lib::template gate_ports>>> + : std::true_type +{}; - template - inline constexpr bool has_get_gate_ports_v = has_get_gate_ports::value; +template +inline constexpr bool has_get_gate_ports_v = has_get_gate_ports::value; #pragma endregion #pragma region has_post_layout_optimization - template - struct has_post_layout_optimization : std::false_type { - }; +template +struct has_post_layout_optimization : std::false_type +{}; - template - struct has_post_layout_optimization< - Lib, Lyt, - std::enable_if_t, std::is_same, technology>>, - std::void_t().post_layout_optimization(std::declval))>>> - : std::true_type { - }; +template +struct has_post_layout_optimization< + Lib, Lyt, + std::enable_if_t, std::is_same, technology>>, + std::void_t().post_layout_optimization(std::declval))>>> + : std::true_type +{}; - template - inline constexpr bool has_post_layout_optimization_v = has_post_layout_optimization::value; +template +inline constexpr bool has_post_layout_optimization_v = has_post_layout_optimization::value; #pragma endregion /** @@ -924,234 +916,228 @@ namespace fiction { */ #pragma region has_is_po - template - struct has_is_po : std::false_type { - }; +template +struct has_is_po : std::false_type +{}; - template - struct has_is_po().is_po(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_po().is_po(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_po_v = has_is_po::value; +template +inline constexpr bool has_is_po_v = has_is_po::value; #pragma endregion #pragma region has_is_buf - template - struct has_is_buf : std::false_type { - }; +template +struct has_is_buf : std::false_type +{}; - template - struct has_is_buf().is_buf(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_buf().is_buf(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_buf_v = has_is_buf::value; +template +inline constexpr bool has_is_buf_v = has_is_buf::value; #pragma endregion #pragma region has_is_inv - template - struct has_is_inv : std::false_type { - }; +template +struct has_is_inv : std::false_type +{}; - template - struct has_is_inv().is_inv(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_inv().is_inv(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_inv_v = has_is_inv::value; +template +inline constexpr bool has_is_inv_v = has_is_inv::value; #pragma endregion #pragma region has_is_fanout - template - struct has_is_fanout : std::false_type { - }; +template +struct has_is_fanout : std::false_type +{}; - template - struct has_is_fanout().is_fanout( - std::declval>()))>> - : std::true_type { - }; +template +struct has_is_fanout().is_fanout(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_fanout_v = has_is_fanout::value; +template +inline constexpr bool has_is_fanout_v = has_is_fanout::value; #pragma endregion #pragma region has_is_nand - template - struct has_is_nand : std::false_type { - }; +template +struct has_is_nand : std::false_type +{}; - template - struct has_is_nand().is_nand(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_nand().is_nand(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_nand_v = has_is_nand::value; +template +inline constexpr bool has_is_nand_v = has_is_nand::value; #pragma endregion #pragma region has_is_nor - template - struct has_is_nor : std::false_type { - }; +template +struct has_is_nor : std::false_type +{}; - template - struct has_is_nor().is_nor(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_nor().is_nor(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_nor_v = has_is_nor::value; +template +inline constexpr bool has_is_nor_v = has_is_nor::value; #pragma endregion #pragma region has_is_xnor - template - struct has_is_xnor : std::false_type { - }; +template +struct has_is_xnor : std::false_type +{}; - template - struct has_is_xnor().is_xnor(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_xnor().is_xnor(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_xnor_v = has_is_xnor::value; +template +inline constexpr bool has_is_xnor_v = has_is_xnor::value; #pragma endregion #pragma region has_is_and3 - template - struct has_is_and3 : std::false_type { - }; +template +struct has_is_and3 : std::false_type +{}; - template - struct has_is_and3().is_and3(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_and3().is_and3(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_and3_v = has_is_and3::value; +template +inline constexpr bool has_is_and3_v = has_is_and3::value; #pragma endregion #pragma region has_is_xor_and - template - struct has_is_xor_and : std::false_type { - }; +template +struct has_is_xor_and : std::false_type +{}; - template - struct has_is_xor_and().is_xor_and( - std::declval>()))>> - : std::true_type { - }; +template +struct has_is_xor_and().is_xor_and(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_xor_and_v = has_is_xor_and::value; +template +inline constexpr bool has_is_xor_and_v = has_is_xor_and::value; #pragma endregion #pragma region has_is_or_and - template - struct has_is_or_and : std::false_type { - }; +template +struct has_is_or_and : std::false_type +{}; - template - struct has_is_or_and().is_or_and( - std::declval>()))>> - : std::true_type { - }; +template +struct has_is_or_and().is_or_and(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_or_and_v = has_is_or_and::value; +template +inline constexpr bool has_is_or_and_v = has_is_or_and::value; #pragma endregion #pragma region has_is_onehot - template - struct has_is_onehot : std::false_type { - }; +template +struct has_is_onehot : std::false_type +{}; - template - struct has_is_onehot().is_onehot( - std::declval>()))>> - : std::true_type { - }; +template +struct has_is_onehot().is_onehot(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_onehot_v = has_is_onehot::value; +template +inline constexpr bool has_is_onehot_v = has_is_onehot::value; #pragma endregion #pragma region has_is_gamble - template - struct has_is_gamble : std::false_type { - }; +template +struct has_is_gamble : std::false_type +{}; - template - struct has_is_gamble().is_gamble( - std::declval>()))>> - : std::true_type { - }; +template +struct has_is_gamble().is_gamble(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_gamble_v = has_is_gamble::value; +template +inline constexpr bool has_is_gamble_v = has_is_gamble::value; #pragma endregion #pragma region has_create_dot - template - struct has_create_dot : std::false_type { - }; +template +struct has_create_dot : std::false_type +{}; - template - struct has_create_dot().create_dot( - std::declval>(), std::declval>(), - std::declval>()))>> : std::true_type { - }; +template +struct has_create_dot().create_dot( + std::declval>(), std::declval>(), + std::declval>()))>> : std::true_type +{}; - template - inline constexpr bool has_create_dot_v = has_create_dot::value; +template +inline constexpr bool has_create_dot_v = has_create_dot::value; #pragma endregion #pragma region has_is_dot - template - struct has_is_dot : std::false_type { - }; +template +struct has_is_dot : std::false_type +{}; - template - struct has_is_dot().is_dot(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_dot().is_dot(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_dot_v = has_is_dot::value; +template +inline constexpr bool has_is_dot_v = has_is_dot::value; #pragma endregion #pragma region has_is_mux - template - struct has_is_mux : std::false_type { - }; +template +struct has_is_mux : std::false_type +{}; - template - struct has_is_mux().is_mux(std::declval>()))>> - : std::true_type { - }; +template +struct has_is_mux().is_mux(std::declval>()))>> + : std::true_type +{}; - template - inline constexpr bool has_is_mux_v = has_is_mux::value; +template +inline constexpr bool has_is_mux_v = has_is_mux::value; #pragma endregion #pragma region has_is_and_xor - template - struct has_is_and_xor : std::false_type { - }; - - template - struct has_is_and_xor().is_and_xor( - std::declval>()))>> - : std::true_type { - }; - - template - inline constexpr bool has_is_and_xor_v = has_is_and_xor::value; +template +struct has_is_and_xor : std::false_type +{}; + +template +struct has_is_and_xor().is_and_xor(std::declval>()))>> + : std::true_type +{}; + +template +inline constexpr bool has_is_and_xor_v = has_is_and_xor::value; #pragma endregion } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 975e6e594..ef06f847d 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -15,7 +15,8 @@ #include #include -namespace fiction { +namespace fiction +{ /** * Returns the number of adjacent coordinates of a given one. This is not a constant value because `c` could be located @@ -26,12 +27,13 @@ namespace fiction { * @param c Coordinate whose number of adjacencies are required. * @return Number of `c`'s adjacent coordinates. */ - template - [[nodiscard]] uint8_t num_adjacent_coordinates(const Lyt &lyt, const coordinate &c) noexcept { - static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); +template +[[nodiscard]] uint8_t num_adjacent_coordinates(const Lyt& lyt, const coordinate& c) noexcept +{ + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); - return static_cast(lyt.adjacent_coordinates(c).size()); - } + return static_cast(lyt.adjacent_coordinates(c).size()); +} /** * Converts a relative cell position within a tile to an absolute cell position within a layout. To compute the absolute @@ -46,93 +48,126 @@ namespace fiction { * @param relative_c Relative cell position within t. * @return Absolute cell position in a layout. */ - template - [[nodiscard]] cell relative_to_absolute_cell_position(const GateLyt &gate_lyt, const tile &t, - const cell &relative_c) noexcept { - static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); +template +[[nodiscard]] cell relative_to_absolute_cell_position(const GateLyt& gate_lyt, const tile& t, + const cell& relative_c) noexcept +{ + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - assert(relative_c.x < GateSizeX && relative_c.y < GateSizeY && - "relative_c must be within the bounds of a single tile"); + assert(relative_c.x < GateSizeX && relative_c.y < GateSizeY && + "relative_c must be within the bounds of a single tile"); - cell absolute_c{}; + cell absolute_c{}; - // Cartesian layouts - if constexpr (is_cartesian_layout_v) { - absolute_c = {t.x * GateSizeX, t.y * GateSizeY, t.z}; + // Cartesian layouts + if constexpr (is_cartesian_layout_v) + { + absolute_c = {t.x * GateSizeX, t.y * GateSizeY, t.z}; + } + // shifted Cartesian layouts + else if constexpr (is_shifted_cartesian_layout_v) + { + if constexpr (has_horizontally_shifted_cartesian_orientation_v) + { + absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY)), t.z}; + } + else if constexpr (has_vertically_shifted_cartesian_orientation_v) + { + absolute_c = {static_cast(t.x * (GateSizeX)), t.y * (GateSizeY), t.z}; } - // shifted Cartesian layouts - else if constexpr (is_shifted_cartesian_layout_v) { - if constexpr (has_horizontally_shifted_cartesian_orientation_v) { - absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY)), t.z}; - } else if constexpr (has_vertically_shifted_cartesian_orientation_v) { - absolute_c = {static_cast(t.x * (GateSizeX)), t.y * (GateSizeY), t.z}; - } - if constexpr (has_odd_row_cartesian_arrangement_v) { - if (gate_lyt.is_in_odd_row(t)) { - // odd rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); - } - } else if constexpr (has_even_row_cartesian_arrangement_v) { - if (gate_lyt.is_in_even_row(t)) { - // even rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); - } - } else if constexpr (has_odd_column_cartesian_arrangement_v) { - if (gate_lyt.is_in_odd_column(t)) { - // odd columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } - } else if constexpr (has_even_column_cartesian_arrangement_v) { - if (gate_lyt.is_in_even_column(t)) { - // even columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } + if constexpr (has_odd_row_cartesian_arrangement_v) + { + if (gate_lyt.is_in_odd_row(t)) + { + // odd rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); } } - // hexagonal layouts - else if constexpr (is_hexagonal_layout_v) { - if constexpr (has_pointy_top_hex_orientation_v) { - // vertical distance between pointy top hexagons is height * 3/4 - absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY * 3 / 4)), t.z}; - } else if constexpr (has_flat_top_hex_orientation_v) { - // horizontal distance between flat top hexagons is width * 3/4 - absolute_c = {static_cast(t.x * (GateSizeX * 3 / 4)), t.y * (GateSizeY), t.z}; + else if constexpr (has_even_row_cartesian_arrangement_v) + { + if (gate_lyt.is_in_even_row(t)) + { + // even rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); } + } + else if constexpr (has_odd_column_cartesian_arrangement_v) + { + if (gate_lyt.is_in_odd_column(t)) + { + // odd columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } + } + else if constexpr (has_even_column_cartesian_arrangement_v) + { + if (gate_lyt.is_in_even_column(t)) + { + // even columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } + } + } + // hexagonal layouts + else if constexpr (is_hexagonal_layout_v) + { + if constexpr (has_pointy_top_hex_orientation_v) + { + // vertical distance between pointy top hexagons is height * 3/4 + absolute_c = {t.x * GateSizeX, static_cast(t.y * (GateSizeY * 3 / 4)), t.z}; + } + else if constexpr (has_flat_top_hex_orientation_v) + { + // horizontal distance between flat top hexagons is width * 3/4 + absolute_c = {static_cast(t.x * (GateSizeX * 3 / 4)), t.y * (GateSizeY), t.z}; + } - if constexpr (has_odd_row_hex_arrangement_v) { - if (gate_lyt.is_in_odd_row(t)) { - // odd rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); - } - } else if constexpr (has_even_row_hex_arrangement_v) { - if (gate_lyt.is_in_even_row(t)) { - // even rows are shifted in by width / 2 - absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); - } - } else if constexpr (has_odd_column_hex_arrangement_v) { - if (gate_lyt.is_in_odd_column(t)) { - // odd columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } - } else if constexpr (has_even_column_hex_arrangement_v) { - if (gate_lyt.is_in_even_column(t)) { - // even columns are shifted in by height / 2 - absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); - } + if constexpr (has_odd_row_hex_arrangement_v) + { + if (gate_lyt.is_in_odd_row(t)) + { + // odd rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } + else if constexpr (has_even_row_hex_arrangement_v) + { + if (gate_lyt.is_in_even_row(t)) + { + // even rows are shifted in by width / 2 + absolute_c.x += static_cast(static_cast(GateSizeX) / 2.0); + } + } + else if constexpr (has_odd_column_hex_arrangement_v) + { + if (gate_lyt.is_in_odd_column(t)) + { + // odd columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); } } - // more gate-level layout types go here - else { - assert(false && "unknown gate-level layout type"); + else if constexpr (has_even_column_hex_arrangement_v) + { + if (gate_lyt.is_in_even_column(t)) + { + // even columns are shifted in by height / 2 + absolute_c.y += static_cast(static_cast(GateSizeY) / 2.0); + } } + } + // more gate-level layout types go here + else + { + assert(false && "unknown gate-level layout type"); + } - absolute_c.x += relative_c.x; - absolute_c.y += relative_c.y; + absolute_c.x += relative_c.x; + absolute_c.y += relative_c.y; - return absolute_c; - } + return absolute_c; +} /** * Port directions address coordinates relative to each other by specifying cardinal directions. This function converts @@ -146,44 +181,55 @@ namespace fiction { * @param port Port direction. * @return Absolute coordinate specified by a coordinate `c` in layout `lyt` and a port direction. */ - template - [[nodiscard]] coordinate port_direction_to_coordinate(const Lyt &lyt, const coordinate &c, - const port_direction &port) noexcept { - static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); +template +[[nodiscard]] coordinate port_direction_to_coordinate(const Lyt& lyt, const coordinate& c, + const port_direction& port) noexcept +{ + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); - switch (port.dir) { - case port_direction::cardinal::NORTH: { - return lyt.north(c); - } - case port_direction::cardinal::NORTH_EAST: { - return lyt.north_east(c); - } - case port_direction::cardinal::EAST: { - return lyt.east(c); - } - case port_direction::cardinal::SOUTH_EAST: { - return lyt.south_east(c); - } - case port_direction::cardinal::SOUTH: { - return lyt.south(c); - } - case port_direction::cardinal::SOUTH_WEST: { - return lyt.south_west(c); - } - case port_direction::cardinal::WEST: { - return lyt.west(c); - } - case port_direction::cardinal::NORTH_WEST: { - return lyt.north_west(c); - } - default: { - assert(false && "Given port does not specify a cardinal direction"); - } + switch (port.dir) + { + case port_direction::cardinal::NORTH: + { + return lyt.north(c); + } + case port_direction::cardinal::NORTH_EAST: + { + return lyt.north_east(c); + } + case port_direction::cardinal::EAST: + { + return lyt.east(c); + } + case port_direction::cardinal::SOUTH_EAST: + { + return lyt.south_east(c); + } + case port_direction::cardinal::SOUTH: + { + return lyt.south(c); + } + case port_direction::cardinal::SOUTH_WEST: + { + return lyt.south_west(c); + } + case port_direction::cardinal::WEST: + { + return lyt.west(c); + } + case port_direction::cardinal::NORTH_WEST: + { + return lyt.north_west(c); + } + default: + { + assert(false && "Given port does not specify a cardinal direction"); } - - return {}; } + return {}; +} + /** * The layout is shifted by x_min and y_min such that the cells' coordinates are positive. * @@ -191,33 +237,38 @@ namespace fiction { * @param lyt The given layout which is shifted. * @return shifted layout. */ - template - Lyt normalize_layout_coordinates(const Lyt &lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); +template +Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept +{ + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - auto x_offset = std::numeric_limits::max(); - auto y_offset = std::numeric_limits::max(); - lyt.foreach_cell( - [&x_offset, &y_offset](const auto &c) { - if (c.y <= y_offset) { - y_offset = c.y; - } - if (c.x <= x_offset) { - x_offset = c.x; - } - }); + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + auto x_offset = std::numeric_limits::max(); + auto y_offset = std::numeric_limits::max(); + lyt.foreach_cell( + [&x_offset, &y_offset](const auto& c) + { + if (c.y <= y_offset) + { + y_offset = c.y; + } + if (c.x <= x_offset) + { + x_offset = c.x; + } + }); - lyt.foreach_cell( - [&lyt_new, &lyt, &x_offset, &y_offset](const auto &c) { - lyt_new.assign_cell_type({c.x - x_offset, c.y - y_offset}, lyt.get_cell_type(c)); - lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); - lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); - return lyt_new; - } + lyt.foreach_cell( + [&lyt_new, &lyt, &x_offset, &y_offset](const auto& c) + { + lyt_new.assign_cell_type({c.x - x_offset, c.y - y_offset}, lyt.get_cell_type(c)); + lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); + lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; +} /** * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is @@ -227,23 +278,25 @@ namespace fiction { * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. * @return new layout based on SiQAD coordinates. */ - template - sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt &lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - 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"); +template +sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept +{ + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + 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"); - sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - lyt.foreach_cell( - [&lyt_new, &lyt](const auto &c) { - lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); + sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_siqad_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); - return lyt_new; - } + return lyt_new; +} /** * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is @@ -253,37 +306,40 @@ namespace fiction { * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. * @return New layout based on Fiction coordinates. */ - template - Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad &lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); - 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"); +template +Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept +{ + static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + 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"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - if constexpr (has_offset_ucoord_v) { - auto lyt_normalized = normalize_layout_coordinates(lyt); - lyt_normalized.foreach_cell( - [&lyt_new, &lyt_normalized](const auto &c) { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), - lyt_normalized.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), - lyt_normalized.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), - lyt_normalized.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt_normalized.get_layout_name()); - } else { - lyt.foreach_cell( - [&lyt_new, &lyt](const auto &c) { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); - }); - lyt_new.set_layout_name(lyt.get_layout_name()); - } - return lyt_new; + if constexpr (has_offset_ucoord_v) + { + auto lyt_normalized = normalize_layout_coordinates(lyt); + lyt_normalized.foreach_cell( + [&lyt_new, &lyt_normalized](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt_normalized.get_layout_name()); + } + else + { + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); + }); + lyt_new.set_layout_name(lyt.get_layout_name()); } + return lyt_new; +} } // namespace fiction diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index a554c7046..6d149768e 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -21,24 +21,23 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia TestType lyt{{4, 4}}; lyt.foreach_coordinate( - [&lyt](const auto &c) { - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH}) == - lyt.north(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_EAST}) == - lyt.north_east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::EAST}) == - lyt.east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_EAST}) == - lyt.south_east(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH}) == - lyt.south(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_WEST}) == - lyt.south_west(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::WEST}) == - lyt.west(c)); - CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_WEST}) == - lyt.north_west(c)); - }); + [&lyt](const auto& c) + { + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH}) == + lyt.north(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_EAST}) == + lyt.north_east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::EAST}) == lyt.east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_EAST}) == + lyt.south_east(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH}) == + lyt.south(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::SOUTH_WEST}) == + lyt.south_west(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::WEST}) == lyt.west(c)); + CHECK(port_direction_to_coordinate(lyt, c, port_direction{port_direction::cardinal::NORTH_WEST}) == + lyt.north_west(c)); + }); } TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) @@ -46,7 +45,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordina SECTION("empty layout") { TestType lyt{{10, 10}, "test"}; - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + auto lyt_transformed = lyt_coordinates_to_siqad(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } @@ -104,7 +103,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -146,7 +145,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordi SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = lyt_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } From 5139d74ae85a8cc707589903cfbfa60763876916 Mon Sep 17 00:00:00 2001 From: Jan Drewniok <97012901+Drewniok@users.noreply.github.com> Date: Tue, 14 Feb 2023 08:02:43 +0100 Subject: [PATCH 11/21] Delete sidb_surface_analysis.hpp --- .../technology/sidb_surface_analysis.hpp | 136 ------------------ 1 file changed, 136 deletions(-) delete mode 100644 include/fiction/technology/sidb_surface_analysis.hpp diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp deleted file mode 100644 index 5d4ffa33f..000000000 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// Created by marcel on 01.04.22. -// - -#ifndef FICTION_SIDB_SURFACE_ANALYSIS_HPP -#define FICTION_SIDB_SURFACE_ANALYSIS_HPP - -#include "fiction/technology/cell_ports.hpp" -#include "fiction/technology/cell_technologies.hpp" -#include "fiction/technology/sidb_surface.hpp" -#include "fiction/traits.hpp" -#include "fiction/utils/layout_utils.hpp" - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace fiction -{ - -/** - * This alias represents a black list of gates that cannot be placed on certain positions on a (layout) surface in - * certain rotations. The type is just a map of tile positions to another map that associates gate functions with port - * lists. The second map ensures that each gate function stays unique while the port lists represent the black listed - * gate rotations. - * - * An empty port list vector means that the gate cannot be placed on the associated tile position AT ALL. This notion is - * to be used preferably as it, e.g., helps the exact physical design algorithm to convert these assertions into unit - * clauses which significantly helps runtime. - */ -template -using surface_black_list = - std::unordered_map, std::unordered_map>, - kitty::hash>>; - -/** - * Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library. Any gate type that - * cannot be realized on a certain tile due to disturbances caused by defects gets blacklisted on said tile. The black - * list is then returned by this function. - * - * @note The given gate library must implement both the `get_functional_implementations()` and `get_gate_ports()` - * functions. - * - * @tparam GateLibrary FCN gate library type to fetch the gate descriptions from. - * @tparam GateLyt Gate-level layout type that specifies the tiling of the SiDB surface. - * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. - * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. - * @param surface SiDB surface that instantiates the defects. - * @return A black list of gate functions associated with tiles. - */ -template -[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface) noexcept -{ - static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); - - static_assert(has_get_functional_implementations_v, - "GateLibrary does not implement the get_functional_implementations function"); - static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); - static_assert(std::is_same_v, technology>, - "CellLyt and GateLibrary must implement the same technology"); - - // fetch the port type used by the gate library - using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; - - surface_black_list black_list{}; - - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); - const auto gate_implementations = GateLibrary::get_functional_implementations(); - const auto gate_ports = GateLibrary::get_gate_ports(); - - // a lambda that analyzes defect impact on a gate at a given layout tile - // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error - // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() - // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it - const auto analyze_gate = [&](const auto& it, const auto& t) noexcept - { - const auto& [fun, impls] = it; - - // for each gate in the list of possible implementations - for (const auto& gate : impls) - { - // for each cell position in the gate - for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) - { - for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) - { - // if the cell type at position (x, y) in the gate is non-empty - if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) - { - // cell position within the gate - const cell relative_cell_pos{x, y, t.z}; - - const auto sidb_pos = - relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); - - // if any SiDB position of the current gate is compromised - if (sidbs_affected_by_defects.count(sidb_pos) > 0) - { - // add this gate's function to the black list of tile t using the ports - // specified by get_gate_ports in GateLibrary - for (const auto& port : gate_ports.at(gate)) - { - black_list[t][fun].push_back(port); - } - - return; // skip to next gate - } - } - } - } - } - }; - - // for each tile in the layout - gate_lyt.foreach_tile([&](const auto& t) constexpr { - // for each gate in the library - std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), - // analyze the defect impact - std::bind(analyze_gate, std::placeholders::_1, t)); - }); - - return black_list; -} - -} // namespace fiction - -#endif // FICTION_SIDB_SURFACE_ANALYSIS_HPP From 05111ad0960739d3c3b44b71f5cc3b9b55af4406 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 14 Feb 2023 08:18:15 +0100 Subject: [PATCH 12/21] :art: reformat code --- .../technology/sidb_surface_analysis.hpp | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 include/fiction/technology/sidb_surface_analysis.hpp diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp new file mode 100644 index 000000000..d90465b0d --- /dev/null +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -0,0 +1,137 @@ +// +// Created by marcel on 01.04.22. +// + +#ifndef FICTION_SIDB_SURFACE_ANALYSIS_HPP +#define FICTION_SIDB_SURFACE_ANALYSIS_HPP + +#include "fiction/technology/cell_ports.hpp" +#include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/sidb_surface.hpp" +#include "fiction/traits.hpp" +#include "fiction/utils/layout_utils.hpp" + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace fiction +{ + +/** + * This alias represents a black list of gates that cannot be placed on certain positions on a (layout) surface in + * certain rotations. The type is just a map of tile positions to another map that associates gate functions with port + * lists. The second map ensures that each gate function stays unique while the port lists represent the black listed + * gate rotations. + * + * An empty port list vector means that the gate cannot be placed on the associated tile position AT ALL. This notion is + * to be used preferably as it, e.g., helps the exact physical design algorithm to convert these assertions into unit + * clauses which significantly helps runtime. + */ +template +using surface_black_list = + std::unordered_map, std::unordered_map>, + kitty::hash>>; +/** + * Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library. Any gate type that + * cannot be realized on a certain tile due to disturbances caused by defects gets blacklisted on said tile. The black + * list is then returned by this function. + * + * @note The given gate library must implement both the `get_functional_implementations()` and `get_gate_ports()` + * functions. + * + * @tparam GateLibrary FCN gate library type to fetch the gate descriptions from. + * @tparam GateLyt Gate-level layout type that specifies the tiling of the SiDB surface. + * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. + * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. + * @param surface SiDB surface that instantiates the defects. + * @return A black list of gate functions associated with tiles. + */ +template +[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface) noexcept +{ + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(std::is_same_v, sidb_technology>, "CellLyt is not an SiDB layout"); + + static_assert(has_get_functional_implementations_v, + "GateLibrary does not implement the get_functional_implementations function"); + static_assert(has_get_gate_ports_v, "GateLibrary does not implement the get_gate_ports function"); + static_assert(std::is_same_v, technology>, + "CellLyt and GateLibrary must implement the same technology"); + + // fetch the port type used by the gate library + using port_type = typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type; + + surface_black_list black_list{}; + + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); + const auto gate_implementations = GateLibrary::get_functional_implementations(); + const auto gate_ports = GateLibrary::get_gate_ports(); + + // a lambda that analyzes defect impact on a gate at a given layout tile + // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error + // on Visual Studio 17 (2022) as it could not access GateLibrary::gate_x_size() and GateLibrary::gate_y_size() + // even though that should be possible and is perfectly valid C++ code... either way, this workaround fixes it + const auto analyze_gate = [&](const auto& it, const auto& t) noexcept + { + const auto& [fun, impls] = it; + + // for each gate in the list of possible implementations + for (const auto& gate : impls) + { + // for each cell position in the gate + for (uint16_t y = 0u; y < GateLibrary::gate_y_size(); ++y) + { + for (uint16_t x = 0u; x < GateLibrary::gate_x_size(); ++x) + { + // if the cell type at position (x, y) in the gate is non-empty + if (const auto cell_type = gate[y][x]; cell_type != technology::cell_type::EMPTY) + { + // cell position within the gate + const cell relative_cell_pos{x, y, t.z}; + + const auto sidb_pos = + relative_to_absolute_cell_position(gate_lyt, t, relative_cell_pos); + + // if any SiDB position of the current gate is compromised + if (sidbs_affected_by_defects.count(sidb_pos) > 0) + { + // add this gate's function to the black list of tile t using the ports + // specified by get_gate_ports in GateLibrary + for (const auto& port : gate_ports.at(gate)) + { + black_list[t][fun].push_back(port); + } + + return; // skip to next gate + } + } + } + } + } + }; + + // for each tile in the layout + gate_lyt.foreach_tile( + [&](const auto& t) constexpr + { + // for each gate in the library + std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), + // analyze the defect impact + std::bind(analyze_gate, std::placeholders::_1, t)); + }); + + return black_list; +} + +} // namespace fiction + +#endif // FICTION_SIDB_SURFACE_ANALYSIS_HPP From 13888036df744d981f41519911c84a59a70464b7 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 15 Feb 2023 11:01:18 +0100 Subject: [PATCH 13/21] :art: updated Marcel's suggestions --- docs/utils/utils.rst | 4 ++-- include/fiction/utils/layout_utils.hpp | 12 ++++++------ test/utils/layout_utils.cpp | 24 ++++++++++++------------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index 557fc4e5f..4ee216e10 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -55,8 +55,8 @@ Layout Utils .. doxygenfunction:: fiction::relative_to_absolute_cell_position .. doxygenfunction:: fiction::port_direction_to_coordinate .. doxygenfunction:: fiction::normalize_layout_coordinates -.. doxygenfunction:: fiction::lyt_coordinates_to_siqad -.. doxygenfunction:: fiction::lyt_coordinates_to_fiction +.. doxygenfunction:: fiction::layout_coordinates_to_siqad +.. doxygenfunction:: fiction::layout_coordinates_to_fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index ef06f847d..f8faaeec5 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -231,7 +231,7 @@ template } /** - * The layout is shifted by x_min and y_min such that the cells' coordinates are positive. + * The layout is shifted by x_offset and y_offset so that the coordinates of the cells are positive and one cell is at the coordinate origin. * * @tparam Lyt Cell-level layout. * @param lyt The given layout which is shifted. @@ -240,7 +240,7 @@ template template Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; @@ -279,9 +279,9 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept * @return new layout based on SiQAD coordinates. */ template -sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept +sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); 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"); @@ -307,9 +307,9 @@ sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt) noexcept * @return New layout based on Fiction coordinates. */ template -Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept +Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept { - static_assert(is_cartesian_layout_v, "Lyt is not a cartesian layout"); + static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); 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"); diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 6d149768e..902d631e9 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -40,12 +40,12 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia }); } -TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_coordinates_to_siqad]", sidb_cell_clk_lyt) { SECTION("empty layout") { TestType lyt{{10, 10}, "test"}; - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + auto lyt_transformed = layout_coordinates_to_siqad(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } @@ -55,7 +55,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordina TestType lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + auto lyt_transformed = layout_coordinates_to_siqad(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::INPUT); @@ -70,7 +70,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordina lyt.assign_cell_name({0, 0}, "normal cell"); lyt.assign_cell_name({5, 3}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); - auto lyt_transformed = lyt_coordinates_to_siqad(lyt); + auto lyt_transformed = layout_coordinates_to_siqad(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::INPUT); @@ -97,13 +97,13 @@ TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates" } } -TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coordinates_to_fiction]", +TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_coordinates_to_fiction]", sidb_cell_clk_lyt) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -113,7 +113,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -128,7 +128,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo lyt.assign_cell_name({5, 3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -139,13 +139,13 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_siqad_coo } } -TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordinates_to_fiction]", +TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_coordinates_to_fiction]", (cell_level_layout>>)) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -155,7 +155,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordi sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, -1, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 2, 0}) == TestType::cell_type::INPUT); @@ -170,7 +170,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordi lyt.assign_cell_name({5, -3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 3}, "output cell"); - auto lyt_transformed = lyt_coordinates_to_fiction(lyt); + auto lyt_transformed = layout_coordinates_to_fiction(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, -6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); From 1bbf6a28fbaac03d96e35661c585c5bafa6de97e Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 15 Feb 2023 11:25:38 +0100 Subject: [PATCH 14/21] :memo: Adjusted docstrings --- include/fiction/utils/layout_utils.hpp | 42 ++++++++++++++------------ 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index f8faaeec5..45050d634 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -231,11 +231,13 @@ template } /** - * The layout is shifted by x_offset and y_offset so that the coordinates of the cells are positive and one cell is at the coordinate origin. + * A new layout is constructed and returned that is equivalent to the given cell-level layout. However, its coordinates + * are normalized, i.e., start at `(0, 0)` and are all positive. To this end, all existing coordinates are shifted by an + * x and y offset. * - * @tparam Lyt Cell-level layout. - * @param lyt The given layout which is shifted. - * @return shifted layout. + * @tparam Lyt Cell-level layout type. + * @param lyt The layout which is to be normalized. + * @return New normalized equivalent layout. */ template Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept @@ -243,9 +245,11 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + auto x_offset = std::numeric_limits::max(); auto y_offset = std::numeric_limits::max(); + lyt.foreach_cell( [&x_offset, &y_offset](const auto& c) { @@ -266,17 +270,17 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept lyt_new.assign_cell_mode({c.x - x_offset, c.y - y_offset}, lyt.get_cell_mode(c)); lyt_new.assign_cell_name({c.x - x_offset, c.y - y_offset}, lyt.get_cell_name(c)); }); - lyt_new.set_layout_name(lyt.get_layout_name()); + return lyt_new; } /** - * The cell coordinates of a given layout are converted to SiQAD coordinates. A new layout with SiQAD coordinates is - * returned. + * Converts the coordinates of a given cell-level layout to SiQAD coordinates. A new equivalent layout based on SiQAD + * coordinates is returned. * - * @tparam Lyt Cell-level layout based on Fiction coordinates (Cube, Offset). - * @param lyt The given layout which is converted to a new layout based on SiQAD coordinates. - * @return new layout based on SiQAD coordinates. + * @tparam Lyt Cell-level layout type based on fiction coordinates, e.g., `offset::ucoord_t` or `cube::coord_t`. + * @param lyt The layout that is to be converted to a new layout based on SiQAD coordinates. + * @return A new equivalent layout based on SiQAD coordinates. */ template sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept @@ -286,6 +290,7 @@ sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + lyt.foreach_cell( [&lyt_new, &lyt](const auto& c) { @@ -293,18 +298,17 @@ sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept lyt_new.assign_cell_mode(siqad::to_siqad_coord>(c), lyt.get_cell_mode(c)); lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); }); - lyt_new.set_layout_name(lyt.get_layout_name()); return lyt_new; } /** - * The cell coordinates of a given layout are converted to Fiction coordinates. A new layout with Fiction coordinates is - * returned. + * Converts the coordinates of a given cell-level layout to fiction coordinates, e.g., `offset::ucoord_t` or + * `cube::coord_t`. A new equivalent layout based on fiction coordinates is returned. * - * @tparam Lyt Cell-level layout based on Fiction coordinates. - * @param lyt The given layout which is converted to a new layout based on Fiction coordinates. - * @return New layout based on Fiction coordinates. + * @tparam Lyt Cell-level layout type based on fiction coordinates. + * @param lyt The layout that is to be converted to a new layout based on fiction coordinates. + * @return A new equivalent layout based on fiction coordinates. */ template Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept @@ -318,6 +322,7 @@ Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept if constexpr (has_offset_ucoord_v) { auto lyt_normalized = normalize_layout_coordinates(lyt); + lyt_normalized.foreach_cell( [&lyt_new, &lyt_normalized](const auto& c) { @@ -325,7 +330,6 @@ Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)); lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); }); - lyt_new.set_layout_name(lyt_normalized.get_layout_name()); } else { @@ -336,8 +340,8 @@ Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); }); - lyt_new.set_layout_name(lyt.get_layout_name()); } + return lyt_new; } From abb53e5b190bbe264f5c670ecfd31df8c35cb859 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 15 Feb 2023 11:27:27 +0100 Subject: [PATCH 15/21] :art: Renamed functions --- docs/utils/utils.rst | 4 ++-- include/fiction/utils/layout_utils.hpp | 4 ++-- test/utils/layout_utils.cpp | 24 ++++++++++++------------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index 4ee216e10..f2f408cbe 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -55,8 +55,8 @@ Layout Utils .. doxygenfunction:: fiction::relative_to_absolute_cell_position .. doxygenfunction:: fiction::port_direction_to_coordinate .. doxygenfunction:: fiction::normalize_layout_coordinates -.. doxygenfunction:: fiction::layout_coordinates_to_siqad -.. doxygenfunction:: fiction::layout_coordinates_to_fiction +.. doxygenfunction:: fiction::convert_to_siqad_coordinates +.. doxygenfunction:: fiction::convert_to_fiction_coordinates diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 45050d634..b5d8f8641 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -283,7 +283,7 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept * @return A new equivalent layout based on SiQAD coordinates. */ template -sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept +sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept { static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); @@ -311,7 +311,7 @@ sidb_cell_clk_lyt_siqad layout_coordinates_to_siqad(const Lyt& lyt) noexcept * @return A new equivalent layout based on fiction coordinates. */ template -Lyt layout_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt) noexcept +Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept { static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 902d631e9..d530714d6 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -40,12 +40,12 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia }); } -TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_coordinates_to_siqad]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[convert_to_siqad_coordinates]", sidb_cell_clk_lyt) { SECTION("empty layout") { TestType lyt{{10, 10}, "test"}; - auto lyt_transformed = layout_coordinates_to_siqad(lyt); + auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } @@ -55,7 +55,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_coordinates_to_s TestType lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); - auto lyt_transformed = layout_coordinates_to_siqad(lyt); + auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::INPUT); @@ -70,7 +70,7 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_coordinates_to_s lyt.assign_cell_name({0, 0}, "normal cell"); lyt.assign_cell_name({5, 3}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); - auto lyt_transformed = layout_coordinates_to_siqad(lyt); + auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::INPUT); @@ -97,13 +97,13 @@ TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates" } } -TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_coordinates_to_fiction]", +TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[convert_to_fiction_coordinates]", sidb_cell_clk_lyt) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -113,7 +113,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_coordinat sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -128,7 +128,7 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_coordinat lyt.assign_cell_name({5, 3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -139,13 +139,13 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[layout_coordinat } } -TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_coordinates_to_fiction]", +TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[convert_to_fiction_coordinates]", (cell_level_layout>>)) { SECTION("empty layout") { sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -155,7 +155,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_coordinates_ sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({5, -1, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 2, 0}) == TestType::cell_type::INPUT); @@ -170,7 +170,7 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_coordinates_ lyt.assign_cell_name({5, -3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 3}, "output cell"); - auto lyt_transformed = layout_coordinates_to_fiction(lyt); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, -6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); From dd7b2641b5736b081d7ac3dadd4e68d74240d040 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 15 Feb 2023 11:33:38 +0100 Subject: [PATCH 16/21] :art: Fixed code duplication --- include/fiction/utils/layout_utils.hpp | 27 +++++++++++++------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index b5d8f8641..e35cfe6b5 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -319,27 +319,26 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept + { + base_lyt.foreach_cell( + [&lyt_new, &base_lyt](const auto& c) + { + lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), base_lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), base_lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), base_lyt.get_cell_name(c)); + }); + }; + if constexpr (has_offset_ucoord_v) { auto lyt_normalized = normalize_layout_coordinates(lyt); - lyt_normalized.foreach_cell( - [&lyt_new, &lyt_normalized](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt_normalized.get_cell_name(c)); - }); + assign_coordinates(lyt_normalized); } else { - lyt.foreach_cell( - [&lyt_new, &lyt](const auto& c) - { - lyt_new.assign_cell_type(siqad::to_fiction_coord>(c), lyt.get_cell_type(c)); - lyt_new.assign_cell_mode(siqad::to_fiction_coord>(c), lyt.get_cell_mode(c)); - lyt_new.assign_cell_name(siqad::to_fiction_coord>(c), lyt.get_cell_name(c)); - }); + assign_coordinates(lyt); } return lyt_new; From 432449d1708ebd436fb3d44341e11206ba4f17fe Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 15 Feb 2023 11:38:46 +0100 Subject: [PATCH 17/21] :art: Restructured tests --- test/utils/layout_utils.cpp | 74 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index d530714d6..f9ba1345b 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -40,12 +40,33 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia }); } -TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[convert_to_siqad_coordinates]", sidb_cell_clk_lyt) +TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates", "[layout-utils]", + sidb_cell_clk_lyt_siqad) +{ + SECTION("empty layout") + { + TestType lyt{{}, "layout based on siqad coordinates"}; + + lyt.assign_cell_type({-5, -1}, TestType::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); + + auto lyt_transformed = normalize_layout_coordinates(lyt); + + CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({10, 2}) == TestType::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({-5, -1}) == TestType::cell_type::EMPTY); + } +} + +TEMPLATE_TEST_CASE("Convert offset::ucoord_t layout to SiQAD coordinate layout", "[layout-utils]", sidb_cell_clk_lyt) { SECTION("empty layout") { TestType lyt{{10, 10}, "test"}; - auto lyt_transformed = convert_to_siqad_coordinates(lyt); + + auto lyt_transformed = convert_to_siqad_coordinates(lyt); + CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "test"); } @@ -53,9 +74,12 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[convert_to_siqad_coordi SECTION("layout with one normal and one input cell") { TestType lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); + auto lyt_transformed = convert_to_siqad_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::INPUT); @@ -64,13 +88,16 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[convert_to_siqad_coordi SECTION("layout with three cells") { TestType lyt{}; + lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 3}, TestType::cell_type::INPUT); lyt.assign_cell_type({5, 1}, TestType::cell_type::OUTPUT); lyt.assign_cell_name({0, 0}, "normal cell"); lyt.assign_cell_name({5, 3}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); + auto lyt_transformed = convert_to_siqad_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::INPUT); @@ -81,29 +108,14 @@ TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[convert_to_siqad_coordi } } -TEMPLATE_TEST_CASE("siqad layout is normalized, shifted to positive coordinates", "[normalize_layout_coordinates]", - sidb_cell_clk_lyt_siqad) +TEMPLATE_TEST_CASE("Convert SiQAD layout to offset::ucoord_t coordinate layout", "[layout-utils]", sidb_cell_clk_lyt) { SECTION("empty layout") { - TestType lyt{{}, "layout based on siqad coordinates"}; - lyt.assign_cell_type({-5, -1}, TestType::cell_type::NORMAL); - lyt.assign_cell_type({5, 1}, TestType::cell_type::NORMAL); - auto lyt_transformed = normalize_layout_coordinates(lyt); - CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); - CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({10, 2}) == TestType::cell_type::NORMAL); - CHECK(lyt_transformed.get_cell_type({-5, -1}) == TestType::cell_type::EMPTY); - } -} + const sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; + + auto lyt_transformed = convert_to_fiction_coordinates(lyt); -TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[convert_to_fiction_coordinates]", - sidb_cell_clk_lyt) -{ - SECTION("empty layout") - { - sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -111,9 +123,12 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[convert_to_ficti SECTION("layout with one normal and one input cell") { sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -122,13 +137,16 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[convert_to_ficti SECTION("layout with three cells") { sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); lyt.assign_cell_type({5, 1}, TestType::cell_type::OUTPUT); lyt.assign_cell_name({5, 3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 1}, "output cell"); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); @@ -139,13 +157,15 @@ TEMPLATE_TEST_CASE("siqad layout to offset::ucoord_t layout", "[convert_to_ficti } } -TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[convert_to_fiction_coordinates]", +TEMPLATE_TEST_CASE("Convert SiQAD layout to cube::coord_t coordinate layout", "[layout-utils]", (cell_level_layout>>)) { SECTION("empty layout") { - sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; - auto lyt_transformed = convert_to_fiction_coordinates(lyt); + const sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"}; + + auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.is_empty()); CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); } @@ -153,9 +173,12 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[convert_to_fiction_ SECTION("layout with one normal and one input cell") { sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5, -1, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 2); CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 2, 0}) == TestType::cell_type::INPUT); @@ -164,13 +187,16 @@ TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[convert_to_fiction_ SECTION("layout with three cells") { sidb_cell_clk_lyt_siqad lyt{}; + lyt.assign_cell_type({5, -3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); lyt.assign_cell_type({5, 3}, TestType::cell_type::OUTPUT); lyt.assign_cell_name({5, -3}, "normal cell"); lyt.assign_cell_name({0, 0}, "input cell"); lyt.assign_cell_name({5, 3}, "output cell"); + auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.num_cells() == 3); CHECK(lyt_transformed.get_cell_type({5, -6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); From 919ddd7e1bade7161591402e8edfb4565b58e40f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 15 Feb 2023 11:48:22 +0100 Subject: [PATCH 18/21] :test_tube: Added failing tests --- test/utils/layout_utils.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index f9ba1345b..6e90e6aaf 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -68,12 +68,13 @@ TEMPLATE_TEST_CASE("Convert offset::ucoord_t layout to SiQAD coordinate layout", auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.is_empty()); - CHECK(lyt_transformed.get_layout_name() == "test"); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); + CHECK(lyt_transformed.get_layout_name() == lyt.get_layout_name()); } SECTION("layout with one normal and one input cell") { - TestType lyt{}; + TestType lyt{{5, 3}}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1}, TestType::cell_type::INPUT); @@ -81,13 +82,14 @@ TEMPLATE_TEST_CASE("Convert offset::ucoord_t layout to SiQAD coordinate layout", auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::INPUT); } SECTION("layout with three cells") { - TestType lyt{}; + TestType lyt{{5, 3}}; lyt.assign_cell_type({0, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 3}, TestType::cell_type::INPUT); @@ -99,6 +101,7 @@ TEMPLATE_TEST_CASE("Convert offset::ucoord_t layout to SiQAD coordinate layout", auto lyt_transformed = convert_to_siqad_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({0, 0, 0}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 1, 1}) == TestType::cell_type::INPUT); CHECK(lyt_transformed.get_cell_type({5, 0, 1}) == TestType::cell_type::OUTPUT); @@ -117,12 +120,13 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to offset::ucoord_t coordinate layout", auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.is_empty()); - CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + CHECK(static_cast(lyt_transformed.area()) == lyt.area()); + CHECK(lyt_transformed.get_layout_name() == lyt.get_layout_name()); } SECTION("layout with one normal and one input cell") { - sidb_cell_clk_lyt_siqad lyt{}; + sidb_cell_clk_lyt_siqad lyt{{5, 3}}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); @@ -130,13 +134,14 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to offset::ucoord_t coordinate layout", auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); + CHECK(static_cast(lyt_transformed.area()) == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); } SECTION("layout with three cells") { - sidb_cell_clk_lyt_siqad lyt{}; + sidb_cell_clk_lyt_siqad lyt{{5, 3}}; lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); @@ -148,6 +153,7 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to offset::ucoord_t coordinate layout", auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); + CHECK(static_cast(lyt_transformed.area()) == lyt.area()); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); CHECK(lyt_transformed.get_cell_type({5, 2}) == TestType::cell_type::OUTPUT); @@ -167,12 +173,13 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to cube::coord_t coordinate layout", "[ auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.is_empty()); - CHECK(lyt_transformed.get_layout_name() == "layout based on siqad coordinates"); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); + CHECK(lyt_transformed.get_layout_name() == lyt.get_layout_name()); } SECTION("layout with one normal and one input cell") { - sidb_cell_clk_lyt_siqad lyt{}; + sidb_cell_clk_lyt_siqad lyt{{5, 1, 1}}; lyt.assign_cell_type({5, -1, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({5, 1, 0}, TestType::cell_type::INPUT); @@ -180,13 +187,14 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to cube::coord_t coordinate layout", "[ auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({5, -1}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({5, 2, 0}) == TestType::cell_type::INPUT); } SECTION("layout with three cells") { - sidb_cell_clk_lyt_siqad lyt{}; + sidb_cell_clk_lyt_siqad lyt{{5, 3}}; lyt.assign_cell_type({5, -3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({0, 0}, TestType::cell_type::INPUT); @@ -198,6 +206,7 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to cube::coord_t coordinate layout", "[ auto lyt_transformed = convert_to_fiction_coordinates(lyt); CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.area() == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({5, -6}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); CHECK(lyt_transformed.get_cell_type({5, 6}) == TestType::cell_type::OUTPUT); From c26d134b26e128fceef1e7e35db1b1a50d82b056 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 15 Feb 2023 12:18:53 +0100 Subject: [PATCH 19/21] :art: aspect-ratio added for copy process --- include/fiction/utils/layout_utils.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index e35cfe6b5..c4ac60a58 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -245,7 +245,7 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; auto x_offset = std::numeric_limits::max(); auto y_offset = std::numeric_limits::max(); @@ -289,7 +289,7 @@ sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept 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"); - sidb_cell_clk_lyt_siqad lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + sidb_cell_clk_lyt_siqad lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; lyt.foreach_cell( [&lyt_new, &lyt](const auto& c) @@ -317,7 +317,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept 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"); - Lyt lyt_new{{}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept { From c3fc617725a738f87cc0ab38df68fd3a7714fb61 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 15 Feb 2023 12:19:11 +0100 Subject: [PATCH 20/21] :art: aspect-ratio added for copy process --- include/fiction/utils/layout_utils.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index c4ac60a58..2819bf4b6 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -245,7 +245,7 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{lyt.x(), lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; auto x_offset = std::numeric_limits::max(); auto y_offset = std::numeric_limits::max(); @@ -289,7 +289,10 @@ sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept 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"); - sidb_cell_clk_lyt_siqad lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + sidb_cell_clk_lyt_siqad lyt_new{{lyt.x(), lyt.y()}, + lyt.get_layout_name(), + lyt.get_tile_size_x(), + lyt.get_tile_size_y()}; lyt.foreach_cell( [&lyt_new, &lyt](const auto& c) @@ -317,7 +320,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept 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"); - Lyt lyt_new{{lyt.x(),lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{lyt.x(), lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept { From bc6ed9e1c66786b1fd2025243deb1247c2c01729 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 16 Feb 2023 14:46:40 +0100 Subject: [PATCH 21/21] :art: aspect-ratio added for copy process --- include/fiction/utils/layout_utils.hpp | 15 +++++++++------ test/utils/layout_utils.cpp | 5 ++++- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 2819bf4b6..9661857d8 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -245,8 +245,6 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - Lyt lyt_new{{lyt.x(), lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; - auto x_offset = std::numeric_limits::max(); auto y_offset = std::numeric_limits::max(); @@ -263,6 +261,11 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept } }); + Lyt lyt_new{{lyt.x() - x_offset, lyt.y() - y_offset, lyt.z()}, + lyt.get_layout_name(), + lyt.get_tile_size_x(), + lyt.get_tile_size_y()}; + lyt.foreach_cell( [&lyt_new, &lyt, &x_offset, &y_offset](const auto& c) { @@ -289,7 +292,7 @@ sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept 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"); - sidb_cell_clk_lyt_siqad lyt_new{{lyt.x(), lyt.y()}, + sidb_cell_clk_lyt_siqad lyt_new{{lyt.x(), lyt.y(), lyt.z()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; @@ -320,7 +323,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept 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"); - Lyt lyt_new{{lyt.x(), lyt.y()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + Lyt lyt_new{{lyt.x(), lyt.y(), lyt.z()}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept { @@ -333,11 +336,11 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept }); }; - if constexpr (has_offset_ucoord_v) + if (has_offset_ucoord_v && !lyt.is_empty()) { auto lyt_normalized = normalize_layout_coordinates(lyt); - assign_coordinates(lyt_normalized); + lyt_new.resize({lyt_normalized.x(), lyt_normalized.y(), lyt_normalized.z()}); } else { diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 6e90e6aaf..b484a01e0 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -130,11 +130,14 @@ TEMPLATE_TEST_CASE("Convert SiQAD layout to offset::ucoord_t coordinate layout", lyt.assign_cell_type({5, 3}, TestType::cell_type::NORMAL); lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT); + CHECK(lyt.x() == 5); + CHECK(lyt.y() == 3); auto lyt_transformed = convert_to_fiction_coordinates(lyt); + CHECK(lyt_transformed.x() == 10); + CHECK(lyt_transformed.y() == 4); CHECK(lyt_transformed.num_cells() == 2); - CHECK(static_cast(lyt_transformed.area()) == static_cast(lyt.area())); CHECK(lyt_transformed.get_cell_type({10, 8}) == TestType::cell_type::NORMAL); CHECK(lyt_transformed.get_cell_type({0, 0}) == TestType::cell_type::INPUT); }