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

🎨 Allow fiction coordinates for simulation and other functions. #336

Merged
merged 10 commits into from
Nov 27, 2023
2 changes: 1 addition & 1 deletion docs/utils/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Layout Utils
.. doxygenfunction:: fiction::convert_to_siqad_coordinates
.. doxygenfunction:: fiction::convert_to_fiction_coordinates
.. doxygenfunction:: fiction::random_coordinate
.. doxygenfunction:: fiction::all_sidbs_in_spanned_area
.. doxygenfunction:: fiction::all_coordinates_in_spanned_area


Placement Utils
Expand Down
1 change: 0 additions & 1 deletion include/fiction/algorithms/iter/bdl_input_iterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ class bdl_input_iterator
{
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");

set_all_inputs();
}
Expand Down
1 change: 0 additions & 1 deletion include/fiction/algorithms/path_finding/distance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ sidb_nanometer_distance([[maybe_unused]] const Lyt& lyt, const coordinate<Lyt>&
{
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 based on SiDB technology");
static_assert(has_siqad_coord_v<Lyt>, "Lyt is not based on SiQAD coordinates");

const auto pos_c1 = sidb_nm_position<Lyt>(sp, source);
const auto pos_c2 = sidb_nm_position<Lyt>(sp, target);
Expand Down
34 changes: 18 additions & 16 deletions include/fiction/algorithms/physical_design/design_sidb_gates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
/**
* This struct contains parameters and settings to design SiDB gates.
*
* @tparam Cell-level layout type.
*
*/
template <typename Lyt>
struct design_sidb_gates_params
{
/**
Expand Down Expand Up @@ -66,7 +69,7 @@
/**
* Canvas spanned by the northwest and southeast cell.
*/
std::pair<siqad::coord_t, siqad::coord_t> canvas{};
std::pair<typename Lyt::cell, typename Lyt::cell> canvas{};
/**
* Number of SiDBs placed in the canvas to create a working gate.
*/
Expand All @@ -92,11 +95,11 @@
* @param tt Expected Boolean function of the layout given as a multi-output truth table.
* @param ps Parameters and settings for the gate designer.
*/
design_sidb_gates_impl(const Lyt& skeleton, const std::vector<TT>& tt, const design_sidb_gates_params& ps) :
design_sidb_gates_impl(const Lyt& skeleton, const std::vector<TT>& tt, const design_sidb_gates_params<Lyt>& ps) :
skeleton_layout{skeleton},
truth_table{tt},
params{ps},
all_sidbs_in_cavas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)}
all_sidbs_in_canvas{all_coordinates_in_spanned_area(params.canvas.first, params.canvas.second)}
{}
/**
* Design gates exhaustively and in parallel.
Expand Down Expand Up @@ -220,11 +223,11 @@
/**
* Parameters for the *SiDB Gate Designer*.
*/
const design_sidb_gates_params& params;
const design_sidb_gates_params<Lyt>& params;
/**
* All cells within the canvas.
*/
const std::vector<fiction::siqad::coord_t> all_sidbs_in_cavas;
const std::vector<typename Lyt::cell> all_sidbs_in_canvas;
/**
* Calculates all possible combinations of distributing the given number of SiDBs within a canvas
* based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in
Expand All @@ -236,9 +239,9 @@
[[nodiscard]] std::vector<std::vector<std::size_t>> determine_all_combinations_of_given_sidbs_in_canvas() noexcept
{
std::vector<std::vector<std::size_t>> all_combinations{};
all_combinations.reserve(binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs));
all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs));

std::vector<std::size_t> numbers(all_sidbs_in_cavas.size());
std::vector<std::size_t> numbers(all_sidbs_in_canvas.size());
std::iota(numbers.begin(), numbers.end(), 0);

combinations::for_each_combination(
Expand Down Expand Up @@ -279,9 +282,8 @@
{
for (std::size_t j = i + 1; j < cell_indices.size(); j++)
{
if (sidb_nanometer_distance<sidb_cell_clk_lyt_siqad>(skeleton_layout,
all_sidbs_in_cavas[cell_indices[i]],
all_sidbs_in_cavas[cell_indices[j]]) < 0.5)
if (sidb_nanometer_distance<Lyt>(skeleton_layout, all_sidbs_in_canvas[cell_indices[i]],
all_sidbs_in_canvas[cell_indices[j]]) < 0.5)

Check warning on line 286 in include/fiction/algorithms/physical_design/design_sidb_gates.hpp

View check run for this annotation

Codecov / codecov/patch

include/fiction/algorithms/physical_design/design_sidb_gates.hpp#L285-L286

Added lines #L285 - L286 were not covered by tests
{
return true;
}
Expand All @@ -301,11 +303,11 @@

for (const auto i : cell_indices)
{
assert(i < all_sidbs_in_cavas.size() && "cell indices are out-of-range");
assert(i < all_sidbs_in_canvas.size() && "cell indices are out-of-range");

if (lyt_copy.get_cell_type(all_sidbs_in_cavas[i]) == sidb_technology::cell_type::EMPTY)
if (lyt_copy.get_cell_type(all_sidbs_in_canvas[i]) == sidb_technology::cell_type::EMPTY)
{
lyt_copy.assign_cell_type(all_sidbs_in_cavas[i], sidb_technology::cell_type::NORMAL);
lyt_copy.assign_cell_type(all_sidbs_in_canvas[i], sidb_technology::cell_type::NORMAL);
}
}

Expand Down Expand Up @@ -344,12 +346,12 @@
*/
template <typename Lyt, typename TT>
[[nodiscard]] std::vector<Lyt> design_sidb_gates(const Lyt& skeleton, const std::vector<TT>& spec,
const design_sidb_gates_params& params = {}) noexcept
const design_sidb_gates_params<Lyt>& params = {}) noexcept
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");
static_assert(!is_charge_distribution_surface_v<Lyt>, "Lyt cannot be a charge distribution surface");

assert(skeleton.num_pis() > 0 && "skeleton needs input cells");
assert(skeleton.num_pos() > 0 && "skeleton needs output cells");
Expand All @@ -361,7 +363,7 @@

detail::design_sidb_gates_impl<Lyt, TT> p{skeleton, spec, params};

if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE)
if (params.design_mode == design_sidb_gates_params<Lyt>::design_sidb_gates_mode::EXHAUSTIVE)
{
return p.run_exhaustive_design();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ assess_physical_population_stability(const Lyt& lyt, const assess_physical_popul
{
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(!is_charge_distribution_surface_v<Lyt>, "Lyt cannot be a charge distribution surface");

detail::assess_physical_population_stability_impl<Lyt> p{lyt, params};
return p.run();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ calculate_energy_and_state_type(const sidb_energy_distribution&
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

assert(!output_bdl_pairs.empty() && "No output cell provided.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ struct bdl_pair
{
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");
}
};

Expand Down Expand Up @@ -96,7 +95,6 @@ std::vector<bdl_pair<Lyt>> detect_bdl_pairs(const Lyt& lyt, const typename techn
{
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");

// sanity check for parameter settings
assert(params.minimum_distance <= params.maximum_distance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ template <typename Lyt>
{
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");

if (exhaustive_results.charge_distributions.empty())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ is_operational(const Lyt& lyt, const std::vector<TT>& spec, const is_operational
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

assert(lyt.num_pis() > 0 && "skeleton needs input cells");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ struct maximum_defect_influence_distance_params
* The pair describes the width and height of the area around the gate, which is
* also used to place defects.
*
* @note The height of the area (second entry of the pair) is given in the y coordinate of the SiQAD coordinates.
* This means that it describes the number of dimer rows.
* @note If SiQAD coordinates are used, the second entry describes the number of dimer rows.
*/
std::pair<int32_t, int32_t> additional_scanning_area{50, 6};
};
Expand Down Expand Up @@ -98,49 +97,53 @@ class maximum_defect_influence_position_and_distance_impl
// simulate the impact of the defect at a given position on the ground state of the SiDB layout
const auto process_defect = [&](const auto& defect) noexcept
{
sidb_surface<Lyt> lyt_defect{};
if (layout.get_cell_type(defect) == Lyt::technology::cell_type::EMPTY)
{
sidb_surface<Lyt> lyt_defect{};

layout.foreach_cell([this, &lyt_defect](const auto& cell)
{ lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); });
layout.foreach_cell([this, &lyt_defect](const auto& cell)
{ lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); });

// assign defect to layout
lyt_defect.assign_sidb_defect(defect, params.defect);
// conduct simulation with defect
auto simulation_result_defect = quickexact(lyt_defect, params_defect);
// assign defect to layout
lyt_defect.assign_sidb_defect(defect, params.defect);
// conduct simulation with defect
auto simulation_result_defect = quickexact(lyt_defect, params_defect);

const auto min_energy_defect = minimum_energy(simulation_result_defect.charge_distributions);
uint64_t charge_index_defect_layout = 0;
const auto min_energy_defect = minimum_energy(simulation_result_defect.charge_distributions);
uint64_t charge_index_defect_layout = 0;

// get the charge index of the ground state
for (const auto& lyt_simulation_with_defect : simulation_result_defect.charge_distributions)
{
if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) -
round_to_n_decimal_places(min_energy_defect, 6)) < std::numeric_limits<double>::epsilon())
// get the charge index of the ground state
for (const auto& lyt_simulation_with_defect : simulation_result_defect.charge_distributions)
{
lyt_simulation_with_defect.charge_distribution_to_index_general();
charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first;
}
}

// defect changes the ground state, i.e., the charge index is changed compared to the charge
// distribution without placed defect.
if (charge_index_defect_layout != charge_index_layout)
{
auto distance = std::numeric_limits<double>::max();
layout.foreach_cell(
[this, &defect, &distance](const auto& cell)
if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) -
round_to_n_decimal_places(min_energy_defect, 6)) <
std::numeric_limits<double>::epsilon())
{
if (sidb_nanometer_distance<Lyt>(layout, cell, defect) < distance)
{
distance = sidb_nanometer_distance<Lyt>(layout, cell, defect);
}
});
lyt_simulation_with_defect.charge_distribution_to_index_general();
charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first;
}
}

// the distance is larger than the current maximum one.
if (distance > avoidance_distance)
// defect changes the ground state, i.e., the charge index is changed compared to the charge
// distribution without placed defect.
if (charge_index_defect_layout != charge_index_layout)
{
max_defect_position = defect;
avoidance_distance = distance;
auto distance = std::numeric_limits<double>::max();
layout.foreach_cell(
[this, &defect, &distance](const auto& cell)
{
if (sidb_nanometer_distance<Lyt>(layout, cell, defect) < distance)
{
distance = sidb_nanometer_distance<Lyt>(layout, cell, defect);
}
});

// the distance is larger than the current maximum one.
if (distance > avoidance_distance)
{
max_defect_position = defect;
avoidance_distance = distance;
}
}
}
};
Expand Down Expand Up @@ -187,43 +190,7 @@ class maximum_defect_influence_position_and_distance_impl
se.x = se.x + params.additional_scanning_area.first;
se.y = se.y + params.additional_scanning_area.second;

// start to place the defect at the north-west cell
auto defect_cell = nw;

// maximum number of placable defects in the given bounding box
const uint64_t max_defect_positions =
static_cast<uint64_t>(std::abs(se.x - nw.x) + 1) * static_cast<uint64_t>(std::abs(se.y - nw.y) + 1) * 2;
defect_cells.reserve(max_defect_positions);

// collect all cells in the bounding box area (spanned by the nw and se) going from top to down from left to
// right.
while (defect_cell <= se)
{
// Defect can only be placed at free locations.
if (layout.get_cell_type(defect_cell) == sidb_technology::cell_type::EMPTY)
{
defect_cells.push_back(defect_cell);
}
if (defect_cell.x < se.x)
{
defect_cell.x += 1;
}
else if ((defect_cell.x == se.x) && defect_cell.z == 0)
{
defect_cell.z += 1;
defect_cell.x = nw.x;
}
else if ((defect_cell.x == se.x) && defect_cell.z == 1)
{
defect_cell.x = nw.x;
defect_cell.y += 1;
defect_cell.z = 0;
}
else
{
break;
}
}
defect_cells = all_coordinates_in_spanned_area(nw, se);
}
};

Expand All @@ -249,7 +216,8 @@ maximum_defect_influence_position_and_distance(const Lyt&
{
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_offset_ucoord_v<Lyt>, "Lyt cannot be based on offset coordinates");
static_assert(!is_charge_distribution_surface_v<Lyt>, "Lyt cannot be a charge distribution surface");

detail::maximum_defect_influence_position_and_distance_impl<Lyt> p{lyt, sim_params};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,6 @@ operational_domain operational_domain_grid_search(const Lyt& lyt, const std::vec
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

operational_domain_stats st{};
Expand Down Expand Up @@ -1017,7 +1016,6 @@ operational_domain operational_domain_random_sampling(const Lyt& lyt, const std:
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

operational_domain_stats st{};
Expand Down Expand Up @@ -1066,7 +1064,6 @@ operational_domain operational_domain_flood_fill(const Lyt& lyt, const std::vect
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

operational_domain_stats st{};
Expand Down Expand Up @@ -1118,7 +1115,6 @@ operational_domain operational_domain_contour_tracing(const Lyt& lyt, const std:
{
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(kitty::is_truth_table<TT>::value, "TT is not a truth table");

operational_domain_stats st{};
Expand Down
Loading
Loading