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

🐛 Include x_min and y_min in OpDomain and check non-emptyness of vector before accessing element. #407

Merged
merged 19 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
62 changes: 41 additions & 21 deletions include/fiction/algorithms/simulation/sidb/operational_domain.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,34 +262,48 @@ class operational_domain_impl
params{ps},
stats{st},
output_bdl_pairs{detect_bdl_pairs<Lyt>(layout, sidb_technology::cell_type::OUTPUT, params.bdl_params)},
x_indices(num_x_steps()), // pre-allocate the x dimension indices
y_indices(num_y_steps()), // pre-allocate the y dimension indices
x_values(num_x_steps()), // pre-allocate the x dimension values
y_values(num_y_steps()) // pre-allocate the y dimension values
x_indices(num_x_steps() + 1), // pre-allocate the x dimension indices
y_indices(num_y_steps() + 1) // pre-allocate the y dimension indices
{
x_values.reserve(num_x_steps() + 1);
y_values.reserve(num_y_steps() + 1);

op_domain.x_dimension = params.x_dimension;
op_domain.y_dimension = params.y_dimension;

std::iota(x_indices.begin(), x_indices.end(), 0ul);
std::iota(y_indices.begin(), y_indices.end(), 0ul);

// If the value of the x-parameter is greater than params.x_max after num_x_steps() steps, this value is
// ignored in the operational domain calculation.
if ((params.x_min + (x_indices.size() - 1) * params.x_step) - params.x_max >
physical_constants::POP_STABILITY_ERR)
{
x_indices.pop_back();
}
// If the value of the y-parameter is greater than params.y_max after num_y_steps() steps, this value is
// ignored in the operational domain calculation.
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
if (((params.y_min + (y_indices.size() - 1) * params.y_step) - params.y_max) >
physical_constants::POP_STABILITY_ERR)
{
y_indices.pop_back();
}

// generate the x dimension values
std::generate(x_values.begin(), x_values.end(),
[x = 0, this]() mutable
{
const double x_val = params.x_min + x * params.x_step;
++x;
return x_val;
});
auto x_val = params.x_min;
for (size_t i = 0; i <= x_indices.size(); ++i)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
x_values.push_back(x_val);
x_val += params.x_step;
}

Drewniok marked this conversation as resolved.
Show resolved Hide resolved
// generate the y dimension values
std::generate(y_values.begin(), y_values.end(),
[y = 0, this]() mutable
{
const double y_val = params.y_min + y * params.y_step;
++y;
return y_val;
});
auto y_val = params.y_min;
for (size_t i = 0; i <= y_indices.size(); ++i)
Drewniok marked this conversation as resolved.
Show resolved Hide resolved
{
y_values.push_back(y_val);
y_val += params.y_step;
}
}
/**
* Performs a grid search over the specified parameter ranges with the specified step sizes. The grid search always
Expand Down Expand Up @@ -455,9 +469,15 @@ class operational_domain_impl
step_point{current_contour_point.x - 1, current_contour_point.y};

auto current_neighborhood = moore_neighborhood(current_contour_point);
auto next_point = current_contour_point == backtrack_point ?
current_neighborhood.front() :
next_clockwise_point(current_neighborhood, backtrack_point);

auto next_point = contour_starting_point;

if (!current_neighborhood.empty())
{
next_point = current_contour_point == backtrack_point ?
current_neighborhood.front() :
next_clockwise_point(current_neighborhood, backtrack_point);
}

while (next_point != contour_starting_point)
{
Expand Down
129 changes: 105 additions & 24 deletions test/algorithms/simulation/sidb/operational_domain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ void check_op_domain_params_and_operational_status(const operational_domain&

for (const auto& [coord, op_value] : op_domain.operational_values)
{
CHECK(coord.x >= params.x_min);
CHECK(coord.x <= params.x_max);
CHECK(coord.y >= params.y_min);
CHECK(coord.y <= params.y_max);
CHECK(coord.x - params.x_min > -physical_constants::POP_STABILITY_ERR);
CHECK(params.x_max - coord.x > -physical_constants::POP_STABILITY_ERR);
CHECK(coord.y - params.y_min > -physical_constants::POP_STABILITY_ERR);
CHECK(params.y_max - coord.y > -physical_constants::POP_STABILITY_ERR);

if (status)
{
Expand Down Expand Up @@ -85,22 +85,103 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")

operational_domain_stats op_domain_stats{};

SECTION("operational area, only one parameter point")
{
op_domain_params.x_min = 5.5;
op_domain_params.x_max = 5.5;
op_domain_params.x_step = 0.1;

op_domain_params.y_min = 5.0;
op_domain_params.y_max = 5.0;
op_domain_params.y_step = 0.1;

SECTION("grid_search")
{
const auto op_domain = operational_domain_grid_search(lat, std::vector<tt>{create_id_tt()},
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 1);

// for the selected range, all samples should be within the parameters and operational
check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL);

CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0);
CHECK(op_domain_stats.num_simulator_invocations == 2);
CHECK(op_domain_stats.num_evaluated_parameter_combinations == 1);
CHECK(op_domain_stats.num_operational_parameter_combinations == 1);
CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0);
}
SECTION("random_sampling")
{
const auto op_domain = operational_domain_random_sampling(lat, std::vector<tt>{create_id_tt()}, 100,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 1);

// for the selected range, all samples should be within the parameters and operational
check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL);

CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0);
CHECK(op_domain_stats.num_simulator_invocations <= 200);
CHECK(op_domain_stats.num_evaluated_parameter_combinations <= 100);
CHECK(op_domain_stats.num_evaluated_parameter_combinations > 0);
CHECK(op_domain_stats.num_operational_parameter_combinations <= 100);
CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0);
}
SECTION("flood_fill")
{
const auto op_domain = operational_domain_flood_fill(lat, std::vector<tt>{create_id_tt()}, 1,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 1);

// for the selected range, all samples should be within the parameters and operational
check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL);

CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0);
CHECK(op_domain_stats.num_simulator_invocations == 2);
CHECK(op_domain_stats.num_evaluated_parameter_combinations == 1);
CHECK(op_domain_stats.num_operational_parameter_combinations == 1);
CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0);
}
SECTION("contour_tracing")
{
const auto op_domain = operational_domain_contour_tracing(lat, std::vector<tt>{create_id_tt()}, 1,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 1);

// for the selected range, all samples should be within the parameters and operational
check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL);

CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0);
CHECK(op_domain_stats.num_simulator_invocations == 2);
CHECK(op_domain_stats.num_evaluated_parameter_combinations == 1);
CHECK(op_domain_stats.num_operational_parameter_combinations == 1);
CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0);
}
}

SECTION("operational area, same number of steps in x- and y-direction")
{
op_domain_params.x_min = 5.1;
op_domain_params.x_max = 6.1;
op_domain_params.x_max = 6.0;
op_domain_params.x_step = 0.1;

op_domain_params.y_min = 4.5;
op_domain_params.y_max = 5.5;
op_domain_params.y_max = 5.4;
op_domain_params.y_step = 0.1;

SECTION("grid_search")
{
const auto op_domain = operational_domain_grid_search(lat, std::vector<tt>{create_id_tt()},
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size (10 steps in each dimension)
// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 100);
Drewniok marked this conversation as resolved.
Show resolved Hide resolved

// for the selected range, all samples should be within the parameters and operational
Expand All @@ -117,7 +198,7 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
const auto op_domain = operational_domain_random_sampling(lat, std::vector<tt>{create_id_tt()}, 100,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size (max 10 steps in each dimension)
// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() <= 100);

// for the selected range, all samples should be within the parameters and operational
Expand All @@ -135,7 +216,7 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
const auto op_domain = operational_domain_flood_fill(lat, std::vector<tt>{create_id_tt()}, 1,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size (max 10 steps in each dimension)
// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 100);

// for the selected range, all samples should be within the parameters and operational
Expand All @@ -152,7 +233,7 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
const auto op_domain = operational_domain_contour_tracing(lat, std::vector<tt>{create_id_tt()}, 1,
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size (max 10 steps in each dimension)
// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() <= 100);

// for the selected range, all samples should be within the parameters and operational
Expand All @@ -169,11 +250,11 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
SECTION("operational area, different number of steps in x- and y-direction")
{
op_domain_params.x_min = 5.1;
op_domain_params.x_max = 6.1;
op_domain_params.x_max = 6.0;
op_domain_params.x_step = 0.1;

op_domain_params.y_min = 4.5;
op_domain_params.y_max = 5.0;
op_domain_params.y_max = 4.9;
op_domain_params.y_step = 0.1;

SECTION("grid_search")
Expand Down Expand Up @@ -251,11 +332,11 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
SECTION("non-operational area")
{
op_domain_params.x_min = 2.5;
op_domain_params.x_max = 3.5;
op_domain_params.x_max = 3.4;
op_domain_params.x_step = 0.1;

op_domain_params.y_min = 4.5;
op_domain_params.y_max = 5.5;
op_domain_params.y_max = 5.4;
op_domain_params.y_step = 0.1;

SECTION("grid_search")
Expand Down Expand Up @@ -334,11 +415,11 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
SECTION("floating-point error")
{
op_domain_params.x_min = 2.5;
op_domain_params.x_max = 4.5;
op_domain_params.x_max = 4.4;
op_domain_params.x_step = 0.9;

op_domain_params.y_min = 2.5;
op_domain_params.y_max = 2.6;
op_domain_params.y_max = 2.5;
op_domain_params.y_step = 0.1;

SECTION("flood_fill")
Expand All @@ -347,20 +428,20 @@ TEST_CASE("BDL wire operational domain computation", "[operational-domain]")
op_domain_params, &op_domain_stats);

// check if the operational domain has the correct size
CHECK(op_domain.operational_values.size() == 2);
CHECK(op_domain.operational_values.size() == 3);

CHECK(op_domain_stats.num_operational_parameter_combinations == 1);
CHECK(op_domain_stats.num_operational_parameter_combinations == 2);
CHECK(op_domain_stats.num_non_operational_parameter_combinations == 1);
}
}
SECTION("semi-operational area")
{
op_domain_params.x_min = 0.5;
op_domain_params.x_max = 4.5;
op_domain_params.x_max = 4.25;
op_domain_params.x_step = 0.25;

op_domain_params.y_min = 0.5;
op_domain_params.y_max = 4.5;
op_domain_params.y_max = 4.25;
op_domain_params.y_step = 0.25;

SECTION("grid_search")
Expand Down Expand Up @@ -467,11 +548,11 @@ TEST_CASE("SiQAD's AND gate operational domain computation", "[operational-domai
op_domain_params.sim_params = sim_params;
op_domain_params.x_dimension = operational_domain::sweep_parameter::EPSILON_R;
op_domain_params.x_min = 5.1;
op_domain_params.x_max = 6.1;
op_domain_params.x_max = 6.0;
op_domain_params.x_step = 0.1;
op_domain_params.y_dimension = operational_domain::sweep_parameter::LAMBDA_TF;
op_domain_params.y_min = 4.5;
op_domain_params.y_max = 5.5;
op_domain_params.y_max = 5.4;
op_domain_params.y_step = 0.1;

operational_domain_stats op_domain_stats{};
Expand Down Expand Up @@ -590,11 +671,11 @@ TEST_CASE("SiQAD's AND gate operational domain computation, using cube coordinat
op_domain_params.sim_params = sim_params;
op_domain_params.x_dimension = operational_domain::sweep_parameter::EPSILON_R;
op_domain_params.x_min = 5.1;
op_domain_params.x_max = 6.1;
op_domain_params.x_max = 6.0;
op_domain_params.x_step = 0.1;
op_domain_params.y_dimension = operational_domain::sweep_parameter::LAMBDA_TF;
op_domain_params.y_min = 4.5;
op_domain_params.y_max = 5.5;
op_domain_params.y_max = 5.4;
op_domain_params.y_step = 0.1;

operational_domain_stats op_domain_stats{};
Expand Down
Loading