From 5c94c5a27625289a2e85d4d58fb7f5809f18f11a Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 15:45:13 +0100 Subject: [PATCH 01/54] :sparkles: Added CMake options for select flow compilation --- cli/CMakeLists.txt | 20 ++++++++++++++++++++ cli/commands.hpp | 15 +++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt index 8f009b738..cef2d5faf 100644 --- a/cli/CMakeLists.txt +++ b/cli/CMakeLists.txt @@ -9,6 +9,26 @@ add_executable(fiction ${SOURCES}) # Link against the project settings, libfiction and alice target_link_libraries(fiction PRIVATE libfiction alice) +# Compile-time decisions on which flows to compile + +# Logic synthesis flow +option(FICTION_LOGIC_SYNTHESIS_FLOW "Enable the logic synthesis flow for the fiction CLI" ON) +if(FICTION_LOGIC_SYNTHESIS_FLOW) + target_compile_definitions(fiction PRIVATE FICTION_LOGIC_SYNTHESIS_FLOW) +endif() + +# Physical design flow +option(FICTION_PHYSICAL_DESIGN_FLOW "Enable the physical design flow for the fiction CLI" ON) +if(FICTION_PHYSICAL_DESIGN_FLOW) + target_compile_definitions(fiction PRIVATE FICTION_PHYSICAL_DESIGN_FLOW) +endif() + +# Physical simulation flow +option(FICTION_SIMULATION_FLOW "Enable the physical simulation flow for the fiction CLI" ON) +if(FICTION_SIMULATION_FLOW) + target_compile_definitions(fiction PRIVATE FICTION_SIMULATION_FLOW) +endif() + # Strip the executable if we are in Release mode if(CMAKE_BUILD_TYPE STREQUAL "Release") if(CMAKE_STRIP) diff --git a/cli/commands.hpp b/cli/commands.hpp index 523d55ab8..baf023eb0 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -5,8 +5,11 @@ #ifndef FICTION_COMMANDS_HPP #define FICTION_COMMANDS_HPP +// general commands #include "cmd/general/clear.hpp" #include "cmd/general/version.hpp" + +// input/output commands #include "cmd/io/blif.hpp" #include "cmd/io/fgl.hpp" #include "cmd/io/fqca.hpp" @@ -17,6 +20,9 @@ #include "cmd/io/sqd.hpp" #include "cmd/io/tt.hpp" #include "cmd/io/verilog.hpp" + +// logic synthesis commands +#ifdef FICTION_LOGIC_SYNTHESIS_FLOW #include "cmd/logic/akers.hpp" #include "cmd/logic/balance.hpp" #include "cmd/logic/fanouts.hpp" @@ -26,6 +32,10 @@ #include "cmd/logic/miginvprop.hpp" #include "cmd/logic/random.hpp" #include "cmd/logic/simulate.hpp" +#endif + +// physical design and validation commands +#ifdef FICTION_PHYSICAL_DESIGN_FLOW #include "cmd/physical_design/exact.hpp" #include "cmd/physical_design/hex.hpp" #include "cmd/physical_design/onepass.hpp" @@ -36,5 +46,10 @@ #include "cmd/technology/energy.hpp" #include "cmd/verification/check.hpp" #include "cmd/verification/equiv.hpp" +#endif + +// physical simulation commands +#ifdef FICTION_SIMULATION_FLOW +#endif #endif // FICTION_COMMANDS_HPP From f7b4cd7fc9154f2b5b34e84ea059b508bed21075 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 15:46:08 +0100 Subject: [PATCH 02/54] :art: Simplified layout printing from store --- cli/stores.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/stores.hpp b/cli/stores.hpp index 0817dcfd4..650756acc 100644 --- a/cli/stores.hpp +++ b/cli/stores.hpp @@ -163,7 +163,7 @@ ALICE_ADD_STORE(fiction::gate_layout_t, "gate_layout", "g", "gate layout", "gate ALICE_PRINT_STORE(fiction::gate_layout_t, os, layout) { - const auto print = [&os](auto&& lyt_ptr) { fiction::print_gate_level_layout(os, *lyt_ptr); }; + const auto print = [&os](auto&& lyt_ptr) { fiction::print_layout(*lyt_ptr, os); }; std::visit(print, layout); } @@ -373,7 +373,7 @@ ALICE_ADD_STORE(fiction::cell_layout_t, "cell_layout", "c", "cell layout", "cell ALICE_PRINT_STORE(fiction::cell_layout_t, os, layout) { - const auto print = [&os](auto&& lyt_ptr) { fiction::print_cell_level_layout(os, *lyt_ptr); }; + const auto print = [&os](auto&& lyt_ptr) { fiction::print_layout(*lyt_ptr, os); }; std::visit(print, layout); } From 175d006b47d801bd20a1ea5e9ce924d83d9db263 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 15:47:35 +0100 Subject: [PATCH 03/54] :sparkles: Added SQD reading and CDS printing to the CLI --- cli/cmd/io/read.hpp | 72 ++++++++++++------- include/fiction/io/print_layout.hpp | 9 ++- .../charge_distribution_surface.hpp | 8 +-- include/fiction/types.hpp | 8 ++- include/fiction/utils/layout_utils.hpp | 20 +++++- 5 files changed, 82 insertions(+), 35 deletions(-) diff --git a/cli/cmd/io/read.hpp b/cli/cmd/io/read.hpp index e28441c89..18901b79b 100644 --- a/cli/cmd/io/read.hpp +++ b/cli/cmd/io/read.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -23,9 +24,9 @@ namespace alice * * Currently parses Verilog, AIGER, and BLIF using the lorina parsers. * - * Parses FGL and FQCA via custom reader functions. - * * For more information see: https://github.com/hriener/lorina + * + * Parses FGL, SQD, and FQCA via custom reader functions. */ class read_command : public command { @@ -40,54 +41,57 @@ class read_command : public command "which will be put into the respective store. Current supported file types are:\n" "Logic networks: Verilog, AIGER, BLIF.\n" "Gate-level layouts: FGL.\n" - "Cell-level layouts: FQCA.\n" + "Cell-level layouts: SQD, FQCA.\n" "In a directory, only files with extension '.v', '.aig', '.blif' are considered.") { add_option("filename", filename, "Filename or directory")->required(); add_option("topology", topology, "Topology for gate-level layouts. Can be 'cartesian' or of the form " "'__'"); - add_flag("--aig,-a", "Parse file as AIG"); - add_flag("--xag,-x", "Parse file as XAG"); - add_flag("--mig,-m", "Parse file as MIG"); - add_flag("--tec,-t", "Parse file as technology network"); - add_flag("--fgl,-f", "Parse file as fiction gate-level layout"); - add_flag("--qca,-q", "Parse file as QCA cell-level layout"); - add_flag("--sort,-s", sort, "Sort networks in given directory by vertex count prior to storing them"); + add_flag("--aig,-a", "Parse Verilog file as AIG"); + add_flag("--xag,-x", "Parse Verilog file as XAG"); + add_flag("--mig,-m", "Parse Verilog file as MIG"); + add_flag("--tec,-t", "Parse Verilog file as technology network"); + add_flag("--fgl,-f", "Parse FGL file as fiction gate-level layout"); + add_flag("--sqd,-s", "Parse SQD file as SiDB cell-level layout"); + add_flag("--fqca,-q", "Parse FQCA file as QCA cell-level layout"); + add_flag("--sort", sort, "Sort networks in given directory by node count prior to storing them"); } protected: /** - * Function to perform the read call. Reads Verilog and creates a logic_network. + * Function to perform the read call. Reads a network or layout from a file. */ void execute() override { - const auto store_ntks = [&](auto&& reader) - { - for (const auto& ln : reader.get_networks(sort)) - { - store().extend() = ln; - } - }; - - if (!is_set("aig") && !is_set("xag") && !is_set("mig") && !is_set("tec") && !is_set("fgl") && !is_set("qca")) + if (!is_set("aig") && !is_set("xag") && !is_set("mig") && !is_set("tec") && !is_set("fgl") && !is_set("sqd") && + !is_set("fqca")) { env->out() << "[e] at least one network or layout type must be specified" << std::endl; } - else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && is_set("fql")) + else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && is_set("fgl")) { env->out() << "[e] cannot parse files as both logic networks and gate-level layouts" << std::endl; } - else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && is_set("qca")) + else if ((is_set("aig") || is_set("xag") || is_set("mig") || is_set("tec")) && + (is_set("sqd") || is_set("fqca"))) { env->out() << "[e] cannot parse files as both logic networks and cell-level layouts" << std::endl; } - else if (is_set("fql") && is_set("qca")) + else if (is_set("fgl") && (is_set("sqd") || is_set("fqca"))) { env->out() << "[e] cannot parse files as both gate-level and cell-level layouts" << std::endl; } else { + const auto store_ntks = [&](auto&& reader) + { + for (const auto& ln : reader.get_networks(sort)) + { + store().extend() = ln; + } + }; + try { if (is_set("aig")) @@ -114,7 +118,7 @@ class read_command : public command store_ntks(reader); } - if (is_set("fgl") || is_set("qca")) + if (is_set("fgl") || is_set("sqd") || is_set("fqca")) { if (std::filesystem::exists(filename)) { @@ -205,7 +209,23 @@ class read_command : public command << std::endl; } } - if (is_set("qca")) + else if (is_set("sqd")) + { + try + { + const auto layout_name = std::filesystem::path{filename}.stem().string(); + + store().extend() = + std::make_shared( + fiction::read_sqd_layout(filename, + layout_name)); + } + catch (const fiction::sqd_parsing_error& e) + { + env->out() << e.what() << std::endl; + } + } + else if (is_set("fqca")) { try { @@ -250,7 +270,7 @@ class read_command : public command } catch (...) { - env->out() << "[e] no networks or layouts were read" << std::endl; + env->out() << "[e] I/O error: no file could be read" << std::endl; } } diff --git a/include/fiction/io/print_layout.hpp b/include/fiction/io/print_layout.hpp index 7e9dfffb9..517323ac1 100644 --- a/include/fiction/io/print_layout.hpp +++ b/include/fiction/io/print_layout.hpp @@ -533,7 +533,14 @@ void print_layout(const Lyt& lyt, std::ostream& os = std::cout) { if constexpr (has_sidb_technology_v) { - print_sidb_layout(os, lyt); + if constexpr (has_siqad_coord_v) + { + print_sidb_layout(os, lyt); + } + else + { + print_sidb_layout(os, convert_to_siqad_coordinates(lyt)); + } } else { diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index f007b2785..464df3cfa 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -271,11 +271,11 @@ class charge_distribution_surface : public Lyt /** * Copy constructor. * - * @param lyt charge_distribution_surface + * @param cds Other `charge_distribution_surface`. */ - explicit charge_distribution_surface(const charge_distribution_surface& lyt) : - Lyt(lyt), - strg{std::make_shared(*lyt.strg)} + charge_distribution_surface(const charge_distribution_surface& cds) : + Lyt(cds), + strg{std::make_shared(*cds.strg)} {} /** * Copy assignment operator. diff --git a/include/fiction/types.hpp b/include/fiction/types.hpp index c1e5415fe..7f6aa6153 100644 --- a/include/fiction/types.hpp +++ b/include/fiction/types.hpp @@ -15,6 +15,7 @@ #include "fiction/layouts/tile_based_layout.hpp" #include "fiction/networks/technology_network.hpp" #include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/technology/sidb_surface.hpp" #include @@ -152,14 +153,17 @@ using inml_cell_clk_lyt_ptr = std::shared_ptr; using sidb_cell_clk_lyt = cell_level_layout>>; using sidb_cell_clk_lyt_ptr = std::shared_ptr; +using cds_sidb_cell_clk_lyt = charge_distribution_surface; +using cds_sidb_cell_clk_lyt_ptr = std::shared_ptr; + using sidb_cell_clk_lyt_siqad = cell_level_layout>>; using sidb_cell_clk_lyt_siqad_ptr = std::shared_ptr; using sidb_defect_cell_clk_lyt_siqad = sidb_surface; using sidb_defect_cell_clk_lyt_siqad_ptr = std::shared_ptr; -using cell_layout_t = - std::variant; +using cell_layout_t = std::variant; } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 5c371908d..4a631528b 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -287,11 +287,12 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept * coordinates is returned. * * @tparam Lyt Cell-level layout type based on fiction coordinates, e.g., `offset::ucoord_t` or `cube::coord_t`. + * @tparam TargetLyt Cell-level layout type based on SiQAD coordinates, i.e., `siqad::coord_t`. * @param lyt The layout that is to be converted to a new layout based on SiQAD coordinates. * @return A new equivalent layout based on SiQAD coordinates. */ template -sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept +auto convert_to_siqad_coordinates(const Lyt& lyt) noexcept { static_assert(is_cartesian_layout_v, "Lyt is not a Cartesian layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); @@ -310,7 +311,22 @@ sidb_cell_clk_lyt_siqad convert_to_siqad_coordinates(const Lyt& lyt) noexcept lyt_new.assign_cell_name(siqad::to_siqad_coord>(c), lyt.get_cell_name(c)); }); - return lyt_new; + if constexpr (is_charge_distribution_surface_v) + { + charge_distribution_surface lyt_new_cds{lyt_new}; + + lyt.foreach_cell( + [&lyt_new_cds, &lyt](const auto& c) + { lyt_new_cds.assign_charge_state(siqad::to_siqad_coord>(c), lyt.get_charge_state(c), false); }); + + lyt_new_cds.assign_physical_parameters(lyt.get_phys_params()); + + return lyt_new_cds; + } + else + { + return lyt_new; + } } /** From 959e0f543cc3e70aa01a3d403439900ab57428b6 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 16:17:17 +0100 Subject: [PATCH 04/54] :sparkles: Added QuickExact to the CLI --- cli/cmd/simulation/quickexact.hpp | 175 ++++++++++++++++++++++++++++++ cli/commands.hpp | 1 + 2 files changed, 176 insertions(+) create mode 100644 cli/cmd/simulation/quickexact.hpp diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp new file mode 100644 index 000000000..342341cd8 --- /dev/null +++ b/cli/cmd/simulation/quickexact.hpp @@ -0,0 +1,175 @@ +// +// Created by marcel on 06.12.23. +// + +#ifndef FICTION_CMD_QUICKEXACT_HPP +#define FICTION_CMD_QUICKEXACT_HPP + +#include +#include +#include +#include + +#include + +#include + +namespace alice +{ +/** + * + */ +class quickexact_command : public command +{ + public: + /** + * Standard constructor. Adds descriptive information, options, and flags. + * + * @param e alice::environment that specifies stores etc. + */ + explicit quickexact_command(const environment::ptr& e) : + command(e, "QuickExact is a quick and exact electrostatic ground state simulation algorithm designed " + "specifically for SiDB layouts. It provides a significant performance advantage of more than " + "three orders of magnitude over ExGS from SiQAD.") + { + add_option("--epsilon_r,-e", physical_params.epsilon_r, "Electric permittivity of the substrate (unit-less)", + true); + add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); + add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); + add_option("--base,-b", physical_params.base, + "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); + add_option("--global_potential,-g", params.global_potential, + "Global potential applied to the entire layout (unit: V)", true); + } + + protected: + /** + * Function to perform the simulation call. + */ + void execute() override + { + // reset sim result + sim_result = {}; + + if (physical_params.epsilon_r <= 0) + { + env->out() << "[e] epsilon_r must be positive" << std::endl; + reset_params(); + return; + } + + if (physical_params.lambda_tf <= 0) + { + env->out() << "[e] lambda_tf must be positive" << std::endl; + reset_params(); + return; + } + + if (physical_params.base != 2 && physical_params.base != 3) + { + env->out() << "[e] base must be 2 or 3" << std::endl; + reset_params(); + return; + } + + auto& s = store(); + + // error case: empty cell layout store + if (s.empty()) + { + env->out() << "[w] no cell layout in store" << std::endl; + reset_params(); + return; + } + + const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); }; + + const auto quickexact = [this, &get_name](auto&& lyt_ptr) + { + using Lyt = typename std::decay_t::element_type; + + if constexpr (fiction::has_sidb_technology_v) + { + if constexpr (fiction::is_charge_distribution_surface_v) + { + env->out() << fmt::format( + "[w] {} already possesses a charge distribution; no simulation is conducted", + get_name(lyt_ptr)) + << std::endl; + } + else + { + params.physical_parameters = physical_params; + + sim_result = fiction::quickexact(*lyt_ptr, params); + + if (sim_result.charge_distributions.empty()) + { + env->out() << fmt::format("[e] ground state of {} could not be determined", get_name(lyt_ptr)) + << std::endl; + } + else + { + store().extend() = + std::make_shared(sim_result.charge_distributions.front()); + } + } + } + else + { + env->out() << fmt::format("[e] {} is not an SiDB layout", get_name(lyt_ptr)) << std::endl; + } + }; + + std::visit(quickexact, s.current()); + + reset_params(); + } + + private: + /** + * Physical parameters for the simulation. + */ + fiction::sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + /** + * QuickExact parameters. + */ + fiction::quickexact_params params{}; + /** + * Simulation result. + */ + fiction::sidb_simulation_result sim_result{}; + + /** + * Logs the resulting information in a log file. + * + * @return JSON object containing details about the simulation. + */ + nlohmann::json log() const override + { + return nlohmann::json{ + {"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {"base", sim_result.physical_parameters.base}, + {"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}}, + {"Ground state energy (meV)", sim_result.charge_distributions.front().get_system_energy()}, + {"Number of stable states", sim_result.charge_distributions.size()}}; + } + /** + * Resets the parameters to their default values. + */ + void reset_params() + { + physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; + params = {}; + } +}; + +ALICE_ADD_COMMAND(quickexact, "Simulation") + +} // namespace alice + +#endif // FICTION_CMD_QUICKEXACT_HPP diff --git a/cli/commands.hpp b/cli/commands.hpp index baf023eb0..b10002429 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -50,6 +50,7 @@ // physical simulation commands #ifdef FICTION_SIMULATION_FLOW +#include "cmd/simulation/quickexact.hpp" #endif #endif // FICTION_COMMANDS_HPP From 6aa8a40bc0a44b5f7d99c56a5b107a8f815f3790 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 16:17:47 +0100 Subject: [PATCH 05/54] :sparkles: Added QuickSim to the CLI --- cli/cmd/simulation/quicksim.hpp | 185 ++++++++++++++++++++++++++++++++ cli/commands.hpp | 1 + 2 files changed, 186 insertions(+) create mode 100644 cli/cmd/simulation/quicksim.hpp diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp new file mode 100644 index 000000000..a2ea99807 --- /dev/null +++ b/cli/cmd/simulation/quicksim.hpp @@ -0,0 +1,185 @@ +// +// Created by marcel on 07.12.23. +// + +#ifndef FICTION_CMD_QUICKSIM_HPP +#define FICTION_CMD_QUICKSIM_HPP + +#include +#include +#include +#include + +#include + +#include + +namespace alice +{ +/** + * + */ +class quicksim_command : public command +{ + public: + /** + * Standard constructor. Adds descriptive information, options, and flags. + * + * @param e alice::environment that specifies stores etc. + */ + explicit quicksim_command(const environment::ptr& e) : + command(e, + "The QuickSim algorithm is a heuristic electrostatic ground state simulation algorithm for SiDB " + "layouts. It determines physically valid charge configurations (with minimal energy). Depending on " + "the simulation parameters, the ground state is found with a certain probability after one run.") + { + add_option("--epsilon_r,-e", physical_params.epsilon_r, "Electric permittivity of the substrate (unit-less)", + true); + add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); + add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); + add_option("--base,-b", physical_params.base, + "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); + add_option("--iterations,-i", params.interation_steps, "Number of iterations to run the simulation for", true); + add_option("--alpha,-a", params.alpha, + "alpha parameter (should be reduced if not charge distribution can be determined)", true); + } + + protected: + /** + * Function to perform the simulation call. + */ + void execute() override + { + // reset sim result + sim_result = {}; + + if (physical_params.epsilon_r <= 0) + { + env->out() << "[e] epsilon_r must be positive" << std::endl; + reset_params(); + return; + } + + if (physical_params.lambda_tf <= 0) + { + env->out() << "[e] lambda_tf must be positive" << std::endl; + reset_params(); + return; + } + + if (physical_params.base != 2 && physical_params.base != 3) + { + env->out() << "[e] base must be 2 or 3" << std::endl; + reset_params(); + return; + } + + if (params.alpha <= 0) + { + env->out() << "[e] alpha must be positive" << std::endl; + reset_params(); + return; + } + + auto& s = store(); + + // error case: empty cell layout store + if (s.empty()) + { + env->out() << "[w] no cell layout in store" << std::endl; + reset_params(); + return; + } + + const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); }; + + const auto quicksim = [this, &get_name](auto&& lyt_ptr) + { + using Lyt = typename std::decay_t::element_type; + + if constexpr (fiction::has_sidb_technology_v) + { + if constexpr (fiction::is_charge_distribution_surface_v) + { + env->out() << fmt::format( + "[w] {} already possesses a charge distribution; no simulation is conducted", + get_name(lyt_ptr)) + << std::endl; + } + else + { + params.phys_params = physical_params; + + sim_result = fiction::quicksim(*lyt_ptr, params); + + if (sim_result.charge_distributions.empty()) + { + env->out() << fmt::format("[e] no stable charge distribution could be determined for {}", + get_name(lyt_ptr)) + << std::endl; + } + else + { + store().extend() = + std::make_shared(sim_result.charge_distributions.front()); + } + } + } + else + { + env->out() << fmt::format("[e] {} is not an SiDB layout", get_name(lyt_ptr)) << std::endl; + } + }; + + std::visit(quicksim, s.current()); + + reset_params(); + } + + private: + /** + * Physical parameters for the simulation. + */ + fiction::sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + /** + * QuickSim parameters. + */ + fiction::quicksim_params params{}; + /** + * Simulation result. + */ + fiction::sidb_simulation_result sim_result{}; + + /** + * Logs the resulting information in a log file. + * + * @return JSON object containing details about the simulation. + */ + nlohmann::json log() const override + { + return nlohmann::json{ + {"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {"base", sim_result.physical_parameters.base}, + {"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}}, + {"Lowest state energy (meV)", sim_result.charge_distributions.front().get_system_energy()}, + {"Number of stable states", sim_result.charge_distributions.size()}}; + } + /** + * Resets the parameters to their default values. + */ + void reset_params() + { + physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; + params = {}; + } +}; + +ALICE_ADD_COMMAND(quicksim, "Simulation") + +} // namespace alice + +#endif // FICTION_CMD_QUICKSIM_HPP diff --git a/cli/commands.hpp b/cli/commands.hpp index b10002429..4108cf593 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -51,6 +51,7 @@ // physical simulation commands #ifdef FICTION_SIMULATION_FLOW #include "cmd/simulation/quickexact.hpp" +#include "cmd/simulation/quicksim.hpp" #endif #endif // FICTION_COMMANDS_HPP From a803b1e63832ac267804c1fa1d7a072482e53951 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 7 Dec 2023 17:12:48 +0100 Subject: [PATCH 06/54] :bug: Try to pacify MSVC --- include/fiction/technology/charge_distribution_surface.hpp | 2 +- include/fiction/types.hpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index 464df3cfa..490aa1fad 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -113,7 +113,7 @@ class charge_distribution_surface : public Lyt */ using distance_matrix = std::vector>; /** - * The potential matrix is a vector of vectors storing the chargless electrostatic potentials in Volt (V). + * The potential matrix is a vector of vectors storing the charge-less electrostatic potentials in Volt (V). */ using potential_matrix = std::vector>; /** diff --git a/include/fiction/types.hpp b/include/fiction/types.hpp index 7f6aa6153..abd3a0693 100644 --- a/include/fiction/types.hpp +++ b/include/fiction/types.hpp @@ -153,7 +153,8 @@ using inml_cell_clk_lyt_ptr = std::shared_ptr; using sidb_cell_clk_lyt = cell_level_layout>>; using sidb_cell_clk_lyt_ptr = std::shared_ptr; -using cds_sidb_cell_clk_lyt = charge_distribution_surface; +using cds_sidb_cell_clk_lyt = + charge_distribution_surface>>>; using cds_sidb_cell_clk_lyt_ptr = std::shared_ptr; using sidb_cell_clk_lyt_siqad = cell_level_layout>>; From e80c84681578428425c62afb7e791e17ccc238ae Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 14:24:56 +0100 Subject: [PATCH 07/54] :bug: Removed base option for the quicksim CLI command --- cli/cmd/simulation/quicksim.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index a2ea99807..b771dc014 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -37,8 +37,6 @@ class quicksim_command : public command true); add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); - add_option("--base,-b", physical_params.base, - "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); add_option("--iterations,-i", params.interation_steps, "Number of iterations to run the simulation for", true); add_option("--alpha,-a", params.alpha, "alpha parameter (should be reduced if not charge distribution can be determined)", true); From cbc5e0a3de1d22781fd2143dd586f7c9396915ab Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 14:52:49 +0100 Subject: [PATCH 08/54] :art: Adjusted `minimum_energy` to be more C++-ish --- .../simulation/sidb/is_ground_state.hpp | 6 +++-- ...defect_influence_position_and_distance.hpp | 13 +++++++--- .../simulation/sidb/minimum_energy.hpp | 25 +++++++++++-------- .../algorithms/simulation/sidb/quickexact.hpp | 1 - .../algorithms/simulation/sidb/quicksim.hpp | 1 - .../simulation/sidb/time_to_solution.hpp | 1 - 6 files changed, 27 insertions(+), 20 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp index 085ef971e..4c62f11e8 100644 --- a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp @@ -38,8 +38,10 @@ template return false; } - const auto min_energy_exact = minimum_energy(exhaustive_results.charge_distributions); - const auto min_energy_new_ap = minimum_energy(quicksim_results.charge_distributions); + const auto min_energy_exact = minimum_energy(exhaustive_results.charge_distributions.cbegin(), + exhaustive_results.charge_distributions.cend()); + const auto min_energy_new_ap = minimum_energy(exhaustive_results.charge_distributions.cbegin(), + exhaustive_results.charge_distributions.cend()); return round_to_n_decimal_places(std::abs(min_energy_exact - min_energy_new_ap), 6) == 0; } diff --git a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp index d15001d90..ab258dc39 100644 --- a/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp +++ b/include/fiction/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.hpp @@ -6,6 +6,7 @@ #define FICTION_MAXIMUM_DEFECT_INFLUENCE_POSITION_AND_DISTANCE_HPP #include "fiction/algorithms/simulation/sidb/critical_temperature.hpp" +#include "fiction/algorithms/simulation/sidb/minimum_energy.hpp" #include "fiction/algorithms/simulation/sidb/quickexact.hpp" #include "fiction/layouts/bounding_box.hpp" #include "fiction/technology/sidb_defects.hpp" @@ -81,8 +82,10 @@ class maximum_defect_influence_position_and_distance_impl quickexact(layout, quickexact_params{params.physical_params, quickexact_params::automatic_base_number_detection::OFF}); - const auto min_energy = minimum_energy(simulation_results.charge_distributions); - uint64_t charge_index_layout = 0; + const auto min_energy = minimum_energy(simulation_results.charge_distributions.cbegin(), + simulation_results.charge_distributions.cend()); + + uint64_t charge_index_layout = 0; for (auto& lyt_result : simulation_results.charge_distributions) { @@ -109,8 +112,10 @@ class maximum_defect_influence_position_and_distance_impl // 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.cbegin(), + simulation_result_defect.charge_distributions.cend()); + + 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) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index e57d797bb..b7ab3597a 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -5,29 +5,32 @@ #ifndef FICTION_MINIMUM_ENERGY_HPP #define FICTION_MINIMUM_ENERGY_HPP -#include "fiction/technology/charge_distribution_surface.hpp" +#include "fiction/traits.hpp" #include +#include #include -#include namespace fiction { /** - * Computes the minimum energy of a vector of charge_distribution_surface objects. + * Computes the minimum energy of a range of `charge_distribution_surface` objects. * - * @tparam Lyt Cell-level layout type. - * @param charge_lyts Vector of charge_distribution_surface objects. - * @return Value of the minimum energy found in the input vector (unit: eV). + * @tparam InputIt must meet the requirements of `LegacyInputIterator`. + * @param first Begin of the range to examime. + * @param last End of the range to examine. + * @return Value of the minimum energy found in the input range (unit: eV). */ -template -[[nodiscard]] double minimum_energy(const std::vector>& charge_lyts) noexcept +template +[[nodiscard]] double minimum_energy(const InputIt first, const InputIt last) noexcept { - static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); + static_assert(std::is_base_of_v::iterator_category>, + "InputIt must meet the requirements of LegacyInputIterator"); + static_assert(is_charge_distribution_surface_v::value_type>, + "Range must be of charge_distribution_surface objects"); - return std::accumulate(charge_lyts.cbegin(), charge_lyts.cend(), std::numeric_limits::max(), + return std::accumulate(first, last, std::numeric_limits::max(), [](const double a, const auto& lyt) { return std::min(a, lyt.get_system_energy()); }); } diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 138a0e326..a0ca4f707 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -7,7 +7,6 @@ #include "fiction/algorithms/iter/gray_code_iterator.hpp" #include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" -#include "fiction/algorithms/simulation/sidb/minimum_energy.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" diff --git a/include/fiction/algorithms/simulation/sidb/quicksim.hpp b/include/fiction/algorithms/simulation/sidb/quicksim.hpp index 771444da7..1577ef657 100644 --- a/include/fiction/algorithms/simulation/sidb/quicksim.hpp +++ b/include/fiction/algorithms/simulation/sidb/quicksim.hpp @@ -6,7 +6,6 @@ #define FICTION_QUICKSIM_HPP #include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" -#include "fiction/algorithms/simulation/sidb/minimum_energy.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" #include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/traits.hpp" diff --git a/include/fiction/algorithms/simulation/sidb/time_to_solution.hpp b/include/fiction/algorithms/simulation/sidb/time_to_solution.hpp index f42dca011..4f66b1c33 100644 --- a/include/fiction/algorithms/simulation/sidb/time_to_solution.hpp +++ b/include/fiction/algorithms/simulation/sidb/time_to_solution.hpp @@ -7,7 +7,6 @@ #include "fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.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_engine.hpp" From 65115466ebe25f8d86b165e9c6642e27f1cdf69a Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 14:55:16 +0100 Subject: [PATCH 09/54] :sparkles: Added a `minimum_energy_distribution` function to obtain the CDS with minimum energy from a range --- docs/algorithms/sidb_simulation.rst | 1 + .../simulation/sidb/minimum_energy.hpp | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/docs/algorithms/sidb_simulation.rst b/docs/algorithms/sidb_simulation.rst index 663995861..e44672425 100644 --- a/docs/algorithms/sidb_simulation.rst +++ b/docs/algorithms/sidb_simulation.rst @@ -71,6 +71,7 @@ Energy Calculation **Header:** ``fiction/algorithms/simulation/sidb/minimum_energy.hpp`` .. doxygenfunction:: fiction::minimum_energy +.. doxygenfunction:: fiction::minimum_energy_distribution **Header:** ``fiction/algorithms/simulation/sidb/is_ground_state.hpp`` diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index b7ab3597a..57c9ced45 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -34,6 +34,27 @@ template [](const double a, const auto& lyt) { return std::min(a, lyt.get_system_energy()); }); } +/** + * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. + * + * @tparam InputIt must meet the requirements of `LegacyInputIterator`. + * @param first Begin of the range to examime. + * @param last End of the range to examine. + * @return Iterator to the minimum energy charge distribution found in the input range. + */ +template +[[nodiscard]] InputIt minimum_energy_distribution(const InputIt first, const InputIt last) noexcept +{ + static_assert(std::is_base_of_v::iterator_category>, + "InputIt must meet the requirements of LegacyInputIterator"); + static_assert(is_charge_distribution_surface_v::value_type>, + "Range must be of charge_distribution_surface objects"); + + return std::min_element(first, last, + [](const auto& cds1, const auto& cds2) + { return cds1.get_system_energy() < cds2.get_system_energy(); }); +} + } // namespace fiction #endif // FICTION_MINIMUM_ENERGY_HPP From 9a6eb1a62be4487f35cf87072d79ad0c676d03f5 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:01:10 +0100 Subject: [PATCH 10/54] :memo: Fixed a wrong header in the documentation and added a missing `:members:` statement --- docs/algorithms/sidb_simulation.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/algorithms/sidb_simulation.rst b/docs/algorithms/sidb_simulation.rst index e44672425..657905da1 100644 --- a/docs/algorithms/sidb_simulation.rst +++ b/docs/algorithms/sidb_simulation.rst @@ -91,7 +91,7 @@ Temperature Behavior .. doxygenfunction:: fiction::critical_temperature_gate_based .. doxygenfunction:: fiction::critical_temperature_non_gate_based -**Header:** ``fiction/algorithms/simulation/sidb/occupation_probability_excited_states.hpp`` +**Header:** ``fiction/algorithms/simulation/sidb/occupation_probability_of_excited_states.hpp`` .. doxygenfunction:: fiction::occupation_probability_gate_based .. doxygenfunction:: fiction::occupation_probability_non_gate_based @@ -130,6 +130,7 @@ Random SiDB Layout Generator **Header:** ``fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp`` .. doxygenstruct:: fiction::generate_random_sidb_layout_params + :members: .. doxygenfunction:: fiction::generate_random_sidb_layout .. doxygenfunction:: fiction::generate_multiple_random_sidb_layouts From 936b7d2c38638a230e4e151d42fd066038d2dc71 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:04:42 +0100 Subject: [PATCH 11/54] :art: Make the quicksim and quickexact commands pick the minimum energy state they found --- cli/cmd/simulation/quickexact.hpp | 6 +++++- cli/cmd/simulation/quicksim.hpp | 6 +++++- .../fiction/algorithms/simulation/sidb/minimum_energy.hpp | 1 - 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 342341cd8..035db7106 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -5,6 +5,7 @@ #ifndef FICTION_CMD_QUICKEXACT_HPP #define FICTION_CMD_QUICKEXACT_HPP +#include #include #include #include @@ -110,8 +111,11 @@ class quickexact_command : public command } else { + const auto min_energy_distr = fiction::minimum_energy_distribution( + sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()); + store().extend() = - std::make_shared(sim_result.charge_distributions.front()); + std::make_shared(*min_energy_distr); } } } diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index b771dc014..6d682640e 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -5,6 +5,7 @@ #ifndef FICTION_CMD_QUICKSIM_HPP #define FICTION_CMD_QUICKSIM_HPP +#include #include #include #include @@ -118,8 +119,11 @@ class quicksim_command : public command } else { + const auto min_energy_distr = fiction::minimum_energy_distribution( + sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()); + store().extend() = - std::make_shared(sim_result.charge_distributions.front()); + std::make_shared(*min_energy_distr); } } } diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index 57c9ced45..3cca49c58 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -33,7 +33,6 @@ template return std::accumulate(first, last, std::numeric_limits::max(), [](const double a, const auto& lyt) { return std::min(a, lyt.get_system_energy()); }); } - /** * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. * From fc0e3e469a53233612e21c564128a05dfac627e9 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:23:14 +0100 Subject: [PATCH 12/54] :bug: Fixed cyclic dependency --- include/fiction/technology/charge_distribution_surface.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index 490aa1fad..80f3ef7b7 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -14,7 +14,6 @@ #include "fiction/technology/sidb_defects.hpp" #include "fiction/technology/sidb_nm_position.hpp" #include "fiction/traits.hpp" -#include "fiction/types.hpp" #include #include From 9b4fe3c19a52739888c5b036948218e38f54d967 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:25:39 +0100 Subject: [PATCH 13/54] :boom: Made `additional_simulation_parameters` in `sidb_simulation_result` an `std::unordered_map` --- include/fiction/algorithms/simulation/sidb/quickexact.hpp | 4 ++-- include/fiction/algorithms/simulation/sidb/quicksim.hpp | 4 ++-- .../algorithms/simulation/sidb/sidb_simulation_result.hpp | 6 +++--- test/algorithms/simulation/sidb/quickexact.cpp | 7 +++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index a0ca4f707..0e5ddcdd1 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -303,13 +303,13 @@ class quickexact_impl if (base_number == required_simulation_base_number::TWO) { - result.additional_simulation_parameters.emplace_back("base_number", uint64_t{2}); + result.additional_simulation_parameters.emplace("base_number", uint64_t{2}); two_state_simulation(charge_layout); } // If positively charged SiDBs can occur in the layout, 3-state simulation is conducted. else { - result.additional_simulation_parameters.emplace_back("base_number", uint64_t{3}); + result.additional_simulation_parameters.emplace("base_number", uint64_t{3}); three_state_simulation(charge_layout); } } diff --git a/include/fiction/algorithms/simulation/sidb/quicksim.hpp b/include/fiction/algorithms/simulation/sidb/quicksim.hpp index 1577ef657..e98f8e24f 100644 --- a/include/fiction/algorithms/simulation/sidb/quicksim.hpp +++ b/include/fiction/algorithms/simulation/sidb/quicksim.hpp @@ -74,8 +74,8 @@ sidb_simulation_result quicksim(const Lyt& lyt, const quicksim_params& ps = sidb_simulation_result st{}; st.algorithm_name = "QuickSim"; - st.additional_simulation_parameters.emplace_back("iteration_steps", ps.interation_steps); - st.additional_simulation_parameters.emplace_back("alpha", ps.alpha); + st.additional_simulation_parameters.emplace("iteration_steps", ps.interation_steps); + st.additional_simulation_parameters.emplace("alpha", ps.alpha); st.physical_parameters = ps.phys_params; st.charge_distributions.reserve(ps.interation_steps); diff --git a/include/fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp b/include/fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp index c90ed5c7f..792c73b7b 100644 --- a/include/fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp +++ b/include/fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace fiction @@ -57,9 +57,9 @@ struct sidb_simulation_result * Additional named simulation parameters. This is used to store algorithm-dependent parameters that are not part of * the `sidb_simulation_parameters` struct. * - * The first element of the pair is the name of the parameter, the second element is the value of the parameter. + * The key of the map is the name of the parameter, the element is the value of the parameter. */ - std::vector> additional_simulation_parameters{}; + std::unordered_map additional_simulation_parameters{}; }; } // namespace fiction diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 77517b5fa..64fd7067f 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -1,5 +1,6 @@ // // Created by Jan Drewniok on 18.12.22. +// #include #include @@ -1150,8 +1151,7 @@ TEMPLATE_TEST_CASE( const auto simulation_results = quickexact(lyt, params); REQUIRE(!simulation_results.additional_simulation_parameters.empty()); - CHECK(simulation_results.additional_simulation_parameters[0].first == "base_number"); - CHECK(std::any_cast(simulation_results.additional_simulation_parameters[0].second) == 3); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("base_number")) == 3); const quickexact_params params_new{sidb_simulation_parameters{2, -0.32}, quickexact_params::automatic_base_number_detection::OFF}; @@ -1159,8 +1159,7 @@ TEMPLATE_TEST_CASE( const auto simulation_results_new = quickexact(lyt, params_new); REQUIRE(!simulation_results_new.additional_simulation_parameters.empty()); - CHECK(simulation_results_new.additional_simulation_parameters[0].first == "base_number"); - CHECK(std::any_cast(simulation_results_new.additional_simulation_parameters[0].second) == 2); + CHECK(std::any_cast(simulation_results_new.additional_simulation_parameters.at("base_number")) == 2); } TEMPLATE_TEST_CASE( From 00e06fda0d577d9de21e48070fec6d341ff04000 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:26:28 +0100 Subject: [PATCH 14/54] :sparkles: Made the quicksim CLI command log its additional parameters --- cli/cmd/simulation/quicksim.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index 6d682640e..182b8845a 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -13,6 +13,7 @@ #include +#include #include namespace alice @@ -168,7 +169,10 @@ class quicksim_command : public command {"lambda_tf", sim_result.physical_parameters.lambda_tf}, {"mu_minus", sim_result.physical_parameters.mu_minus}}, {"Lowest state energy (meV)", sim_result.charge_distributions.front().get_system_energy()}, - {"Number of stable states", sim_result.charge_distributions.size()}}; + {"Number of stable states", sim_result.charge_distributions.size()}, + {"Iteration steps", + std::any_cast(sim_result.additional_simulation_parameters.at("iteration_steps"))}, + {"alpha", std::any_cast(sim_result.additional_simulation_parameters.at("alpha"))}}; } /** * Resets the parameters to their default values. From 87bad9e81c43de0f42c806a0f22e549b90ff4900 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Sat, 9 Dec 2023 19:46:32 +0100 Subject: [PATCH 15/54] :sparkles: Display proper cell type names in the CLI's `ps -c` and `store -c` commands --- cli/stores.hpp | 11 ++++++----- include/fiction/types.hpp | 10 ++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cli/stores.hpp b/cli/stores.hpp index 650756acc..9a0761632 100644 --- a/cli/stores.hpp +++ b/cli/stores.hpp @@ -24,6 +24,7 @@ namespace alice { + /** * Truth tables. * @@ -391,10 +392,10 @@ ALICE_DESCRIBE_STORE(fiction::cell_layout_t, layout) z = lyt_ptr->z() + 1; } - return fmt::format("{} ({}) - {} × {}{}, I/O: {}/{}, cells: {}", lyt_ptr->get_layout_name(), + return fmt::format("{} ({}) - {} × {}{}, I/O: {}/{}, {}: {}", lyt_ptr->get_layout_name(), fiction::tech_impl_name>, lyt_ptr->x() + 1, lyt_ptr->y() + 1, (z ? fmt::format(" × {}", z) : ""), lyt_ptr->num_pis(), lyt_ptr->num_pos(), - lyt_ptr->num_cells()); + fiction::tech_cell_name>, lyt_ptr->num_cells()); }; return std::visit(describe, layout); @@ -413,10 +414,10 @@ ALICE_PRINT_STORE_STATISTICS(fiction::cell_layout_t, os, layout) z = lyt_ptr->z() + 1; } - os << fmt::format("[i] {} ({}) - {} × {}{}, I/O: {}/{}, cells: {}\n", lyt_ptr->get_layout_name(), + os << fmt::format("[i] {} ({}) - {} × {}{}, I/O: {}/{}, {}: {}\n", lyt_ptr->get_layout_name(), fiction::tech_impl_name>, lyt_ptr->x() + 1, lyt_ptr->y() + 1, (z ? fmt::format(" × {}", z) : ""), lyt_ptr->num_pis(), lyt_ptr->num_pos(), - lyt_ptr->num_cells()); + fiction::tech_cell_name>, lyt_ptr->num_cells()); }; std::visit(print_statistics, layout); @@ -432,7 +433,7 @@ ALICE_LOG_STORE_STATISTICS(fiction::cell_layout_t, layout) {"technology", fiction::tech_impl_name>}, {"inputs", lyt_ptr->num_pis()}, {"outputs", lyt_ptr->num_pos()}, - {"cells", lyt_ptr->num_cells()}, + {fiction::tech_cell_name>, lyt_ptr->num_cells()}, {"layout", {{"x-size", lyt_ptr->x() + 1}, {"y-size", lyt_ptr->y() + 1}, diff --git a/include/fiction/types.hpp b/include/fiction/types.hpp index abd3a0693..5f5cd7966 100644 --- a/include/fiction/types.hpp +++ b/include/fiction/types.hpp @@ -135,6 +135,16 @@ inline constexpr const char* tech_impl_name = std::is_same_v, std::is_same_v, sidb_technology> ? sidb_name : "?"; +constexpr const char* qca_cell_name = "cells"; +constexpr const char* inml_cell_name = "magnets"; +constexpr const char* sidb_cell_name = "dots"; + +template +inline constexpr const char* tech_cell_name = std::is_same_v, qca_technology> ? qca_cell_name : + std::is_same_v, inml_technology> ? inml_cell_name : + std::is_same_v, sidb_technology> ? sidb_cell_name : + "?"; + /** * FCN cell-level layouts. */ From 828d3cf6d6774895b387f8f6ffe372a63337db2a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 10 Dec 2023 18:01:33 +0100 Subject: [PATCH 16/54] :white_check_mark: update unit tests after code changes. --- .../simulation/sidb/minimum_energy.hpp | 13 +++++++++++-- .../io/write_location_and_ground_state.hpp | 4 ++-- .../sidb/can_positive_charges_occur.cpp | 2 ++ .../simulation/sidb/minimum_energy.cpp | 17 ++++++++++------- test/algorithms/simulation/sidb/quicksim.cpp | 6 ++---- test/io/write_sqd_sim_result.cpp | 8 ++++---- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index 3cca49c58..c8b2746a6 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -30,8 +30,17 @@ template static_assert(is_charge_distribution_surface_v::value_type>, "Range must be of charge_distribution_surface objects"); - return std::accumulate(first, last, std::numeric_limits::max(), - [](const double a, const auto& lyt) { return std::min(a, lyt.get_system_energy()); }); + if (first != last) + { + return std::min_element(first, last, + [](const auto& cds1, const auto& cds2) + { return cds1.get_system_energy() < cds2.get_system_energy(); }) + ->get_system_energy(); + } + else + { + return std::numeric_limits::infinity(); + } } /** * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. diff --git a/include/fiction/io/write_location_and_ground_state.hpp b/include/fiction/io/write_location_and_ground_state.hpp index ed6a1a2f0..6af35875a 100644 --- a/include/fiction/io/write_location_and_ground_state.hpp +++ b/include/fiction/io/write_location_and_ground_state.hpp @@ -39,8 +39,8 @@ class write_location_and_ground_state_impl void run() { // this part searches for the ground state(s) among all physically valid charge distributions - const auto min_energy = - round_to_n_decimal_places(minimum_energy(sim_result.charge_distributions), 6); + const auto min_energy = round_to_n_decimal_places( + minimum_energy(sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()), 6); std::vector> ground_state_layouts{}; for (const auto& valid_layout : sim_result.charge_distributions) diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index 1fd7822d1..9fe28d9aa 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -5,7 +5,9 @@ #include #include +#include #include +#include using namespace fiction; diff --git a/test/algorithms/simulation/sidb/minimum_energy.cpp b/test/algorithms/simulation/sidb/minimum_energy.cpp index 937055ecc..904c94f52 100644 --- a/test/algorithms/simulation/sidb/minimum_energy.cpp +++ b/test/algorithms/simulation/sidb/minimum_energy.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -32,11 +32,12 @@ TEMPLATE_TEST_CASE( const charge_distribution_surface charge_layout{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.begin(), all_lyts.end()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); all_lyts.push_back(charge_layout); - CHECK(std::abs(minimum_energy(all_lyts) - 0) < 0.00000001); + CHECK(std::abs(minimum_energy(all_lyts.begin(), all_lyts.end()) - 0) < 0.00000001); } SECTION("layout with one SiDB placed") @@ -46,11 +47,12 @@ TEMPLATE_TEST_CASE( const charge_distribution_surface charge_layout{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); all_lyts.push_back(charge_layout); - CHECK(std::abs(minimum_energy(all_lyts) - 0) < 0.00000001); + CHECK(std::abs(minimum_energy(all_lyts.cbegin(), all_lyts.cend()) - 0) < 0.00000001); } SECTION("layout with three SiDBs placed") @@ -62,7 +64,8 @@ TEMPLATE_TEST_CASE( charge_distribution_surface charge_layout_first{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); charge_layout_first.assign_charge_state({0, 0}, sidb_charge_state::NEUTRAL); @@ -79,6 +82,6 @@ TEMPLATE_TEST_CASE( charge_layout_second.recompute_system_energy(); all_lyts.push_back(charge_layout_second); - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(0.0, 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), Catch::Matchers::WithinAbs(0.0, 0.00001)); } } diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index b8de465b7..68b8df98e 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -46,10 +46,8 @@ TEMPLATE_TEST_CASE( CHECK(simulation_results.charge_distributions.empty()); REQUIRE(!simulation_results.additional_simulation_parameters.empty()); CHECK(simulation_results.algorithm_name == "QuickSim"); - CHECK(simulation_results.additional_simulation_parameters[0].first == "iteration_steps"); - CHECK(std::any_cast(simulation_results.additional_simulation_parameters[0].second) == 80); - CHECK(simulation_results.additional_simulation_parameters[1].first == "alpha"); - CHECK(std::any_cast(simulation_results.additional_simulation_parameters[1].second) == 0.7); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("iteration_steps")) == 80); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("alpha")) == 0.7); CHECK(simulation_results.charge_distributions.empty()); } diff --git a/test/io/write_sqd_sim_result.cpp b/test/io/write_sqd_sim_result.cpp index f05a5b4cd..1e72797ac 100644 --- a/test/io/write_sqd_sim_result.cpp +++ b/test/io/write_sqd_sim_result.cpp @@ -222,10 +222,10 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") sim_result.physical_parameters.lambda_tf, sim_result.physical_parameters.epsilon_r, sim_result.physical_parameters.mu_minus); - sim_result.additional_simulation_parameters.emplace_back("param1", "value1"); - sim_result.additional_simulation_parameters.emplace_back("param2", 2); - sim_result.additional_simulation_parameters.emplace_back("param3", 3.14); - sim_result.additional_simulation_parameters.emplace_back("param4", 'c'); + sim_result.additional_simulation_parameters.emplace("param1", "value1"); + sim_result.additional_simulation_parameters.emplace("param2", 2); + sim_result.additional_simulation_parameters.emplace("param3", 3.14); + sim_result.additional_simulation_parameters.emplace("param4", 'c'); write_sqd_sim_result(sim_result, simulation_stream); From 6a91562338383d597b1210838e50048882289800 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 10 Dec 2023 18:17:11 +0100 Subject: [PATCH 17/54] :white_check_mark: update test after code changes. --- .../simulation/sidb/minimum_energy.hpp | 13 +++++++++++-- .../io/write_location_and_ground_state.hpp | 4 ++-- .../sidb/can_positive_charges_occur.cpp | 2 ++ .../simulation/sidb/minimum_energy.cpp | 17 ++++++++++------- test/algorithms/simulation/sidb/quicksim.cpp | 6 ++---- test/io/write_sqd_sim_result.cpp | 8 ++++---- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index 3cca49c58..c8b2746a6 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -30,8 +30,17 @@ template static_assert(is_charge_distribution_surface_v::value_type>, "Range must be of charge_distribution_surface objects"); - return std::accumulate(first, last, std::numeric_limits::max(), - [](const double a, const auto& lyt) { return std::min(a, lyt.get_system_energy()); }); + if (first != last) + { + return std::min_element(first, last, + [](const auto& cds1, const auto& cds2) + { return cds1.get_system_energy() < cds2.get_system_energy(); }) + ->get_system_energy(); + } + else + { + return std::numeric_limits::infinity(); + } } /** * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. diff --git a/include/fiction/io/write_location_and_ground_state.hpp b/include/fiction/io/write_location_and_ground_state.hpp index ed6a1a2f0..6af35875a 100644 --- a/include/fiction/io/write_location_and_ground_state.hpp +++ b/include/fiction/io/write_location_and_ground_state.hpp @@ -39,8 +39,8 @@ class write_location_and_ground_state_impl void run() { // this part searches for the ground state(s) among all physically valid charge distributions - const auto min_energy = - round_to_n_decimal_places(minimum_energy(sim_result.charge_distributions), 6); + const auto min_energy = round_to_n_decimal_places( + minimum_energy(sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()), 6); std::vector> ground_state_layouts{}; for (const auto& valid_layout : sim_result.charge_distributions) diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index 1fd7822d1..9fe28d9aa 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -5,7 +5,9 @@ #include #include +#include #include +#include using namespace fiction; diff --git a/test/algorithms/simulation/sidb/minimum_energy.cpp b/test/algorithms/simulation/sidb/minimum_energy.cpp index 937055ecc..904c94f52 100644 --- a/test/algorithms/simulation/sidb/minimum_energy.cpp +++ b/test/algorithms/simulation/sidb/minimum_energy.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include @@ -32,11 +32,12 @@ TEMPLATE_TEST_CASE( const charge_distribution_surface charge_layout{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.begin(), all_lyts.end()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); all_lyts.push_back(charge_layout); - CHECK(std::abs(minimum_energy(all_lyts) - 0) < 0.00000001); + CHECK(std::abs(minimum_energy(all_lyts.begin(), all_lyts.end()) - 0) < 0.00000001); } SECTION("layout with one SiDB placed") @@ -46,11 +47,12 @@ TEMPLATE_TEST_CASE( const charge_distribution_surface charge_layout{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); all_lyts.push_back(charge_layout); - CHECK(std::abs(minimum_energy(all_lyts) - 0) < 0.00000001); + CHECK(std::abs(minimum_energy(all_lyts.cbegin(), all_lyts.cend()) - 0) < 0.00000001); } SECTION("layout with three SiDBs placed") @@ -62,7 +64,8 @@ TEMPLATE_TEST_CASE( charge_distribution_surface charge_layout_first{lyt}; std::vector> all_lyts{}; - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(std::numeric_limits::max(), 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), + Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.00001)); charge_layout_first.assign_charge_state({0, 0}, sidb_charge_state::NEUTRAL); @@ -79,6 +82,6 @@ TEMPLATE_TEST_CASE( charge_layout_second.recompute_system_energy(); all_lyts.push_back(charge_layout_second); - CHECK_THAT(minimum_energy(all_lyts), Catch::Matchers::WithinAbs(0.0, 0.00001)); + CHECK_THAT(minimum_energy(all_lyts.cbegin(), all_lyts.cend()), Catch::Matchers::WithinAbs(0.0, 0.00001)); } } diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index b8de465b7..68b8df98e 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -46,10 +46,8 @@ TEMPLATE_TEST_CASE( CHECK(simulation_results.charge_distributions.empty()); REQUIRE(!simulation_results.additional_simulation_parameters.empty()); CHECK(simulation_results.algorithm_name == "QuickSim"); - CHECK(simulation_results.additional_simulation_parameters[0].first == "iteration_steps"); - CHECK(std::any_cast(simulation_results.additional_simulation_parameters[0].second) == 80); - CHECK(simulation_results.additional_simulation_parameters[1].first == "alpha"); - CHECK(std::any_cast(simulation_results.additional_simulation_parameters[1].second) == 0.7); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("iteration_steps")) == 80); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("alpha")) == 0.7); CHECK(simulation_results.charge_distributions.empty()); } diff --git a/test/io/write_sqd_sim_result.cpp b/test/io/write_sqd_sim_result.cpp index f05a5b4cd..1e72797ac 100644 --- a/test/io/write_sqd_sim_result.cpp +++ b/test/io/write_sqd_sim_result.cpp @@ -222,10 +222,10 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") sim_result.physical_parameters.lambda_tf, sim_result.physical_parameters.epsilon_r, sim_result.physical_parameters.mu_minus); - sim_result.additional_simulation_parameters.emplace_back("param1", "value1"); - sim_result.additional_simulation_parameters.emplace_back("param2", 2); - sim_result.additional_simulation_parameters.emplace_back("param3", 3.14); - sim_result.additional_simulation_parameters.emplace_back("param4", 'c'); + sim_result.additional_simulation_parameters.emplace("param1", "value1"); + sim_result.additional_simulation_parameters.emplace("param2", 2); + sim_result.additional_simulation_parameters.emplace("param3", 3.14); + sim_result.additional_simulation_parameters.emplace("param4", 'c'); write_sqd_sim_result(sim_result, simulation_stream); From 81215b4d3a19906126bb44b04d37fd4d5bc2b17a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 10 Dec 2023 19:15:06 +0100 Subject: [PATCH 18/54] :art: remove ``else`` after return. --- .../algorithms/simulation/sidb/minimum_energy.hpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index c8b2746a6..76b84407d 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -32,15 +32,11 @@ template if (first != last) { - return std::min_element(first, last, - [](const auto& cds1, const auto& cds2) + return std::min_element(first, last, [](const auto& cds1, const auto& cds2) { return cds1.get_system_energy() < cds2.get_system_energy(); }) ->get_system_energy(); } - else - { - return std::numeric_limits::infinity(); - } + return std::numeric_limits::infinity(); } /** * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. @@ -58,8 +54,7 @@ template static_assert(is_charge_distribution_surface_v::value_type>, "Range must be of charge_distribution_surface objects"); - return std::min_element(first, last, - [](const auto& cds1, const auto& cds2) + return std::min_element(first, last, [](const auto& cds1, const auto& cds2) { return cds1.get_system_energy() < cds2.get_system_energy(); }); } From 7940028fd6b251698fd2d5e95fb2efcc429b794f Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Sun, 10 Dec 2023 18:26:01 +0000 Subject: [PATCH 19/54] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../fiction/algorithms/simulation/sidb/minimum_energy.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index 76b84407d..d8bc16772 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -32,7 +32,8 @@ template if (first != last) { - return std::min_element(first, last, [](const auto& cds1, const auto& cds2) + return std::min_element(first, last, + [](const auto& cds1, const auto& cds2) { return cds1.get_system_energy() < cds2.get_system_energy(); }) ->get_system_energy(); } @@ -54,7 +55,8 @@ template static_assert(is_charge_distribution_surface_v::value_type>, "Range must be of charge_distribution_surface objects"); - return std::min_element(first, last, [](const auto& cds1, const auto& cds2) + return std::min_element(first, last, + [](const auto& cds1, const auto& cds2) { return cds1.get_system_energy() < cds2.get_system_energy(); }); } From 6491bfc9359e6a23c6cdd9ff094a4fe74bae735b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 08:07:17 +0100 Subject: [PATCH 20/54] :memo: Add documentation to the CLI chapter in the RTD pages. --- docs/cli.rst | 58 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index f50241ecd..78e2242ce 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -81,9 +81,11 @@ or be obtained by :ref:`simulating` a ``network`` or ``gate_la `kitty documentation `_): An expression ``E`` is a constant ``0`` or ``1``, or a variable ``a, b, ..., p``, the negation of an expression ``!E``, the -conjunction of multiple expressions ``(E...E)``, the disjunction of multiple expressions ``{E...E}``, the exclusive OR of +conjunction of multiple expressions ``(E...E)``, the disjunction of multiple expressions ``{ + E... E}``, the exclusive OR of multiple expressions ``[E...E]``, or the majority of three expressions ````. Examples are ``[(ab)(!ac)]`` to describe -if-then-else, or ``!{!a!b}`` to describe the application of De Morgan's law to ``(ab)``. The size of the truth table must +if-then-else, or ``!{ + !a !b}`` to describe the application of De Morgan's law to ``(ab)``. The size of the truth table must fit the largest variable in the expression, e.g., if ``c`` is the largest variable, then the truth table has at least three variables. @@ -215,6 +217,55 @@ throughput (TP) and thereby, the amount of clock cycles the PIs need to be stall A ``network`` can also be simulated for comparison by using ``simulate -n``. + +Physical Simulation of SiDBs +---------------------------- + +Performing physical simulations on SiDB layouts is crucial for understanding layout behavior and +facilitating rapid prototyping, eliminating the need for expensive and time-intensive fabrication processes. +The command ``read --sqd`` (or ``read -s``) is used to import a SiDB layout from an sqd-file, a format compatible with `SiQAD `_. +The SiDB layout can be visualized using the ``print -c`` command. Currently, *fiction* provides two electrostatic physical simulators: +an exact one (*QuickExact*) and a scalable one (*QuickSim*). + +QuickExact (``quickexact``) +########################### + +*QuickExact* serves as an exact simulator, meticulously determining all physically valid charge distributions. +It enumerates all possible charge distributions. However, by incorporating three techniques, namely +1.) Physically-informed Search Space Pruning, 2.) Partial Solution Caching, and 3.) Effective State Enumeration, it provides +a significant performance advantage of more than three orders of magnitude over ExGS from SiQAD. For additional details, +see the `paper `_. + +Most important Parameters: + +- Relative permittivity (``-e``). +- Thomas-Fermi screening (``-l``). +- Energy transition level (0/-) (``-m``). +- Base number for the simulation (``-b``) + +See ``quickexact -h`` for a full list. + +The simulated ground state charge distribution can be printed with ``print -c``. + + +QuickSim (``quicksim``) +####################### + +*QuickSim* serves as a scalable simulator designed to determine the ground state charge distribution +for a given SiDB layout. To enhance efficiency, effective search space pruning techniques, such as +(`max-min diversity distributions `_), are integrated. +For more in-depth information, refer to the `paper `_. + +Most important Parameters: + +- Relative permittivity (``-e``). +- Thomas-Fermi screening (``-l``). +- Energy transition level (0/-) (``-m``). +- Number of iterations (``-i``). +- Alpha value (``-a``). + +The simulated ground state charge distribution can be printed with ``print -c``. + Equivalence checking (``equiv``) -------------------------------- @@ -365,7 +416,8 @@ Additionally, *fiction* itself can be part of a bash script. Consider the follow for filepath in ../benchmarks/TOY/*.v; do f="${filepath##*/}" - ./fiction -c "read $filepath; ortho; cell; qca ${f%.*}.qca" + + ./fiction -c "read $filepath; ortho; cell; qca ${f%.*}.qca" done where the for-loop iterates over all Verilog files in the ``../benchmarks/TOY/`` folder. By using the flag ``-c``, a From ef1285e61bda76f36bfc5a804755883f97043647 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 08:18:31 +0100 Subject: [PATCH 21/54] :memo: revert wrong changes. --- docs/cli.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index 78e2242ce..1d177c540 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -81,11 +81,9 @@ or be obtained by :ref:`simulating` a ``network`` or ``gate_la `kitty documentation `_): An expression ``E`` is a constant ``0`` or ``1``, or a variable ``a, b, ..., p``, the negation of an expression ``!E``, the -conjunction of multiple expressions ``(E...E)``, the disjunction of multiple expressions ``{ - E... E}``, the exclusive OR of +conjunction of multiple expressions ``(E...E)``, the disjunction of multiple expressions ``{E...E}``, the exclusive OR of multiple expressions ``[E...E]``, or the majority of three expressions ````. Examples are ``[(ab)(!ac)]`` to describe -if-then-else, or ``!{ - !a !b}`` to describe the application of De Morgan's law to ``(ab)``. The size of the truth table must +if-then-else, or ``!{!a!b}`` to describe the application of De Morgan's law to ``(ab)``. The size of the truth table must fit the largest variable in the expression, e.g., if ``c`` is the largest variable, then the truth table has at least three variables. From ae803fada502575609ea5b9b925f512e6520278d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 09:25:18 +0100 Subject: [PATCH 22/54] :art: three as a base number is not supported by quicksim. --- cli/cmd/simulation/quicksim.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index 182b8845a..c15307b5b 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -67,9 +67,9 @@ class quicksim_command : public command return; } - if (physical_params.base != 2 && physical_params.base != 3) + if (physical_params.base != 2) { - env->out() << "[e] base must be 2 or 3" << std::endl; + env->out() << "[e] base must be 2" << std::endl; reset_params(); return; } @@ -164,11 +164,10 @@ class quicksim_command : public command {"Algorithm name", sim_result.algorithm_name}, {"Simulation runtime", sim_result.simulation_runtime.count()}, {"Physical parameters", - {"base", sim_result.physical_parameters.base}, {"epsilon_r", sim_result.physical_parameters.epsilon_r}, {"lambda_tf", sim_result.physical_parameters.lambda_tf}, {"mu_minus", sim_result.physical_parameters.mu_minus}}, - {"Lowest state energy (meV)", sim_result.charge_distributions.front().get_system_energy()}, + {"Lowest state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, {"Number of stable states", sim_result.charge_distributions.size()}, {"Iteration steps", std::any_cast(sim_result.additional_simulation_parameters.at("iteration_steps"))}, From 6630695a1223be321041b113e91fb00405173ec9 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 09:31:54 +0100 Subject: [PATCH 23/54] :memo: change position of simulation paragraph. --- docs/cli.rst | 96 ++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index 1d177c540..e76dc2d4a 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -216,54 +216,6 @@ throughput (TP) and thereby, the amount of clock cycles the PIs need to be stall A ``network`` can also be simulated for comparison by using ``simulate -n``. -Physical Simulation of SiDBs ----------------------------- - -Performing physical simulations on SiDB layouts is crucial for understanding layout behavior and -facilitating rapid prototyping, eliminating the need for expensive and time-intensive fabrication processes. -The command ``read --sqd`` (or ``read -s``) is used to import a SiDB layout from an sqd-file, a format compatible with `SiQAD `_. -The SiDB layout can be visualized using the ``print -c`` command. Currently, *fiction* provides two electrostatic physical simulators: -an exact one (*QuickExact*) and a scalable one (*QuickSim*). - -QuickExact (``quickexact``) -########################### - -*QuickExact* serves as an exact simulator, meticulously determining all physically valid charge distributions. -It enumerates all possible charge distributions. However, by incorporating three techniques, namely -1.) Physically-informed Search Space Pruning, 2.) Partial Solution Caching, and 3.) Effective State Enumeration, it provides -a significant performance advantage of more than three orders of magnitude over ExGS from SiQAD. For additional details, -see the `paper `_. - -Most important Parameters: - -- Relative permittivity (``-e``). -- Thomas-Fermi screening (``-l``). -- Energy transition level (0/-) (``-m``). -- Base number for the simulation (``-b``) - -See ``quickexact -h`` for a full list. - -The simulated ground state charge distribution can be printed with ``print -c``. - - -QuickSim (``quicksim``) -####################### - -*QuickSim* serves as a scalable simulator designed to determine the ground state charge distribution -for a given SiDB layout. To enhance efficiency, effective search space pruning techniques, such as -(`max-min diversity distributions `_), are integrated. -For more in-depth information, refer to the `paper `_. - -Most important Parameters: - -- Relative permittivity (``-e``). -- Thomas-Fermi screening (``-l``). -- Energy transition level (0/-) (``-m``). -- Number of iterations (``-i``). -- Alpha value (``-a``). - -The simulated ground state charge distribution can be printed with ``print -c``. - Equivalence checking (``equiv``) -------------------------------- @@ -312,6 +264,54 @@ simulators are currently supported: If no filename is given, the stored layout name will be used and the file will be written to the current folder. +Physical Simulation of SiDBs +---------------------------- + +Performing physical simulation of SiDB layouts is crucial for understanding layout behavior and +facilitating rapid prototyping, eliminating the need for expensive and time-intensive fabrication processes. +The command ``read --sqd`` (or ``read -s``) is used to import a SiDB layout from an sqd-file, a format compatible with `SiQAD `_. +The SiDB layout can be visualized using the ``print -c`` command. Currently, *fiction* provides two electrostatic physical simulators: +an exact one (*QuickExact*) and a scalable one (*QuickSim*). + +QuickExact (``quickexact``) +########################### + +*QuickExact* serves as an exact simulator, meticulously determining all physically valid charge distributions. +It enumerates all possible charge distributions. However, by incorporating three techniques, namely +1.) Physically-informed Search Space Pruning, 2.) Partial Solution Caching, and 3.) Effective State Enumeration, it provides +a significant performance advantage of more than three orders of magnitude over ExGS from SiQAD. For additional details, +see the `paper `_. + +Most important Parameters: + +- Relative permittivity (``-e``). +- Thomas-Fermi screening (``-l``). +- Energy transition level (0/-) (``-m``). +- Base number for the simulation (``-b``) + +See ``quickexact -h`` for a full list. + +The simulated ground state charge distribution can be printed with ``print -c``. + + +QuickSim (``quicksim``) +####################### + +*QuickSim* serves as a scalable simulator designed to determine the ground state charge distribution +for a given SiDB layout. To enhance efficiency, effective search space pruning techniques, such as +(`max-min diversity distributions `_), are integrated. +For more in-depth information, refer to the `paper `_. + +Most important Parameters: + +- Relative permittivity (``-e``). +- Thomas-Fermi screening (``-l``). +- Energy transition level (0/-) (``-m``). +- Number of iterations (``-i``). +- Alpha value (``-a``). + +The simulated ground state charge distribution can be printed with ``print -c``. + Area usage (``area``) --------------------- From 816a2dcfa3e2b2cbefd6637a68afefa3c289325a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 09:38:06 +0100 Subject: [PATCH 24/54] :white_check_mark: update test due to code changes. --- test/io/write_sqd_sim_result.cpp | 41 +++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/test/io/write_sqd_sim_result.cpp b/test/io/write_sqd_sim_result.cpp index 1e72797ac..629a65b85 100644 --- a/test/io/write_sqd_sim_result.cpp +++ b/test/io/write_sqd_sim_result.cpp @@ -191,7 +191,7 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") CHECK(simulation_stream.str() == sim_result_str); } - SECTION("with additional parameters") + SECTION("with additional parameter (string)") { const std::string sim_result_str = fmt::format( "\n" @@ -209,9 +209,6 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") " {}\n" " {}\n" " value1\n" - " 2\n" - " 3.140000\n" - " c\n" " \n" " \n" " \n" @@ -223,9 +220,41 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") sim_result.physical_parameters.mu_minus); sim_result.additional_simulation_parameters.emplace("param1", "value1"); - sim_result.additional_simulation_parameters.emplace("param2", 2); + + write_sqd_sim_result(sim_result, simulation_stream); + + CHECK(simulation_stream.str() == sim_result_str); + } + + SECTION("with additional parameters (double)") + { + const std::string sim_result_str = fmt::format( + "\n" + "\n" + " \n" + " TestSim\n" + " {}\n" + " {}\n" + " 0\n" + " {}\n" + " 42.0\n" + " \n" + " \n" + " {}\n" + " {}\n" + " {}\n" + " 3.140000\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n", + FICTION_VERSION, FICTION_REPO, fmt::format("{:%Y-%m-%d %H:%M:%S}", fmt::localtime(std::time(nullptr))), + sim_result.physical_parameters.lambda_tf, sim_result.physical_parameters.epsilon_r, + sim_result.physical_parameters.mu_minus); + sim_result.additional_simulation_parameters.emplace("param3", 3.14); - sim_result.additional_simulation_parameters.emplace("param4", 'c'); write_sqd_sim_result(sim_result, simulation_stream); From 086e90ac7cc53ffd4243d74d02368d0fe132aa49 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 10:22:24 +0100 Subject: [PATCH 25/54] :green_heart: try to fix macos issue. --- .github/workflows/macos.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 933fb87ab..ccaa1312b 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -65,7 +65,7 @@ jobs: submodules: recursive # Setup TBB for parallel STL algorithms via Homebrew (macOS 11 is no longer supported) - - if: matrix.os != macos-11 + - if: matrix.os != 'macos-11' name: Setup TBB run: brew install tbb From 016c9c73b26f2b7e49ea449a88f6d191b7783e0b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 10:51:48 +0100 Subject: [PATCH 26/54] :art: add global potential and automatic base number detection. --- cli/cmd/simulation/quickexact.hpp | 2 ++ docs/cli.rst | 3 ++- include/fiction/algorithms/simulation/sidb/quickexact.hpp | 1 + test/algorithms/simulation/sidb/quickexact.cpp | 3 +-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 035db7106..6ed8b543a 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -39,6 +39,8 @@ class quickexact_command : public command add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); add_option("--base,-b", physical_params.base, "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); + add_option("--base_number_detection, -bd", params.base_number_detection, + "Automatic base number detection (ON/OFF)", true); add_option("--global_potential,-g", params.global_potential, "Global potential applied to the entire layout (unit: V)", true); } diff --git a/docs/cli.rst b/docs/cli.rst index e76dc2d4a..06bea63d6 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -287,7 +287,8 @@ Most important Parameters: - Relative permittivity (``-e``). - Thomas-Fermi screening (``-l``). - Energy transition level (0/-) (``-m``). -- Base number for the simulation (``-b``) +- Base number for the simulation (``-b``). +- Automatic base number detection (``-bd``). See ``quickexact -h`` for a full list. diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 0e5ddcdd1..c22503877 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -97,6 +97,7 @@ class quickexact_impl { result.algorithm_name = "QuickExact"; result.physical_parameters = params.physical_parameters; + result.additional_simulation_parameters.emplace("global_potential", params.global_potential); mockturtle::stopwatch<>::duration time_counter{}; { diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 64fd7067f..9b5f3f9d7 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -29,9 +29,7 @@ TEMPLATE_TEST_CASE( const auto simulation_results = quickexact(lyt, params); CHECK(simulation_results.charge_distributions.empty()); - CHECK(simulation_results.additional_simulation_parameters.empty()); CHECK(simulation_results.algorithm_name == "QuickExact"); - CHECK(simulation_results.additional_simulation_parameters.empty()); } TEMPLATE_TEST_CASE( @@ -253,6 +251,7 @@ TEMPLATE_TEST_CASE( const auto simulation_results = quickexact(lyt, params); REQUIRE(simulation_results.charge_distributions.size() == 1); + CHECK(std::any_cast(simulation_results.additional_simulation_parameters.at("global_potential")) == -0.26); CHECK(simulation_results.charge_distributions.front().get_charge_state_by_index(0) == sidb_charge_state::NEUTRAL); } From 1d18e1277b4701c448c96b8f78b3f481510410e3 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 11 Dec 2023 11:28:05 +0100 Subject: [PATCH 27/54] :memo: Extended documentation on `minimum_energy` to reflect the error cases --- .../simulation/sidb/minimum_energy.hpp | 20 +++++++++---------- .../algorithms/simulation/sidb/quicksim.hpp | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp index d8bc16772..9a37c1147 100644 --- a/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp +++ b/include/fiction/algorithms/simulation/sidb/minimum_energy.hpp @@ -15,12 +15,13 @@ namespace fiction { /** - * Computes the minimum energy of a range of `charge_distribution_surface` objects. + * Computes the minimum energy of a range of `charge_distribution_surface` objects. If the range is empty, infinity is + * returned. * - * @tparam InputIt must meet the requirements of `LegacyInputIterator`. + * @tparam InputIt Must meet the requirements of `LegacyInputIterator`. * @param first Begin of the range to examime. * @param last End of the range to examine. - * @return Value of the minimum energy found in the input range (unit: eV). + * @return Value of the minimum energy found in the input range (unit: eV), or infinity if the range is empty. */ template [[nodiscard]] double minimum_energy(const InputIt first, const InputIt last) noexcept @@ -32,20 +33,19 @@ template if (first != last) { - return std::min_element(first, last, - [](const auto& cds1, const auto& cds2) - { return cds1.get_system_energy() < cds2.get_system_energy(); }) - ->get_system_energy(); + return minimum_energy_distribution(first, last)->get_system_energy(); } + return std::numeric_limits::infinity(); } /** - * Returns the charge distribution of minimum energy contained in a range of `charge_distribution_surface` objects. + * Returns an iterator to the charge distribution of minimum energy contained in a range of + * `charge_distribution_surface` objects. If the range is empty, `last` is returned. * - * @tparam InputIt must meet the requirements of `LegacyInputIterator`. + * @tparam InputIt Must meet the requirements of `LegacyInputIterator`. * @param first Begin of the range to examime. * @param last End of the range to examine. - * @return Iterator to the minimum energy charge distribution found in the input range. + * @return Iterator to the minimum energy charge distribution found in the input range, or `last` if the range is empty. */ template [[nodiscard]] InputIt minimum_energy_distribution(const InputIt first, const InputIt last) noexcept diff --git a/include/fiction/algorithms/simulation/sidb/quicksim.hpp b/include/fiction/algorithms/simulation/sidb/quicksim.hpp index e98f8e24f..75e940b78 100644 --- a/include/fiction/algorithms/simulation/sidb/quicksim.hpp +++ b/include/fiction/algorithms/simulation/sidb/quicksim.hpp @@ -56,7 +56,7 @@ struct quicksim_params * charge distribution layout. Depending on the simulation parameters, the ground state is found with a certain * probability after one run. * - * @tparam Lyt Cell-level layout type. + * @tparam Lyt SiDB cell-level layout type. * @param lyt The layout to simulate. * @param ps Physical parameters. They are material-specific and may vary from experiment to experiment. * @return sidb_simulation_result is returned with all results. From 89e6344fd467a2ea6235b2d01f5c529d0fb5d502 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 11 Dec 2023 11:29:43 +0100 Subject: [PATCH 28/54] :bug: Fixed unit --- cli/cmd/simulation/quickexact.hpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 6ed8b543a..6ec3270af 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -153,16 +153,15 @@ class quickexact_command : public command */ nlohmann::json log() const override { - return nlohmann::json{ - {"Algorithm name", sim_result.algorithm_name}, - {"Simulation runtime", sim_result.simulation_runtime.count()}, - {"Physical parameters", - {"base", sim_result.physical_parameters.base}, - {"epsilon_r", sim_result.physical_parameters.epsilon_r}, - {"lambda_tf", sim_result.physical_parameters.lambda_tf}, - {"mu_minus", sim_result.physical_parameters.mu_minus}}, - {"Ground state energy (meV)", sim_result.charge_distributions.front().get_system_energy()}, - {"Number of stable states", sim_result.charge_distributions.size()}}; + return nlohmann::json{{"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {"base", sim_result.physical_parameters.base}, + {"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}}, + {"Ground state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, + {"Number of stable states", sim_result.charge_distributions.size()}}; } /** * Resets the parameters to their default values. From 69c3286e438f4b597cb01e05738635f7f4320229 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 11 Dec 2023 11:35:17 +0100 Subject: [PATCH 29/54] :memo: Small doc update --- docs/cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli.rst b/docs/cli.rst index 06bea63d6..fa56b80e3 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -271,7 +271,7 @@ Performing physical simulation of SiDB layouts is crucial for understanding layo facilitating rapid prototyping, eliminating the need for expensive and time-intensive fabrication processes. The command ``read --sqd`` (or ``read -s``) is used to import a SiDB layout from an sqd-file, a format compatible with `SiQAD `_. The SiDB layout can be visualized using the ``print -c`` command. Currently, *fiction* provides two electrostatic physical simulators: -an exact one (*QuickExact*) and a scalable one (*QuickSim*). +the exact one *QuickExact* and the scalable one *QuickSim*. QuickExact (``quickexact``) ########################### From b931dd1dd044e01168d8c2377b623b9a68776c99 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 11 Dec 2023 11:37:37 +0100 Subject: [PATCH 30/54] :memo: Revert Jan's change --- docs/cli.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/cli.rst b/docs/cli.rst index fa56b80e3..1903d48f6 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -415,7 +415,6 @@ Additionally, *fiction* itself can be part of a bash script. Consider the follow for filepath in ../benchmarks/TOY/*.v; do f="${filepath##*/}" - ./fiction -c "read $filepath; ortho; cell; qca ${f%.*}.qca" done From 7d13b46b44ca378aa4314f2ffee4a983972a6f70 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 12:30:26 +0100 Subject: [PATCH 31/54] :bug Add missing header --- include/fiction/technology/charge_distribution_surface.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index 80f3ef7b7..a7276bac9 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include From 532b4926393b3bab474abafbe43e326731e8f05b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 11 Dec 2023 12:31:02 +0100 Subject: [PATCH 32/54] :art: delete automatic base number detection. --- cli/cmd/simulation/quickexact.hpp | 2 -- docs/cli.rst | 1 - 2 files changed, 3 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 6ec3270af..44c5baf40 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -39,8 +39,6 @@ class quickexact_command : public command add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); add_option("--base,-b", physical_params.base, "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); - add_option("--base_number_detection, -bd", params.base_number_detection, - "Automatic base number detection (ON/OFF)", true); add_option("--global_potential,-g", params.global_potential, "Global potential applied to the entire layout (unit: V)", true); } diff --git a/docs/cli.rst b/docs/cli.rst index 1903d48f6..2b334e95f 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -288,7 +288,6 @@ Most important Parameters: - Thomas-Fermi screening (``-l``). - Energy transition level (0/-) (``-m``). - Base number for the simulation (``-b``). -- Automatic base number detection (``-bd``). See ``quickexact -h`` for a full list. From 13b171c871a61e3e56d6bfca0b420f1042b562ce Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Mon, 11 Dec 2023 15:25:39 +0100 Subject: [PATCH 33/54] :bug: Set CMP0135 only if CMake >= 3.24 is used --- cmake/PackageProject.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/PackageProject.cmake b/cmake/PackageProject.cmake index 6179d9005..24321c536 100644 --- a/cmake/PackageProject.cmake +++ b/cmake/PackageProject.cmake @@ -8,8 +8,8 @@ function(fiction_package_project) cmake_policy(SET CMP0103 NEW) # disallow multiple calls with the same NAME endif() - # if CMake version >= 3.23 - if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.23") + # if CMake version >= 3.24 + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.24") cmake_policy(SET CMP0135 NEW) # enable new timestamp checking behavior for # fetching content endif() From b0130bb3933ea5044c040b8f2cbf910ed1fff091 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 12 Dec 2023 07:21:51 +0100 Subject: [PATCH 34/54] :art: disable automatic base number detection in CLI. --- cli/cmd/simulation/quickexact.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 44c5baf40..58e480448 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -101,6 +101,8 @@ class quickexact_command : public command else { params.physical_parameters = physical_params; + params.base_number_detection = + fiction::quickexact_params::automatic_base_number_detection::OFF; sim_result = fiction::quickexact(*lyt_ptr, params); @@ -168,6 +170,8 @@ class quickexact_command : public command { physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; params = {}; + params.base_number_detection = + fiction::quickexact_params::automatic_base_number_detection::OFF; } }; From b5c425a81bf25c7e61542661e69651967935965e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 12 Dec 2023 07:26:34 +0100 Subject: [PATCH 35/54] :memo: add variable names. --- docs/cli.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index 2b334e95f..ed9ff83d5 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -284,9 +284,9 @@ see the `paper Date: Tue, 12 Dec 2023 16:19:54 +0100 Subject: [PATCH 36/54] :art: Cleaned up includes --- .../simulation/sidb/critical_temperature.hpp | 23 ++++++++----------- .../simulation/sidb/operational_domain.hpp | 2 ++ .../algorithms/simulation/sidb/quickexact.hpp | 4 ++-- .../algorithms/simulation/sidb/quicksim.hpp | 5 +--- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp index d54934b27..a228fa68a 100644 --- a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp +++ b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp @@ -9,21 +9,16 @@ #include "fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp" #include "fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp" #include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" -#include "fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.hpp" -#include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/algorithms/simulation/sidb/occupation_probability_of_excited_states.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/cell_technologies.hpp" -#include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/technology/physical_constants.hpp" -#include "fiction/technology/sidb_charge_state.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/hash.hpp" #include "fiction/utils/math_utils.hpp" -#include "fiction/utils/truth_table_utils.hpp" #include #include @@ -35,8 +30,8 @@ #include #include #include -#include #include +#include #include #include @@ -51,7 +46,7 @@ struct critical_temperature_params /** * An enumeration of modes to use for the *Critical Temperature* Simulation. */ - enum class critical_temperature_mode + enum class critical_temperature_mode : uint8_t { /** * The *Critical Temperature* is determined by considering the gate logic of the given layout. In this mode, it @@ -70,7 +65,7 @@ struct critical_temperature_params /** * An enumeration of simulation modes (exact vs. approximate) to use for the *Critical Temperature* Simulation. */ - enum class simulation_engine + enum class simulation_engine : uint8_t { /** * This simulation engine computes *Critical Temperature* values with 100 % accuracy. @@ -187,7 +182,8 @@ class critical_temperature_impl stats.critical_temperature = 0.0; return; } - else if (layout.num_cells() > 1) + + if (layout.num_cells() > 1) { const auto output_bdl_pairs = detect_bdl_pairs(layout, sidb_technology::cell_type::OUTPUT, params.bdl_params); @@ -256,8 +252,8 @@ class critical_temperature_impl else { stats.algorithm_name = "QuickSim"; - // All physically valid charge configurations are determined for the given layout (exhaustive ground state - // simulation is used to provide 100 % accuracy for the Critical Temperature). + // All physically valid charge configurations are determined for the given layout (probabilistic ground + // state simulation is used). simulation_results = quicksim(layout, params.simulation_params); } @@ -467,8 +463,9 @@ double critical_temperature_gate_based(const Lyt& lyt, const std::vector& sp assert(!spec.empty()); // all elements in tts must have the same number of variables - assert(std::adjacent_find(spec.begin(), spec.end(), - [](const auto& a, const auto& b) { return a.num_vars() != b.num_vars(); }) == spec.end()); + assert(std::adjacent_find(spec.cbegin(), spec.cend(), + [](const auto& a, const auto& b) + { return a.num_vars() != b.num_vars(); }) == spec.cend()); critical_temperature_stats st{}; diff --git a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp index ee6726dcd..cc56ec383 100644 --- a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp +++ b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp @@ -16,6 +16,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/cell_level_layout.hpp" +#include "fiction/technology/cell_technologies.hpp" #include "fiction/traits.hpp" #include "fiction/utils/execution_utils.hpp" #include "fiction/utils/hash.hpp" @@ -33,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index c22503877..a1cb738f8 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -6,14 +6,14 @@ #define FICTION_QUICKEXACT_HPP #include "fiction/algorithms/iter/gray_code_iterator.hpp" -#include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" #include "fiction/technology/charge_distribution_surface.hpp" +#include "fiction/technology/sidb_charge_state.hpp" +#include "fiction/technology/sidb_defects.hpp" #include "fiction/traits.hpp" -#include #include #include diff --git a/include/fiction/algorithms/simulation/sidb/quicksim.hpp b/include/fiction/algorithms/simulation/sidb/quicksim.hpp index 75e940b78..d2eb69dc4 100644 --- a/include/fiction/algorithms/simulation/sidb/quicksim.hpp +++ b/include/fiction/algorithms/simulation/sidb/quicksim.hpp @@ -5,19 +5,16 @@ #ifndef FICTION_QUICKSIM_HPP #define FICTION_QUICKSIM_HPP -#include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" #include "fiction/technology/charge_distribution_surface.hpp" +#include "fiction/technology/sidb_charge_state.hpp" #include "fiction/traits.hpp" -#include #include #include #include #include -#include -#include #include #include #include From 3ec4190079a3f4213f4bd414fbb7da13303a26b4 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 10:09:30 +0100 Subject: [PATCH 37/54] :fire: Remove base toggle from quickexact and quicksim CLI commands --- cli/cmd/simulation/quickexact.hpp | 14 ++++---------- cli/cmd/simulation/quicksim.hpp | 14 +++++--------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 58e480448..1d5ab1bf6 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -13,6 +13,10 @@ #include +#include +#include +#include +#include #include namespace alice @@ -37,8 +41,6 @@ class quickexact_command : public command true); add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); - add_option("--base,-b", physical_params.base, - "2-state (neutral/negative) vs. 3-state (positive/neutral/negative) simulation", true); add_option("--global_potential,-g", params.global_potential, "Global potential applied to the entire layout (unit: V)", true); } @@ -58,7 +60,6 @@ class quickexact_command : public command reset_params(); return; } - if (physical_params.lambda_tf <= 0) { env->out() << "[e] lambda_tf must be positive" << std::endl; @@ -66,13 +67,6 @@ class quickexact_command : public command return; } - if (physical_params.base != 2 && physical_params.base != 3) - { - env->out() << "[e] base must be 2 or 3" << std::endl; - reset_params(); - return; - } - auto& s = store(); // error case: empty cell layout store diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index c15307b5b..9275f3fc3 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -14,6 +14,11 @@ #include #include +#include +#include +#include +#include +#include #include namespace alice @@ -59,21 +64,12 @@ class quicksim_command : public command reset_params(); return; } - if (physical_params.lambda_tf <= 0) { env->out() << "[e] lambda_tf must be positive" << std::endl; reset_params(); return; } - - if (physical_params.base != 2) - { - env->out() << "[e] base must be 2" << std::endl; - reset_params(); - return; - } - if (params.alpha <= 0) { env->out() << "[e] alpha must be positive" << std::endl; From 5519f1fe34b3cc8a763721f2b3ec1b65f71e2255 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 12:56:28 +0100 Subject: [PATCH 38/54] :art: Further header include fixes --- cli/cmd/simulation/quickexact.hpp | 4 ++++ cli/cmd/simulation/quicksim.hpp | 2 ++ .../fiction/algorithms/simulation/sidb/operational_domain.hpp | 2 -- include/fiction/io/write_operational_domain.hpp | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 1d5ab1bf6..79676db69 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -7,12 +7,16 @@ #include #include +#include #include #include #include #include +#include +#include +#include #include #include #include diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index 9275f3fc3..05d8e7cbc 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -7,11 +7,13 @@ #include #include +#include #include #include #include #include +#include #include #include diff --git a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp index cc56ec383..b38d43c79 100644 --- a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp +++ b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp @@ -22,7 +22,6 @@ #include "fiction/utils/hash.hpp" #include "fiction/utils/phmap_utils.hpp" -#include #include #include #include @@ -33,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/include/fiction/io/write_operational_domain.hpp b/include/fiction/io/write_operational_domain.hpp index 2c9244204..83021368a 100644 --- a/include/fiction/io/write_operational_domain.hpp +++ b/include/fiction/io/write_operational_domain.hpp @@ -11,6 +11,7 @@ #include #include +#include #include namespace fiction From 1f020176b8c6ebbc08d7b09cd84e602ed1ddc245 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 12:57:21 +0100 Subject: [PATCH 39/54] :art: Adjustments to logging and [[nodiscard]] --- cli/cmd/simulation/quickexact.hpp | 28 +++++++++---------- cli/cmd/simulation/quicksim.hpp | 2 +- .../fiction/io/write_operational_domain.hpp | 3 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 79676db69..92fb54de5 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -99,8 +99,6 @@ class quickexact_command : public command else { params.physical_parameters = physical_params; - params.base_number_detection = - fiction::quickexact_params::automatic_base_number_detection::OFF; sim_result = fiction::quickexact(*lyt_ptr, params); @@ -149,17 +147,21 @@ class quickexact_command : public command * * @return JSON object containing details about the simulation. */ - nlohmann::json log() const override + [[nodiscard]] nlohmann::json log() const override { - return nlohmann::json{{"Algorithm name", sim_result.algorithm_name}, - {"Simulation runtime", sim_result.simulation_runtime.count()}, - {"Physical parameters", - {"base", sim_result.physical_parameters.base}, - {"epsilon_r", sim_result.physical_parameters.epsilon_r}, - {"lambda_tf", sim_result.physical_parameters.lambda_tf}, - {"mu_minus", sim_result.physical_parameters.mu_minus}}, - {"Ground state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, - {"Number of stable states", sim_result.charge_distributions.size()}}; + return nlohmann::json{ + {"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {"base", std::any_cast(sim_result.additional_simulation_parameters.at( + "base_number"))}, // fetch the automatically inferred base + {"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}, + {"global_potential", + std::any_cast(sim_result.additional_simulation_parameters.at("global_potential"))}}, + {"Ground state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, + {"Number of stable states", sim_result.charge_distributions.size()}}; } /** * Resets the parameters to their default values. @@ -168,8 +170,6 @@ class quickexact_command : public command { physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; params = {}; - params.base_number_detection = - fiction::quickexact_params::automatic_base_number_detection::OFF; } }; diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index 05d8e7cbc..4abee4903 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -156,7 +156,7 @@ class quicksim_command : public command * * @return JSON object containing details about the simulation. */ - nlohmann::json log() const override + [[nodiscard]] nlohmann::json log() const override { return nlohmann::json{ {"Algorithm name", sim_result.algorithm_name}, diff --git a/include/fiction/io/write_operational_domain.hpp b/include/fiction/io/write_operational_domain.hpp index 83021368a..8cd2f07ae 100644 --- a/include/fiction/io/write_operational_domain.hpp +++ b/include/fiction/io/write_operational_domain.hpp @@ -41,7 +41,8 @@ namespace detail * @param param The sweep parameter to be converted. * @return The string representation of the sweep parameter. */ -static inline std::string sweep_parameter_to_string(const operational_domain::sweep_parameter& param) noexcept +[[nodiscard]] static inline std::string +sweep_parameter_to_string(const operational_domain::sweep_parameter& param) noexcept { switch (param) { From 0ef8e89419b355fb24aaa7b38336acfa25746592 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 12:58:17 +0100 Subject: [PATCH 40/54] :sparkles: Added Operational Domain computation to the CLI --- cli/cmd/simulation/opdom.hpp | 309 +++++++++++++++++++++++++++++++++++ cli/commands.hpp | 1 + 2 files changed, 310 insertions(+) create mode 100644 cli/cmd/simulation/opdom.hpp diff --git a/cli/cmd/simulation/opdom.hpp b/cli/cmd/simulation/opdom.hpp new file mode 100644 index 000000000..c5e821548 --- /dev/null +++ b/cli/cmd/simulation/opdom.hpp @@ -0,0 +1,309 @@ +// +// Created by marcel on 12.12.23. +// + +#ifndef FICTION_CMD_OPDOM_HPP +#define FICTION_CMD_OPDOM_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace alice +{ +/** + * + */ +class opdom_command : public command +{ + public: + /** + * Standard constructor. Adds descriptive information, options, and flags. + * + * @param e alice::environment that specifies stores etc. + */ + explicit opdom_command(const environment::ptr& e) : + command(e, "Opdom is a quick and exact electrostatic ground state simulation algorithm designed " + "specifically for SiDB layouts. It provides a significant performance advantage of more than " + "three orders of magnitude over ExGS from SiQAD.") + { + add_option("--random_sampling,-r", num_random_samples, + "Use random sampling instead of grid search with this many random samples"); + add_option("--flood_fill,-f", num_random_samples, + "Use flood fill instead of grid search with this many initial random samples"); + add_option("--contour_tracing,-c", num_random_samples, + "Use contour tracing instead of grid search with up to this many random " + "samples"); + + add_option("filename", filename, "CSV filename to write the operational domain to")->required(); + + add_option("--epsilon_r,-e", physical_params.epsilon_r, "Electric permittivity of the substrate (unit-less)", + true); + add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); + add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); + + add_option("--x_sweep", x_sweep, "Sweep parameter of the x dimension [epsilon_r, lambda_tf, mu_minus]", true); + add_option("--y_sweep", y_sweep, "Sweep parameter of the y dimension [epsilon_r, lambda_tf, mu_minus]", true); + + add_option("--x_min", params.x_min, "Minimum value of the x dimension sweep", true); + add_option("--x_max", params.x_max, "Maximum value of the x dimension sweep", true); + add_option("--x_step", params.x_step, "Step size of the x dimension sweep", true); + add_option("--y_min", params.y_min, "Minimum value of the y dimension sweep", true); + add_option("--y_max", params.y_max, "Maximum value of the y dimension sweep", true); + add_option("--y_step", params.y_step, "Step size of the y dimension sweep", true); + } + + protected: + /** + * Function to perform the operational domain call. + */ + void execute() override + { + // reset operational domain and stats + op_domain = {}; + stats = {}; + + if (physical_params.epsilon_r <= 0) + { + env->out() << "[e] epsilon_r must be positive" << std::endl; + reset_params(); + return; + } + if (physical_params.lambda_tf <= 0) + { + env->out() << "[e] lambda_tf must be positive" << std::endl; + reset_params(); + return; + } + + auto& cs = store(); + + // error case: empty cell layout store + if (cs.empty()) + { + env->out() << "[w] no cell layout in store" << std::endl; + reset_params(); + return; + } + + auto& ts = store(); + + // error case: empty truth table store + if (ts.empty()) + { + env->out() << "[w] no truth table in store" << std::endl; + reset_params(); + return; + } + + // default sweep parameters + if (x_sweep.empty() && y_sweep.empty()) + { + x_sweep = "epsilon_r"; + y_sweep = "lambda_tf"; + } + else + { + // overwrite x and y sweep with their respective lower-case string representations + std::transform(x_sweep.begin(), x_sweep.end(), x_sweep.begin(), ::tolower); + std::transform(y_sweep.begin(), y_sweep.end(), y_sweep.begin(), ::tolower); + + static constexpr const std::array valid_sweep_params = {"epsilon_r", "lambda_tf", "mu_minus"}; + + // check if x sweep parameter is valid + if (std::find(valid_sweep_params.cbegin(), valid_sweep_params.cend(), x_sweep) == valid_sweep_params.cend()) + { + env->out() << "[e] invalid x sweep parameter \"" << x_sweep + << "\". Has to be one of [epsilon_r, lambda_tf, " + "mu_minus]" + << std::endl; + reset_params(); + return; + } + + // check if y sweep parameter is valid + if (std::find(valid_sweep_params.cbegin(), valid_sweep_params.cend(), y_sweep) == valid_sweep_params.cend()) + { + env->out() << "[e] invalid y sweep parameter \"" << y_sweep + << "\". Has to be one of [epsilon_r, lambda_tf, " + "mu_minus]" + << std::endl; + reset_params(); + return; + } + } + + // assign x sweep parameters + if (x_sweep == "epsilon_r") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::EPSILON_R; + } + else if (x_sweep == "lambda_tf") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::LAMBDA_TF; + } + else if (x_sweep == "mu_minus") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::MU_MINUS; + } + + // assign y sweep parameters + if (y_sweep == "epsilon_r") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::EPSILON_R; + } + else if (y_sweep == "lambda_tf") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::LAMBDA_TF; + } + else if (y_sweep == "mu_minus") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::MU_MINUS; + } + + const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); }; + + const auto opdom = [this, &ts, &get_name](auto&& lyt_ptr) + { + const auto tt_ptr = ts.current(); + + using Lyt = typename std::decay_t::element_type; + using TT = typename std::decay_t::element_type; + + if constexpr (fiction::has_sidb_technology_v) + { + params.sim_params = physical_params; + + if (is_set("random_sampling")) + { + op_domain = fiction::operational_domain_random_sampling( + *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + } + else if (is_set("flood_fill")) + { + op_domain = fiction::operational_domain_flood_fill(*lyt_ptr, std::vector{*tt_ptr}, + num_random_samples, params, &stats); + } + else if (is_set("contour_tracing")) + { + op_domain = fiction::operational_domain_contour_tracing( + *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + } + else + { + op_domain = fiction::operational_domain_grid_search(*lyt_ptr, std::vector{*tt_ptr}, + params, &stats); + } + } + else + { + env->out() << fmt::format("[e] {} is not an SiDB layout", get_name(lyt_ptr)) << std::endl; + } + }; + + std::visit(opdom, cs.current()); + + write_op_domain(); + + reset_params(); + } + + private: + /** + * Physical parameters for the simulation. + */ + fiction::sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + /** + * Operational domain parameters. + */ + fiction::operational_domain_params params{}; + /** + * Operational domain stats. + */ + fiction::operational_domain_stats stats{}; + /** + * Number of random samples. + */ + std::size_t num_random_samples{}; + /** + * User input for the x dimension sweep parameter. + */ + std::string x_sweep{}; + /** + * User input for the y dimension sweep parameter. + */ + std::string y_sweep{}; + /** + * CSV filename to write the operational domain to. + */ + std::string filename{}; + /** + * The operational domain. + */ + fiction::operational_domain op_domain{}; + + /** + * Writes the operational domain to the specified CSV file. + */ + void write_op_domain() const + { + static const fiction::write_operational_domain_params write_opdom_params{"1", "0"}; + try + { + fiction::write_operational_domain(op_domain, filename, write_opdom_params); + } + catch (const std::exception& e) + { + env->out() << fmt::format("[e] {}", e.what()) << std::endl; + } + } + /** + * Logs the resulting information in a log file. + * + * @return JSON object containing details about the operational domain. + */ + [[nodiscard]] nlohmann::json log() const override + { + return nlohmann::json{ + {"Algorithm name", "QuickExact"}, + {"Runtime in seconds", mockturtle::to_seconds(stats.time_total)}, + {"Number of simulator invocations", stats.num_simulator_invocations}, + {"Number of evaluated parameter combinations", stats.num_evaluated_parameter_combinations}, + {"Number of operational parameter combinations", stats.num_operational_parameter_combinations}, + {"Number of non-operational parameter combinations", stats.num_non_operational_parameter_combinations}}; + } + /** + * Resets the parameters to their default values. + */ + void reset_params() + { + physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; + params = {}; + x_sweep = {}; + y_sweep = {}; + filename = {}; + } +}; + +ALICE_ADD_COMMAND(opdom, "Simulation") + +} // namespace alice + +#endif // FICTION_CMD_OPDOM_HPP diff --git a/cli/commands.hpp b/cli/commands.hpp index 4108cf593..8fc4e57f1 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -50,6 +50,7 @@ // physical simulation commands #ifdef FICTION_SIMULATION_FLOW +#include "cmd/simulation/opdom.hpp" #include "cmd/simulation/quickexact.hpp" #include "cmd/simulation/quicksim.hpp" #endif From 3d31d81ddf73442ce0c181e6312b037d2c4d7e99 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 12:58:17 +0100 Subject: [PATCH 41/54] :sparkles: Added Operational Domain computation to the CLI --- cli/cmd/simulation/opdom.hpp | 333 +++++++++++++++++++++++++++++++++++ cli/commands.hpp | 1 + 2 files changed, 334 insertions(+) create mode 100644 cli/cmd/simulation/opdom.hpp diff --git a/cli/cmd/simulation/opdom.hpp b/cli/cmd/simulation/opdom.hpp new file mode 100644 index 000000000..12ad6f972 --- /dev/null +++ b/cli/cmd/simulation/opdom.hpp @@ -0,0 +1,333 @@ +// +// Created by marcel on 12.12.23. +// + +#ifndef FICTION_CMD_OPDOM_HPP +#define FICTION_CMD_OPDOM_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace alice +{ +/** + * + */ +class opdom_command : public command +{ + public: + /** + * Standard constructor. Adds descriptive information, options, and flags. + * + * @param e alice::environment that specifies stores etc. + */ + explicit opdom_command(const environment::ptr& e) : + command(e, "Opdom is a quick and exact electrostatic ground state simulation algorithm designed " + "specifically for SiDB layouts. It provides a significant performance advantage of more than " + "three orders of magnitude over ExGS from SiQAD.") + { + add_option("--random_sampling,-r", num_random_samples, + "Use random sampling instead of grid search with this many random samples"); + add_option("--flood_fill,-f", num_random_samples, + "Use flood fill instead of grid search with this many initial random samples"); + add_option("--contour_tracing,-c", num_random_samples, + "Use contour tracing instead of grid search with up to this many random " + "samples"); + + add_option("filename", filename, "CSV filename to write the operational domain to")->required(); + + add_option("--epsilon_r,-e", physical_params.epsilon_r, "Electric permittivity of the substrate (unit-less)", + true); + add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); + add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); + + add_option("--x_sweep", x_sweep, "Sweep parameter of the x dimension [epsilon_r, lambda_tf, mu_minus]", true); + add_option("--y_sweep", y_sweep, "Sweep parameter of the y dimension [epsilon_r, lambda_tf, mu_minus]", true); + + add_option("--x_min", params.x_min, "Minimum value of the x dimension sweep", true); + add_option("--x_max", params.x_max, "Maximum value of the x dimension sweep", true); + add_option("--x_step", params.x_step, "Step size of the x dimension sweep", true); + add_option("--y_min", params.y_min, "Minimum value of the y dimension sweep", true); + add_option("--y_max", params.y_max, "Maximum value of the y dimension sweep", true); + add_option("--y_step", params.y_step, "Step size of the y dimension sweep", true); + } + + protected: + /** + * Function to perform the operational domain call. + */ + void execute() override + { + // reset operational domain and stats + op_domain = {}; + stats = {}; + + if (physical_params.epsilon_r <= 0) + { + env->out() << "[e] epsilon_r must be positive" << std::endl; + reset_params(); + return; + } + if (physical_params.lambda_tf <= 0) + { + env->out() << "[e] lambda_tf must be positive" << std::endl; + reset_params(); + return; + } + + // check for valid x and y parameter bounds + if (params.x_min >= params.x_max) + { + env->out() << "[e] x_min must be smaller than x_max" << std::endl; + reset_params(); + return; + } + if (params.y_min >= params.y_max) + { + env->out() << "[e] y_min must be smaller than y_max" << std::endl; + reset_params(); + return; + } + + // make sure that at most one algorithm is selected + const std::array algorithm_selections = {is_set("random_sampling"), is_set("flood_fill"), + is_set("contour_tracing")}; + if (std::count(algorithm_selections.cbegin(), algorithm_selections.cend(), true) > 1) + { + env->out() << "[e] only one algorithm can be selected at a time" << std::endl; + reset_params(); + return; + } + + auto& cs = store(); + + // error case: empty cell layout store + if (cs.empty()) + { + env->out() << "[w] no cell layout in store" << std::endl; + reset_params(); + return; + } + + auto& ts = store(); + + // error case: empty truth table store + if (ts.empty()) + { + env->out() << "[w] no truth table in store" << std::endl; + reset_params(); + return; + } + + // default sweep parameters + if (x_sweep.empty() && y_sweep.empty()) + { + x_sweep = "epsilon_r"; + y_sweep = "lambda_tf"; + } + else + { + // overwrite x and y sweep with their respective lower-case string representations + std::transform(x_sweep.begin(), x_sweep.end(), x_sweep.begin(), ::tolower); + std::transform(y_sweep.begin(), y_sweep.end(), y_sweep.begin(), ::tolower); + + static constexpr const std::array valid_sweep_params = {"epsilon_r", "lambda_tf", "mu_minus"}; + + // check if x sweep parameter is valid + if (std::find(valid_sweep_params.cbegin(), valid_sweep_params.cend(), x_sweep) == valid_sweep_params.cend()) + { + env->out() << "[e] invalid x sweep parameter \"" << x_sweep + << "\". Has to be one of [epsilon_r, lambda_tf, " + "mu_minus]" + << std::endl; + reset_params(); + return; + } + + // check if y sweep parameter is valid + if (std::find(valid_sweep_params.cbegin(), valid_sweep_params.cend(), y_sweep) == valid_sweep_params.cend()) + { + env->out() << "[e] invalid y sweep parameter \"" << y_sweep + << "\". Has to be one of [epsilon_r, lambda_tf, " + "mu_minus]" + << std::endl; + reset_params(); + return; + } + } + + // assign x sweep parameters + if (x_sweep == "epsilon_r") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::EPSILON_R; + } + else if (x_sweep == "lambda_tf") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::LAMBDA_TF; + } + else if (x_sweep == "mu_minus") + { + params.x_dimension = fiction::operational_domain::sweep_parameter::MU_MINUS; + } + + // assign y sweep parameters + if (y_sweep == "epsilon_r") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::EPSILON_R; + } + else if (y_sweep == "lambda_tf") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::LAMBDA_TF; + } + else if (y_sweep == "mu_minus") + { + params.y_dimension = fiction::operational_domain::sweep_parameter::MU_MINUS; + } + + const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); }; + + const auto opdom = [this, &ts, &get_name](auto&& lyt_ptr) + { + const auto tt_ptr = ts.current(); + + using Lyt = typename std::decay_t::element_type; + using TT = typename std::decay_t::element_type; + + if constexpr (fiction::has_sidb_technology_v) + { + params.sim_params = physical_params; + + if (is_set("random_sampling")) + { + op_domain = fiction::operational_domain_random_sampling( + *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + } + else if (is_set("flood_fill")) + { + op_domain = fiction::operational_domain_flood_fill(*lyt_ptr, std::vector{*tt_ptr}, + num_random_samples, params, &stats); + } + else if (is_set("contour_tracing")) + { + op_domain = fiction::operational_domain_contour_tracing( + *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + } + else + { + op_domain = fiction::operational_domain_grid_search(*lyt_ptr, std::vector{*tt_ptr}, + params, &stats); + } + } + else + { + env->out() << fmt::format("[e] {} is not an SiDB layout", get_name(lyt_ptr)) << std::endl; + } + }; + + std::visit(opdom, cs.current()); + + write_op_domain(); + + reset_params(); + } + + private: + /** + * Physical parameters for the simulation. + */ + fiction::sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + /** + * Operational domain parameters. + */ + fiction::operational_domain_params params{}; + /** + * Operational domain stats. + */ + fiction::operational_domain_stats stats{}; + /** + * Number of random samples. + */ + std::size_t num_random_samples{}; + /** + * User input for the x dimension sweep parameter. + */ + std::string x_sweep{}; + /** + * User input for the y dimension sweep parameter. + */ + std::string y_sweep{}; + /** + * CSV filename to write the operational domain to. + */ + std::string filename{}; + /** + * The operational domain. + */ + fiction::operational_domain op_domain{}; + + /** + * Writes the operational domain to the specified CSV file. + */ + void write_op_domain() const + { + static const fiction::write_operational_domain_params write_opdom_params{"1", "0"}; + try + { + fiction::write_operational_domain(op_domain, filename, write_opdom_params); + } + catch (const std::exception& e) + { + env->out() << fmt::format("[e] {}", e.what()) << std::endl; + } + } + /** + * Logs the resulting information in a log file. + * + * @return JSON object containing details about the operational domain. + */ + [[nodiscard]] nlohmann::json log() const override + { + return nlohmann::json{ + {"Algorithm name", "QuickExact"}, + {"Runtime in seconds", mockturtle::to_seconds(stats.time_total)}, + {"Number of simulator invocations", stats.num_simulator_invocations}, + {"Number of evaluated parameter combinations", stats.num_evaluated_parameter_combinations}, + {"Number of operational parameter combinations", stats.num_operational_parameter_combinations}, + {"Number of non-operational parameter combinations", stats.num_non_operational_parameter_combinations}}; + } + /** + * Resets the parameters to their default values. + */ + void reset_params() + { + physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; + params = {}; + x_sweep = {}; + y_sweep = {}; + filename = {}; + } +}; + +ALICE_ADD_COMMAND(opdom, "Simulation") + +} // namespace alice + +#endif // FICTION_CMD_OPDOM_HPP diff --git a/cli/commands.hpp b/cli/commands.hpp index 4108cf593..8fc4e57f1 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -50,6 +50,7 @@ // physical simulation commands #ifdef FICTION_SIMULATION_FLOW +#include "cmd/simulation/opdom.hpp" #include "cmd/simulation/quickexact.hpp" #include "cmd/simulation/quicksim.hpp" #endif From bee789c16a9dafd0ea7f259943244dd4ae355e90 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 13:25:59 +0100 Subject: [PATCH 42/54] :memo: Added Operational Domain CLI documentation --- docs/cli.rst | 63 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index ed9ff83d5..326c26ec3 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -280,14 +280,13 @@ QuickExact (``quickexact``) It enumerates all possible charge distributions. However, by incorporating three techniques, namely 1.) Physically-informed Search Space Pruning, 2.) Partial Solution Caching, and 3.) Effective State Enumeration, it provides a significant performance advantage of more than three orders of magnitude over ExGS from SiQAD. For additional details, -see the `paper `_. +see `the paper `_. -Most important Parameters: +Most important parameters: -- Relative permittivity :math: `\epsilon_r` (``-e``). -- Thomas-Fermi screening :math: `\lambda_tf` (``-l``). -- Energy transition level (0/-) :math: `\mu_-` (``-m``). -- Base number for the simulation (``-b``). +- Relative permittivity :math:`\epsilon_r` (``-e``) +- Thomas-Fermi screening length :math:`\lambda_tf` (``-l``) +- Energy transition level (0/-) :math:`\mu_-` (``-m``) See ``quickexact -h`` for a full list. @@ -300,18 +299,56 @@ QuickSim (``quicksim``) *QuickSim* serves as a scalable simulator designed to determine the ground state charge distribution for a given SiDB layout. To enhance efficiency, effective search space pruning techniques, such as (`max-min diversity distributions `_), are integrated. -For more in-depth information, refer to the `paper `_. +For more in-depth information, refer to `the paper `_. -Most important Parameters: +Most important parameters: -- Relative permittivity :math: `\epsilon_r` (``-e``). -- Thomas-Fermi screening :math: `\lambda_tf` (``-l``). -- Energy transition level (0/-) :math: `\mu_-` (``-m``). -- Number of iterations I (``-i``). -- Alpha value :math: `\alpha` (``-a``). +- Relative permittivity :math:`\epsilon_r` (``-e``) +- Thomas-Fermi screening :math:`\lambda_tf` (``-l``) +- Energy transition level (0/-) :math:`\mu_-` (``-m``) +- Number of iterations (``-i``) +- :math:`\alpha` value (``-a``) The simulated ground state charge distribution can be printed with ``print -c``. + +Operational Domain (``opdom``) +############################## + +Computes the operational domain of the current SiDB cell-level layout in store. The operational domain is the set of all +parameter combinations for which the layout is logically operational. Logical operation is defined as the layout +implementing the current truth table in store. The input BDL pairs of the layout are assumed to be in the same order as +the inputs of the truth table. +For more information, see `the paper `_. + +The command ``opdom`` writes the operational domain to a CSV file with the given filename from where it can be further +processed by other tools. + +The parameter space to sweep over can be specified by the user via the flags +- ``--x_sweep`` +- ``--y_sweep`` +which have to be either ``epsilon_r``, ``lambda_tf``, or ``mu_minus``. The default is ``epsilon_r`` for ``--x_sweep`` and +``lambda_tf`` for ``--y_sweep``. + +Additionally, min, max, and step size values can be specified for each parameter using the flags +- ``--x_min`` +- ``--x_max`` +- ``--x_step`` +- ``--y_min`` +- ``--y_max`` +- ``--y_step`` +respectively. The default values are 1, 10, and 0.1 on both axis, for min, max, and step, respectively. + +By default, grid search is applied to explore the operational domain. The algorithm can be changed by specifying one of +the following options: +- ``--random_sampling``/``-r`` +- ``--flood_fill``/``-f`` +- ``--contour_tracing``/``-c`` +each of which start from a set of random samples, whose number has to be passed as an argument to the flag. + +See ``opdom -h`` for a full list of arguments. + + Area usage (``area``) --------------------- From 4e60b69dc78b71927bbfd293495fff78f708fe88 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 13:32:31 +0100 Subject: [PATCH 43/54] :bug: Added missing includes to `critical_temperature` --- .../fiction/algorithms/simulation/sidb/critical_temperature.hpp | 1 + test/algorithms/simulation/sidb/critical_temperature.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp index a228fa68a..686234b39 100644 --- a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp +++ b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp @@ -7,6 +7,7 @@ #include "fiction/algorithms/iter/bdl_input_iterator.hpp" #include "fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp" +#include "fiction/algorithms/simulation/sidb/can_positive_charges_occur.hpp" #include "fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp" #include "fiction/algorithms/simulation/sidb/energy_distribution.hpp" #include "fiction/algorithms/simulation/sidb/occupation_probability_of_excited_states.hpp" diff --git a/test/algorithms/simulation/sidb/critical_temperature.cpp b/test/algorithms/simulation/sidb/critical_temperature.cpp index bfa509d31..8ea903dfb 100644 --- a/test/algorithms/simulation/sidb/critical_temperature.cpp +++ b/test/algorithms/simulation/sidb/critical_temperature.cpp @@ -11,9 +11,9 @@ #include #include #include -#include #include #include +#include #include #include From 965553aa2a083e4ba5860c7023d3afd5fc06c4df Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 13 Dec 2023 13:40:15 +0100 Subject: [PATCH 44/54] :memo: Small doc fix --- docs/cli.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index 326c26ec3..9605ea4aa 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -285,7 +285,7 @@ see `the paper Date: Wed, 13 Dec 2023 14:13:45 +0100 Subject: [PATCH 45/54] :bug: Added missing includes to `quicksim` --- test/algorithms/simulation/sidb/quicksim.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index 68b8df98e..e5133639c 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include From 265910663a0e049ee02a6390ad2b7d83340108dd Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 10:36:34 +0100 Subject: [PATCH 46/54] :bug: Added missing includes to `quicksim`'s tests --- test/algorithms/simulation/sidb/quicksim.cpp | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index e5133639c..6da36cd06 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -7,11 +7,17 @@ #include #include +#include #include #include #include +#include #include +#include #include +#include + +#include using namespace fiction; @@ -372,8 +378,8 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({10, 8, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({16, 1, 0}, TestType::cell_type::NORMAL); - sidb_simulation_result quicksimstats{}; - const sidb_simulation_parameters params{2, -0.28}; + const sidb_simulation_result quicksim_stats{}; + const sidb_simulation_parameters params{2, -0.28}; quicksim_params quicksim_params{params}; @@ -458,20 +464,19 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({6, 2, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({8, 2, 0}, TestType::cell_type::NORMAL); - const sidb_simulation_result quicksimstats{}; - const sidb_simulation_parameters params{2, -0.25}; + const sidb_simulation_parameters params{2, -0.25}; quicksim_params quicksim_params{params}; REQUIRE(quicksim_params.phys_params.mu_minus == -0.25); - const auto check_charge_configuration = [](const sidb_simulation_result& stats) noexcept + const auto check_charge_configuration = [](const sidb_simulation_result& result) noexcept { - REQUIRE(!stats.charge_distributions.empty()); + REQUIRE(!result.charge_distributions.empty()); - REQUIRE(!energy_distribution(stats.charge_distributions).empty()); + REQUIRE(!energy_distribution(result.charge_distributions).empty()); - const auto& charge_lyt_first = stats.charge_distributions.front(); + const auto& charge_lyt_first = result.charge_distributions.front(); CHECK((((charge_lyt_first.get_charge_state({6, 2, 0}) == sidb_charge_state::NEGATIVE) && (charge_lyt_first.get_charge_state({8, 2, 0}) == sidb_charge_state::NEUTRAL)) || @@ -558,8 +563,7 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({8, 10, 1}, TestType::cell_type::NORMAL); - const sidb_simulation_result quicksimstats{}; - const sidb_simulation_parameters params{2, -0.32}; + const sidb_simulation_parameters params{2, -0.32}; quicksim_params quicksim_params{params}; @@ -667,7 +671,7 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({30, 15, 0}, TestType::cell_type::NORMAL); - const sidb_simulation_result quicksimstats{}; + const sidb_simulation_result quicksim_stats{}; const sidb_simulation_parameters params{2, -0.32}; quicksim_params quicksim_params{params}; From 70b57ba653b9b7a20d0daf0337e83e41a10dbdaa Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 12:40:22 +0100 Subject: [PATCH 47/54] :art: Code cleanup in `critical_temperature` --- .../simulation/sidb/critical_temperature.hpp | 71 +++-- .../algorithms/simulation/sidb/quicksim.hpp | 1 + .../simulation/sidb/critical_temperature.cpp | 244 ++++++++++-------- 3 files changed, 174 insertions(+), 142 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp index 686234b39..ecd5f5f64 100644 --- a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp +++ b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp @@ -13,12 +13,11 @@ #include "fiction/algorithms/simulation/sidb/occupation_probability_of_excited_states.hpp" #include "fiction/algorithms/simulation/sidb/quickexact.hpp" #include "fiction/algorithms/simulation/sidb/quicksim.hpp" +#include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/physical_constants.hpp" #include "fiction/traits.hpp" -#include "fiction/types.hpp" -#include "fiction/utils/hash.hpp" #include "fiction/utils/math_utils.hpp" #include @@ -29,9 +28,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -44,25 +43,6 @@ namespace fiction */ struct critical_temperature_params { - /** - * An enumeration of modes to use for the *Critical Temperature* Simulation. - */ - enum class critical_temperature_mode : uint8_t - { - /** - * The *Critical Temperature* is determined by considering the gate logic of the given layout. In this mode, it - * is distinguished between excited charge distributions that produce the correct output (with respect to a - * truth table) and those that do not. - */ - GATE_BASED_SIMULATION, - /** - * The *Critical Temperature* is determined by ignoring the gate logic of the given layout. This mode does not - * distinguish between excited charge distributions that produce the correct output (with respect to a truth - * table) and those that do not. - */ - NON_GATE_BASED_SIMULATION - }; - /** * An enumeration of simulation modes (exact vs. approximate) to use for the *Critical Temperature* Simulation. */ @@ -79,26 +59,35 @@ struct critical_temperature_params APPROXIMATE }; /** - * All Parameters for physical SiDB simulations. + * All parameters for physical SiDB simulations. */ - quicksim_params simulation_params{}; + sidb_simulation_parameters physical_parameters{}; /** * Simulation mode to determine the *Critical Temperature*. */ simulation_engine engine = simulation_engine::EXACT; /** - * Probability that the ground state is less populated due to temperature. For gate-based simulation, this is the - * probability of erroneous calculations of the gate. + * Probability threshold for ground state population. The temperature at which the simulation finds the ground state + * to be populated with a probability of less than the given percentage, is determined to be the critical + * temperature. For gate-based simulation, this is the probability of erroneous calculations of the gate. */ double confidence_level{0.99}; /** - * Simulation stops at max_temperature (~ 126 °C by default) (unit: K). + * Maximum simulation temperature beyond which no simulation will be conducted (~ 126 °C by default) (unit: K). */ double max_temperature{400}; /** * Parameters for the BDL pair detection algorithms. */ detect_bdl_pairs_params bdl_params{}; + /** + * Number of iteration steps for the *QuickSim* algorithm (only applicable if engine == APPROXIMATE). + */ + uint64_t iteration_steps{80}; + /** + * Alpha parameter for the *QuickSim* algorithm (only applicable if engine == APPROXIMATE). + */ + double alpha{0.7}; }; /** @@ -193,7 +182,7 @@ class critical_temperature_impl for (auto i = 0u; i < spec.front().num_bits(); ++i, ++bii) { // if positively charged SiDBs can occur, the SiDB layout is considered as non-operational - if (can_positive_charges_occur(*bii, params.simulation_params.phys_params)) + if (can_positive_charges_occur(*bii, params.physical_parameters)) { stats.critical_temperature = 0.0; return; @@ -241,21 +230,23 @@ class critical_temperature_impl void non_gate_based_simulation() noexcept { sidb_simulation_result simulation_results{}; + if (params.engine == critical_temperature_params::simulation_engine::EXACT) { - stats.algorithm_name = "QuickExact"; + const quickexact_params qe_params{params.physical_parameters, + quickexact_params::automatic_base_number_detection::OFF}; + // All physically valid charge configurations are determined for the given layout (`QuickExact` simulation // is used to provide 100 % accuracy for the Critical Temperature). - const quickexact_params qe_params{params.simulation_params.phys_params, - quickexact_params::automatic_base_number_detection::OFF}; simulation_results = quickexact(layout, qe_params); } else { - stats.algorithm_name = "QuickSim"; + const quicksim_params qs_params{params.physical_parameters, params.iteration_steps, params.alpha}; + // All physically valid charge configurations are determined for the given layout (probabilistic ground // state simulation is used). - simulation_results = quicksim(layout, params.simulation_params); + simulation_results = quicksim(layout, qs_params); } // The number of physically valid charge configurations is stored. @@ -414,19 +405,20 @@ class critical_temperature_impl [[nodiscard]] sidb_simulation_result physical_simulation_of_layout(const bdl_input_iterator& bdl_iterator) noexcept { - assert(params.simulation_params.phys_params.base == 2 && "base number is set to 3"); + assert(params.physical_parameters.base == 2 && "base number has to be 2"); + if (params.engine == critical_temperature_params::simulation_engine::EXACT) { // perform exact simulation - const quickexact_params quickexact_params{ - params.simulation_params.phys_params, - fiction::quickexact_params::automatic_base_number_detection::OFF}; - return quickexact(*bdl_iterator, quickexact_params); + const quickexact_params qe_params{ + params.physical_parameters, fiction::quickexact_params::automatic_base_number_detection::OFF}; + return quickexact(*bdl_iterator, qe_params); } if (params.engine == critical_temperature_params::simulation_engine::APPROXIMATE) { - return quicksim(*bdl_iterator, params.simulation_params); + const quicksim_params qs_params{params.physical_parameters, params.iteration_steps, params.alpha}; + return quicksim(*bdl_iterator, qs_params); } assert(false && "unsupported simulation engine"); @@ -499,7 +491,6 @@ double critical_temperature_non_gate_based(const Lyt& lyt, const critical_temper { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); critical_temperature_stats st{}; diff --git a/include/fiction/algorithms/simulation/sidb/quicksim.hpp b/include/fiction/algorithms/simulation/sidb/quicksim.hpp index d2eb69dc4..41b886ec2 100644 --- a/include/fiction/algorithms/simulation/sidb/quicksim.hpp +++ b/include/fiction/algorithms/simulation/sidb/quicksim.hpp @@ -5,6 +5,7 @@ #ifndef FICTION_QUICKSIM_HPP #define FICTION_QUICKSIM_HPP +#include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_result.hpp" #include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/technology/sidb_charge_state.hpp" diff --git a/test/algorithms/simulation/sidb/critical_temperature.cpp b/test/algorithms/simulation/sidb/critical_temperature.cpp index 8ea903dfb..6ef56d35f 100644 --- a/test/algorithms/simulation/sidb/critical_temperature.cpp +++ b/test/algorithms/simulation/sidb/critical_temperature.cpp @@ -6,17 +6,19 @@ #include #include -#include -#include +#include #include #include #include +#include #include +#include #include #include #include #include +#include using namespace fiction; @@ -25,40 +27,50 @@ TEMPLATE_TEST_CASE( (cell_level_layout>>), (charge_distribution_surface>>>)) { + TestType lyt{}; + + critical_temperature_params params{}; + sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + + critical_temperature_stats critical_stats{}; + SECTION("No physically valid charge distribution could be found") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({6, 1, 0}, sidb_technology::cell_type::OUTPUT); lyt.assign_cell_type({8, 1, 0}, sidb_technology::cell_type::OUTPUT); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}, 0, 0.0}, - critical_temperature_params::simulation_engine::APPROXIMATE, 0.99, - 350}; - critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &criticalstats); - CHECK(criticalstats.num_valid_lyt == 0); - CHECK(criticalstats.critical_temperature == 0.0); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::APPROXIMATE; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 0; + params.alpha = 0.0; + + critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &critical_stats); + + CHECK(critical_stats.num_valid_lyt == 0); + CHECK(critical_stats.critical_temperature == 0.0); } - SECTION("One SiDB") + SECTION("No SiDB") { - TestType lyt{}; - - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{tt{}}, params, &criticalstats); - CHECK(criticalstats.num_valid_lyt == 0); - CHECK(criticalstats.critical_temperature == 0.0); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_gate_based(lyt, std::vector{tt{}}, params, &critical_stats); + + CHECK(critical_stats.num_valid_lyt == 0); + CHECK(critical_stats.critical_temperature == 0.0); } - SECTION("Not working diagonal Wire where positively charged SiDBs can occur") + SECTION("Not working diagonal wire where positively charged SiDBs can occur") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -80,37 +92,43 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &criticalstats); - CHECK(criticalstats.critical_temperature == 0.0); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &critical_stats); + + CHECK(critical_stats.critical_temperature == 0.0); } SECTION("four SiDBs with two valid charge distributions, QuickExact") { - TestType lyt{}; lyt.assign_cell_type({0, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({2, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({4, 1}, TestType::cell_type::NORMAL); lyt.assign_cell_type({2, 0}, TestType::cell_type::NORMAL); lyt.assign_cell_type({2, 2}, TestType::cell_type::NORMAL); - critical_temperature_stats criticalstats_non_gate_based{}; - const critical_temperature_params params_non_gate_based{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, - 0.99, 350}; - critical_temperature_non_gate_based(lyt, params_non_gate_based, &criticalstats_non_gate_based); - CHECK(criticalstats_non_gate_based.num_valid_lyt == 2); - CHECK_THAT(std::abs(criticalstats_non_gate_based.energy_between_ground_state_and_first_erroneous), + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_non_gate_based(lyt, params, &critical_stats); + + CHECK(critical_stats.num_valid_lyt == 2); + CHECK_THAT(std::abs(critical_stats.energy_between_ground_state_and_first_erroneous), Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.01)); - CHECK(criticalstats_non_gate_based.critical_temperature == 350); + CHECK(critical_stats.critical_temperature == 350); } SECTION("Y-shape SiDB AND gate") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 1}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 1}, sidb_technology::cell_type::INPUT); @@ -128,20 +146,24 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.28}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &criticalstats); + physical_params.mu_minus = -0.28; + + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; - CHECK_THAT(std::abs(criticalstats.energy_between_ground_state_and_first_erroneous), + critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &critical_stats); + + CHECK_THAT(std::abs(critical_stats.energy_between_ground_state_and_first_erroneous), Catch::Matchers::WithinAbs(std::numeric_limits::infinity(), 0.01)); - CHECK(criticalstats.critical_temperature == 350); + CHECK(critical_stats.critical_temperature == 350); } SECTION("Bestagon AND gate, QuickExact") { - TestType lyt{}; - lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -171,19 +193,22 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &criticalstats); - CHECK_THAT(std::abs(criticalstats.energy_between_ground_state_and_first_erroneous), + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &critical_stats); + + CHECK_THAT(std::abs(critical_stats.energy_between_ground_state_and_first_erroneous), Catch::Matchers::WithinAbs(26.02, 0.01)); - CHECK_THAT(std::abs(criticalstats.critical_temperature - 59.19), Catch::Matchers::WithinAbs(0.00, 0.01)); + CHECK_THAT(std::abs(critical_stats.critical_temperature - 59.19), Catch::Matchers::WithinAbs(0.00, 0.01)); } SECTION("Bestagon AND gate, QuickSim") { - TestType lyt{}; - lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -213,18 +238,20 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}, 500, 0.6}, - critical_temperature_params::simulation_engine::APPROXIMATE, 0.99, - 350}; - critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &criticalstats); - CHECK(criticalstats.critical_temperature > 0); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::APPROXIMATE; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 500; + params.alpha = 0.6; + + critical_temperature_gate_based(lyt, std::vector{create_and_tt()}, params, &critical_stats); + + CHECK(critical_stats.critical_temperature > 0); } SECTION("Bestagon FO2 gate") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -253,20 +280,22 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_fan_out_tt()}, params, &criticalstats); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; - CHECK_THAT(std::abs(criticalstats.energy_between_ground_state_and_first_erroneous - 0.56), + critical_temperature_gate_based(lyt, std::vector{create_fan_out_tt()}, params, &critical_stats); + + CHECK_THAT(std::abs(critical_stats.energy_between_ground_state_and_first_erroneous - 0.56), Catch::Matchers::WithinAbs(0.00, 0.01)); - CHECK_THAT(std::abs(criticalstats.critical_temperature - 1.46), Catch::Matchers::WithinAbs(0.00, 0.01)); + CHECK_THAT(std::abs(critical_stats.critical_temperature - 1.46), Catch::Matchers::WithinAbs(0.00, 0.01)); } SECTION("Bestagon CX gate") { - TestType lyt{}; - lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -307,20 +336,22 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_crossing_wire_tt()}, params, &criticalstats); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; - CHECK_THAT(std::fabs(criticalstats.energy_between_ground_state_and_first_erroneous - 0.32), + critical_temperature_gate_based(lyt, std::vector{create_crossing_wire_tt()}, params, &critical_stats); + + CHECK_THAT(std::fabs(critical_stats.energy_between_ground_state_and_first_erroneous - 0.32), Catch::Matchers::WithinAbs(0.00, 0.01)); - CHECK_THAT(std::abs(criticalstats.critical_temperature - 0.85), Catch::Matchers::WithinAbs(0.00, 0.01)); + CHECK_THAT(std::abs(critical_stats.critical_temperature - 0.85), Catch::Matchers::WithinAbs(0.00, 0.01)); } SECTION("OR gate") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({26, 0, 0}, sidb_technology::cell_type::INPUT); @@ -343,18 +374,22 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.25}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_or_tt()}, params, &criticalstats); + physical_params.mu_minus = -0.25; + + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_gate_based(lyt, std::vector{create_or_tt()}, params, &critical_stats); - CHECK(criticalstats.critical_temperature < 350); + CHECK(critical_stats.critical_temperature < 350); } SECTION("Not working diagonal Wire") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); @@ -374,22 +409,24 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}}, - critical_temperature_params::simulation_engine::EXACT, 0.99, 350}; - critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &criticalstats); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::EXACT; + params.confidence_level = 0.99; + params.max_temperature = 350; + params.iteration_steps = 80; + params.alpha = 0.7; + + critical_temperature_gate_based(lyt, std::vector{create_id_tt()}, params, &critical_stats); - CHECK(criticalstats.algorithm_name == "QuickExact"); + CHECK(critical_stats.algorithm_name == "QuickExact"); - CHECK_THAT(std::abs(criticalstats.energy_between_ground_state_and_first_erroneous), + CHECK_THAT(std::abs(critical_stats.energy_between_ground_state_and_first_erroneous), Catch::Matchers::WithinAbs(305.95, 0.01)); - CHECK_THAT(std::abs(criticalstats.critical_temperature), Catch::Matchers::WithinAbs(0.00, 0.01)); + CHECK_THAT(std::abs(critical_stats.critical_temperature), Catch::Matchers::WithinAbs(0.00, 0.01)); } SECTION("nine SiDBs, QuickSim, non-gate-based") { - TestType lyt{}; - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({3, 0, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({6, 0, 0}, sidb_technology::cell_type::NORMAL); @@ -401,14 +438,17 @@ TEMPLATE_TEST_CASE( lyt.assign_cell_type({9, 1, 1}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({12, 1, 1}, sidb_technology::cell_type::NORMAL); - critical_temperature_stats criticalstats{}; - const critical_temperature_params params{quicksim_params{sidb_simulation_parameters{2, -0.32}, 500, 0.6}, - critical_temperature_params::simulation_engine::APPROXIMATE, 0.99, - 750}; - critical_temperature_non_gate_based(lyt, params, &criticalstats); + params.physical_parameters = physical_params; + params.engine = critical_temperature_params::simulation_engine::APPROXIMATE; + params.confidence_level = 0.99; + params.max_temperature = 750; + params.iteration_steps = 500; + params.alpha = 0.6; + + critical_temperature_non_gate_based(lyt, params, &critical_stats); - CHECK(criticalstats.algorithm_name == "QuickSim"); + CHECK(critical_stats.algorithm_name == "QuickSim"); - CHECK_THAT(std::abs(criticalstats.critical_temperature), Catch::Matchers::WithinAbs(11.55, 0.01)); + CHECK_THAT(std::abs(critical_stats.critical_temperature), Catch::Matchers::WithinAbs(11.55, 0.01)); } } From 12c80b02cebc06dc475277ad2951a5ac737bbd7a Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 14:40:27 +0100 Subject: [PATCH 48/54] :art: Added physical parameters used for the simulation to the `critical_temperature_stats` --- .../algorithms/simulation/sidb/critical_temperature.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp index ecd5f5f64..6aa93652c 100644 --- a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp +++ b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp @@ -98,6 +98,10 @@ struct critical_temperature_params template struct critical_temperature_stats { + /** + * All parameters for physical SiDB simulations. + */ + sidb_simulation_parameters physical_parameters{}; /** * Name of the algorithm used to compute the physically valid charge distributions. */ @@ -153,9 +157,10 @@ class critical_temperature_impl bii(bdl_input_iterator{layout, params.bdl_params}) { - stats.critical_temperature = params.max_temperature; + stats.physical_parameters = params.physical_parameters; stats.algorithm_name = (params.engine == critical_temperature_params::simulation_engine::EXACT) ? "QuickExact" : "QuickSim"; + stats.critical_temperature = params.max_temperature; } /** From 51943c4b20076973b8322972623eca84b39a2b3f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 15:21:29 +0100 Subject: [PATCH 49/54] :bug: Fix logging for `quickexact` and `quicksim` CLI commands --- cli/cmd/simulation/quickexact.hpp | 41 +++++++++++++++++++++---------- cli/cmd/simulation/quicksim.hpp | 39 ++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 25 deletions(-) diff --git a/cli/cmd/simulation/quickexact.hpp b/cli/cmd/simulation/quickexact.hpp index 92fb54de5..9114f9cdd 100644 --- a/cli/cmd/simulation/quickexact.hpp +++ b/cli/cmd/simulation/quickexact.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ class quickexact_command : public command { // reset sim result sim_result = {}; + min_energy = std::numeric_limits::infinity(); if (physical_params.epsilon_r <= 0) { @@ -112,6 +114,8 @@ class quickexact_command : public command const auto min_energy_distr = fiction::minimum_energy_distribution( sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()); + min_energy = min_energy_distr->get_system_energy(); + store().extend() = std::make_shared(*min_energy_distr); } @@ -141,6 +145,10 @@ class quickexact_command : public command * Simulation result. */ fiction::sidb_simulation_result sim_result{}; + /** + * Minimum energy. + */ + double min_energy{std::numeric_limits::infinity()}; /** * Logs the resulting information in a log file. @@ -149,19 +157,26 @@ class quickexact_command : public command */ [[nodiscard]] nlohmann::json log() const override { - return nlohmann::json{ - {"Algorithm name", sim_result.algorithm_name}, - {"Simulation runtime", sim_result.simulation_runtime.count()}, - {"Physical parameters", - {"base", std::any_cast(sim_result.additional_simulation_parameters.at( - "base_number"))}, // fetch the automatically inferred base - {"epsilon_r", sim_result.physical_parameters.epsilon_r}, - {"lambda_tf", sim_result.physical_parameters.lambda_tf}, - {"mu_minus", sim_result.physical_parameters.mu_minus}, - {"global_potential", - std::any_cast(sim_result.additional_simulation_parameters.at("global_potential"))}}, - {"Ground state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, - {"Number of stable states", sim_result.charge_distributions.size()}}; + try + { + return nlohmann::json{ + {"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {{"base", std::any_cast(sim_result.additional_simulation_parameters.at( + "base_number"))}, // fetch the automatically inferred base number + {"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}, + {"global_potential", + std::any_cast(sim_result.additional_simulation_parameters.at("global_potential"))}}}, + {"Ground state energy (eV)", min_energy}, + {"Number of stable states", sim_result.charge_distributions.size()}}; + } + catch (...) + { + return nlohmann::json{}; + } } /** * Resets the parameters to their default values. diff --git a/cli/cmd/simulation/quicksim.hpp b/cli/cmd/simulation/quicksim.hpp index 4abee4903..93acb708b 100644 --- a/cli/cmd/simulation/quicksim.hpp +++ b/cli/cmd/simulation/quicksim.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -59,6 +60,7 @@ class quicksim_command : public command { // reset sim result sim_result = {}; + min_energy = std::numeric_limits::infinity(); if (physical_params.epsilon_r <= 0) { @@ -121,6 +123,8 @@ class quicksim_command : public command const auto min_energy_distr = fiction::minimum_energy_distribution( sim_result.charge_distributions.cbegin(), sim_result.charge_distributions.cend()); + min_energy = min_energy_distr->get_system_energy(); + store().extend() = std::make_shared(*min_energy_distr); } @@ -150,6 +154,10 @@ class quicksim_command : public command * Simulation result. */ fiction::sidb_simulation_result sim_result{}; + /** + * Minimum energy. + */ + double min_energy{std::numeric_limits::infinity()}; /** * Logs the resulting information in a log file. @@ -158,18 +166,25 @@ class quicksim_command : public command */ [[nodiscard]] nlohmann::json log() const override { - return nlohmann::json{ - {"Algorithm name", sim_result.algorithm_name}, - {"Simulation runtime", sim_result.simulation_runtime.count()}, - {"Physical parameters", - {"epsilon_r", sim_result.physical_parameters.epsilon_r}, - {"lambda_tf", sim_result.physical_parameters.lambda_tf}, - {"mu_minus", sim_result.physical_parameters.mu_minus}}, - {"Lowest state energy (eV)", sim_result.charge_distributions.front().get_system_energy()}, - {"Number of stable states", sim_result.charge_distributions.size()}, - {"Iteration steps", - std::any_cast(sim_result.additional_simulation_parameters.at("iteration_steps"))}, - {"alpha", std::any_cast(sim_result.additional_simulation_parameters.at("alpha"))}}; + try + { + return nlohmann::json{ + {"Algorithm name", sim_result.algorithm_name}, + {"Simulation runtime", sim_result.simulation_runtime.count()}, + {"Physical parameters", + {{"epsilon_r", sim_result.physical_parameters.epsilon_r}, + {"lambda_tf", sim_result.physical_parameters.lambda_tf}, + {"mu_minus", sim_result.physical_parameters.mu_minus}}}, + {"Lowest state energy (eV)", min_energy}, + {"Number of stable states", sim_result.charge_distributions.size()}, + {"Iteration steps", + std::any_cast(sim_result.additional_simulation_parameters.at("iteration_steps"))}, + {"alpha", std::any_cast(sim_result.additional_simulation_parameters.at("alpha"))}}; + } + catch (...) + { + return nlohmann::json{}; + } } /** * Resets the parameters to their default values. From 6bf65d3dd9ee91208b1df3d334fbeb9f59f7a0c9 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 15:22:02 +0100 Subject: [PATCH 50/54] :bug: Fix `opdom` error when no PI/PO cells are available --- cli/cmd/simulation/opdom.hpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/cli/cmd/simulation/opdom.hpp b/cli/cmd/simulation/opdom.hpp index 12ad6f972..d1e2b495a 100644 --- a/cli/cmd/simulation/opdom.hpp +++ b/cli/cmd/simulation/opdom.hpp @@ -209,31 +209,39 @@ class opdom_command : public command const auto tt_ptr = ts.current(); using Lyt = typename std::decay_t::element_type; - using TT = typename std::decay_t::element_type; if constexpr (fiction::has_sidb_technology_v) { + if (lyt_ptr->num_pis() == 0 || lyt_ptr->num_pos() == 0) + { + env->out() << fmt::format("[e] {} requires primary input and output cells to simulate its " + "Boolean function", + get_name(lyt_ptr)) + << std::endl; + return; + } + params.sim_params = physical_params; if (is_set("random_sampling")) { - op_domain = fiction::operational_domain_random_sampling( - *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + op_domain = fiction::operational_domain_random_sampling(*lyt_ptr, std::vector{*tt_ptr}, + num_random_samples, params, &stats); } else if (is_set("flood_fill")) { - op_domain = fiction::operational_domain_flood_fill(*lyt_ptr, std::vector{*tt_ptr}, - num_random_samples, params, &stats); + op_domain = fiction::operational_domain_flood_fill(*lyt_ptr, std::vector{*tt_ptr}, + num_random_samples, params, &stats); } else if (is_set("contour_tracing")) { - op_domain = fiction::operational_domain_contour_tracing( - *lyt_ptr, std::vector{*tt_ptr}, num_random_samples, params, &stats); + op_domain = fiction::operational_domain_contour_tracing(*lyt_ptr, std::vector{*tt_ptr}, + num_random_samples, params, &stats); } else { - op_domain = fiction::operational_domain_grid_search(*lyt_ptr, std::vector{*tt_ptr}, - params, &stats); + op_domain = fiction::operational_domain_grid_search(*lyt_ptr, std::vector{*tt_ptr}, + params, &stats); } } else From 50fc8636f55594f1a4c176bd4e5fd68951332429 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 15:22:45 +0100 Subject: [PATCH 51/54] :sparkles: Added command `temp` for critical temperature SiDB simulation to the CLI --- cli/cmd/simulation/temp.hpp | 234 ++++++++++++++++++++++++++++++++++++ cli/commands.hpp | 1 + docs/cli.rst | 18 +++ 3 files changed, 253 insertions(+) create mode 100644 cli/cmd/simulation/temp.hpp diff --git a/cli/cmd/simulation/temp.hpp b/cli/cmd/simulation/temp.hpp new file mode 100644 index 000000000..394154186 --- /dev/null +++ b/cli/cmd/simulation/temp.hpp @@ -0,0 +1,234 @@ +// +// Created by marcel on 06.12.23. +// + +#ifndef FICTION_CMD_TEMP_HPP +#define FICTION_CMD_TEMP_HPP + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +namespace alice +{ +/** + * + */ +class temp_command : public command +{ + public: + /** + * Standard constructor. Adds descriptive information, options, and flags. + * + * @param e alice::environment that specifies stores etc. + */ + explicit temp_command(const environment::ptr& e) : + command(e, "Temperature-aware simulation of SiDB layouts. Uses QuickExact to determine the critical " + "temperature at which the ground state of the current SiDB layout is populated with a " + "probability below a given confidence level. For gate-based simulation, the probability of " + "erroneous calculations of the gate are applied.") + { + add_option( + "--confidence_level,-c", params.confidence_level, + "Probability threshold for ground state population. The temperature at which the simulation finds the " + "ground state to be populated with a probability of less than the given percentage, is determined to be " + "the critical temperature. For gate-based simulation, this is the probability of erroneous calculations of " + "the gate.", + true); + add_option("--max_temperature,-t", params.max_temperature, + "Maximum simulation temperature beyond which no simulation will be conducted (~ 126 °C by default) " + "(unit: K)", + true); + add_flag("--gate_based,-g", + "Gate-based simulation that matches the current SiDB layout in store against the current truth table " + "in store and considers the probability of erroneous calculations of the gate."); + + add_option("--epsilon_r,-e", physical_params.epsilon_r, "Electric permittivity of the substrate (unit-less)", + true); + add_option("--lambda_tf,-l", physical_params.lambda_tf, "Thomas-Fermi screening distance (unit: nm)", true); + add_option("--mu_minus,-m", physical_params.mu_minus, "Energy transition level (0/-) (unit: eV)", true); + } + + protected: + /** + * Function to perform the simulation call. + */ + void execute() override + { + // reset statistics + stats = {}; + + if (params.confidence_level <= 0 || params.confidence_level > 1) + { + env->out() << "[e] confidence_level must be in (0, 1]" << std::endl; + reset_params(); + return; + } + if (physical_params.epsilon_r <= 0) + { + env->out() << "[e] epsilon_r must be positive" << std::endl; + reset_params(); + return; + } + if (physical_params.lambda_tf <= 0) + { + env->out() << "[e] lambda_tf must be positive" << std::endl; + reset_params(); + return; + } + + auto& cs = store(); + + // error case: empty cell layout store + if (cs.empty()) + { + env->out() << "[w] no cell layout in store" << std::endl; + reset_params(); + return; + } + + auto& ts = store(); + + // error case: empty truth table store + if (is_set("gate_based")) + { + if (ts.empty()) + { + env->out() << "[w] no truth table in store" << std::endl; + reset_params(); + return; + } + } + + const auto get_name = [](auto&& lyt_ptr) -> std::string { return fiction::get_name(*lyt_ptr); }; + + const auto temp = [this, &ts, &get_name](auto&& lyt_ptr) + { + using Lyt = typename std::decay_t::element_type; + + if constexpr (fiction::has_sidb_technology_v) + { + if constexpr (fiction::is_charge_distribution_surface_v) + { + env->out() << fmt::format( + "[w] {} already possesses a charge distribution; no simulation is conducted", + get_name(lyt_ptr)) + << std::endl; + } + else + { + params.physical_parameters = physical_params; + + if (is_set("gate_based")) + { + if (lyt_ptr->num_pis() == 0 || lyt_ptr->num_pos() == 0) + { + env->out() << fmt::format("[e] {} requires primary input and output cells to simulate its " + "Boolean function", + get_name(lyt_ptr)) + << std::endl; + return; + } + + const auto tt_ptr = ts.current(); + + fiction::critical_temperature_gate_based(*lyt_ptr, std::vector{*tt_ptr}, params, + &stats); + } + else + { + fiction::critical_temperature_non_gate_based(*lyt_ptr, params, &stats); + } + + if (stats.num_valid_lyt == 0) + { + env->out() << fmt::format("[e] ground state of {} could not be determined", get_name(lyt_ptr)) + << std::endl; + } + else + { + env->out() << fmt::format("[i] critical temperature of {} is {}{} K", get_name(lyt_ptr), + (stats.critical_temperature == params.max_temperature ? "> " : ""), + stats.critical_temperature) + << std::endl; + + if (stats.num_valid_lyt > 1) + { + env->out() << fmt::format( + "[i] energy between the ground state and the first erroneous is {} eV", + fiction::round_to_n_decimal_places( + stats.energy_between_ground_state_and_first_erroneous, 2)) + << std::endl; + } + } + } + } + else + { + env->out() << fmt::format("[e] {} is not an SiDB layout", get_name(lyt_ptr)) << std::endl; + } + }; + + std::visit(temp, cs.current()); + + reset_params(); + } + + private: + /** + * Physical parameters for the simulation. + */ + fiction::sidb_simulation_parameters physical_params{2, -0.32, 5.6, 5.0}; + /** + * Critical temperature parameters. + */ + fiction::critical_temperature_params params{}; + /** + * Critical temperature statistics. + */ + fiction::critical_temperature_stats stats{}; + + /** + * Logs the resulting information in a log file. + * + * @return JSON object containing details about the simulation. + */ + [[nodiscard]] nlohmann::json log() const override + { + return nlohmann::json{{"Algorithm name", stats.algorithm_name}, + {"Physical parameters", + {{"base", stats.physical_parameters.base}, + {"epsilon_r", stats.physical_parameters.epsilon_r}, + {"lambda_tf", stats.physical_parameters.lambda_tf}, + {"mu_minus", stats.physical_parameters.mu_minus}}}, + {"Critical temperature", stats.critical_temperature}, + {"Number of stable states", stats.num_valid_lyt}, + {"Energy difference between ground state and first erroneous state", + stats.energy_between_ground_state_and_first_erroneous}}; + } + /** + * Resets the parameters to their default values. + */ + void reset_params() + { + physical_params = fiction::sidb_simulation_parameters{2, -0.32, 5.6, 5.0}; + params = {}; + } +}; + +ALICE_ADD_COMMAND(temp, "Simulation") + +} // namespace alice + +#endif // FICTION_CMD_TEMP_HPP diff --git a/cli/commands.hpp b/cli/commands.hpp index 8fc4e57f1..8e37a7b96 100644 --- a/cli/commands.hpp +++ b/cli/commands.hpp @@ -53,6 +53,7 @@ #include "cmd/simulation/opdom.hpp" #include "cmd/simulation/quickexact.hpp" #include "cmd/simulation/quicksim.hpp" +#include "cmd/simulation/temp.hpp" #endif #endif // FICTION_COMMANDS_HPP diff --git a/docs/cli.rst b/docs/cli.rst index 9605ea4aa..44693edab 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -311,6 +311,24 @@ Most important parameters: The simulated ground state charge distribution can be printed with ``print -c``. +Critical Temperature (``temp``) +############################### + +The critical temperature of an SiDB layout is the temperature at which the layout's ground state is populated with a +probability larger than a certain threshold. This threshold is specified as a confidence level :math:`1 - \eta`, where +:math:`\eta \in [0,1]`. The simulation can be conducted for gate-based SiDB layouts as well, where the gate is +simulated with respect to the stability of a given Boolean function in form of the current truth table in store. +For more in-depth information, refer to `the paper `_. + +Most important parameters: + +- Confidence level :math:`1 - \eta` (``-c``) +- Maximum temperature in K to explore (``-t``) +- Gate-based simulation toggle (``-g``) +- Relative permittivity :math:`\epsilon_r` (``-e``) +- Thomas-Fermi screening :math:`\lambda_{tf}` (``-l``) +- Energy transition level (0/-) :math:`\mu_-` (``-m``) + Operational Domain (``opdom``) ############################## From 3a70265e9847c03ad68e597cf024e5df77c62b69 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Dec 2023 15:23:14 +0100 Subject: [PATCH 52/54] :art: Added missing header and `std::forward` --- include/fiction/layouts/cell_level_layout.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/fiction/layouts/cell_level_layout.hpp b/include/fiction/layouts/cell_level_layout.hpp index aea701153..0fb1b99a5 100644 --- a/include/fiction/layouts/cell_level_layout.hpp +++ b/include/fiction/layouts/cell_level_layout.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -418,7 +419,7 @@ class cell_level_layout : public ClockedLayout using iterator_type = decltype(strg->cell_type_map.cbegin()); mockturtle::detail::foreach_element_transform( strg->cell_type_map.cbegin(), strg->cell_type_map.cend(), - [](const auto& ct) { return static_cast(ct.first); }, fn); + [](const auto& ct) { return static_cast(ct.first); }, std::forward(fn)); } /** * Applies a function to all cell positions in the layout, even empty ones. This function, thereby, renames @@ -445,7 +446,8 @@ class cell_level_layout : public ClockedLayout { using iterator_type = decltype(strg->inputs.cbegin()); mockturtle::detail::foreach_element_transform( - strg->inputs.cbegin(), strg->inputs.cend(), [](const auto& i) { return static_cast(i); }, fn); + strg->inputs.cbegin(), strg->inputs.cend(), [](const auto& i) { return static_cast(i); }, + std::forward(fn)); } /** * Applies a function to all primary output cells in the layout. @@ -459,7 +461,8 @@ class cell_level_layout : public ClockedLayout { using iterator_type = decltype(strg->outputs.cbegin()); mockturtle::detail::foreach_element_transform( - strg->outputs.cbegin(), strg->outputs.end(), [](const auto& o) { return static_cast(o); }, fn); + strg->outputs.cbegin(), strg->outputs.end(), [](const auto& o) { return static_cast(o); }, + std::forward(fn)); } #pragma endregion From bb40f45d55d60571f2287a9d860be9b54b538de6 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 14 Dec 2023 17:49:07 +0100 Subject: [PATCH 53/54] :bug: fix unit bug. --- .../algorithms/simulation/sidb/critical_temperature.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp index 6aa93652c..ef2b4c65b 100644 --- a/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp +++ b/include/fiction/algorithms/simulation/sidb/critical_temperature.hpp @@ -115,7 +115,7 @@ struct critical_temperature_stats */ uint64_t num_valid_lyt{}; /** - * Energy difference between the ground state and the first (erroneous) excited state (unit: eV). + * Energy difference between the ground state and the first (erroneous) excited state (unit: meV). */ double energy_between_ground_state_and_first_erroneous = std::numeric_limits::infinity(); /** @@ -130,7 +130,7 @@ struct critical_temperature_stats if (num_valid_lyt != 0) { out << fmt::format("'# of physically valid charge configurations': {} | Energy between ground state and " - "first erroneous: {}\n", + "first erroneous in meV: {}\n", num_valid_lyt, energy_between_ground_state_and_first_erroneous); } else From 870d0eaa0ce2256485bc89f6a4e58d3109c7fa4d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 14 Dec 2023 21:22:03 +0100 Subject: [PATCH 54/54] :art: set description to meV. --- cli/cmd/simulation/temp.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/cmd/simulation/temp.hpp b/cli/cmd/simulation/temp.hpp index 394154186..f19c6294a 100644 --- a/cli/cmd/simulation/temp.hpp +++ b/cli/cmd/simulation/temp.hpp @@ -166,7 +166,7 @@ class temp_command : public command if (stats.num_valid_lyt > 1) { env->out() << fmt::format( - "[i] energy between the ground state and the first erroneous is {} eV", + "[i] energy between the ground state and the first erroneous is {} meV", fiction::round_to_n_decimal_places( stats.energy_between_ground_state_and_first_erroneous, 2)) << std::endl;