Skip to content

Commit

Permalink
✨ Multi-dimensional operational domain computation (#493)
Browse files Browse the repository at this point in the history
* ✨ Added I/O coloring to SiDB layout printing

* 🎨 Changed the default operational/non-operational tags to `1` and `0`

* 🎨 Small changes

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 💩 Save commit, stuff doesn't work yet

* ✨ Exposed `bdl_input_iterator` in pyfiction

* 📝 Added RST documentation

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🧵 First attempt to port grid search from execution policies to manual threading

* 🧵 Rewrite `random_sampling` in `operational_domain.hpp` to use `std::thread`s instead of execution policies

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🎨 Reduced code duplication; more work can be done here in `grid_search`

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ✨ Introduce n-dimensional operational domain computation (needs testing)

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🎨 Small code clean up

* ✨ Added 3D Moore neighborhood

* ✅ Added test cases for 3-dimensional operational domain computation

* ✨ Support n-dimensional operational domains in `write_operational_domain`

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ✨ Support n-dimensional operational domains in experiments

* ✨ Added Bestagon experiment script

* ✨ Enabled Contour Tracing-based operational domain computation to work on operational domains that possess multiple islands

* ⚗️ Added an operational domain computation experiment script for the Bestagon gate library

* ⚗️ Added 3D versions of the operational domain computation experiment scripts and added total runtime tracking

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ✨ Added a flag to `write_operational_domain` to skip the writing of non-operational samples to reduce the resulting CSV file

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ⚡ Performance improvements by reserving vector space prior to assignment

* 🎨 Minor consistency fixes

* ⚗️ Small 3D operational domain experiment adjustments

* ⚗️ Increased number of random samples

* ⚗️ Increased resolution for 3D operational domain experiments

* ⚡ Improved load-balancing in multithreaded grid search-based operational domain computation, which increases performance

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ✏️ Fixed a typo

* 📝 Fixed a docstring ambiguity

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🔀 conduct merge. Python bindings are not updated yet.

* 🎨 Incorporated pre-commit fixes

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🔀 adjust some python APIs

* 🎨 small adjustments after merge.

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ⬆️ use submodule versions from main.

* 🎨 Incorporated pre-commit fixes

* 🎨 small fix of experiments after merge.

* 🐍 adjust python binding after merge

* 🐛 use mutex to avoid race conditions.

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🧵 use multithreading for grid_search_for_physically_valid_parameters

* 📝 fix docu.

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 📝 small fix.

* 📝 fix missing doc-label.

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* ✅ unit test for math utils function.

* ✅ add unit tests.

* ✅ add test for parameter point.

* 🎨 Improved consistency in naming, docstrings, formatting, etc.

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🎨 Remove unnecessary lock guards

* 🎨 Remove unnecessary lock guards

* 🧵 Thread-safe value-retrieval from std::atomic types

* 🎨 Minor consistency fixes

* 🧵 Switched std::mutex to std::shared_mutex for parallel read access

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🧵 Removed the need for manual mutexes and locks in operational domain computation

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🚸 Added sweep parameter validity checks

* 🐛 Fixed operational domain z-dimension handling in the CLI's `opdom` command

* 🐛 Fixed command `tt`'s truth table string parsing

* 📝 Added documentation on the new `opdom` CLI functionality

* 📝 Updated the operational domain docstrings for flood fill and contour tracing in accordance with the latest changes

* 🚸 Added checks for step size values (negative, 0) to operational domain computation

* 📝 Clarified docstring

* 📝 Fixed a documentation copy-paste bug

* 🎨 `const`ness and include cleanup

* 📝 Fixed header date in experiment script

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🐛 Fixed return value of `operational_domain::get_value`

* 🐍 Updated pyfiction docstrings with regard to operational domain computation changes

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 📝 Fixed Python documentation for `bdl_input_iterator`

* 🎨 Removed unused include

* 🎨 Moved `contains_parameter_point` and `find_key_with_tolerance` to the `detail` namespace

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🐛 Added missing forward-declaration to fix compiler error

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🐛 Fixed compiler error in `determine_physically_valid_parameters`

* 🎨 Incorporated Jan's feedback

* 🎨 Restructured code in an effort to circumvent the alice bug that doesn't reset the CLI parameters properly

* 📝 Mentioned CLI bug in docstring

* 📝 Update pyfiction docstrings

Signed-off-by: GitHub Actions <[email protected]>

* 🐍 Added `sample_writing_mode` to `write_operational_domain`'s Python bindings

---------

Signed-off-by: GitHub Actions <[email protected]>
Co-authored-by: GitHub Actions <[email protected]>
Co-authored-by: Drewniok <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jan Drewniok <[email protected]>
  • Loading branch information
5 people authored Aug 21, 2024
1 parent d18ead1 commit b213292
Show file tree
Hide file tree
Showing 40 changed files with 3,401 additions and 1,029 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
//
// Created by marcel on 19.05.24.
//

#ifndef PYFICTION_BDL_INPUT_ITERATOR_HPP
#define PYFICTION_BDL_INPUT_ITERATOR_HPP

#include "pyfiction/documentation.hpp"
#include "pyfiction/types.hpp"

#include <fiction/algorithms/iter/bdl_input_iterator.hpp>
#include <fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp>

#include <fmt/format.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <cstdint>
#include <string>

namespace pyfiction
{

namespace detail
{

template <typename Lyt>
void bdl_input_iterator(pybind11::module& m, const std::string& lattice)
{
namespace py = pybind11;
using namespace py::literals;

py::class_<fiction::bdl_input_iterator<Lyt>>(m, fmt::format("bdl_input_iterator_{}", lattice).c_str(),
DOC(fiction_bdl_input_iterator))
.def(py::init<const Lyt&, const fiction::detect_bdl_pairs_params&>(), "lyt"_a,
"params"_a = fiction::detect_bdl_pairs_params{}, DOC(fiction_bdl_input_iterator_bdl_input_iterator))
.def(
"__next__",
[](fiction::bdl_input_iterator<Lyt>& self) -> Lyt&
{
if (self >= ((1ull << self.num_input_pairs()) - 1))
{
throw py::stop_iteration();
}

auto result = *self;
++self;
return result;
},
DOC(fiction_bdl_input_iterator_operator_mul))
.def(
"__eq__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self == m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_eq))
.def(
"__ne__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self != m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_ne))
.def(
"__lt__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self < m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_lt))
.def(
"__le__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self <= m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_le))
.def(
"__gt__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self > m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_gt))
.def(
"__ge__", [](const fiction::bdl_input_iterator<Lyt>& self, const uint64_t m) -> bool { return self >= m; },
"m"_a, DOC(fiction_bdl_input_iterator_operator_ge))
.def(
"__add__", [](const fiction::bdl_input_iterator<Lyt>& self, const int m) -> fiction::bdl_input_iterator<Lyt>
{ return self + m; }, "m"_a, DOC(fiction_bdl_input_iterator_operator_add))
.def(
"__iadd__",
[](fiction::bdl_input_iterator<Lyt>& self, const int m) -> fiction::bdl_input_iterator<Lyt>&
{
self += m;
return self;
},
"m"_a, DOC(fiction_bdl_input_iterator_operator_iadd))
.def(
"__sub__", [](const fiction::bdl_input_iterator<Lyt>& self, const int m) { return self - m; }, "m"_a,
DOC(fiction_bdl_input_iterator_operator_sub))
.def(
"__isub__",
[](fiction::bdl_input_iterator<Lyt>& self, const int m) -> fiction::bdl_input_iterator<Lyt>&
{
self -= m;
return self;
},
"m"_a, DOC(fiction_bdl_input_iterator_operator_isub))
.def(
"__getitem__", [](const fiction::bdl_input_iterator<Lyt>& self, int m) -> fiction::bdl_input_iterator<Lyt>
{ return self[m]; }, "m"_a, DOC(fiction_bdl_input_iterator_operator_array))

.def("num_input_pairs", &fiction::bdl_input_iterator<Lyt>::num_input_pairs)
.def("get_layout", [](const fiction::bdl_input_iterator<Lyt>& self) -> const Lyt& { return *self; })

;
}

} // namespace detail

inline void bdl_input_iterator(pybind11::module& m)
{
// NOTE be careful with the order of the following calls! Python will resolve the first matching overload!

detail::bdl_input_iterator<py_sidb_100_lattice>(m, "100");
detail::bdl_input_iterator<py_sidb_111_lattice>(m, "111");
}

} // namespace pyfiction

#endif // PYFICTION_BDL_INPUT_ITERATOR_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@
#include "pyfiction/types.hpp"

#include <fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp>
#include <fiction/technology/cell_technologies.hpp>
#include <fiction/traits.hpp>

#include <fmt/format.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <string>

namespace pyfiction
{

Expand Down Expand Up @@ -49,7 +54,9 @@ inline void detect_bdl_pairs(pybind11::module& m)
.def_readwrite("minimum_distance", &fiction::detect_bdl_pairs_params::minimum_distance,
DOC(fiction_detect_bdl_pairs_params_minimum_distance))
.def_readwrite("maximum_distance", &fiction::detect_bdl_pairs_params::maximum_distance,
DOC(fiction_detect_bdl_pairs_params_maximum_distance));
DOC(fiction_detect_bdl_pairs_params_maximum_distance))

;

// NOTE be careful with the order of the following calls! Python will resolve the first matching overload!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,9 @@ inline void determine_physically_valid_parameters(pybind11::module& m)

py::class_<fiction::operational_domain<fiction::parameter_point, uint64_t>>(m, "physically_valid_parameters_domain",
DOC(fiction_operational_domain))
// todo add docu
.def(py::init<>())
.def_readwrite("x_dimension_parameter",
&fiction::operational_domain<fiction::parameter_point, uint64_t>::x_dimension,
DOC(fiction_operational_domain_x_dimension))
.def_readwrite("y_dimension_parameter",
&fiction::operational_domain<fiction::parameter_point, uint64_t>::y_dimension,
DOC(fiction_operational_domain_y_dimension))
.def_readwrite("dimensions", &fiction::operational_domain<fiction::parameter_point, uint64_t>::dimensions)

.def(
"get_excited_state_number_for_parameter",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
#include "pyfiction/documentation.hpp"
#include "pyfiction/types.hpp"

#include <fiction/algorithms/simulation/sidb/is_operational.hpp>
#include <fiction/algorithms/simulation/sidb/operational_domain.hpp>

#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>

#include <string>
#include <vector>

namespace pyfiction
{
Expand Down Expand Up @@ -51,18 +52,10 @@ inline void operational_domain(pybind11::module& m)
namespace py = pybind11;
using namespace pybind11::literals;

py::enum_<fiction::sweep_parameter>(m, "sweep_parameter", DOC(fiction_sweep_parameter))
.value("EPSILON_R", fiction::sweep_parameter::EPSILON_R, DOC(fiction_sweep_parameter_EPSILON_R))
.value("LAMBDA_TF", fiction::sweep_parameter::LAMBDA_TF, DOC(fiction_sweep_parameter_LAMBDA_TF))
.value("MU_MINUS", fiction::sweep_parameter::MU_MINUS, DOC(fiction_sweep_parameter_MU_MINUS))

;

py::class_<fiction::parameter_point>(m, "parameter_point", DOC(fiction_parameter_point))
.def(py::init<>())
.def(py::init<const double, const double>(), "x_val"_a, "y_val"_a)
.def_readwrite("x", &fiction::parameter_point::x, DOC(fiction_parameter_point_x))
.def_readwrite("y", &fiction::parameter_point::y, DOC(fiction_parameter_point_y))
.def(py::init<>(), DOC(fiction_parameter_point_parameter_point))
.def(py::init<const std::vector<double>>(), "values"_a, DOC(fiction_parameter_point_parameter_point_2))
.def_readwrite("parameters", &fiction::parameter_point::parameters, DOC(fiction_parameter_point))

.def(py::self == py::self, "other"_a, DOC(fiction_parameter_point_operator_eq))
.def(py::self != py::self, "other"_a, DOC(fiction_parameter_point_operator_ne))
Expand All @@ -72,19 +65,44 @@ inline void operational_domain(pybind11::module& m)

;

py::enum_<fiction::sweep_parameter>(m, "sweep_parameter", DOC(fiction_sweep_parameter))
.value("EPSILON_R", fiction::sweep_parameter::EPSILON_R, DOC(fiction_sweep_parameter_EPSILON_R))
.value("LAMBDA_TF", fiction::sweep_parameter::LAMBDA_TF, DOC(fiction_sweep_parameter_LAMBDA_TF))
.value("MU_MINUS", fiction::sweep_parameter::MU_MINUS, DOC(fiction_sweep_parameter_MU_MINUS))

;

py::class_<fiction::operational_domain<fiction::parameter_point, fiction::operational_status>>(
m, "operational_domain", DOC(fiction_operational_domain))
.def(py::init<>())
.def_readwrite("x_dimension",
&fiction::operational_domain<fiction::parameter_point, fiction::operational_status>::x_dimension,
DOC(fiction_operational_domain_x_dimension))
.def_readwrite("y_dimension",
&fiction::operational_domain<fiction::parameter_point, fiction::operational_status>::y_dimension,
DOC(fiction_operational_domain_y_dimension))
.def_readwrite("dimensions",
&fiction::operational_domain<fiction::parameter_point, fiction::operational_status>::dimensions,
DOC(fiction_operational_domain_dimensions))
.def_readwrite(
"operational_values",
&fiction::operational_domain<fiction::parameter_point, fiction::operational_status>::operational_values,
DOC(fiction_operational_domain_operational_values));
DOC(fiction_operational_domain_operational_values))

.def("get_value",
&fiction::operational_domain<fiction::parameter_point, fiction::operational_status>::get_value, "point"_a,
DOC(fiction_operational_domain_get_value))

;

py::class_<fiction::operational_domain_value_range>(m, "operational_domain_value_range",
DOC(fiction_operational_domain_value_range))
.def(py::init<fiction::sweep_parameter>(), "dimension"_a)
.def(py::init<fiction::sweep_parameter, double, double, double>(), "dimension"_a, "min"_a, "max"_a, "step"_a)
.def_readwrite("dimension", &fiction::operational_domain_value_range::dimension,
DOC(fiction_operational_domain_value_range_dimension))
.def_readwrite("min", &fiction::operational_domain_value_range::min,
DOC(fiction_operational_domain_value_range_dimension))
.def_readwrite("max", &fiction::operational_domain_value_range::max,
DOC(fiction_operational_domain_value_range_max))
.def_readwrite("step", &fiction::operational_domain_value_range::step,
DOC(fiction_operational_domain_value_range_step))

;

py::class_<fiction::operational_domain_params>(m, "operational_domain_params",
DOC(fiction_operational_domain_params))
Expand All @@ -93,42 +111,30 @@ inline void operational_domain(pybind11::module& m)
DOC(fiction_operational_domain_params_simulation_parameters))
.def_readwrite("sim_engine", &fiction::operational_domain_params::sim_engine,
DOC(fiction_operational_domain_params_sim_engine))
.def_readwrite("x_dimension", &fiction::operational_domain_params::x_dimension,
DOC(fiction_operational_domain_params_x_dimension))
.def_readwrite("x_min", &fiction::operational_domain_params::x_min,
DOC(fiction_operational_domain_params_x_min))
.def_readwrite("x_max", &fiction::operational_domain_params::x_max,
DOC(fiction_operational_domain_params_x_max))
.def_readwrite("x_step", &fiction::operational_domain_params::x_step,
DOC(fiction_operational_domain_params_x_step))
.def_readwrite("y_dimension", &fiction::operational_domain_params::y_dimension,
DOC(fiction_operational_domain_params_y_dimension))
.def_readwrite("y_min", &fiction::operational_domain_params::y_min,
DOC(fiction_operational_domain_params_y_min))
.def_readwrite("y_max", &fiction::operational_domain_params::y_max,
DOC(fiction_operational_domain_params_y_max))
.def_readwrite("y_step", &fiction::operational_domain_params::y_step,
DOC(fiction_operational_domain_params_y_step))
.def_readwrite("sweep_dimensions", &fiction::operational_domain_params::sweep_dimensions,
DOC(fiction_operational_domain_params_sweep_dimensions))
.def_readwrite("bdl_params", &fiction::operational_domain_params::bdl_params,
DOC(fiction_operational_domain_params_bdl_params))

;

py::class_<fiction::operational_domain_stats>(m, "operational_domain_stats", DOC(fiction_operational_domain_stats))
.def(py::init<>())
.def_readwrite("time_total", &fiction::operational_domain_stats::time_total,
DOC(fiction_operational_domain_stats_duration))
.def_readwrite("num_simulator_invocations", &fiction::operational_domain_stats::num_simulator_invocations,
DOC(fiction_operational_domain_stats_num_simulator_invocations))
.def_readwrite("num_evaluated_parameter_combinations",
&fiction::operational_domain_stats::num_evaluated_parameter_combinations,
DOC(fiction_operational_domain_stats_num_evaluated_parameter_combinations))
.def_readwrite("num_operational_parameter_combinations",
&fiction::operational_domain_stats::num_operational_parameter_combinations,
DOC(fiction_operational_domain_stats_num_operational_parameter_combinations))
.def_readwrite("num_non_operational_parameter_combinations",
&fiction::operational_domain_stats::num_non_operational_parameter_combinations,
DOC(fiction_operational_domain_stats_num_non_operational_parameter_combinations));
.def_readonly("time_total", &fiction::operational_domain_stats::time_total,
DOC(fiction_operational_domain_stats_duration))
.def_readonly("num_simulator_invocations", &fiction::operational_domain_stats::num_simulator_invocations,
DOC(fiction_operational_domain_stats_num_simulator_invocations))
.def_readonly("num_evaluated_parameter_combinations",
&fiction::operational_domain_stats::num_evaluated_parameter_combinations,
DOC(fiction_operational_domain_stats_num_evaluated_parameter_combinations))
.def_readonly("num_operational_parameter_combinations",
&fiction::operational_domain_stats::num_operational_parameter_combinations,
DOC(fiction_operational_domain_stats_num_operational_parameter_combinations))
.def_readonly("num_non_operational_parameter_combinations",
&fiction::operational_domain_stats::num_non_operational_parameter_combinations,
DOC(fiction_operational_domain_stats_num_non_operational_parameter_combinations))

;

// NOTE be careful with the order of the following calls! Python will resolve the first matching overload!

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ inline void write_operational_domain(pybind11::module& m)
namespace py = pybind11;
using namespace py::literals;

py::enum_<fiction::write_operational_domain_params::sample_writing_mode>(
m, "sample_writing_mode", DOC(fiction_write_operational_domain_params_sample_writing_mode))
.value("ALL_SAMPLES", fiction::write_operational_domain_params::sample_writing_mode::ALL_SAMPLES,
DOC(fiction_write_operational_domain_params_sample_writing_mode_ALL_SAMPLES))
.value("OPERATIONAL_ONLY", fiction::write_operational_domain_params::sample_writing_mode::OPERATIONAL_ONLY,
DOC(fiction_write_operational_domain_params_sample_writing_mode_OPERATIONAL_ONLY))

;

py::class_<fiction::write_operational_domain_params>(m, "write_operational_domain_params",
DOC(fiction_write_operational_domain_params))
.def(py::init<>())
.def_readwrite("operational_tag", &fiction::write_operational_domain_params::operational_tag,
DOC(fiction_write_operational_domain_params_operational_tag))
.def_readwrite("non_operational_tag", &fiction::write_operational_domain_params::non_operational_tag,
DOC(fiction_write_operational_domain_params_non_operational_tag))
.def_readwrite("writing_mode", &fiction::write_operational_domain_params::writing_mode,
DOC(fiction_write_operational_domain_params_writing_mode))

;

Expand Down
Loading

0 comments on commit b213292

Please sign in to comment.