Skip to content

Commit

Permalink
🐛 Bug fixes and improvements related to the coordinate system (#225)
Browse files Browse the repository at this point in the history
* ✨ Added a specialisation for iteration over SiQAD coordinates

* ✅ Added tests for coordinate iteration

* 📝 Updated foreach coordinate documentation to clarify last coordinate exclusivity

* 🎨 Updated print_charge_layout to use the new foreach_coordinate specialisation

* 🎨 ClangFormat suggestions

* 🎨 Implemented suggestions from PR conversations

* 💚 Added a no-lint block to please Clang-Tidy (std namespace overloading)

* ✨ Made siqad::coord_t compatible with fmt::format

* ✅ Increased test coverage

* 🎨 Reformatted file

* 🎨 Rewrote test to make use of TEMPLATE_TEST_CASE

* 📝 Split coordinate enumeration documentation into offset and cubic vs. SiQAD

* 📝 Removed "Offset coordinates are required" from cartesian layouts docs

* 🐛 Cartesian layouts based on SiQAD coordinates now always have full dimer rows

* ✨ Added an abs function defined on arbitrary number types to math_utils

* 🐛 Addition and subtraction on SiQAD coordinates is now defined properly

* 🐛 Area computation is now dependent on the coordinate type

* ✨ Added a clamping function to each coordinate type

* 🐛 Coordinate iteration is now defined on out-of-bounds iterators

* 🥅 Added static_asserts checking the absence of SiQAD coordinates

* ✨ Made cropped charge layout printing opt-in optional

* 🔥 Removed unnecessary import

* 🐛 Converting a layout from fiction to SiQAD coordinates or vice versa now resizes the layout appropriately

* 🎨 Applied ClangFormat to all files

* ⚡ Made initialize_dimension const

* 🎨 Made use of bounding_box_2d

* 🔥 Removed debug output

* ✅ Increased test coverage

* 🐛 Avoided multiplication before casting to a higher type

* 📝 Reinterpreted coordinate clamping to coordinate wrapping

* ✅ Added test and newline at end of file

* ✅ Addition/subtraction of cube coordinates now actually uses cube coordinates

* ✅ Avoided equality test on floating point values

* 🎨 Avoided double variable declaration

* 🔥 Removed floating point support from new abs function (use std::fabs for this)

* 🎨 Added `noexcept` to `math_utils` functions
  • Loading branch information
wlambooy authored Jun 2, 2023
1 parent 08792fe commit 80fe66b
Show file tree
Hide file tree
Showing 12 changed files with 591 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ template <typename CellLyt, typename GateLibrary, typename GateLyt>
CellLyt apply_gate_library(const GateLyt& lyt)
{
static_assert(is_cell_level_layout_v<CellLyt>, "CellLyt is not a cell-level layout");
static_assert(!has_siqad_coord_v<CellLyt>, "CellLyt cannot have SiQAD coordinates");
static_assert(is_gate_level_layout_v<GateLyt>, "GateLyt is not a gate-level layout");
static_assert(mockturtle::has_is_constant_v<GateLyt>, "GateLyt does not implement the is_constant function");
static_assert(mockturtle::has_foreach_node_v<GateLyt>, "GateLyt does not implement the foreach_node function");
Expand Down
41 changes: 18 additions & 23 deletions include/fiction/io/print_layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FICTION_PRINT_LAYOUT_HPP
#define FICTION_PRINT_LAYOUT_HPP

#include "fiction/layouts/bounding_box.hpp"
#include "fiction/technology/charge_distribution_surface.hpp"
#include "fiction/traits.hpp"
#include "fiction/types.hpp"
Expand All @@ -16,7 +17,6 @@
#include <array>
#include <cstdint>
#include <iostream>
#include <limits>
#include <string>
#include <vector>

Expand Down Expand Up @@ -331,11 +331,13 @@ void print_cell_level_layout(std::ostream& os, const Lyt& layout, const bool io_
* @param os Output stream to write into.
* @param cds The charge distribution surface of which the charge layout 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 charge_distribution_surface<Lyt>& cds, const bool cs_color = true,
const bool draw_lattice = true) noexcept
const bool crop_layout = false, const bool draw_lattice = true) noexcept
{
// empty layout
if (cds.is_empty())
Expand All @@ -344,34 +346,27 @@ void print_charge_layout(std::ostream& os, const charge_distribution_surface<Lyt
return;
}

// obtain the crop dimensions
auto min_x = std::numeric_limits<decltype(cds.x())>::max();
auto max_x = std::numeric_limits<decltype(cds.x())>::min();
coordinate<Lyt> min{};
coordinate<Lyt> max{cds.x(), cds.y(), 1};

auto min_y = std::numeric_limits<decltype(cds.y())>::max();
auto max_y = std::numeric_limits<decltype(cds.y())>::min();

cds.foreach_cell(
[&cds, &min_x, &max_x, &min_y, &max_y](const cell<Lyt>& c)
{
if (!cds.is_empty_cell(c))
{
min_x = std::min(min_x, c.x);
max_x = std::max(max_x, c.x);
if (crop_layout)
{
const auto bb = bounding_box_2d{cds};

min_y = std::min(min_y, c.y);
max_y = std::max(max_y, c.y);
}
});
// 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};

const coordinate<Lyt> min{std::max(min_x - 2, 0), std::max(min_y - 1, 0)};
const coordinate<Lyt> max{std::min(max_x + 2, cds.x()), std::min(max_y + 1, cds.y())};
// ensure only full dimer rows are printed
min.z = 0;
max.z = 1;
}

// iterate over all coordinates in the rows determined by the vertical crop
cds.foreach_coordinate(
[&](const coordinate<Lyt>& c)
{
if (c.x < min.x || c.x > max.x) // apply horizontal crop
if (crop_layout && (c.x < min.x || c.x > max.x)) // apply horizontal crop
{
return;
}
Expand Down Expand Up @@ -406,7 +401,7 @@ void print_charge_layout(std::ostream& os, const charge_distribution_surface<Lyt
os << (c.z == 1 ? "\n\n" : "\n");
}
},
min, {0, max.y + 1, 0});
min, max + coordinate<Lyt>{1, 0});

// flush stream
os << std::endl;
Expand Down
27 changes: 22 additions & 5 deletions include/fiction/layouts/cartesian_layout.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
#include <cstdint>
#include <functional>
#include <memory>
#include <type_traits>
#include <utility>
#include <vector>

namespace fiction
{

/**
* A layout type that utilizes offset coordinates to represent a Cartesian grid. Its faces are organized in the
* following way:
Expand All @@ -39,7 +41,7 @@ namespace fiction
+-------+-------+-------+-------+
\endverbatim
*
* @tparam OffsetCoordinateType The coordinate implementation to be used. Offset coordinates are required.
* @tparam OffsetCoordinateType The coordinate implementation to be used.
*/
template <typename OffsetCoordinateType = offset::ucoord_t>
class cartesian_layout
Expand Down Expand Up @@ -70,7 +72,9 @@ class cartesian_layout
*
* @param ar Highest possible position in the layout.
*/
explicit cartesian_layout(const aspect_ratio& ar = {}) : strg{std::make_shared<cartesian_layout_storage>(ar)} {}
explicit cartesian_layout(const aspect_ratio& ar = {}) :
strg{std::make_shared<cartesian_layout_storage>(initialize_dimension(ar))}
{}
/**
* Copy constructor from another layout's storage.
*
Expand Down Expand Up @@ -109,13 +113,13 @@ class cartesian_layout
return strg->dimension.z;
}
/**
* Returns the layout's number of faces which are equal to \f$ (x + 1) \cdot (y + 1) \f$.
* Returns the layout's number of faces depending on the coordinate type.
*
* @return Area of layout.
*/
[[nodiscard]] auto area() const noexcept
{
return (x() + 1) * (y() + 1);
return fiction::area(strg->dimension);
}
/**
* Updates the layout's dimensions, effectively resizing it.
Expand All @@ -124,7 +128,7 @@ class cartesian_layout
*/
void resize(const aspect_ratio& ar) noexcept
{
strg->dimension = ar;
strg->dimension = initialize_dimension(ar);
}

#pragma endregion
Expand Down Expand Up @@ -782,6 +786,19 @@ class cartesian_layout

private:
storage strg;
/*
* Initializer for a cartesian layout dimension. When using SiQAD coordinates, it will default the z value to 1 if
* the y value is greater than 0.
*/
constexpr OffsetCoordinateType initialize_dimension(const OffsetCoordinateType& coord) const
{
if constexpr (std::is_same_v<OffsetCoordinateType, siqad::coord_t>)
{
return OffsetCoordinateType{coord.x, coord.y, 1};
}

return coord;
}
};

} // namespace fiction
Expand Down
Loading

0 comments on commit 80fe66b

Please sign in to comment.