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

✨ Support defects in print function. #261

Merged
merged 61 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
9622e83
:arrow_up: Bump libs/Catch2 from `6783411` to `1f881ab` (#27)
dependabot[bot] Apr 2, 2023
2da4f7e
Merge branch 'marcelwa:main' into main
Drewniok Apr 14, 2023
8f5f52f
:arrow_up: Bump libs/parallel-hashmap from `7883cb6` to `d2bed96` (#33)
dependabot[bot] Apr 14, 2023
a8cbc27
Merge branch 'marcelwa:main' into main
Drewniok Apr 18, 2023
3b11f93
Merge branch 'marcelwa:main' into main
Drewniok Apr 18, 2023
e9e2fa3
Merge branch 'marcelwa:main' into main
Drewniok Apr 18, 2023
37c881e
Merge branch 'marcelwa:main' into main
Drewniok Apr 19, 2023
4aa8489
Merge branch 'marcelwa:main' into main
Drewniok Apr 19, 2023
1587ef3
Merge branch 'marcelwa:main' into main
Drewniok Apr 20, 2023
04ed1c3
Merge branch 'marcelwa:main' into main
Drewniok Apr 21, 2023
9eaaf1f
Merge branch 'marcelwa:main' into main
Drewniok Apr 25, 2023
0dca9cf
Merge branch 'marcelwa:main' into main
Drewniok Apr 26, 2023
ce8b2e2
Merge branch 'marcelwa:main' into main
Drewniok May 1, 2023
64501c1
Merge branch 'marcelwa:main' into main
Drewniok May 10, 2023
68f6885
Merge branch 'marcelwa:main' into main
Drewniok May 11, 2023
84634cd
Merge branch 'marcelwa:main' into main
Drewniok May 12, 2023
597b1a7
Merge branch 'marcelwa:main' into main
Drewniok May 12, 2023
1920794
Merge branch 'marcelwa:main' into main
Drewniok May 14, 2023
5d74ac6
Merge branch 'marcelwa:main' into main
Drewniok May 21, 2023
f408962
Merge branch 'marcelwa:main' into main
Drewniok May 24, 2023
b4138de
Merge branch 'marcelwa:main' into main
Drewniok May 25, 2023
930fcf2
Merge branch 'marcelwa:main' into main
Drewniok Jun 5, 2023
cbd8345
Merge branch 'marcelwa:main' into main
Drewniok Jun 7, 2023
2903532
Merge branch 'marcelwa:main' into main
Drewniok Jun 12, 2023
f70ceb6
Merge branch 'marcelwa:main' into main
Drewniok Jun 14, 2023
24ff3a7
Merge branch 'marcelwa:main' into main
Drewniok Jun 16, 2023
a4f3150
Merge branch 'marcelwa:main' into main
Drewniok Jun 19, 2023
9c78984
Merge branch 'marcelwa:main' into main
Drewniok Jun 23, 2023
c3f4e96
Merge branch 'marcelwa:main' into main
Drewniok Jun 28, 2023
853be74
Merge branch 'cda-tum:main' into main
Drewniok Jul 5, 2023
13eab3c
Merge branch 'cda-tum:main' into main
Drewniok Jul 10, 2023
1c59a58
Merge branch 'cda-tum:main' into main
Drewniok Jul 18, 2023
1f87c22
Merge branch 'cda-tum:main' into main
Drewniok Jul 20, 2023
d300bc1
Merge branch 'cda-tum:main' into main
Drewniok Jul 24, 2023
2dc75ac
Merge branch 'cda-tum:main' into main
Drewniok Jul 25, 2023
9fc5819
Merge branch 'cda-tum:main' into main
Drewniok Jul 26, 2023
bd5cfc3
Merge branch 'cda-tum:main' into main
Drewniok Jul 26, 2023
51b93cb
Merge branch 'cda-tum:main' into main
Drewniok Jul 26, 2023
88dee4d
:art: small changes here and there.
Drewniok Jul 28, 2023
337c655
:white_check_mark: add unit test.
Drewniok Jul 28, 2023
dc51c99
:art: add color for defects.
Drewniok Jul 28, 2023
e652382
:bug: wrong charge state.
Drewniok Jul 28, 2023
62fcaa7
:white_check_mark: add additional test.
Drewniok Jul 28, 2023
2c911d8
:art: use ternary conditional operator ``?:``.
Drewniok Aug 2, 2023
53d06af
:art: remove ``<cstdint>``.
Drewniok Aug 2, 2023
751369c
Merge branch 'cda-tum:main' into main
Drewniok Aug 3, 2023
8031b33
Merge branch 'main' into add_defects_to_print_function
Drewniok Aug 3, 2023
0cae87e
:art: add defect operators as members.
Drewniok Aug 3, 2023
0bad685
:art: implement Marcel's suggestions.
Drewniok Aug 3, 2023
b466760
:art: implement Marcel's suggestions.
Drewniok Aug 5, 2023
311339b
Merge branch 'cda-tum:main' into main
Drewniok Aug 10, 2023
df7e094
Merge branch 'main' into add_defects_to_print_function
Drewniok Aug 10, 2023
16c12e4
Merge branch 'cda-tum:main' into main
Drewniok Aug 27, 2023
317c887
Merge branch 'main' into add_defects_to_print_function
Drewniok Aug 27, 2023
7b2fc73
:art: siqad coordinates support in bounding box.
Drewniok Aug 28, 2023
e3123c6
:fire: delete separate bounding box function for siqad coordinates.
Drewniok Aug 28, 2023
b6aec60
:sparkles: print sidbs, charges and defects of sidb layout.
Drewniok Aug 28, 2023
3ea1c74
:art: implement clang-tidy suggestions.
Drewniok Aug 28, 2023
a984dc9
:art: Applied some pedantic small fixes
marcelwa Aug 29, 2023
15641f1
:art: implement suggestions.
Drewniok Aug 29, 2023
859d79a
Merge branch 'main' into add_defects_to_print_function
Drewniok Aug 29, 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
2 changes: 1 addition & 1 deletion docs/io/visualization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Layout Printing

.. doxygenfunction:: fiction::print_gate_level_layout
.. doxygenfunction:: fiction::print_cell_level_layout
.. doxygenfunction:: fiction::print_charge_layout
.. doxygenfunction:: fiction::print_sidb_layout
.. doxygenfunction:: fiction::print_layout

Graphviz (DOT) Drawers
Expand Down
168 changes: 131 additions & 37 deletions include/fiction/io/print_layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

#include "fiction/layouts/bounding_box.hpp"
#include "fiction/technology/charge_distribution_surface.hpp"
#include "fiction/technology/sidb_defects.hpp"
#include "fiction/technology/sidb_surface.hpp"
#include "fiction/traits.hpp"
#include "fiction/types.hpp"
#include "fiction/utils/layout_utils.hpp"

#include <fmt/color.h>
#include <fmt/format.h>
Expand Down Expand Up @@ -45,6 +48,13 @@
static const auto SIDB_NEUT_COLOR = fmt::fg(fmt::color::white);
// Escape color sequence for lattice background colors (grey).
static const auto SIDB_LAT_COLOR = fmt::fg(fmt::color::gray);

// Escape color sequence for positively charged defect colors (red).
static const auto SIDB_DEF_POS_COLOR = fmt::fg(fmt::color::red);
// Escape color sequence for negatively charged defect colors (blue).
static const auto SIDB_DEF_NEG_COLOR = fmt::fg(fmt::color::blue);
// Escape color sequence for neutrally charged defect colors (yellow).
static const auto SIDB_DEF_NEU_COLOR = fmt::fg(fmt::color::yellow);
// Empty escape color sequence
inline constexpr auto NO_COLOR = fmt::text_style{};

Expand Down Expand Up @@ -325,90 +335,174 @@
os << std::endl;
}
/**
* Writes a simplified 2D representation of an SiDB charge layout to an output stream.
* Writes a simplified 2D representation of an SiDB layout (SiDB and defect charges are supported) to an output stream.
*
* @tparam Lyt SiDB cell-level layout with charge-information based on SiQAD coordinates, e.g., a
* charge_distribution_surface object.
* @tparam Lyt SiDB cell-level layout with charge-information based on SiQAD coordinates or defect-information, e.g., a
* charge_distribution_surface or sidb_surface.
* @param os Output stream to write into.
* @param lyt The layout of which the charge distribution is to be printed.
* @param lyt The layout of which the information is to be printed.
* @param cs_color Flag to utilize color escapes for charge states.
* @param crop_layout Flag to print the 2D bounding box of the layout, while leaving a maximum padding of one dimer row
* and two columns.
* @param draw_lattice Flag to enable lattice background drawing.
*/
template <typename Lyt>
void print_charge_layout(std::ostream& os, const Lyt& lyt, const bool cs_color = true, const bool crop_layout = false,
const bool draw_lattice = true)
void print_sidb_layout(std::ostream& os, const Lyt& lyt, const bool cs_color = true, const bool crop_layout = false,
const bool draw_lattice = true)
{
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");
static_assert(has_sidb_technology_v<Lyt>, "Lyt is not an SiDB layout");
static_assert(has_siqad_coord_v<Lyt>, "Lyt is not based on SiQAD coordinates");
static_assert(has_get_charge_state_v<Lyt>, "Lyt does not implement the get_charge_state function");

// empty layout
if (lyt.is_empty())
{
os << "[i] empty layout" << std::endl;
return;
if constexpr (has_get_sidb_defect_v<Lyt>)
{
if (lyt.num_defects() == 0)
{
os << "[i] empty layout" << std::endl;
return;
}
}
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
else
{
os << "[i] empty layout" << std::endl;
return;
}
}

coordinate<Lyt> min{};
coordinate<Lyt> max{lyt.x(), lyt.y(), 1};
const bounding_box_2d bb{lyt};

if (crop_layout)
auto min_nw = bb.get_min();
auto max_se = bb.get_max();

std::vector<typename Lyt::cell> defects{};

// Check if defects exist in the layout.
if constexpr (has_get_sidb_defect_v<Lyt>)
{
const auto bb = bounding_box_2d{lyt};
if (lyt.num_defects() != 0)
{
defects.reserve(lyt.num_defects());
lyt.foreach_sidb_defect([&defects](const auto& c) { defects.push_back(c.first); });
std::sort(defects.begin(), defects.end());
min_nw = min_nw > defects.front() ?
defects.front() :

Check warning on line 391 in include/fiction/io/print_layout.hpp

View check run for this annotation

Codecov / codecov/patch

include/fiction/io/print_layout.hpp#L391

Added line #L391 was not covered by tests
min_nw; // if a defect is more north-west than nw, this position is used as min.
max_se = max_se < defects.back() ?
defects.back() :

Check warning on line 394 in include/fiction/io/print_layout.hpp

View check run for this annotation

Codecov / codecov/patch

include/fiction/io/print_layout.hpp#L394

Added line #L394 was not covered by tests
max_se; // if a defect is more south-east than se, this position is used as max.
}
}

if (crop_layout)
{
// apply padding of maximally one dimer row and two columns
min = bb.get_min() - coordinate<Lyt>{2, 1};
max = bb.get_max() + coordinate<Lyt>{2, 1};
min_nw = min_nw - coordinate<Lyt>{2, 1};
max_se = max_se + coordinate<Lyt>{2, 1};

// ensure only full dimer rows are printed
min.z = 0;
max.z = 1;
min_nw.z = 0;
max_se.z = 1;
}

// iterate over all coordinates in the rows determined by the vertical crop
lyt.foreach_coordinate(
[&](const coordinate<Lyt>& c)
{
if (crop_layout && (c.x < min.x || c.x > max.x)) // apply horizontal crop
{
return;
}
// loop coordinate is initialized with the north-west coordinate.
auto loop_coordinate = min_nw;

while (loop_coordinate <= max_se)
{
// Is set to true if either charge or defect is printed at loop coordinate.
bool already_printed = false;

switch (lyt.get_charge_state(c)) // switch over the charge state of the SiDB at the current coordinate
// Check if layout is only a charge distribution surface.
if constexpr (has_get_charge_state_v<Lyt>)
{
switch (lyt.get_charge_state(
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
loop_coordinate)) // switch over the charge state of the SiDB at the current coordinate
{
case sidb_charge_state::NEGATIVE:
{
os << fmt::format(cs_color ? detail::SIDB_NEG_COLOR : detail::NO_COLOR, " ● ");
already_printed = true;
break;
}
case sidb_charge_state::POSITIVE:
{
os << fmt::format(cs_color ? detail::SIDB_POS_COLOR : detail::NO_COLOR, " ⨁ ");
already_printed = true;
break;
}
case sidb_charge_state::NEUTRAL:
{
os << fmt::format(cs_color ? detail::SIDB_NEUT_COLOR : detail::NO_COLOR, " ◯ ");
already_printed = true;
break;
}
default: // NONE charge state case -> empty cell
}
Fixed Show fixed Hide fixed
}

if constexpr (has_get_sidb_defect_v<Lyt>)
{
if (lyt.get_sidb_defect(loop_coordinate) != sidb_defect{sidb_defect_type::NONE})
{
if (is_negatively_charged_defect(lyt.get_sidb_defect(loop_coordinate)))
{
os << fmt::format(cs_color ? detail::SIDB_DEF_NEG_COLOR : detail::NO_COLOR, " ⊟ ");
already_printed = true;
}

else if (is_positively_charged_defect(lyt.get_sidb_defect(loop_coordinate)))
{
os << fmt::format(cs_color ? detail::SIDB_DEF_POS_COLOR : detail::NO_COLOR, " ⊞ ");
already_printed = true;
}
else if (is_neutrally_charged_defect(lyt.get_sidb_defect(loop_coordinate)))
{
os << (draw_lattice || !lyt.is_empty_cell(c) ?
fmt::format(cs_color ? detail::SIDB_LAT_COLOR : detail::NO_COLOR, " · ") :
" ");
os << fmt::format(cs_color ? detail::SIDB_DEF_NEU_COLOR : detail::NO_COLOR, " ⊡ ");
already_printed = true;
}
}
}

if (c.x == max.x)
if (!already_printed && lyt.get_cell_type(loop_coordinate) != sidb_technology::cell_type::EMPTY)
{
os << fmt::format(cs_color ? detail::SIDB_DEF_NEU_COLOR : detail::NO_COLOR, " o ");
already_printed = true;
}

if (!already_printed)
{
os << (draw_lattice ? fmt::format(cs_color ? detail::SIDB_LAT_COLOR : detail::NO_COLOR, " · ") : " ");
}

// If the x-coordinate of loop_coordinate is still less than the x-coordinate of the south-west cell, the
// x-coordinate is increased by 1.
if (loop_coordinate.x < max_se.x)
{
loop_coordinate.x += 1;
}

else if (loop_coordinate.x == max_se.x && loop_coordinate != max_se)
{
if (loop_coordinate.z == 1)
{
os << (c.z == 1 ? "\n\n" : "\n");
os << "\n\n"; // gap between two dimers.
}
},
min, max + coordinate<Lyt>{1, 0});

else
{
os << "\n";
}
loop_coordinate.x = min_nw.x;
loop_coordinate.y += (loop_coordinate.z == 1) ? 1 : 0;
loop_coordinate.z = (loop_coordinate.z == 0) ? 1 : 0;
}
else if (loop_coordinate == max_se)
{
os << "\n\n"; // add a gap between two dimers.
break;
}
}
// flush stream
os << std::endl;
}
Expand All @@ -433,9 +527,9 @@
}
else if constexpr (is_cell_level_layout_v<Lyt>)
{
if constexpr (has_sidb_technology_v<Lyt> && has_siqad_coord_v<Lyt> && has_get_charge_state_v<Lyt>)
if constexpr (has_sidb_technology_v<Lyt>)
{
print_charge_layout(os, lyt);
print_sidb_layout(os, lyt);
}
else
{
Expand Down
80 changes: 62 additions & 18 deletions include/fiction/layouts/bounding_box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
#ifndef FICTION_BOUNDING_BOX_HPP
#define FICTION_BOUNDING_BOX_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 "fiction/utils/layout_utils.hpp"

// data types cannot properly be converted to bit field types
#pragma GCC diagnostic push
Expand Down Expand Up @@ -53,35 +58,74 @@ class bounding_box_2d
return;
}

// set min to max coordinate in the layout
min = {layout.x(), layout.y()};
// the layout is based on siqad-coordinates
if constexpr (has_siqad_coord_v<Lyt>)
{
// the layout is first converted to fiction coordinates
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
const auto converted_layout = convert_to_fiction_coordinates<
cell_level_layout<sidb_technology, clocked_layout<cartesian_layout<cube::coord_t>>>>(layout);

int32_t min_x = std::numeric_limits<int32_t>::max();
int32_t max_x = std::numeric_limits<int32_t>::min();

int32_t min_y = std::numeric_limits<int32_t>::max();
int32_t max_y = std::numeric_limits<int32_t>::min();

layout.foreach_coordinate(
[this](const auto& c)
{
if (!is_empty_coordinate(c))
converted_layout.foreach_cell(
[&converted_layout, &min_x, &max_x, &min_y, &max_y](const auto& c)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
if (c.x < min.x)
if (c.x < min_x)
{
min_x = c.x;
}
if (c.y < min_y)
{
min.x = c.x;
min_y = c.y;
}
if (c.y < min.y)
if (c.x > max_x)
{
min.y = c.y;
max_x = c.x;
}
if (c.x > max.x)
if (c.y > max_y)
{
max.x = c.x;
max_y = c.y;
}
if (c.y > max.y)
});
min = siqad::to_siqad_coord(cube::coord_t{min_x, min_y});
max = siqad::to_siqad_coord(cube::coord_t{max_x, max_y});
}
else
{
// set min to max coordinate in the layout
min = {layout.x(), layout.y()};

layout.foreach_coordinate(
[this](const auto& c)
{
if (!is_empty_coordinate(c))
{
max.y = c.y;
if (c.x < min.x)
{
min.x = c.x;
}
if (c.y < min.y)
{
min.y = c.y;
}
if (c.x > max.x)
{
max.x = c.x;
}
if (c.y > max.y)
{
max.y = c.y;
}
}
}
});
});

x_size = max.x - min.x;
y_size = max.y - min.y;
x_size = max.x - min.x;
y_size = max.y - min.y;
}
}
/**
* Returns the minimum corner of the bounding box.
Expand Down
Loading
Loading