Skip to content

Commit

Permalink
🎨 implement Marcel's suggestions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Drewniok committed Jul 18, 2023
1 parent a18d52c commit 7354ef0
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 151 deletions.
5 changes: 3 additions & 2 deletions docs/algorithms/sidb_simulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ Random Layout Generator

**Header:** ``fiction/algorithms/simulation/sidb/random_layout_generator.hpp``

.. doxygenstruct:: fiction::random_layout_params
.. doxygenenum:: fiction::positive_charges
.. doxygenstruct:: fiction::generate_random_layout_params
.. doxygenfunction:: fiction::generate_random_layout
.. doxygenfunction:: fiction::generate_multiple_random_layout
.. doxygenfunction:: fiction::generate_multiple_random_layouts
6 changes: 3 additions & 3 deletions docs/io/physical_simulation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ SiQAD
.. doxygenfunction:: fiction::write_sqd_sim_result(const sidb_simulation_result<Lyt>& sim_result, std::ostream& os)
.. doxygenfunction:: fiction::write_sqd_sim_result(const sidb_simulation_result<Lyt>& sim_result, const std::string_view& filename)

**Header:** ``fiction/io/write_txt_sim_result.hpp``
**Header:** ``fiction/io/write_loc_sim_result.hpp``

.. doxygenfunction:: fiction::write_txt_sim_result(const sidb_simulation_result<Lyt>& sim_result, std::ostream& os)
.. doxygenfunction:: fiction::write_txt_sim_result(const sidb_simulation_result<Lyt>& sim_result, const std::string_view& filename)
.. doxygenfunction:: fiction::write_loc_sim_result(const sidb_simulation_result<Lyt>& sim_result, std::ostream& os)
.. doxygenfunction:: fiction::write_loc_sim_result(const sidb_simulation_result<Lyt>& sim_result, const std::string_view& filename)

**Header:** ``fiction/io/read_sqd_layout.hpp``

Expand Down
102 changes: 79 additions & 23 deletions experiments/random_layout_generation/random_layout_generation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,86 @@
#include <fiction/io/read_sqd_layout.hpp>
#include <fiction/types.hpp>

#include <fmt/format.h>

#include <filesystem>
#include <iomanip>
#include <iostream>
#include <string>

using namespace fiction;

int main() // NOLINT
int main(int argc, const char* argv[]) // NOLINT
{
std::unordered_map<std::string, std::variant<std::string>> options{{"--folder_name", "layout_random_cli/"},
{"--NW_x", "0"},
{"--NW_y", "0"},
{"--SE_x", "20"},
{"--SE_y", "20"},
{"--positive_charges", "FORBIDDEN"},
{"--lower", "5"},
{"--upper", "10"},
{"--num_layouts", "10"},
{"--step", "1"}};

// Parse command-line arguments
for (auto i = 1u; i < argc; ++i)
{
const std::string arg = argv[i];
if (options.count(arg) > 0)
{
if (i + 1 < argc)
{
options[arg] = argv[i + 1];
++i; // Skip the next argument
}
else
{
std::cerr << "Error: Argument " << arg << " is missing a value." << std::endl;
return 1;
}
}
}

// Extract values from options map
const std::string folder_name = std::get<std::string>(options["--folder_name"]);
// x-coordinate of north-west cell.
const int32_t nw_x = std::stoi(std::get<std::string>(options["--NW_x"]));
// y-coordinate of north-west cell.
const int32_t nw_y = std::stoi(std::get<std::string>(options["--NW_y"]));
// x-coordinate of south-east cell.
const int32_t se_x = std::stoi(std::get<std::string>(options["--SE_x"]));
// y-coordinate of south-east cell.
const int32_t se_y = std::stoi(std::get<std::string>(options["--SE_y"]));
const std::string charges_str = std::get<std::string>(options["--positive_charges"]);
// It labels if positively charged SiDBs are allowed.
const positive_charges charges =
(charges_str == "ALLOWED") ? positive_charges::ALLOWED : positive_charges::FORBIDDEN;
// Number of SiDBs of the first bunch of layouts.
const uint64_t lower_limit = std::stoull(std::get<std::string>(options["--lower"]));
// Number of SiDBs of the last bunch of layouts.
const uint64_t upper_limit = std::stoull(std::get<std::string>(options["--upper"]));
// Number of layouts for each number of placed SiDBs (e.g., num_layouts = 10 means that 10 different layouts for a
// given number of SiDBs is generated).
const uint64_t number_of_layouts = std::stoull(std::get<std::string>(options["--num_layouts"]));
// Step size for moving from lower limit to upper limit.
const uint64_t step = std::stoull(std::get<std::string>(options["--step"]));

// Print the parsed values
std::cout << "Folder name: " << folder_name << std::endl;
std::cout << fmt::format("NW: {} | {}", nw_x, nw_y) << std::endl;
std::cout << fmt::format("SE: {} | {}", se_x, se_y) << std::endl;
std::cout << fmt::format("positive_charges: {}", charges_str) << std::endl;
std::cout << "lower_limit: " << lower_limit << std::endl;
std::cout << "upper_limit: " << upper_limit << std::endl;
std::cout << "number_of_layouts: " << number_of_layouts << std::endl;
std::cout << "step: " << step << std::endl;

// This script generates random layouts as .sqd file.
using cell_level_layout = cell_level_layout<sidb_technology, clocked_layout<cartesian_layout<cube::coord_t>>>;

try
{
// This script generates random layouts as .sqd file.
using cell_level_layout = cell_level_layout<sidb_technology, clocked_layout<cartesian_layout<cube::coord_t>>>;
constexpr const char* folder_name = "random_layouts_test_new/";
std::filesystem::path folder_path(EXPERIMENTS_PATH);

folder_path /= folder_name;
Expand All @@ -39,25 +105,14 @@ int main() // NOLINT
std::cout << "Failed to create folder" << std::endl;
}
}
// number of randomly generated layouts for a given number of placed SiDBs.
const uint64_t number_of_layouts = 10;
// number of SiDBs of the first bunch of randomly generated layouts.
uint64_t number_of_sidbs_lower_limit = 20;
// number of SiDBs of the final bunch of randomly generated layouts.
uint64_t number_of_sidbs_upper_limit = 21;

if (number_of_sidbs_upper_limit < number_of_sidbs_lower_limit)
for (uint64_t place_sidbs = lower_limit; place_sidbs <= upper_limit; place_sidbs += step)
{
std::swap(number_of_sidbs_upper_limit, number_of_sidbs_lower_limit);
}

for (uint64_t num_sidbs = number_of_sidbs_lower_limit; num_sidbs < number_of_sidbs_upper_limit; num_sidbs++)
{
const std::filesystem::path dir_path = folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs);
const std::filesystem::path dir_path = folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs);
const std::filesystem::path dir_path_sqd =
folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs) + "/sqd";
folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs) + "/sqd";
const std::filesystem::path dir_path_loc =
folder_path.string() + "number_sidbs_" + std::to_string(num_sidbs) + "/loc";
folder_path.string() + "number_sidbs_" + std::to_string(place_sidbs) + "/loc";
try
{
if (!std::filesystem::exists(dir_path))
Expand All @@ -72,13 +127,14 @@ int main() // NOLINT
std::cout << "Folder already exists." << std::endl;
}

const random_layout_params<cell_level_layout> params{{{0, 0}, {20, 20}}, num_sidbs, false};

const generate_random_layout_params<cell_level_layout> params{
{{nw_x, nw_y}, {se_x, se_y}}, place_sidbs, charges, 2,
static_cast<uint64_t>(10E6), number_of_layouts};
const auto unique_lyts =
generate_multiple_random_layout<cell_level_layout>(params, cell_level_layout{}, number_of_layouts);
generate_multiple_random_layouts<cell_level_layout>(cell_level_layout{}, params);
for (auto i = 0u; i < unique_lyts.size(); i++)
{
write_sqd_layout(unique_lyts[i], dir_path_sqd.string() + "/layout_" + std::to_string(i) + ".sqd");
write_sqd_layout(unique_lyts[i], fmt::format("{}/layout_{}.sqd", dir_path_sqd.string(), i));
}
}
catch (const std::filesystem::filesystem_error& ex)
Expand Down
51 changes: 41 additions & 10 deletions experiments/random_layout_generation/simulation_result_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "fiction/algorithms/simulation/sidb/exhaustive_ground_state_simulation.hpp"
#include "fiction/io/read_sqd_layout.hpp"
#include "fiction/io/write_txt_sim_result.hpp"
#include "fiction/io/write_loc_sim_result.hpp"
#include "fiction/technology/charge_distribution_surface.hpp"
#include "fiction/types.hpp"

Expand All @@ -17,14 +17,45 @@

using namespace fiction;

int main() // NOLINT
int main(int argc, const char* argv[]) // NOLINT
{
// This script uses the randomly generated layouts (hence, random_layout_generation.cpp should be executed first),
// simulates them, and collects the simulation results as a text file. The text file has three columns: x,y, charge
// state (as integer) of the ground state.

std::unordered_map<std::string, std::variant<std::string>> options{{"--folder_name", "layout_random_cli/"},
{"--mu_minus", "-0.32"}};

// Parse command-line arguments
for (auto i = 1u; i < argc; ++i)
{
const std::string arg = argv[i];
if (options.count(arg) > 0)
{
if (i + 1 < argc)
{
options[arg] = argv[i + 1];
++i; // Skip the next argument
}
else
{
std::cerr << "Error: Argument " << arg << " is missing a value." << std::endl;
return 1;
}
}
}

// Folder name where the randomly generated layouts are located.
const std::string folder_name = std::get<std::string>(options["--folder_name"]);
// µ-value used for the simulation.
const double mu = std::stod(std::get<std::string>(options["--mu_minus"]));

// Print the parsed values
std::cout << "Folder name: " << folder_name << std::endl;
std::cout << fmt::format("µ_minus: {}", mu) << std::endl;

try
{
constexpr const char* folder_name = "random_layouts_test_new/";
std::filesystem::path folder_path(EXPERIMENTS_PATH);
folder_path /= folder_name;

Expand All @@ -50,31 +81,31 @@ int main() // NOLINT

auto lyt = read_sqd_layout<sidb_cell_clk_lyt_siqad>(benchmark.string());

const sidb_simulation_parameters params{2, -0.32};
const sidb_simulation_parameters params{2, units::energy::electron_volt_t{mu}};
const auto simulation_results =
exhaustive_ground_state_simulation<sidb_cell_clk_lyt_siqad>(lyt, params);
std::stringstream ss;
ss << std::fixed << std::setprecision(3) << -params.mu;
std::string const file_path =
folder.path().string() + "/loc/" + name + "_sim_µ_minus_" + ss.str() + ".txt";
const std::string file_path = fmt::format("{}/loc/{}_sim_µ_minus_{:.3f}.txt",
folder.path().string(), name, -params.mu.value());

// Some layouts where positively charged SiDBs may occur cannot be simulated (i.e., no
// physically valid charge distribution is found) because the physical model currently works
// reliably for layouts with neutrally and negatively charged SiDBs.
if (!simulation_results.charge_distributions.empty())
{
write_txt_sim_result(simulation_results, file_path);
write_loc_sim_result(simulation_results, file_path);
}
}
}
else
{
std::cout << "Folder" + std::string("/sqd") + "does not exist." << std::endl;
std::cout << "Folder */sqd* does not exist." << std::endl;
}
}
}
else
{
std::cout << "Folder" + std::string(folder_name) + "does not exist." << std::endl;
std::cout << fmt::format("Folder {} does not exist", folder_name) << std::endl;
}
}
catch (const std::filesystem::filesystem_error& ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,33 @@
#include <random>
#include <string_view>
#include <unordered_set>
#include <utility>
#include <vector>

namespace fiction
{

/**
* An enumeration of modes to use for the generation of random layout to control control the appearance of positive
* charges.
*/
enum class positive_charges
{
/**
* Positive charges can occur (i.e. SiDBs can be placed right next to each other).
*/
ALLOWED,
/**
* Positive charges are not allowed to occur (i.e. SiDBs need to be seperated by a few lattice points).
*/
FORBIDDEN
};

/**
* This struct stores the parameters for the *generate_random_layout* algorithm.
*/
template <typename Lyt>
struct random_layout_params
struct generate_random_layout_params
{
/**
* Two coordinates that span the region where SiDBs may be placed (order is not important).
Expand All @@ -42,16 +60,24 @@ struct random_layout_params
/**
* If positively charged SiDBs should be prevented, SiDBs are not placed closer than the minimal_spacing.
*/
bool prevent_positive_charges = true;
positive_charges positive_sidbs = positive_charges::ALLOWED;
/**
* If positively charged SiDBs should be prevented, SiDBs are not placed closer than this value (2 cells as
* Euclidean distance by default).
* If positively charged SiDBs should be prevented, SiDBs are not placed closer than this value (Euclidean distance
* of two cells).
*/
double minimal_spacing = 2;
/**
* Maximal number of steps to place the given number of SiDBs.
*/
uint64_t maximal_attempts = 10E6;
/**
* The desired number of unique layouts to be generated.
*/
uint64_t number_of_unique_generated_layouts = 1;
/**
* The maximum number of attempts allowed to generate the given number of unique layouts (default: \f$ 10^{6} \f$).
*/
uint64_t maximal_attempts_for_multiple_layouts = 10E6;
};

/**
Expand All @@ -61,10 +87,10 @@ struct random_layout_params
* @param params The parameters for generating the random layout.
* @param lyt_skeleton A layout to which random cells are added (useful if you need to add random cells to a given
* layout).
* @return A randomly generated layout of SiDBs.
* @return A randomly-generated layout of SiDBs.
*/
template <typename Lyt>
Lyt generate_random_layout(const random_layout_params<Lyt>& params, const Lyt& lyt_skeleton)
Lyt generate_random_layout(const Lyt& lyt_skeleton, const generate_random_layout_params<Lyt>& params)
{
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");

Expand All @@ -78,8 +104,7 @@ Lyt generate_random_layout(const random_layout_params<Lyt>& params, const Lyt& l
{ lyt.assign_cell_type(cell, lyt_skeleton.get_cell_type(cell)); });
}

bool successful_generation = false;
uint64_t attempt_counter = 0;
uint64_t attempt_counter = 0;

// Stops if either all SiDBs are placed or the maximum number of attempts were performed.
while (lyt.num_cells() < number_of_sidbs_of_final_layout && attempt_counter < params.maximal_attempts)
Expand All @@ -88,7 +113,7 @@ Lyt generate_random_layout(const random_layout_params<Lyt>& params, const Lyt& l

bool constraint_violation_positive_sidbs = false;

if (params.prevent_positive_charges)
if (params.positive_sidbs == positive_charges::FORBIDDEN)
{
// Checks if the new coordinate is not closer than 2 cells (Euclidean distance) from an already
// placed SiDB.
Expand Down Expand Up @@ -116,26 +141,24 @@ Lyt generate_random_layout(const random_layout_params<Lyt>& params, const Lyt& l
* Generates multiple unique random layouts of SiDBs based on the provided parameters.
*
* @tparam Lyt The layout type.
* @param params The parameters for generating the random layouts.
* @param lyt_skeleton A layout to which random cells are added (useful if you need to add random cells to a given
* layout).
* @param number_of_unique_generated_layouts The desired number of unique layouts to be generated.
* @param maximal_attempts The maximum number of attempts allowed to generate a unique layout (default: \f$ 10^{6} \f$).
* @param params The parameters for generating the random layouts.
* @return A vector containing the unique randomly generated layouts.
*/
template <typename Lyt>
std::vector<Lyt> generate_multiple_random_layout(const random_layout_params<Lyt>& params, const Lyt& lyt_skeleton,
const uint64_t number_of_unique_generated_layouts,
const uint64_t maximal_attemps = 10E6)
std::vector<Lyt> generate_multiple_random_layouts(const Lyt& lyt_skeleton,
const generate_random_layout_params<Lyt>& params)
{
static_assert(is_cell_level_layout_v<Lyt>, "Lyt is not a cell-level layout");

std::vector<Lyt> unique_lyts{};
unique_lyts.reserve(number_of_unique_generated_layouts);
unique_lyts.reserve(params.number_of_unique_generated_layouts);
uint64_t counter = 0;
while (unique_lyts.size() < number_of_unique_generated_layouts && counter < maximal_attemps)
while (unique_lyts.size() < params.number_of_unique_generated_layouts &&
counter < params.maximal_attempts_for_multiple_layouts)
{
const auto random_lyt = generate_random_layout(params, lyt_skeleton);
const auto random_lyt = generate_random_layout(lyt_skeleton, params);

uint64_t identical_layout_counter = 0;
for (const auto& old_lyt : unique_lyts)
Expand Down
Loading

0 comments on commit 7354ef0

Please sign in to comment.