Skip to content

Commit

Permalink
Merge branch 'main' into fast_three_state
Browse files Browse the repository at this point in the history
  • Loading branch information
Drewniok authored Jul 26, 2023
2 parents 4421776 + 2c1d621 commit 2d54ba6
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ struct time_to_solution_stats
* Exhaustive simulation algorithm used to simulate the ground state as reference.
*/
std::string algorithm;

/**
* Print the results to the given output stream.
*
Expand Down
230 changes: 165 additions & 65 deletions test/algorithms/simulation/sidb/time_to_solution.cpp
Original file line number Diff line number Diff line change
@@ -1,78 +1,178 @@
//
// Created by Jan Drewniok on 02.02.23.
// Created by Jan Drewniok on 23.12.22.
//

#include <catch2/catch_template_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>

#include <fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.hpp>
#include <fiction/algorithms/simulation/sidb/quickexact.hpp>
#include <fiction/algorithms/simulation/sidb/quicksim.hpp>
#include <fiction/algorithms/simulation/sidb/time_to_solution.hpp>
#include <fiction/layouts/cartesian_layout.hpp>
#include <fiction/layouts/cell_level_layout.hpp>
#include <fiction/layouts/clocked_layout.hpp>
#include <fiction/layouts/hexagonal_layout.hpp>
#include <fiction/technology/cell_technologies.hpp>

using namespace fiction;

TEMPLATE_TEST_CASE(
"time to solution test", "[sim_acc_tss]",
(cell_level_layout<sidb_technology, clocked_layout<cartesian_layout<siqad::coord_t>>>),
(cell_level_layout<sidb_technology, clocked_layout<hexagonal_layout<siqad::coord_t, odd_row_hex>>>),
(cell_level_layout<sidb_technology, clocked_layout<hexagonal_layout<siqad::coord_t, even_row_hex>>>),
(cell_level_layout<sidb_technology, clocked_layout<hexagonal_layout<siqad::coord_t, odd_column_hex>>>),
(cell_level_layout<sidb_technology, clocked_layout<hexagonal_layout<siqad::coord_t, even_column_hex>>>))
#ifndef FICTION_TIME_TO_SOLUTION_HPP
#define FICTION_TIME_TO_SOLUTION_HPP

#include "fiction/algorithms/simulation/sidb/enum_class_exhaustive_algorithm.hpp"
#include "fiction/algorithms/simulation/sidb/is_ground_state.hpp"
#include "fiction/algorithms/simulation/sidb/minimum_energy.hpp"
#include "fiction/algorithms/simulation/sidb/quickexact.hpp"
#include "fiction/algorithms/simulation/sidb/quicksim.hpp"
#include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp"
#include "fiction/technology/charge_distribution_surface.hpp"
#include "fiction/traits.hpp"

#include <fmt/format.h>

#include <algorithm>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>

namespace fiction
{

struct time_to_solution_params
{
/**
* Exhaustive simulation algorithm used to simulate the ground state as reference.
*/
exhaustive_algorithm engine = exhaustive_algorithm::QUICKEXACT;
/**
* Number of iterations of the heuristic algorithm used to determine the simulation accuracy (`repetitions = 100`
* means that accuracy is precise to 1%).
*/
uint64_t repetitions = 100;
/**
* Confidence level.
*/
double confidence_level = 0.997;
};

/**
* This struct stores the time-to-solution, the simulation accuracy and the average single simulation runtime of
* *QuickSim* (see quicksim.hpp), the single runtime of the exact simulator used, and the number of valid charge
* configurations found by the exact algorithm.
*
*/
struct time_to_solution_stats
{
/**
* Time-to-solution in seconds.
*/
double time_to_solution{0};
/**
* Accuracy of the simulation.
*/
double acc{};
/**
* Average single simulation runtime in seconds.
*/
double mean_single_runtime{};
/**
* Single simulation runtime of the exhaustive ground state searcher in seconds.
*/
double single_runtime_exhaustive{};
/**
* Exhaustive simulation algorithm used to simulate the ground state as reference.
*/
std::string algorithm;

/**
* Print the results to the given output stream.
*
* @param out Output stream.
*/
void report(std::ostream& out = std::cout)
{
out << fmt::format("[i] time_to_solution: {} | acc: {} | t_(s): {} | t_exhaustive(s): {} | exact alg.: {}\n",
time_to_solution, acc, mean_single_runtime,
single_runtime_exhaustive, algorithm);
}
};
/**
* This function determines the time-to-solution (TTS) and the accuracy (acc) of the *QuickSim* algorithm.
*
* @tparam Lyt Cell-level layout type.
* @param lyt Layout that is used for the simulation.
* @param quicksim_params Parameters required for the QuickSim algorithm.
* @param ps Pointer to a struct where the results (time_to_solution, acc, single runtime) are stored.
* @param tts_params Parameters used for the time-to-solution calculation.
*/
template <typename Lyt>
void sim_acc_tts(Lyt& lyt, const quicksim_params& quicksim_params, const time_to_solution_params& tts_params = {},
time_to_solution_stats* ps = nullptr) 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");

const auto simulation_results_exgs = exhaustive_ground_state_simulation(lyt, quicksim_params.phys_params);

time_to_solution_stats st{};

sidb_simulation_result<Lyt> simulation_result{};
if (tts_params.engine == exhaustive_algorithm::EXGS)
{
st.algorithm = "exgs";
simulation_result = exhaustive_ground_state_simulation(lyt, quicksim_params.phys_params);
}
else
{
const quickexact_params<Lyt> params{quicksim_params.phys_params};
st.algorithm = "quickexact";
simulation_result = quickexact(lyt, params);
}

st.single_runtime_exhaustive =mockturtle::to_seconds(simulation_results_exgs.simulation_runtime);

std::size_t gs_count = 0;
std::vector<double> time{};
time.reserve(tts_params.repetitions);

for (auto i = 0u; i < tts_params.repetitions; ++i)
{
sidb_simulation_result<Lyt> stats_quick{};

const auto t_start = std::chrono::high_resolution_clock::now();

const auto simulation_results_quicksim = quicksim<Lyt>(lyt, quicksim_params);

const auto t_end = std::chrono::high_resolution_clock::now();
const auto elapsed = t_end - t_start;
const auto diff_first = std::chrono::duration<double>(elapsed).count();

time.push_back(diff_first);

TestType lyt{{20, 10}};
if (is_ground_state(simulation_results_quicksim, simulation_results_exgs))
{
gs_count += 1;
}
}

const auto single_runtime =
std::accumulate(time.cbegin(), time.cend(), 0.0) / static_cast<double>(tts_params.repetitions);
const auto acc = static_cast<double>(gs_count) / static_cast<double>(tts_params.repetitions);

double tts = single_runtime;

SECTION("Empty layout")
if (acc == 1)
{
const sidb_simulation_parameters params{2, -0.30};
const quicksim_params quicksim_params{params};
time_to_solution_stats tts_stat{};

const time_to_solution_params tts_params{};
sim_acc_tts<TestType>(lyt, quicksim_params, tts_params, &tts_stat);

CHECK(tts_stat.algorithm == "quickexact");
CHECK_THAT(tts_stat.acc, Catch::Matchers::WithinAbs(0.0, 0.00001));
CHECK_THAT(tts_stat.time_to_solution,
Catch::Matchers::WithinAbs(std::numeric_limits<double>::max(), 0.00001));
CHECK(tts_stat.mean_single_runtime > 0.0);

time_to_solution_stats tts_stat_exgs{};
const time_to_solution_params tts_params_exgs{exhaustive_algorithm::EXGS};
sim_acc_tts<TestType>(lyt, quicksim_params, tts_params_exgs, &tts_stat_exgs);
CHECK(tts_stat_exgs.algorithm == "exgs");

CHECK_THAT(tts_stat.acc, Catch::Matchers::WithinAbs(0.0, 0.00001));
CHECK_THAT(tts_stat.time_to_solution, Catch::Matchers::WithinAbs(std::numeric_limits<double>::max(), 0.00001));
CHECK(tts_stat.mean_single_runtime > 0.0);
tts = single_runtime;
}
else if (acc == 0)
{
tts = std::numeric_limits<double>::max();
}
else
{
tts = (single_runtime * std::log(1.0 - tts_params.confidence_level) / std::log(1.0 - acc));
}

st.time_to_solution = tts;
st.acc = acc * 100;
st.mean_single_runtime = single_runtime;

SECTION("layout with seven SiDBs placed")
if (ps)
{
lyt.assign_cell_type({1, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({3, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({4, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({2, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({5, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({10, 3, 0}, TestType::cell_type::NORMAL);
lyt.assign_cell_type({12, 3, 0}, TestType::cell_type::NORMAL);

const sidb_simulation_parameters params{3, -0.30};
const quicksim_params quicksim_params{params};

const time_to_solution_params tts_params_exgs{exhaustive_algorithm::EXGS};
time_to_solution_stats tts_stat_exgs{};
sim_acc_tts<TestType>(lyt, quicksim_params, tts_params_exgs, &tts_stat_exgs);

CHECK(tts_stat_exgs.acc > 0);
CHECK(tts_stat_exgs.time_to_solution > 0.0);
CHECK(tts_stat_exgs.mean_single_runtime > 0.0);
*ps = st;
}
}

} // namespace fiction

#endif // FICTION_TIME_TO_SOLUTION_HPP

0 comments on commit 2d54ba6

Please sign in to comment.