Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Added conversion functions for layouts of different coordinate types #125

Merged
merged 25 commits into from
Mar 2, 2023
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
f76860b
:sparkles: functions to convert layouts to a new layout based on a ne…
Feb 12, 2023
dfa2269
Merge branch 'main' into siqad_coodinates_to_fiction_vs
Feb 12, 2023
e40fbc1
:sparkles: functions to convert layouts to a new layout based on a ne…
Feb 12, 2023
d7de6c3
:art: put functions in different header, added missing attributes, up…
Feb 13, 2023
514b990
:memo: docu updated
Feb 13, 2023
2a058a3
:art: new function to shift layout to positive coordinates
Feb 13, 2023
35e3728
:art: new function to shift layout to positive coordinates
Feb 13, 2023
f46f4e3
:art: updated Marcel's suggestions
Feb 13, 2023
c258e70
:art: reformat code
Feb 13, 2023
8ea6c24
:art: reformat code
Feb 13, 2023
1e04450
:art: reformat code
Feb 13, 2023
5139d74
Delete sidb_surface_analysis.hpp
Drewniok Feb 14, 2023
05111ad
:art: reformat code
Feb 14, 2023
1388803
:art: updated Marcel's suggestions
Feb 15, 2023
1bbf6a2
:memo: Adjusted docstrings
marcelwa Feb 15, 2023
abb53e5
:art: Renamed functions
marcelwa Feb 15, 2023
dd7b264
:art: Fixed code duplication
marcelwa Feb 15, 2023
432449d
:art: Restructured tests
marcelwa Feb 15, 2023
919ddd7
:test_tube: Added failing tests
marcelwa Feb 15, 2023
c26d134
:art: aspect-ratio added for copy process
Feb 15, 2023
c3fc617
:art: aspect-ratio added for copy process
Feb 15, 2023
bc6ed9e
:art: aspect-ratio added for copy process
Feb 16, 2023
04c7b66
Merge branch 'main' into siqad_coodinates_to_fiction_vs
Drewniok Feb 17, 2023
bbb9721
Merge branch 'main' into siqad_coodinates_to_fiction_vs
Drewniok Feb 19, 2023
23db248
Merge branch 'main' into siqad_coodinates_to_fiction_vs
marcelwa Mar 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/utils/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ 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
.. doxygenfunction:: fiction::normalize_layout_coordinates
Drewniok marked this conversation as resolved.
Show resolved Hide resolved


Placement Utils
Expand Down
2 changes: 2 additions & 0 deletions include/fiction/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,8 @@ template <typename Lyt>
inline constexpr const bool has_sidb_technology_v = std::is_same_v<technology<Lyt>, sidb_technology>;
template <typename Lyt>
inline constexpr const bool has_siqad_coord_v = std::is_same_v<coordinate<Lyt>, siqad::coord_t>;
template <typename Lyt>
inline constexpr const bool has_offset_ucoord_v = std::is_same_v<coordinate<Lyt>, offset::ucoord_t>;
Drewniok marked this conversation as resolved.
Show resolved Hide resolved

#pragma region is_cell_level_layout
template <class Lyt, class = void>
Expand Down
120 changes: 120 additions & 0 deletions include/fiction/utils/layout_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <cassert>
#include <cstdint>
Expand Down Expand Up @@ -224,6 +227,123 @@ template <typename Lyt>
return {};
}

/**
* The layout is shifted by x_min and y_min such that the cells' coordinates are positive.
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
*
* @tparam Lyt Cell-level layout.
* @param lyt The given layout which is shifted.
* @return shifted layout.
*/
template <typename Lyt>
Lyt normalize_layout_coordinates(const Lyt& lyt)
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
if (lyt.num_cells() == 0)
{
return lyt;
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
}
Lyt lyt_new{};
auto x_min = INT32_MAX;
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
auto y_min = INT32_MAX;
lyt.foreach_cell(
[&lyt, &x_min, &y_min](const auto& c)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
if (c.y <= y_min && c.x <= x_min)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
y_min = c.y;
x_min = c.x;
}
else if (c.y <= y_min)
{
y_min = c.y;
}
else if (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)),
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
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());
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
return lyt_new;
}

/**
* 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 <typename Lyt>
sidb_cell_clk_lyt_siqad lyt_coordinates_to_siqad(const Lyt& lyt)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
static_assert(is_cartesian_layout_v<Lyt>, "Lyt is not a cartesian layout");
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");
static_assert(has_sidb_technology_v<Lyt>, "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<cell<Lyt>>(c), lyt.get_cell_type(c)),
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
lyt_new.assign_cell_mode(siqad::to_siqad_coord<cell<Lyt>>(c), lyt.get_cell_mode(c)),
lyt_new.assign_cell_name(siqad::to_siqad_coord<cell<Lyt>>(c), lyt.get_cell_name(c));
});
lyt_new.set_layout_name(lyt.get_layout_name());
marcelwa marked this conversation as resolved.
Show resolved Hide resolved

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 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 <typename Lyt>
Lyt lyt_coordinates_to_fiction(const sidb_cell_clk_lyt_siqad& lyt)
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
{
static_assert(is_cartesian_layout_v<Lyt>, "Lyt is not a cartesian layout");
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");
static_assert(has_sidb_technology_v<Lyt>, "Lyt is not an SiDB layout");

Lyt lyt_new{};

if constexpr (has_offset_ucoord_v<Lyt>)
{
auto lyt_normalized = normalize_layout_coordinates<sidb_cell_clk_lyt_siqad>(lyt);
lyt_normalized.foreach_cell(
[&lyt_new, &lyt_normalized](const auto& c)
marcelwa marked this conversation as resolved.
Show resolved Hide resolved
{
lyt_new.assign_cell_type(siqad::to_fiction_coord<cell<Lyt>>(c), lyt_normalized.get_cell_type(c)),
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
lyt_new.assign_cell_mode(siqad::to_fiction_coord<cell<Lyt>>(c), lyt_normalized.get_cell_mode(c)),
lyt_new.assign_cell_name(siqad::to_fiction_coord<cell<Lyt>>(c), lyt_normalized.get_cell_name(c));
});
lyt_new.set_layout_name(lyt_normalized.get_layout_name());
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
lyt.foreach_cell(
[&lyt_new, &lyt](const auto& c)
{
lyt_new.assign_cell_type(siqad::to_fiction_coord<cell<Lyt>>(c), lyt.get_cell_type(c)),
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
lyt_new.assign_cell_mode(siqad::to_fiction_coord<cell<Lyt>>(c), lyt.get_cell_mode(c)),
lyt_new.assign_cell_name(siqad::to_fiction_coord<cell<Lyt>>(c), lyt.get_cell_name(c));
});
lyt_new.set_layout_name(lyt.get_layout_name());
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
}
return lyt_new;
}

} // namespace fiction

#endif // FICTION_LAYOUT_UTILS_HPP
139 changes: 139 additions & 0 deletions test/utils/layout_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <catch2/catch_template_test_macros.hpp>

#include <fiction/layouts/cartesian_layout.hpp>
#include <fiction/layouts/cell_level_layout.hpp>
#include <fiction/layouts/coordinates.hpp>
#include <fiction/layouts/hexagonal_layout.hpp>
#include <fiction/utils/layout_utils.hpp>
Expand Down Expand Up @@ -38,3 +39,141 @@ TEMPLATE_TEST_CASE("Port directions to coordinates", "[layout-utils]", (cartesia
lyt.north_west(c));
});
}

TEMPLATE_TEST_CASE("offset::ucoord_t to siqad layout", "[layout_fiction_coordinates_to_siqad]", sidb_cell_clk_lyt)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
SECTION("empty layout")
{
TestType lyt{{10, 10}, "test"};
auto lyt_transformed = lyt_coordinates_to_siqad<TestType>(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<TestType>(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<TestType>(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("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<TestType>(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<TestType>(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, 3}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({-5, -1}, TestType::cell_type::INPUT);
auto lyt_transformed = lyt_coordinates_to_fiction<TestType>(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);
}

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 = lyt_coordinates_to_fiction<TestType>(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");
}
}

TEMPLATE_TEST_CASE("siqad layout to cube::coord_t layout", "[layout_siqad_coordinates_to_fiction]", (cell_level_layout<sidb_technology, clocked_layout<cartesian_layout<cube::coord_t>>>))
{
SECTION("empty layout")
{
sidb_cell_clk_lyt_siqad lyt{{}, "layout based on siqad coordinates"};
auto lyt_transformed = lyt_coordinates_to_fiction<TestType>(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<TestType>(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<TestType>(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");
}
}