From 162421c25832145e2313b8a7a15177fe6fb8c848 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 6 Sep 2023 14:36:13 +0200 Subject: [PATCH 001/191] :art: Refactored the technology mapping interface into its own header for better re-usability --- cli/cmd/logic/map.hpp | 244 +++------ .../technology_mapping.hpp | 474 ++++++++++++++++++ .../technology_mapping.cpp | 106 ++++ 3 files changed, 637 insertions(+), 187 deletions(-) create mode 100644 include/fiction/algorithms/network_transformation/technology_mapping.hpp create mode 100644 test/algorithms/network_transformation/technology_mapping.cpp diff --git a/cli/cmd/logic/map.hpp b/cli/cmd/logic/map.hpp index bd5f31984..831c0ad3c 100644 --- a/cli/cmd/logic/map.hpp +++ b/cli/cmd/logic/map.hpp @@ -5,26 +5,14 @@ #ifndef FICTION_CMD_MAP_HPP #define FICTION_CMD_MAP_HPP -#include -#include -#include +#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include -#include #include -#include namespace alice { @@ -42,31 +30,31 @@ class map_command : public command explicit map_command(const environment::ptr& e) : command(e, "Performs technology mapping to transform a network into another one using specific gates.") { - add_flag("--and,-a", "Enable the use of AND gates"); - add_flag("--nand", "Enable the use of NAND gates"); - add_flag("--or,-o", "Enable the use of OR gates"); - add_flag("--nor", "Enable the use of NOR gates"); - add_flag("--xor,-x", "Enable the use of XOR gates"); - add_flag("--xnor", "Enable the use of XNOR gates"); - add_flag("--inv,-i", "Enable the use of NOT gates"); - add_flag("--maj,-m", "Enable the use of MAJ gates"); - add_flag("--dot,-d", "Enable the use of DOT gates"); - - add_flag("--and3", "Enable the use of AND3 gates"); - add_flag("--xor_and", "Enable the use of XOR-AND gates"); - add_flag("--or_and", "Enable the use of OR-AND gates"); - add_flag("--onehot", "Enable the use of ONEHOT gates"); - add_flag("--gamble", "Enable the use of GAMBLE gates"); - add_flag("--mux", "Enable the use of MUX gates"); - add_flag("--and_xor", "Enable the use of AND-XOR gates"); + add_flag("--and,-a", ps.and2, "Enable the use of AND gates"); + add_flag("--nand", ps.nand2, "Enable the use of NAND gates"); + add_flag("--or,-o", ps.or2, "Enable the use of OR gates"); + add_flag("--nor", ps.nor2, "Enable the use of NOR gates"); + add_flag("--xor,-x", ps.xor2, "Enable the use of XOR gates"); + add_flag("--xnor", ps.xnor2, "Enable the use of XNOR gates"); + add_flag("--inv,-i", ps.inv, "Enable the use of NOT gates"); + + add_flag("--maj,-m", ps.maj3, "Enable the use of MAJ gates"); + add_flag("--dot,-d", ps.dot, "Enable the use of DOT gates"); + add_flag("--and3", ps.and3, "Enable the use of AND3 gates"); + add_flag("--xor_and", ps.xor_and, "Enable the use of XOR-AND gates"); + add_flag("--or_and", ps.or_and, "Enable the use of OR-AND gates"); + add_flag("--onehot", ps.onehot, "Enable the use of ONEHOT gates"); + add_flag("--gamble", ps.gamble, "Enable the use of GAMBLE gates"); + add_flag("--mux", ps.mux, "Enable the use of MUX gates"); + add_flag("--and_xor", ps.and_xor, "Enable the use of AND-XOR gates"); add_flag("--all2", "Enable the use of all supported 2-input gates + inverters"); add_flag("--all3", "Enable the use of all supported 3-input gates + inverters"); add_flag("--all", "Enable the use of all supported gates"); add_flag("--decay", "Enforce the application of at least one constant input to three-input gates"); - add_flag("--logic_sharing,-s", ps.enable_logic_sharing, "Enable logic sharing optimization"); - add_flag("--verbose,-v", ps.verbose, "Be verbose"); + add_flag("--logic_sharing,-s", "Enable logic sharing optimization"); + add_flag("--verbose,-v", "Be verbose"); } protected: @@ -85,186 +73,68 @@ class map_command : public command return; } - // gather library description - std::stringstream library_stream{}; - - library_stream << fiction::GATE_ZERO << fiction::GATE_ONE << fiction::GATE_BUF; - - if (is_set("and") || is_set("all2") || is_set("all")) - { - library_stream << fiction::GATE_AND2; - } - if (is_set("nand") || is_set("all2") || is_set("all")) - { - library_stream << fiction::GATE_NAND2; - } - if (is_set("or") || is_set("all2") || is_set("all")) - { - library_stream << fiction::GATE_OR2; - } - if (is_set("nor") || is_set("all2") || is_set("all")) - { - library_stream << fiction::GATE_NOR2; - } - if (is_set("xor") || is_set("all2") || is_set("all")) + if (static_cast(is_set("all2")) + static_cast(is_set("all3")) + static_cast(is_set("all")) > 1) { - library_stream << fiction::GATE_XOR2; + env->out() << "[w] only one of '--all2', '--all3', or '--all' must be set" << std::endl; + ps = {}; + return; } - if (is_set("xnor") || is_set("all2") || is_set("all")) + + if (is_set("all2")) { - library_stream << fiction::GATE_XNOR2; + ps = fiction::all_standard_2_input_functions(); } - if (is_set("inv") || is_set("all2") || is_set("all3") || is_set("all")) + else if (is_set("all3")) { - library_stream << fiction::GATE_INV; + ps = fiction::all_standard_3_input_functions(); } - if (is_set("maj") || is_set("all3") || is_set("all")) + else if (is_set("all")) { - if (!is_set("decay")) - { - library_stream << fiction::GATE_MAJ3; - } - - library_stream << fiction::DECAY_MAJ3; + ps = fiction::all_supported_standard_functions(); } - if (is_set("dot") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) - { - library_stream << fiction::GATE_DOT; - } - library_stream << fiction::DECAY_DOT; - } - if (is_set("and3") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) - { - library_stream << fiction::GATE_AND3; - } + ps.decay = is_set("decay"); + ps.mapper_params.enable_logic_sharing = is_set("logic_sharing"); + ps.mapper_params.verbose = is_set("verbose"); - library_stream << fiction::DECAY_AND3; - } - if (is_set("xor_and") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) - { - library_stream << fiction::GATE_XOR_AND; - } + const std::vector gate_flags{is_set("and"), is_set("nand"), is_set("or"), is_set("nor"), + is_set("xor"), is_set("xnor"), is_set("inv"), is_set("maj"), + is_set("dot"), is_set("and3"), is_set("xor_and"), is_set("or_and"), + is_set("onehot"), is_set("gamble"), is_set("mux"), is_set("and_xor"), + is_set("all2"), is_set("all3"), is_set("all")}; - library_stream << fiction::DECAY_XOR_AND; - } - if (is_set("or_and") || is_set("all3") || is_set("all")) + if (std::none_of(gate_flags.cbegin(), gate_flags.cend(), [](const auto& f) { return f; })) { - if (!is_set("decay")) - { - library_stream << fiction::GATE_OR_AND; - } - - library_stream << fiction::DECAY_OR_AND; + env->out() << "[e] no gates specified; cannot perform technology mapping" << std::endl; + ps = {}; + return; } - if (is_set("onehot") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) - { - library_stream << fiction::GATE_ONEHOT; - } - library_stream << fiction::DECAY_ONEHOT; - } - if (is_set("gamble") || is_set("all3") || is_set("all")) + const auto perform_mapping = [this, &s](auto&& ntk_ptr) { - if (!is_set("decay")) - { - library_stream << fiction::GATE_GAMBLE; - } + fiction::technology_mapping_stats st{}; - library_stream << fiction::DECAY_GAMBLE; - } - if (is_set("mux") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) - { - library_stream << fiction::GATE_MUX; - } + const auto mapped_ntk = fiction::technology_mapping(*ntk_ptr, ps, &st); - library_stream << fiction::DECAY_MUX; - } - if (is_set("and_xor") || is_set("all3") || is_set("all")) - { - if (!is_set("decay")) + if (st.mapper_stats.mapping_error) { - library_stream << fiction::GATE_AND_XOR; + env->out() << "[e] an error occurred in mockturtle's technology mapper" << std::endl; + return; } - library_stream << fiction::DECAY_AND_XOR; - } - - // generate technology library - std::vector gates{}; - - auto result = lorina::read_genlib(library_stream, mockturtle::genlib_reader{gates}); + s.extend() = std::make_shared(mapped_ntk); + }; - if (result == lorina::return_code::success) - { - if (is_set("maj") || is_set("dot") || is_set("and3") || is_set("xor_and") || is_set("or_and") || - is_set("onehot") || is_set("gamble") || is_set("mux") || is_set("and_xor") || is_set("all3") || - is_set("all")) - { - synthesize_and_store<3>(gates); - } - else if (is_set("and") || is_set("nand") || is_set("or") || is_set("nor") || is_set("xor") || - is_set("xnor") || is_set("all2")) - { - synthesize_and_store<2>(gates); - } - else if (is_set("inv")) - { - synthesize_and_store<1>(gates); - } - else - { - env->out() << "[e] no gates specified; cannot perform technology mapping" << std::endl; - ps = {}; - return; - } - } - else - { - env->out() << "[e] error parsing technology library" << std::endl; - } + std::visit(perform_mapping, s.current()); ps = {}; } private: - mockturtle::map_params ps{}; - - template - void synthesize_and_store(const std::vector& gates) - { - auto& s = store(); - - mockturtle::tech_library lib{gates}; - - const auto mapper = [this, &s, &lib](auto&& ntk_ptr) - { - mockturtle::map_stats st{}; - - const auto mapped_ntk = mockturtle::map(*ntk_ptr, lib, ps, &st); - - if (!st.mapping_error) - { - // convert network - auto converted_ntk = fiction::convert_network(mapped_ntk); - fiction::restore_network_name(*ntk_ptr, converted_ntk); - - s.extend() = std::make_shared(converted_ntk); - } - }; - - std::visit(mapper, s.current()); - } + /** + * Technology mapping parameters. + */ + fiction::technology_mapping_params ps{}; }; ALICE_ADD_COMMAND(map, "Logic") diff --git a/include/fiction/algorithms/network_transformation/technology_mapping.hpp b/include/fiction/algorithms/network_transformation/technology_mapping.hpp new file mode 100644 index 000000000..5cd6feb5e --- /dev/null +++ b/include/fiction/algorithms/network_transformation/technology_mapping.hpp @@ -0,0 +1,474 @@ +// +// Created by marcel on 06.09.23. +// + +#ifndef FICTION_TECHNOLOGY_MAPPING_HPP +#define FICTION_TECHNOLOGY_MAPPING_HPP + +#include "fiction/algorithms/network_transformation/network_conversion.hpp" +#include "fiction/technology/technology_mapping_library.hpp" +#include "fiction/types.hpp" +#include "fiction/utils/name_utils.hpp" + +#include +#include +#include +#include + +#include +#include +#include + +namespace fiction +{ + +struct technology_mapping_params +{ + /** + * mockturtle's mapper parameters. + */ + mockturtle::map_params mapper_params{}; + + /** + * Enforce the application of at least one constant input to three-input gates. + */ + bool decay{false}; + + // 1-input functions + + bool inv{false}; + + // 2-input functions + + /** + * 2-input AND gate. + */ + bool and2{false}; + /** + * 2-input NAND gate. + */ + bool nand2{false}; + /** + * 2-input OR gate. + */ + bool or2{false}; + /** + * 2-input NOR gate. + */ + bool nor2{false}; + /** + * 2-input XOR gate. + */ + bool xor2{false}; + /** + * 2-input XNOR gate. + */ + bool xnor2{false}; + + // 3-input functions + + /** + * 3-input AND gate. + */ + bool and3{false}; + /** + * 3-input XOR-AND gate. + */ + bool xor_and{false}; + /** + * 3-input OR-AND gate. + */ + bool or_and{false}; + /** + * 3-input ONEHOT gate. + */ + bool onehot{false}; + /** + * 3-input MAJ gate. + */ + bool maj3{false}; + /** + * 3-input GAMBLE gate. + */ + bool gamble{false}; + /** + * 3-input DOT gate. + */ + bool dot{false}; + /** + * 3-input MUX gate. + */ + bool mux{false}; + /** + * 3-input AND-XOR gate. + */ + bool and_xor{false}; +}; +/** + * Auxiliary function to create technology mapping parameters for AND, OR, and NOT gates. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] technology_mapping_params and_or_not() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + params.and2 = true; + params.or2 = true; + + return params; +} +/** + * Auxiliary function to create technology mapping parameters for AND, OR, NOT, and MAJ gates. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] technology_mapping_params and_or_not_maj() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + params.and2 = true; + params.or2 = true; + params.maj3 = true; + + return params; +} +/** + * Auxiliary function to create technology mapping parameters for AND, OR, NAND, NOR, XOR, XNOR, and NOT gates. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] technology_mapping_params all_standard_2_input_functions() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + + params.and2 = true; + params.nand2 = true; + params.or2 = true; + params.nor2 = true; + params.xor2 = true; + params.xnor2 = true; + + return params; +} +/** + * Auxiliary function to create technology mapping parameters for AND3, XOR_AND, OR_AND, ONEHOT, MAJ3, GAMBLE, DOT, MUX, + * and AND_XOR gates. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] technology_mapping_params all_standard_3_input_functions() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + + params.and3 = true; + params.xor_and = true; + params.or_and = true; + params.onehot = true; + params.maj3 = true; + params.gamble = true; + params.dot = true; + params.mux = true; + params.and_xor = true; + + return params; +} +/** + * Auxiliary function to create technology mapping parameters for all supported standard functions. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] technology_mapping_params all_supported_standard_functions() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + + params.and2 = true; + params.nand2 = true; + params.or2 = true; + params.nor2 = true; + params.xor2 = true; + params.xnor2 = true; + + params.and3 = true; + params.xor_and = true; + params.or_and = true; + params.onehot = true; + params.maj3 = true; + params.gamble = true; + params.dot = true; + params.mux = true; + params.and_xor = true; + + return params; +} +/** + * Statistics for technology mapping. + */ +struct technology_mapping_stats +{ + /** + * Statistics for mockturtle's mapper. + */ + mockturtle::map_stats mapper_stats{}; + /** + * Report statistics. + */ + void report() const + { + mapper_stats.report(); + } +}; + +namespace detail +{ + +template +class technology_mapping_impl +{ + public: + technology_mapping_impl(const Ntk& src, const technology_mapping_params& ps, technology_mapping_stats& st) : + ntk{src}, + params{ps}, + stats{st} + {} + + tec_nt run() + { + const auto gate_library = set_up_gates(); + + tec_nt mapped_ntk{}; + + if (params.maj3 || params.dot || params.and3 || params.xor_and || params.or_and || params.onehot || + params.gamble || params.mux || params.and_xor) + { + mapped_ntk = perform_mapping<3>(gate_library); + } + else if (params.and2 || params.nand2 || params.or2 || params.nor2 || params.xor2 || params.xnor2) + { + mapped_ntk = perform_mapping<2>(gate_library); + } + else if (params.inv) + { + mapped_ntk = perform_mapping<1>(gate_library); + } + + return mapped_ntk; + } + + private: + /** + * Input network to be mapped. + */ + Ntk ntk; + /** + * Technology mapping parameters. + */ + technology_mapping_params params; + /** + * Technology mapping statistics. + */ + technology_mapping_stats& stats; + + /** + * Create a mockturtle gate library from the given parameters. + * + * @return A vector of mockturtle gates. + */ + [[nodiscard]] std::vector set_up_gates() const + { + // gather library description + std::stringstream library_stream{}; + + library_stream << fiction::GATE_ZERO << fiction::GATE_ONE << fiction::GATE_BUF; + + // 1-input functions + if (params.inv) + { + library_stream << fiction::GATE_INV; + } + // 2-input functions + if (params.and2) + { + library_stream << fiction::GATE_AND2; + } + if (params.nand2) + { + library_stream << fiction::GATE_NAND2; + } + if (params.or2) + { + library_stream << fiction::GATE_OR2; + } + if (params.nor2) + { + library_stream << fiction::GATE_NOR2; + } + if (params.xor2) + { + library_stream << fiction::GATE_XOR2; + } + if (params.xnor2) + { + library_stream << fiction::GATE_XNOR2; + } + // 3-input functions + if (params.maj3) + { + if (!params.decay) + { + library_stream << fiction::GATE_MAJ3; + } + + library_stream << fiction::DECAY_MAJ3; + } + if (params.dot) + { + if (!params.decay) + { + library_stream << fiction::GATE_DOT; + } + + library_stream << fiction::DECAY_DOT; + } + if (params.and3) + { + if (!params.decay) + { + library_stream << fiction::GATE_AND3; + } + + library_stream << fiction::DECAY_AND3; + } + if (params.xor_and) + { + if (!params.decay) + { + library_stream << fiction::GATE_XOR_AND; + } + + library_stream << fiction::DECAY_XOR_AND; + } + if (params.or_and) + { + if (!params.decay) + { + library_stream << fiction::GATE_OR_AND; + } + + library_stream << fiction::DECAY_OR_AND; + } + if (params.onehot) + { + if (!params.decay) + { + library_stream << fiction::GATE_ONEHOT; + } + + library_stream << fiction::DECAY_ONEHOT; + } + if (params.gamble) + { + if (!params.decay) + { + library_stream << fiction::GATE_GAMBLE; + } + + library_stream << fiction::DECAY_GAMBLE; + } + if (params.mux) + { + if (!params.decay) + { + library_stream << fiction::GATE_MUX; + } + + library_stream << fiction::DECAY_MUX; + } + if (params.and_xor) + { + if (!params.decay) + { + library_stream << fiction::GATE_AND_XOR; + } + + library_stream << fiction::DECAY_AND_XOR; + } + + // generate technology library + std::vector gates{}; + + [[maybe_unused]] const auto result = lorina::read_genlib(library_stream, mockturtle::genlib_reader{gates}); + assert(result == lorina::return_code::success && "Could not parse technology library."); + + return gates; + } + /** + * Perform technology mapping with the given number of inputs. + * + * @tparam NumInp Maximum input number of the gates in the technology library. + * @param gates Technology library. + * @return Mapped network. + */ + template + [[nodiscard]] tec_nt perform_mapping(const std::vector& gates) const noexcept + { + mockturtle::tech_library lib{gates}; + + const auto mapped_ntk = mockturtle::map(ntk, lib, params.mapper_params, &stats.mapper_stats); + + tec_nt converted_ntk{}; + + if (!stats.mapper_stats.mapping_error) + { + // convert network + converted_ntk = convert_network(mapped_ntk); + restore_names(ntk, converted_ntk); + } + + return converted_ntk; + } +}; + +} // namespace detail + +/** + * Performs technology mapping on the given network. Technology mapping is the process of replacing the gates in a + * network with gates from a given technology library. This function utilizes `mockturtle::map` to perform the + * technology mapping. This function is a wrapper around that interface to provide a more convenient usage. + * + * @tparam Ntk Input logic network type. + * @param ntk Input logic network. + * @param params Technology mapping parameters. + * @param pst Technology mapping statistics. + * @return Mapped network exclusively using gates from the provided library. + */ +template +tec_nt technology_mapping(const Ntk& ntk, const technology_mapping_params& params = {}, + technology_mapping_stats* pst = nullptr) +{ + static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); + + technology_mapping_stats st{}; + detail::technology_mapping_impl p{ntk, params, st}; + + const auto result = p.run(); + + if (pst) + { + *pst = st; + } + + return result; +} + +} // namespace fiction + +#endif // FICTION_TECHNOLOGY_MAPPING_HPP diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp new file mode 100644 index 000000000..9676c4f3f --- /dev/null +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -0,0 +1,106 @@ +// +// Created by marcel on 06.09.23. +// + +#include + +#include "utils/blueprints/network_blueprints.hpp" +#include "utils/equivalence_checking_utils.hpp" + +#include +#include + +#include +#include +#include +#include + +using namespace fiction; + +template +void map_and_check_aoim(const Ntk& ntk) noexcept +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, and_or_not_maj(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + CHECK(gt_stats.num_and2 >= 0); + CHECK(gt_stats.num_or2 >= 0); + CHECK(gt_stats.num_maj3 >= 0); + + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); +} + +template +void map_and_check_all_3_inp(const Ntk& ntk) noexcept +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, all_standard_3_input_functions(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + CHECK(gt_stats.num_and3 >= 0); + CHECK(gt_stats.num_xor_and >= 0); + CHECK(gt_stats.num_or_and >= 0); + CHECK(gt_stats.num_onehot >= 0); + CHECK(gt_stats.num_maj3 >= 0); + CHECK(gt_stats.num_gamble >= 0); + CHECK(gt_stats.num_dot >= 0); + CHECK(gt_stats.num_mux >= 0); + CHECK(gt_stats.num_and_xor >= 0); + + CHECK(gt_stats.num_and2 == 0); + CHECK(gt_stats.num_or2 == 0); + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); +} + +TEMPLATE_TEST_CASE("Name conservation after technology mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) +{ + auto maj = blueprints::maj1_network>(); + maj.set_network_name("maj"); + + technology_mapping_stats stats{}; + + const auto mapped_maj = technology_mapping(maj, and_or_not_maj(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + // network name + CHECK(mapped_maj.get_network_name() == "maj"); +} + +TEMPLATE_TEST_CASE("Simple AOIM network mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) +{ + map_and_check_aoim(blueprints::maj1_network()); + map_and_check_aoim(blueprints::and_or_network()); + map_and_check_aoim(blueprints::inverter_network()); +} + +TEMPLATE_TEST_CASE("Complex 3-input network mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) +{ + map_and_check_all_3_inp(blueprints::maj4_network()); +} From c7723ad4f792a05cc36ccb0006c171376bc5385f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 6 Sep 2023 14:40:26 +0200 Subject: [PATCH 002/191] :memo: Added documentation --- docs/algorithms/network_transformation.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/algorithms/network_transformation.rst b/docs/algorithms/network_transformation.rst index 1ee757b05..5aa6284c9 100644 --- a/docs/algorithms/network_transformation.rst +++ b/docs/algorithms/network_transformation.rst @@ -22,3 +22,19 @@ Fanout Substitution .. doxygenstruct:: fiction::fanout_substitution_params :members: .. doxygenfunction:: fiction::fanout_substitution + +Technology Mapping +------------------ + +**Header:** ``fiction/algorithms/network_transformation/technology_mapping.hpp`` + +.. doxygenstruct:: fiction::technology_mapping_params + :members: +.. doxygenfunction:: fiction::and_or_not +.. doxygenfunction:: fiction::and_or_not_maj +.. doxygenfunction:: fiction::all_standard_2_input_functions +.. doxygenfunction:: fiction::all_standard_3_input_functions +.. doxygenfunction:: fiction::all_supported_standard_functions +.. doxygenstruct:: fiction::technology_mapping_stats + :members: +.. doxygenfunction:: fiction::technology_mapping From c7098e0cbf3044080601aaac1b0aa6b384f54014 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 6 Sep 2023 17:08:07 +0200 Subject: [PATCH 003/191] :art: Addressed `clang-tidy`'s warnings --- .../network_transformation/technology_mapping.hpp | 10 +++++----- .../network_transformation/fanout_substitution.cpp | 12 ++++++------ .../network_transformation/technology_mapping.cpp | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/fiction/algorithms/network_transformation/technology_mapping.hpp b/include/fiction/algorithms/network_transformation/technology_mapping.hpp index 5cd6feb5e..d50690b3d 100644 --- a/include/fiction/algorithms/network_transformation/technology_mapping.hpp +++ b/include/fiction/algorithms/network_transformation/technology_mapping.hpp @@ -109,7 +109,7 @@ struct technology_mapping_params * * @return Technology mapping parameters. */ -[[nodiscard]] technology_mapping_params and_or_not() noexcept +[[nodiscard]] inline technology_mapping_params and_or_not() noexcept { technology_mapping_params params{}; @@ -124,7 +124,7 @@ struct technology_mapping_params * * @return Technology mapping parameters. */ -[[nodiscard]] technology_mapping_params and_or_not_maj() noexcept +[[nodiscard]] inline technology_mapping_params and_or_not_maj() noexcept { technology_mapping_params params{}; @@ -140,7 +140,7 @@ struct technology_mapping_params * * @return Technology mapping parameters. */ -[[nodiscard]] technology_mapping_params all_standard_2_input_functions() noexcept +[[nodiscard]] inline technology_mapping_params all_standard_2_input_functions() noexcept { technology_mapping_params params{}; @@ -161,7 +161,7 @@ struct technology_mapping_params * * @return Technology mapping parameters. */ -[[nodiscard]] technology_mapping_params all_standard_3_input_functions() noexcept +[[nodiscard]] inline technology_mapping_params all_standard_3_input_functions() noexcept { technology_mapping_params params{}; @@ -184,7 +184,7 @@ struct technology_mapping_params * * @return Technology mapping parameters. */ -[[nodiscard]] technology_mapping_params all_supported_standard_functions() noexcept +[[nodiscard]] inline technology_mapping_params all_supported_standard_functions() noexcept { technology_mapping_params params{}; diff --git a/test/algorithms/network_transformation/fanout_substitution.cpp b/test/algorithms/network_transformation/fanout_substitution.cpp index 264d165b6..6dc9c198c 100644 --- a/test/algorithms/network_transformation/fanout_substitution.cpp +++ b/test/algorithms/network_transformation/fanout_substitution.cpp @@ -52,8 +52,8 @@ TEST_CASE("Simple fanout substitution", "[fanout-substitution]") { const auto tec = blueprints::multi_output_and_network(); - fanout_substitution_params ps_depth{fanout_substitution_params::substitution_strategy::DEPTH}; - fanout_substitution_params ps_breadth{fanout_substitution_params::substitution_strategy::BREADTH}; + const fanout_substitution_params ps_depth{fanout_substitution_params::substitution_strategy::DEPTH}; + const fanout_substitution_params ps_breadth{fanout_substitution_params::substitution_strategy::BREADTH}; substitute(tec, ps_depth, tec.size() + 3); substitute(tec, ps_breadth, tec.size() + 3); @@ -64,8 +64,8 @@ TEST_CASE("Complex fanout substitution", "[fanout-substitution]") const auto tec = blueprints::maj4_network(); CHECK(!is_fanout_substituted(tec)); - fanout_substitution_params ps_depth{fanout_substitution_params::substitution_strategy::DEPTH}; - fanout_substitution_params ps_breadth{fanout_substitution_params::substitution_strategy::BREADTH}; + const fanout_substitution_params ps_depth{fanout_substitution_params::substitution_strategy::DEPTH}; + const fanout_substitution_params ps_breadth{fanout_substitution_params::substitution_strategy::BREADTH}; substitute(tec, ps_depth, tec.size() + 7); @@ -79,8 +79,8 @@ TEST_CASE("Degree and threshold in fanout substitution", "[fanout-substitution]" { const auto aig = blueprints::maj4_network(); - fanout_substitution_params ps_31{fanout_substitution_params::substitution_strategy::BREADTH, 3, 1}; - fanout_substitution_params ps_22{fanout_substitution_params::substitution_strategy::DEPTH, 2, 2}; + const fanout_substitution_params ps_31{fanout_substitution_params::substitution_strategy::BREADTH, 3, 1}; + const fanout_substitution_params ps_22{fanout_substitution_params::substitution_strategy::DEPTH, 2, 2}; substitute(aig, ps_31, aig.size() + 35); substitute(aig, ps_22, aig.size() + 34); diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp index 9676c4f3f..71998a678 100644 --- a/test/algorithms/network_transformation/technology_mapping.cpp +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -18,7 +18,7 @@ using namespace fiction; template -void map_and_check_aoim(const Ntk& ntk) noexcept +void map_and_check_aoim(const Ntk& ntk) { technology_mapping_stats stats{}; @@ -43,7 +43,7 @@ void map_and_check_aoim(const Ntk& ntk) noexcept } template -void map_and_check_all_3_inp(const Ntk& ntk) noexcept +void map_and_check_all_3_inp(const Ntk& ntk) { technology_mapping_stats stats{}; From 7de9081c9509adf5cf94aa63d8fff2319d0ab2a8 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 6 Sep 2023 17:22:25 +0200 Subject: [PATCH 004/191] :white_check_mark: Increased test coverage --- .../technology_mapping.cpp | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp index 71998a678..778e13386 100644 --- a/test/algorithms/network_transformation/technology_mapping.cpp +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -17,6 +17,40 @@ using namespace fiction; +template +void map_and_check_aoi(const Ntk& ntk) +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, and_or_not(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + CHECK(gt_stats.num_and2 >= 0); + CHECK(gt_stats.num_or2 >= 0); + + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); + + CHECK(gt_stats.num_and3 == 0); + CHECK(gt_stats.num_xor_and == 0); + CHECK(gt_stats.num_or_and == 0); + CHECK(gt_stats.num_onehot == 0); + CHECK(gt_stats.num_maj3 == 0); + CHECK(gt_stats.num_gamble == 0); + CHECK(gt_stats.num_dot == 0); + CHECK(gt_stats.num_mux == 0); + CHECK(gt_stats.num_and_xor == 0); +} + template void map_and_check_aoim(const Ntk& ntk) { @@ -40,6 +74,49 @@ void map_and_check_aoim(const Ntk& ntk) CHECK(gt_stats.num_nor2 == 0); CHECK(gt_stats.num_xor2 == 0); CHECK(gt_stats.num_xnor2 == 0); + + CHECK(gt_stats.num_and3 == 0); + CHECK(gt_stats.num_xor_and == 0); + CHECK(gt_stats.num_or_and == 0); + CHECK(gt_stats.num_onehot == 0); + CHECK(gt_stats.num_gamble == 0); + CHECK(gt_stats.num_dot == 0); + CHECK(gt_stats.num_mux == 0); + CHECK(gt_stats.num_and_xor == 0); +} + +template +void map_and_check_all_2_inp(const Ntk& ntk) +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, all_standard_2_input_functions(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + + CHECK(gt_stats.num_and2 >= 0); + CHECK(gt_stats.num_or2 >= 0); + CHECK(gt_stats.num_nand2 >= 0); + CHECK(gt_stats.num_nor2 >= 0); + CHECK(gt_stats.num_xor2 >= 0); + CHECK(gt_stats.num_xnor2 >= 0); + + CHECK(gt_stats.num_and3 == 0); + CHECK(gt_stats.num_xor_and == 0); + CHECK(gt_stats.num_or_and == 0); + CHECK(gt_stats.num_onehot == 0); + CHECK(gt_stats.num_maj3 == 0); + CHECK(gt_stats.num_gamble == 0); + CHECK(gt_stats.num_dot == 0); + CHECK(gt_stats.num_mux == 0); + CHECK(gt_stats.num_and_xor == 0); } template @@ -75,6 +152,40 @@ void map_and_check_all_3_inp(const Ntk& ntk) CHECK(gt_stats.num_xnor2 == 0); } +template +void map_and_check_all_func(const Ntk& ntk) +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, all_supported_standard_functions(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + + CHECK(gt_stats.num_and2 >= 0); + CHECK(gt_stats.num_or2 >= 0); + CHECK(gt_stats.num_nand2 >= 0); + CHECK(gt_stats.num_nor2 >= 0); + CHECK(gt_stats.num_xor2 >= 0); + CHECK(gt_stats.num_xnor2 >= 0); + + CHECK(gt_stats.num_and3 >= 0); + CHECK(gt_stats.num_xor_and >= 0); + CHECK(gt_stats.num_or_and >= 0); + CHECK(gt_stats.num_onehot >= 0); + CHECK(gt_stats.num_maj3 >= 0); + CHECK(gt_stats.num_gamble >= 0); + CHECK(gt_stats.num_dot >= 0); + CHECK(gt_stats.num_mux >= 0); + CHECK(gt_stats.num_and_xor >= 0); +} + TEMPLATE_TEST_CASE("Name conservation after technology mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) { @@ -91,6 +202,13 @@ TEMPLATE_TEST_CASE("Name conservation after technology mapping", "[technology-ma CHECK(mapped_maj.get_network_name() == "maj"); } +TEMPLATE_TEST_CASE("Simple AOI network mapping", "[technology-mapping]", mockturtle::aig_network) +{ + map_and_check_aoi(blueprints::maj1_network()); + map_and_check_aoi(blueprints::and_or_network()); + map_and_check_aoi(blueprints::inverter_network()); +} + TEMPLATE_TEST_CASE("Simple AOIM network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) { @@ -99,8 +217,28 @@ TEMPLATE_TEST_CASE("Simple AOIM network mapping", "[technology-mapping]", mocktu map_and_check_aoim(blueprints::inverter_network()); } +TEMPLATE_TEST_CASE("Simple 2-input network mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network) +{ + map_and_check_all_2_inp(blueprints::maj1_network()); + map_and_check_all_2_inp(blueprints::and_or_network()); + map_and_check_all_2_inp(blueprints::inverter_network()); +} + +TEMPLATE_TEST_CASE("Complex 2-input network mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network) +{ + map_and_check_all_2_inp(blueprints::maj4_network()); +} + TEMPLATE_TEST_CASE("Complex 3-input network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) { map_and_check_all_3_inp(blueprints::maj4_network()); } + +TEMPLATE_TEST_CASE("Complex all function network mapping", "[technology-mapping]", mockturtle::aig_network, + mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) +{ + map_and_check_all_func(blueprints::maj4_network()); +} From 6d5f0294d88eb8e1bbde599dae0ae000f6531f93 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 8 Sep 2023 09:51:56 +0200 Subject: [PATCH 005/191] :construction_worker: Updated workflows to disable benchmark compilation --- .github/workflows/clang-tidy-review.yml | 1 + .github/workflows/codeql-analysis.yml | 1 + .github/workflows/coverage.yml | 1 + .github/workflows/macos.yml | 2 +- .github/workflows/ubuntu.yml | 2 +- .github/workflows/windows.yml | 2 +- Dockerfile | 1 + 7 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/clang-tidy-review.yml b/.github/workflows/clang-tidy-review.yml index b86ac987c..5124e42eb 100644 --- a/.github/workflows/clang-tidy-review.yml +++ b/.github/workflows/clang-tidy-review.yml @@ -32,6 +32,7 @@ jobs: -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DFICTION_CLI=ON -DFICTION_TEST=ON + -DFICTION_BENCHMARK=OFF -DFICTION_EXPERIMENTS=ON -DMOCKTURTLE_EXAMPLES=OFF build_dir: build diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index a7df3da47..308cfaec3 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -109,6 +109,7 @@ jobs: -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFICTION_CLI=ON -DFICTION_TEST=ON + -DFICTION_BENCHMARK=OFF -DFICTION_EXPERIMENTS=ON -DFICTION_Z3=ON -DFICTION_ENABLE_MUGEN=ON diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 0190669ef..baaae1ed9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -94,6 +94,7 @@ jobs: -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DFICTION_CLI=OFF -DFICTION_TEST=ON + -DFICTION_BENCHMARK=OFF -DFICTION_Z3=ON -DFICTION_ENABLE_MUGEN=ON -DFICTION_PROGRESS_BARS=OFF diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 01a8de948..ac0241a5f 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -103,7 +103,7 @@ jobs: -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFICTION_CLI=ON -DFICTION_TEST=ON - -DFICTION_BENCHMARK=ON + -DFICTION_BENCHMARK=OFF -DFICTION_EXPERIMENTS=ON -DFICTION_Z3=ON -DFICTION_PROGRESS_BARS=OFF diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 170360eac..92cbd07bc 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -111,7 +111,7 @@ jobs: -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFICTION_CLI=ON -DFICTION_TEST=ON - -DFICTION_BENCHMARK=ON + -DFICTION_BENCHMARK=OFF -DFICTION_EXPERIMENTS=ON -DFICTION_Z3=ON -DFICTION_ENABLE_MUGEN=ON diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index b704d0d3c..4e0a672d7 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -87,7 +87,7 @@ jobs: -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DFICTION_CLI=ON -DFICTION_TEST=ON - -DFICTION_BENCHMARK=ON + -DFICTION_BENCHMARK=OFF -DFICTION_EXPERIMENTS=ON -DFICTION_Z3=ON -DMOCKTURTLE_EXAMPLES=OFF diff --git a/Dockerfile b/Dockerfile index dc0579862..ddc018789 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ RUN cmake -S fiction -B fiction/build \ -DCMAKE_BUILD_TYPE=Release \ -DFICTION_CLI=ON \ -DFICTION_TEST=OFF \ + -DFICTION_BENCHMARK=OFF \ -DFICTION_EXPERIMENTS=OFF \ -DFICTION_Z3=ON \ -DFICTION_ENABLE_MUGEN=OFF \ From ffab67e27ac6ce0118be0b06a7f10bd6f09ddb56 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Thu, 14 Sep 2023 18:48:07 +0200 Subject: [PATCH 006/191] :sparkles: Introduce support for 2-ary LT, GT, LE, and GE gates --- cli/cmd/logic/map.hpp | 8 +- .../technology_mapping.hpp | 95 +++++++++++- .../properties/count_gate_types.hpp | 55 ++++++- include/fiction/io/dot_drawers.hpp | 140 ++++++++++++++++++ .../fiction/networks/technology_network.hpp | 30 ++++ .../technology/technology_mapping_library.hpp | 7 + include/fiction/traits.hpp | 56 +++++++ .../technology_mapping.cpp | 54 ++++++- test/networks/technology_network.cpp | 28 +++- 9 files changed, 455 insertions(+), 18 deletions(-) diff --git a/cli/cmd/logic/map.hpp b/cli/cmd/logic/map.hpp index 831c0ad3c..ae96f0319 100644 --- a/cli/cmd/logic/map.hpp +++ b/cli/cmd/logic/map.hpp @@ -36,6 +36,10 @@ class map_command : public command add_flag("--nor", ps.nor2, "Enable the use of NOR gates"); add_flag("--xor,-x", ps.xor2, "Enable the use of XOR gates"); add_flag("--xnor", ps.xnor2, "Enable the use of XNOR gates"); + add_flag("--lt", ps.lt2, "Enable the use of LT gates"); + add_flag("--gt", ps.gt2, "Enable the use of GT gates"); + add_flag("--le", ps.le2, "Enable the use of LE gates"); + add_flag("--ge", ps.ge2, "Enable the use of GE gates"); add_flag("--inv,-i", ps.inv, "Enable the use of NOT gates"); add_flag("--maj,-m", ps.maj3, "Enable the use of MAJ gates"); @@ -82,7 +86,7 @@ class map_command : public command if (is_set("all2")) { - ps = fiction::all_standard_2_input_functions(); + ps = fiction::all_2_input_functions(); } else if (is_set("all3")) { @@ -90,7 +94,7 @@ class map_command : public command } else if (is_set("all")) { - ps = fiction::all_supported_standard_functions(); + ps = fiction::all_supported_functions(); } ps.decay = is_set("decay"); diff --git a/include/fiction/algorithms/network_transformation/technology_mapping.hpp b/include/fiction/algorithms/network_transformation/technology_mapping.hpp index d50690b3d..e499b6262 100644 --- a/include/fiction/algorithms/network_transformation/technology_mapping.hpp +++ b/include/fiction/algorithms/network_transformation/technology_mapping.hpp @@ -64,6 +64,22 @@ struct technology_mapping_params * 2-input XNOR gate. */ bool xnor2{false}; + /** + * 2-input less-than gate. + */ + bool lt2{false}; + /** + * 2-input greater-than gate. + */ + bool gt2{false}; + /** + * 2-input less-or-equal gate. + */ + bool le2{false}; + /** + * 2-input greater-or-equal gate. + */ + bool ge2{false}; // 3-input functions @@ -155,6 +171,31 @@ struct technology_mapping_params return params; } +/** + * Auxiliary function to create technology mapping parameters for AND, OR, NAND, NOR, XOR, XNOR, IMPL, REPL, ANB, BNA, + * and NOT gates. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] inline technology_mapping_params all_2_input_functions() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + + params.and2 = true; + params.nand2 = true; + params.or2 = true; + params.nor2 = true; + params.xor2 = true; + params.xnor2 = true; + params.lt2 = true; + params.gt2 = true; + params.le2 = true; + params.ge2 = true; + + return params; +} /** * Auxiliary function to create technology mapping parameters for AND3, XOR_AND, OR_AND, ONEHOT, MAJ3, GAMBLE, DOT, MUX, * and AND_XOR gates. @@ -209,6 +250,40 @@ struct technology_mapping_params return params; } +/** + * Auxiliary function to create technology mapping parameters for all supported functions. + * + * @return Technology mapping parameters. + */ +[[nodiscard]] inline technology_mapping_params all_supported_functions() noexcept +{ + technology_mapping_params params{}; + + params.inv = true; + + params.and2 = true; + params.nand2 = true; + params.or2 = true; + params.nor2 = true; + params.xor2 = true; + params.xnor2 = true; + params.lt2 = true; + params.gt2 = true; + params.le2 = true; + params.ge2 = true; + + params.and3 = true; + params.xor_and = true; + params.or_and = true; + params.onehot = true; + params.maj3 = true; + params.gamble = true; + params.dot = true; + params.mux = true; + params.and_xor = true; + + return params; +} /** * Statistics for technology mapping. */ @@ -319,6 +394,22 @@ class technology_mapping_impl { library_stream << fiction::GATE_XNOR2; } + if (params.lt2) + { + library_stream << fiction::GATE_LT2; + } + if (params.gt2) + { + library_stream << fiction::GATE_GT2; + } + if (params.le2) + { + library_stream << fiction::GATE_LE2; + } + if (params.ge2) + { + library_stream << fiction::GATE_GE2; + } // 3-input functions if (params.maj3) { @@ -451,8 +542,8 @@ class technology_mapping_impl * @return Mapped network exclusively using gates from the provided library. */ template -tec_nt technology_mapping(const Ntk& ntk, const technology_mapping_params& params = {}, - technology_mapping_stats* pst = nullptr) +[[nodiscard]] tec_nt technology_mapping(const Ntk& ntk, const technology_mapping_params& params = {}, + technology_mapping_stats* pst = nullptr) { static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); diff --git a/include/fiction/algorithms/properties/count_gate_types.hpp b/include/fiction/algorithms/properties/count_gate_types.hpp index 8a2d1c25c..64f95a7fb 100644 --- a/include/fiction/algorithms/properties/count_gate_types.hpp +++ b/include/fiction/algorithms/properties/count_gate_types.hpp @@ -22,8 +22,8 @@ struct count_gate_types_stats { uint64_t num_fanout{0}, num_buf{0}, num_inv{0}, num_and2{0}, num_or2{0}, num_nand2{0}, num_nor2{0}, num_xor2{0}, - num_xnor2{0}, num_and3{0}, num_xor_and{0}, num_or_and{0}, num_onehot{0}, num_maj3{0}, num_gamble{0}, num_dot{0}, - num_mux{0}, num_and_xor{0}, num_other{0}; + num_xnor2{0}, num_lt2{0}, num_gt2{0}, num_le2{0}, num_ge2{0}, num_and3{0}, num_xor_and{0}, num_or_and{0}, + num_onehot{0}, num_maj3{0}, num_gamble{0}, num_dot{0}, num_mux{0}, num_and_xor{0}, num_other{0}; void report(std::ostream& out = std::cout, const bool detailed = false) const { @@ -40,6 +40,11 @@ struct count_gate_types_stats if (detailed) { + out << fmt::format("[i] LT2 = {}\n", num_lt2); + out << fmt::format("[i] GT2 = {}\n", num_gt2); + out << fmt::format("[i] LE2 = {}\n", num_le2); + out << fmt::format("[i] GE2 = {}\n", num_ge2); + out << fmt::format("[i] AND3 = {}\n", num_and3); out << fmt::format("[i] XORAND = {}\n", num_xor_and); out << fmt::format("[i] ORAND = {}\n", num_or_and); @@ -48,18 +53,20 @@ struct count_gate_types_stats out << fmt::format("[i] DOT = {}\n", num_dot); out << fmt::format("[i] MUX = {}\n", num_mux); out << fmt::format("[i] ANDXOR = {}\n", num_and_xor); + out << fmt::format("[i] other = {}\n", num_other); } else { - out << fmt::format("[i] other = {}\n", num_and3 + num_xor_and + num_or_and + num_onehot + num_gamble + - num_dot + num_mux + num_and_xor + num_other); + out << fmt::format("[i] other = {}\n", num_le2 + num_ge2 + num_gt2 + num_lt2 + num_and3 + num_xor_and + + num_or_and + num_onehot + num_gamble + num_dot + num_mux + + num_and_xor + num_other); } - out << fmt::format("[i] total = {}\n", num_fanout + num_buf + num_inv + num_and2 + num_or2 + num_nand2 + - num_nor2 + num_xor2 + num_xnor2 + num_and3 + num_xor_and + - num_or_and + num_onehot + num_maj3 + num_gamble + num_dot + - num_mux + num_and_xor + num_other); + out << fmt::format("[i] total = {}\n", + num_fanout + num_buf + num_inv + num_and2 + num_or2 + num_nand2 + num_nor2 + num_xor2 + + num_xnor2 + num_le2 + num_ge2 + num_gt2 + num_lt2 + num_and3 + num_xor_and + num_or_and + + num_onehot + num_maj3 + num_gamble + num_dot + num_mux + num_and_xor + num_other); } }; @@ -160,6 +167,38 @@ class count_gate_types_impl return true; } } + if constexpr (fiction::has_is_lt_v) + { + if (ntk.is_lt(n)) + { + ++pst.num_lt2; + return true; + } + } + if constexpr (fiction::has_is_gt_v) + { + if (ntk.is_gt(n)) + { + ++pst.num_gt2; + return true; + } + } + if constexpr (fiction::has_is_le_v) + { + if (ntk.is_le(n)) + { + ++pst.num_le2; + return true; + } + } + if constexpr (fiction::has_is_ge_v) + { + if (ntk.is_ge(n)) + { + ++pst.num_ge2; + return true; + } + } if constexpr (fiction::has_is_and3_v) { if (ntk.is_and3(n)) diff --git a/include/fiction/io/dot_drawers.hpp b/include/fiction/io/dot_drawers.hpp index d792d5c03..6360f8992 100644 --- a/include/fiction/io/dot_drawers.hpp +++ b/include/fiction/io/dot_drawers.hpp @@ -90,6 +90,41 @@ class technology_dot_drawer : public mockturtle::gate_dot_drawer return "palegreen2"; } } + if constexpr (has_is_xnor_v) + { + if (ntk.is_xnor(n)) + { + return "lightskyblue"; + } + } + if constexpr (has_is_lt_v) + { + if (ntk.is_lt(n)) + { + return "seagreen1"; + } + } + if constexpr (has_is_le_v) + { + if (ntk.is_le(n)) + { + return "seagreen4"; + } + } + if constexpr (has_is_gt_v) + { + if (ntk.is_gt(n)) + { + return "firebrick1"; + } + } + if constexpr (has_is_ge_v) + { + if (ntk.is_ge(n)) + { + return "firebrick4"; + } + } if constexpr (has_is_dot_v) { if (ntk.is_dot(n)) @@ -97,6 +132,41 @@ class technology_dot_drawer : public mockturtle::gate_dot_drawer return "thistle"; } } + if constexpr (has_is_xor_and_v) + { + if (ntk.is_xor_and(n)) + { + return "lightpink"; + } + } + if constexpr (has_is_or_and_v) + { + if (ntk.is_or_and(n)) + { + return "lightgreen"; + } + } + if constexpr (has_is_onehot_v) + { + if (ntk.is_onehot(n)) + { + return "lightgoldenrod"; + } + } + if constexpr (has_is_gamble_v) + { + if (ntk.is_gamble(n)) + { + return "lightsteelblue"; + } + } + if constexpr (mockturtle::has_is_ite_v) + { + if (ntk.is_ite(n)) + { + return "lightcyan"; + } + } return mockturtle::gate_dot_drawer::node_fillcolor(ntk, n); } @@ -139,6 +209,41 @@ class technology_dot_drawer : public mockturtle::gate_dot_drawer return "NOR"; } } + if constexpr (has_is_xnor_v) + { + if (ntk.is_xnor(n)) + { + return "XNOR"; + } + } + if constexpr (has_is_lt_v) + { + if (ntk.is_lt(n)) + { + return "LT"; + } + } + if constexpr (has_is_le_v) + { + if (ntk.is_le(n)) + { + return "LE"; + } + } + if constexpr (has_is_gt_v) + { + if (ntk.is_gt(n)) + { + return "GT"; + } + } + if constexpr (has_is_ge_v) + { + if (ntk.is_ge(n)) + { + return "GE"; + } + } if constexpr (has_is_dot_v) { if (ntk.is_dot(n)) @@ -146,6 +251,41 @@ class technology_dot_drawer : public mockturtle::gate_dot_drawer return "DOT"; } } + if constexpr (has_is_xor_and_v) + { + if (ntk.is_xor_and(n)) + { + return "XOR_AND"; + } + } + if constexpr (has_is_or_and_v) + { + if (ntk.is_or_and(n)) + { + return "OR_AND"; + } + } + if constexpr (has_is_onehot_v) + { + if (ntk.is_onehot(n)) + { + return "ONEHOT"; + } + } + if constexpr (has_is_gamble_v) + { + if (ntk.is_gamble(n)) + { + return "GAMBLE"; + } + } + if constexpr (mockturtle::has_is_ite_v) + { + if (ntk.is_ite(n)) + { + return "ITE"; + } + } const auto label = mockturtle::gate_dot_drawer::node_label(ntk, n); diff --git a/include/fiction/networks/technology_network.hpp b/include/fiction/networks/technology_network.hpp index e4b76e29a..6e4ed9b3b 100644 --- a/include/fiction/networks/technology_network.hpp +++ b/include/fiction/networks/technology_network.hpp @@ -112,6 +112,16 @@ class technology_network : public mockturtle::klut_network return _create_node({a, b}, 8); } + signal create_ge(signal a, signal b) + { + return _create_node({a, b}, 9); + } + + signal create_gt(signal a, signal b) + { + return _create_node({a, b}, 10); + } + signal create_le(signal a, signal b) { return _create_node({a, b}, 11); @@ -278,6 +288,26 @@ class technology_network : public mockturtle::klut_network return _storage->nodes[n].data[1].h1 == 7; } + [[nodiscard]] bool is_lt(const node& n) const noexcept + { + return _storage->nodes[n].data[1].h1 == 8; + } + + [[nodiscard]] bool is_ge(const node& n) const noexcept + { + return _storage->nodes[n].data[1].h1 == 9; + } + + [[nodiscard]] bool is_gt(const node& n) const noexcept + { + return _storage->nodes[n].data[1].h1 == 10; + } + + [[nodiscard]] bool is_le(const node& n) const noexcept + { + return _storage->nodes[n].data[1].h1 == 11; + } + [[nodiscard]] bool is_xor(const node& n) const noexcept { return _storage->nodes[n].data[1].h1 == 12; diff --git a/include/fiction/technology/technology_mapping_library.hpp b/include/fiction/technology/technology_mapping_library.hpp index d091047e3..67ae945f6 100644 --- a/include/fiction/technology/technology_mapping_library.hpp +++ b/include/fiction/technology/technology_mapping_library.hpp @@ -33,6 +33,13 @@ inline constexpr const char* GATE_OR2 = "GATE or2 1 O=a+b; PIN * NONINV inline constexpr const char* GATE_NOR2 = "GATE nor2 1 O=!(a+b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; inline constexpr const char* GATE_XOR2 = "GATE xor2 1 O=a^b; PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; inline constexpr const char* GATE_XNOR2 = "GATE xnor2 1 O=!(a^b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; +/** + * Non-standard 2-ary functions. + */ +inline constexpr const char* GATE_LT2 = "GATE lt2 1 O=(!a*b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; +inline constexpr const char* GATE_GT2 = "GATE gt2 1 O=(a*!b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; +inline constexpr const char* GATE_LE2 = "GATE le2 1 O=!(a*!b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; +inline constexpr const char* GATE_GE2 = "GATE ge2 1 O=!(!a*b); PIN * NONINV 1 999 1.0 1.0 1.0 1.0\n"; /** * 3-ary functions. diff --git a/include/fiction/traits.hpp b/include/fiction/traits.hpp index a61c4120b..0a82b7ee4 100644 --- a/include/fiction/traits.hpp +++ b/include/fiction/traits.hpp @@ -1000,6 +1000,62 @@ template inline constexpr bool has_is_xnor_v = has_is_xnor::value; #pragma endregion +#pragma region has_is_le +template +struct has_is_le : std::false_type +{}; + +template +struct has_is_le().is_le(std::declval>()))>> + : std::true_type +{}; + +template +inline constexpr bool has_is_le_v = has_is_le::value; +#pragma endregion + +#pragma region has_is_ge +template +struct has_is_ge : std::false_type +{}; + +template +struct has_is_ge().is_ge(std::declval>()))>> + : std::true_type +{}; + +template +inline constexpr bool has_is_ge_v = has_is_ge::value; +#pragma endregion + +#pragma region has_is_gt +template +struct has_is_gt : std::false_type +{}; + +template +struct has_is_gt().is_gt(std::declval>()))>> + : std::true_type +{}; + +template +inline constexpr bool has_is_gt_v = has_is_gt::value; +#pragma endregion + +#pragma region has_is_lt +template +struct has_is_lt : std::false_type +{}; + +template +struct has_is_lt().is_lt(std::declval>()))>> + : std::true_type +{}; + +template +inline constexpr bool has_is_lt_v = has_is_lt::value; +#pragma endregion + #pragma region has_is_and3 template struct has_is_and3 : std::false_type diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp index 778e13386..034f4fac7 100644 --- a/test/algorithms/network_transformation/technology_mapping.cpp +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -86,7 +86,7 @@ void map_and_check_aoim(const Ntk& ntk) } template -void map_and_check_all_2_inp(const Ntk& ntk) +void map_and_check_all_standard_2_inp(const Ntk& ntk) { technology_mapping_stats stats{}; @@ -120,7 +120,45 @@ void map_and_check_all_2_inp(const Ntk& ntk) } template -void map_and_check_all_3_inp(const Ntk& ntk) +void map_and_check_all_2_inp(const Ntk& ntk) +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, all_2_input_functions(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + + CHECK(gt_stats.num_and2 >= 0); + CHECK(gt_stats.num_or2 >= 0); + CHECK(gt_stats.num_nand2 >= 0); + CHECK(gt_stats.num_nor2 >= 0); + CHECK(gt_stats.num_xor2 >= 0); + CHECK(gt_stats.num_xnor2 >= 0); + CHECK(gt_stats.num_lt2 >= 0); + CHECK(gt_stats.num_gt2 >= 0); + CHECK(gt_stats.num_le2 >= 0); + CHECK(gt_stats.num_ge2 >= 0); + + CHECK(gt_stats.num_and3 == 0); + CHECK(gt_stats.num_xor_and == 0); + CHECK(gt_stats.num_or_and == 0); + CHECK(gt_stats.num_onehot == 0); + CHECK(gt_stats.num_maj3 == 0); + CHECK(gt_stats.num_gamble == 0); + CHECK(gt_stats.num_dot == 0); + CHECK(gt_stats.num_mux == 0); + CHECK(gt_stats.num_and_xor == 0); +} + +template +void map_and_check_all_standard_3_inp(const Ntk& ntk) { technology_mapping_stats stats{}; @@ -153,7 +191,7 @@ void map_and_check_all_3_inp(const Ntk& ntk) } template -void map_and_check_all_func(const Ntk& ntk) +void map_and_check_all_standard_func(const Ntk& ntk) { technology_mapping_stats stats{}; @@ -220,6 +258,10 @@ TEMPLATE_TEST_CASE("Simple AOIM network mapping", "[technology-mapping]", mocktu TEMPLATE_TEST_CASE("Simple 2-input network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network) { + map_and_check_all_standard_2_inp(blueprints::maj1_network()); + map_and_check_all_standard_2_inp(blueprints::and_or_network()); + map_and_check_all_standard_2_inp(blueprints::inverter_network()); + map_and_check_all_2_inp(blueprints::maj1_network()); map_and_check_all_2_inp(blueprints::and_or_network()); map_and_check_all_2_inp(blueprints::inverter_network()); @@ -228,17 +270,19 @@ TEMPLATE_TEST_CASE("Simple 2-input network mapping", "[technology-mapping]", moc TEMPLATE_TEST_CASE("Complex 2-input network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network) { + map_and_check_all_standard_2_inp(blueprints::maj4_network()); + map_and_check_all_2_inp(blueprints::maj4_network()); } TEMPLATE_TEST_CASE("Complex 3-input network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) { - map_and_check_all_3_inp(blueprints::maj4_network()); + map_and_check_all_standard_3_inp(blueprints::maj4_network()); } TEMPLATE_TEST_CASE("Complex all function network mapping", "[technology-mapping]", mockturtle::aig_network, mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) { - map_and_check_all_func(blueprints::maj4_network()); + map_and_check_all_standard_func(blueprints::maj4_network()); } diff --git a/test/networks/technology_network.cpp b/test/networks/technology_network.cpp index 33244588a..35e162f62 100644 --- a/test/networks/technology_network.cpp +++ b/test/networks/technology_network.cpp @@ -21,7 +21,7 @@ using namespace fiction; TEST_CASE("create and use constants in a technology network", "[technology-network]") { - technology_network tec{}; + const technology_network tec{}; CHECK(mockturtle::has_size_v); CHECK(mockturtle::has_get_constant_v); @@ -550,12 +550,30 @@ TEST_CASE("Node functions of a technology network", "[technology-network]") { technology_network tec{}; + CHECK(mockturtle::has_create_and_v); + CHECK(mockturtle::has_create_nand_v); + CHECK(mockturtle::has_create_or_v); + CHECK(mockturtle::has_create_nor_v); + CHECK(mockturtle::has_create_xor_v); + CHECK(mockturtle::has_create_xnor_v); + CHECK(mockturtle::has_create_lt_v); + CHECK(mockturtle::has_create_le_v); + CHECK(mockturtle::has_create_gt_v); + CHECK(mockturtle::has_create_ge_v); + CHECK(mockturtle::has_create_maj_v); + CHECK(mockturtle::has_create_ite_v); + CHECK(mockturtle::has_create_xor3_v); + CHECK(mockturtle::has_is_and_v); CHECK(fiction::has_is_nand_v); CHECK(mockturtle::has_is_or_v); CHECK(fiction::has_is_nor_v); CHECK(mockturtle::has_is_xor_v); CHECK(fiction::has_is_xnor_v); + CHECK(fiction::has_is_lt_v); + CHECK(fiction::has_is_le_v); + CHECK(fiction::has_is_gt_v); + CHECK(fiction::has_is_ge_v); CHECK(mockturtle::has_is_maj_v); CHECK(mockturtle::has_is_ite_v); CHECK(mockturtle::has_is_xor3_v); @@ -570,6 +588,10 @@ TEST_CASE("Node functions of a technology network", "[technology-network]") const auto nor_signal = tec.create_nor(x1, x2); const auto xor2_signal = tec.create_xor(x1, x2); const auto xnor2_signal = tec.create_xnor(x1, x2); + const auto lt_signal = tec.create_lt(x1, x2); + const auto le_signal = tec.create_le(x1, x2); + const auto gt_signal = tec.create_gt(x1, x2); + const auto ge_signal = tec.create_ge(x1, x2); const auto maj_signal = tec.create_maj(x1, x2, x3); const auto dot_signal = tec.create_dot(x1, x2, x3); const auto ite_signal = tec.create_ite(x1, x2, x3); @@ -591,6 +613,10 @@ TEST_CASE("Node functions of a technology network", "[technology-network]") CHECK(tec.is_or(tec.get_node(or_signal))); CHECK(tec.is_nor(tec.get_node(nor_signal))); CHECK(tec.is_xor(tec.get_node(xor2_signal))); + CHECK(tec.is_lt(tec.get_node(lt_signal))); + CHECK(tec.is_le(tec.get_node(le_signal))); + CHECK(tec.is_gt(tec.get_node(gt_signal))); + CHECK(tec.is_ge(tec.get_node(ge_signal))); CHECK(tec.is_xnor(tec.get_node(xnor2_signal))); CHECK(tec.is_maj(tec.get_node(maj_signal))); CHECK(tec.is_dot(tec.get_node(dot_signal))); From b9446494d1b0f997bd9d2b102cb7fda97a79ba4c Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 12:51:31 +0200 Subject: [PATCH 007/191] :sparkles: Introduce support for the LT, GT, LE, and GE gates in the truth table utils --- include/fiction/utils/truth_table_utils.hpp | 82 +++++++++++++++++---- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/include/fiction/utils/truth_table_utils.hpp b/include/fiction/utils/truth_table_utils.hpp index 202dbfea1..fa9396c63 100644 --- a/include/fiction/utils/truth_table_utils.hpp +++ b/include/fiction/utils/truth_table_utils.hpp @@ -20,7 +20,7 @@ namespace fiction * * @return Identity function in one variable. */ -inline kitty::dynamic_truth_table create_id_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_id_tt() noexcept { constexpr const uint64_t lit = 0x2; @@ -34,7 +34,7 @@ inline kitty::dynamic_truth_table create_id_tt() noexcept * * @return Negation in one variable. */ -inline kitty::dynamic_truth_table create_not_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_not_tt() noexcept { constexpr const uint64_t lit = 0x1; @@ -48,7 +48,7 @@ inline kitty::dynamic_truth_table create_not_tt() noexcept * * @return Conjunction in two variables. */ -inline kitty::dynamic_truth_table create_and_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_and_tt() noexcept { constexpr const uint64_t lit = 0x8; @@ -62,7 +62,7 @@ inline kitty::dynamic_truth_table create_and_tt() noexcept * * @return Disjunction in two variables. */ -inline kitty::dynamic_truth_table create_or_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_or_tt() noexcept { constexpr const uint64_t lit = 0xe; @@ -76,7 +76,7 @@ inline kitty::dynamic_truth_table create_or_tt() noexcept * * @return Negated conjunction in two variables. */ -inline kitty::dynamic_truth_table create_nand_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_nand_tt() noexcept { constexpr const uint64_t lit = 0x7; @@ -90,7 +90,7 @@ inline kitty::dynamic_truth_table create_nand_tt() noexcept * * @return Negated disjunction in two variables. */ -inline kitty::dynamic_truth_table create_nor_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_nor_tt() noexcept { constexpr const uint64_t lit = 0x1; @@ -104,7 +104,7 @@ inline kitty::dynamic_truth_table create_nor_tt() noexcept * * @return Exclusive disjunction in two variables. */ -inline kitty::dynamic_truth_table create_xor_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_xor_tt() noexcept { constexpr const uint64_t lit = 0x6; @@ -118,7 +118,7 @@ inline kitty::dynamic_truth_table create_xor_tt() noexcept * * @return Negated exclusive disjunction in two variables. */ -inline kitty::dynamic_truth_table create_xnor_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_xnor_tt() noexcept { constexpr const uint64_t lit = 0x9; @@ -127,12 +127,68 @@ inline kitty::dynamic_truth_table create_xnor_tt() noexcept return table; } +/** + * Creates and returns a truth table that implements the less-than function in two variables. + * + * @return Less-than function in two variables. + */ +[[nodiscard]] inline kitty::dynamic_truth_table create_lt_tt() noexcept +{ + constexpr const uint64_t lit = 0x2; + + kitty::dynamic_truth_table table{2}; + kitty::create_from_words(table, &lit, &lit + 1); + + return table; +} +/** + * Creates and returns a truth table that implements the greater-than function in two variables. + * + * @return Greater-than function in two variables. + */ +[[nodiscard]] inline kitty::dynamic_truth_table create_gt_tt() noexcept +{ + constexpr const uint64_t lit = 0x4; + + kitty::dynamic_truth_table table{2}; + kitty::create_from_words(table, &lit, &lit + 1); + + return table; +} +/** + * Creates and returns a truth table that implements the less-than-or-equal function in two variables. + * + * @return Less-than-or-equal function in two variables. + */ +[[nodiscard]] inline kitty::dynamic_truth_table create_le_tt() noexcept +{ + constexpr const uint64_t lit = 0x11; + + kitty::dynamic_truth_table table{2}; + kitty::create_from_words(table, &lit, &lit + 1); + + return table; +} +/** + * Creates and returns a truth table that implements the greater-than-or-equal function in two variables. + * + * @return Greater-than-or-equal function in two variables. + */ +[[nodiscard]] inline kitty::dynamic_truth_table create_ge_tt() noexcept +{ + constexpr const uint64_t lit = 0x13; + + kitty::dynamic_truth_table table{2}; + kitty::create_from_words(table, &lit, &lit + 1); + + return table; +} /** * Creates and returns a truth table that implements an identity function in two variables. * * @return identity function in two variables. */ -inline kitty::dynamic_truth_table create_double_wire_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_double_wire_tt() noexcept { static constexpr const char* truth_table_string = "11100100"; @@ -146,7 +202,7 @@ inline kitty::dynamic_truth_table create_double_wire_tt() noexcept * * @return crossing in two variables. */ -inline kitty::dynamic_truth_table create_crossing_wire_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_crossing_wire_tt() noexcept { static constexpr const char* truth_table_string = "11011000"; @@ -160,7 +216,7 @@ inline kitty::dynamic_truth_table create_crossing_wire_tt() noexcept * * @return fan-out in one variable. */ -inline kitty::dynamic_truth_table create_fan_out_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_fan_out_tt() noexcept { static constexpr const char* truth_table_string = "1100"; @@ -174,7 +230,7 @@ inline kitty::dynamic_truth_table create_fan_out_tt() noexcept * * @return half-adder in two variables. */ -inline kitty::dynamic_truth_table create_half_adder_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_half_adder_tt() noexcept { static constexpr const char* truth_table_string = "01101000"; @@ -189,7 +245,7 @@ inline kitty::dynamic_truth_table create_half_adder_tt() noexcept * * @return Majority function in three variables. */ -inline kitty::dynamic_truth_table create_maj_tt() noexcept +[[nodiscard]] inline kitty::dynamic_truth_table create_maj_tt() noexcept { constexpr const uint64_t lit = 0xe8; From 1430e98a9588f7a49a71f50687a5313123fb971f Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 13:04:20 +0200 Subject: [PATCH 008/191] :sparkles: Added the outline for the SiDB dynamic gate library for on-the-fly gate generation --- .../technology/inml_topolinano_library.hpp | 4 +- .../fiction/technology/qca_one_library.hpp | 2 +- .../technology/sidb_bestagon_library.hpp | 6 +- .../technology/sidb_dynamic_gate_library.hpp | 94 +++++++++++++++++++ 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 include/fiction/technology/sidb_dynamic_gate_library.hpp diff --git a/include/fiction/technology/inml_topolinano_library.hpp b/include/fiction/technology/inml_topolinano_library.hpp index 44b7220e0..18008b68b 100644 --- a/include/fiction/technology/inml_topolinano_library.hpp +++ b/include/fiction/technology/inml_topolinano_library.hpp @@ -43,8 +43,8 @@ class inml_topolinano_library : public fcn_gate_library template [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) { - static_assert(is_gate_level_layout_v, "Lyt must be a gate-level layout"); - static_assert(is_shifted_cartesian_layout_v, "Lyt must be a shifted Cartesian layout"); + static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); + static_assert(is_shifted_cartesian_layout_v, "GateLyt must be a shifted Cartesian layout"); // crossing magnets are handled only in the ground layer if (lyt.is_crossing_layer(t)) diff --git a/include/fiction/technology/qca_one_library.hpp b/include/fiction/technology/qca_one_library.hpp index d238e4ebf..3374af337 100644 --- a/include/fiction/technology/qca_one_library.hpp +++ b/include/fiction/technology/qca_one_library.hpp @@ -45,7 +45,7 @@ class qca_one_library : public fcn_gate_library template [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) { - static_assert(is_gate_level_layout_v, "Lyt must be a gate-level layout"); + static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); const auto n = lyt.get_node(t); const auto p = determine_port_routing(lyt, t); diff --git a/include/fiction/technology/sidb_bestagon_library.hpp b/include/fiction/technology/sidb_bestagon_library.hpp index 62fd2f82d..951760bec 100644 --- a/include/fiction/technology/sidb_bestagon_library.hpp +++ b/include/fiction/technology/sidb_bestagon_library.hpp @@ -51,9 +51,9 @@ class sidb_bestagon_library : public fcn_gate_library template [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) { - static_assert(is_gate_level_layout_v, "Lyt must be a gate-level layout"); - static_assert(is_hexagonal_layout_v, "Lyt must be a hexagonal layout"); - static_assert(has_pointy_top_hex_orientation_v, "Lyt must be a pointy-top hexagonal layout"); + static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); + static_assert(is_hexagonal_layout_v, "GateLyt must be a hexagonal layout"); + static_assert(has_pointy_top_hex_orientation_v, "GateLyt must be a pointy-top hexagonal layout"); const auto n = lyt.get_node(t); const auto p = determine_port_routing(lyt, t); diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp new file mode 100644 index 000000000..8a8ce04c2 --- /dev/null +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -0,0 +1,94 @@ +// +// Created by marcel on 15.09.23. +// + +#ifndef FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP +#define FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP + +#include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/fcn_gate_library.hpp" +#include "fiction/traits.hpp" + +namespace fiction +{ + +class sidb_dynamic_gate_library : fcn_gate_library // width and height of a hexagon +{ + public: + explicit sidb_dynamic_gate_library() = delete; + + template + [[nodiscard]] fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) + { + static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); + + const auto n = lyt.get_node(t); + const auto f = lyt.node_function(n); + const auto p = determine_port_routing(lyt, n); + + // TODO implement on-the-fly gate design here and return an fcn_gate object + + // if the gate type is unknown, throw an exception + throw unsupported_gate_type_exception(t); + } + + private: + template + [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept + { + port_list p{}; + + // determine incoming connector ports + if (lyt.has_north_eastern_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_EAST); + } + if (lyt.has_north_western_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + } + + // determine outgoing connector ports + if (lyt.has_south_eastern_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + if (lyt.has_south_western_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_WEST); + } + + // gates without connector ports + + // 1-input functions + if (const auto n = lyt.get_node(t); lyt.is_pi(n) || lyt.is_po(n) || lyt.is_buf(n) || lyt.is_inv(n)) + { + if (lyt.has_no_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + } + if (lyt.has_no_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + } + else // 2-input functions + { + if (lyt.has_no_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + p.inp.emplace(port_direction::cardinal::NORTH_EAST); + } + if (lyt.has_no_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + } + + return p; + } +}; + +} // namespace fiction + +#endif // FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP From 5cbc1bb9bb3354a74cee8b2c2ae516cbc9601fb0 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 14:05:45 +0200 Subject: [PATCH 009/191] :sparkles: Added the outline for the SiDB dynamic gate library experiment script --- .../dynamic_gate_design.cpp | 186 ++++++++++++++++++ .../technology/sidb_dynamic_gate_library.hpp | 7 +- 2 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 experiments/dynamic_gate_design/dynamic_gate_design.cpp diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp new file mode 100644 index 000000000..53383df6f --- /dev/null +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -0,0 +1,186 @@ +// +// Created by marcel on 16.11.21. +// + +#if (FICTION_Z3_SOLVER) + +#include "fiction_experiments.hpp" + +#include // technology mapping +#include // layout conversion to cell-level +#include // SMT-based physical design of FCN layouts +#include // critical path and throughput calculations +#include // reader for SiQAD files +#include // writer for SiQAD files (physical simulation) +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations +#include // a dynamic SiDB gate library +#include // SiDB surface with support for atomic defects +#include // pre-defined types suitable for the FCN domain + +#include // output formatting +#include // Verilog/BLIF/AIGER/... file parsing +#include // logic optimization with cut rewriting +#include // equivalence checking +#include // miter structure +#include // NPN databases for cut rewriting of XAGs and AIGs +#include // call-backs to read Verilog files into networks +#include // XOR-AND-inverter graphs +#include // to determine network levels + +#include +#include +#include +#include +#include + +int main() // NOLINT +{ + using gate_lyt = fiction::hex_even_row_gate_clk_lyt; + using cell_lyt = fiction::sidb_cell_clk_lyt; + + static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); + static const std::string surface_data_path = + fmt::format("{}/dynamic_gate_design/PATH-TO-SURFACE-DATA.sqd", EXPERIMENTS_PATH); + + experiments::experiment + bestagon_exp{"bestagon", + "benchmark", + "inputs", + "outputs", + "initial nodes", + "initial depth", + "optimized nodes", + "optimized depth", + "layout width (in tiles)", + "layout height (in tiles)", + "layout area (in tiles)", + "gates", + "wires", + "critical path", + "throughput", + "runtime (in sec)", + "equivalent", + "SiDB dots", + "layout area in nm²"}; + + // parameterize the H-Si(100) 2x1 surface to ignore certain defect types + const fiction::sidb_surface_params surface_params{ + std::unordered_set{fiction::sidb_defect_type::DB}}; + + fiction::sidb_surface surface_lattice{surface_params}; + fiction::read_sqd_layout(surface_lattice, surface_data_path); + + // instantiate a complete XAG NPN database for node re-synthesis + const mockturtle::xag_npn_resynthesis // the kind of database to use + resynthesis_function{}; + + // parameters for cut rewriting + mockturtle::cut_rewriting_params cut_params{}; + cut_params.cut_enumeration_ps.cut_size = 4; + + const fiction::technology_mapping_params tech_map_params = fiction::all_standard_2_input_functions(); + + // parameters for SMT-based physical design + fiction::exact_physical_design_params exact_params{}; + exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); + exact_params.crossings = true; + exact_params.border_io = true; + exact_params.desynchronize = true; + exact_params.timeout = 3'600'000; // 1h in ms + fiction::exact_physical_design_stats exact_stats{}; + + static constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::b1_r2 & + ~fiction_experiments::clpl & ~fiction_experiments::two_bit_add_maj & + ~fiction_experiments::parity & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl; + + for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) + { + fmt::print("[i] processing {}\n", benchmark); + mockturtle::xag_network xag{}; + + const auto read_verilog_result = + lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); + assert(read_verilog_result == lorina::return_code::success); + + // compute depth + const mockturtle::depth_view depth_xag{xag}; + + // rewrite network cuts using the given re-synthesis function + const auto cut_xag = mockturtle::cut_rewriting(xag, resynthesis_function, cut_params); + + // perform technology mapping + const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); + // compute depth + const mockturtle::depth_view depth_mapped_network{mapped_network}; + + // perform layout generation with an SMT-based exact algorithm + const auto gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); + + if (gate_level_layout.has_value()) + { + // check equivalence + const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); + const auto eq = mockturtle::equivalence_checking(*miter); + assert(eq.has_value()); + + // compute critical path and throughput + fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; + fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); + + // TODO incorporate surface_lattice into apply_gate_library + // TODO this can be achieved by implementing an in-place version of apply_gate_library + + // apply gate library + const auto cell_level_layout = + fiction::apply_gate_library(*gate_level_layout); + + // compute area + fiction::area_stats area_stats{}; + fiction::area_params area_ps{}; + fiction::area(cell_level_layout, area_ps, &area_stats); + + // write a SiQAD simulation file + fiction::write_sqd_layout(cell_level_layout, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); + + // log results + bestagon_exp( + benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), mapped_network.num_gates(), + depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1, + (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(), + gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput, + mockturtle::to_seconds(exact_stats.time_total), *eq, cell_level_layout.num_cells(), area_stats.area); + } + else // no layout was obtained + { + // log results + bestagon_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), + mapped_network.num_gates(), depth_mapped_network.depth(), 0, 0, 0, 0, 0, 0, 0, + mockturtle::to_seconds(exact_stats.time_total), false, 0, 0); + } + + bestagon_exp.save(); + bestagon_exp.table(); + } + + return EXIT_SUCCESS; +} + +#else // FICTION_Z3_SOLVER + +#include +#include + +int main() // NOLINT +{ + std::cerr << "[e] Z3 solver is not available, please install Z3 and recompile the code" << std::endl; + + return EXIT_FAILURE; +} + +#endif // FICTION_Z3_SOLVER diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 8a8ce04c2..d40dfc118 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -12,21 +12,22 @@ namespace fiction { -class sidb_dynamic_gate_library : fcn_gate_library // width and height of a hexagon +class sidb_dynamic_gate_library : public fcn_gate_library // width and height of a hexagon { public: explicit sidb_dynamic_gate_library() = delete; template - [[nodiscard]] fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) + [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); - const auto p = determine_port_routing(lyt, n); + const auto p = determine_port_routing(lyt, t); // TODO implement on-the-fly gate design here and return an fcn_gate object + return fcn_gate{}; // if the gate type is unknown, throw an exception throw unsupported_gate_type_exception(t); From d94fc4bf61888bffc0dd77cbe965566053f436e3 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 14:08:39 +0200 Subject: [PATCH 010/191] :art: Added folder to write layouts into --- experiments/dynamic_gate_design/layouts/.gitkeep | 0 experiments/dynamic_gate_design/layouts/fontes18/.gitkeep | 0 experiments/dynamic_gate_design/layouts/trindade16/.gitkeep | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 experiments/dynamic_gate_design/layouts/.gitkeep create mode 100644 experiments/dynamic_gate_design/layouts/fontes18/.gitkeep create mode 100644 experiments/dynamic_gate_design/layouts/trindade16/.gitkeep diff --git a/experiments/dynamic_gate_design/layouts/.gitkeep b/experiments/dynamic_gate_design/layouts/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/experiments/dynamic_gate_design/layouts/fontes18/.gitkeep b/experiments/dynamic_gate_design/layouts/fontes18/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/experiments/dynamic_gate_design/layouts/trindade16/.gitkeep b/experiments/dynamic_gate_design/layouts/trindade16/.gitkeep new file mode 100644 index 000000000..e69de29bb From 7b53df8fc23970b19ad62113fc773638ed298b82 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 14:14:18 +0200 Subject: [PATCH 011/191] :art: Utilize ALL 2-input functions --- experiments/dynamic_gate_design/dynamic_gate_design.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 53383df6f..b2775595f 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -83,7 +83,7 @@ int main() // NOLINT mockturtle::cut_rewriting_params cut_params{}; cut_params.cut_enumeration_ps.cut_size = 4; - const fiction::technology_mapping_params tech_map_params = fiction::all_standard_2_input_functions(); + const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; From a06498105d46f51fe50ebaf78b02f97b89fd7bbe Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Fri, 15 Sep 2023 16:14:44 +0200 Subject: [PATCH 012/191] :memo: Added truth table helper functions to the RST documentation --- docs/utils/utils.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/utils/utils.rst b/docs/utils/utils.rst index e99a02f12..e82eb07d0 100644 --- a/docs/utils/utils.rst +++ b/docs/utils/utils.rst @@ -43,6 +43,10 @@ Truth Table Utils .. doxygenfunction:: fiction::create_nor_tt .. doxygenfunction:: fiction::create_xor_tt .. doxygenfunction:: fiction::create_xnor_tt +.. doxygenfunction:: fiction::create_lt_tt +.. doxygenfunction:: fiction::create_gt_tt +.. doxygenfunction:: fiction::create_le_tt +.. doxygenfunction:: fiction::create_ge_tt .. doxygenfunction:: fiction::create_maj_tt From 0e84fb58c5211c061b9637630fe5bc594f8fb709 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 21 Sep 2023 09:39:01 +0200 Subject: [PATCH 013/191] :sparkles: support defects in the ``SiDB Gate Designer`` --- .../physical_design/design_sidb_gates.hpp | 6 +- .../sidb/random_sidb_layout_generator.hpp | 18 ++- include/fiction/technology/sidb_surface.hpp | 12 ++ .../physical_design/design_sidb_gates.cpp | 65 +++++++- .../sidb/random_sidb_layout_generator.cpp | 140 +++++++++++++++--- 5 files changed, 210 insertions(+), 31 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 57c6017ba..fd40c3e8c 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -11,6 +11,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/coordinates.hpp" +#include "fiction/technology/sidb_surface.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" @@ -123,7 +124,6 @@ class design_sidb_gates_impl if (!are_sidbs_too_close(combination)) { auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(combination); - if (const auto [status, sim_calls] = is_operational(layout_with_added_cells, truth_table, params_is_operational); status == operational_status::OPERATIONAL) @@ -317,8 +317,8 @@ class design_sidb_gates_impl /** * The *SiDB Gate Designer* designs SiDB gate implementations based on a specified Boolean function, a - * skeleton structure, canvas size, and a predetermined number of canvas SiDBs. Two different design modes are - * implemented: `exhaustive` and `random design`. + * skeleton layout (can hold defects), canvas size, and a predetermined number of canvas SiDBs. Two different design + * modes are implemented: `exhaustive` and `random design`. * * The `exhaustive design` is composed of three steps: * 1. In the initial step, all possible distributions of `number_of_sidbs` SiDBs within a given canvas are diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index e4a258c32..42f4724cc 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -115,6 +115,7 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s const auto random_coord = random_coordinate(params.coordinate_pair.first, params.coordinate_pair.second); bool constraint_violation_positive_sidbs = false; + bool identical_wih_defect = false; if (params.positive_sidbs == generate_random_sidb_layout_params::positive_charges::FORBIDDEN) { @@ -129,8 +130,23 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s } }); } + + // check if a defect does not already occupy random coordinate. + if constexpr (has_get_sidb_defect_v) + { + lyt.foreach_sidb_defect( + [&identical_wih_defect, &random_coord](const auto& cd) + { + const auto& [cell, defect] = cd; + if (cell == random_coord) + { + identical_wih_defect = true; + } + }); + } + // if the constraint that no positive SiDBs occur is satisfied, the SiDB is added to the layout - if (!constraint_violation_positive_sidbs) + if (!constraint_violation_positive_sidbs && !identical_wih_defect) { lyt.assign_cell_type(random_coord, Lyt::cell_type::NORMAL); } diff --git a/include/fiction/technology/sidb_surface.hpp b/include/fiction/technology/sidb_surface.hpp index 7a1d54c2a..42ce5f522 100644 --- a/include/fiction/technology/sidb_surface.hpp +++ b/include/fiction/technology/sidb_surface.hpp @@ -105,6 +105,18 @@ class sidb_surface : public Lyt assert(strg->params.ignore.count(sidb_defect_type::NONE) == 0 && "The defect type 'NONE' cannot be ignored"); } + /** + * Clones the layout returning a deep copy. + * + * @return Deep copy of the layout. + */ + [[nodiscard]] sidb_surface clone() const noexcept + { + sidb_surface copy{Lyt::clone()}; + copy.strg = std::make_shared(*strg); + + return copy; + } /** * Assigns a given defect type to the given coordinate. * diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 7953ea5ca..896ad40b5 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -44,7 +44,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 5, 1}}, + {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -134,20 +134,45 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); - - // generate gate by placing one SiDB const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{17, 11, 0}, {17, 11, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); + SECTION("generate original fo2") + { + CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 21); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + // generate gate by placing one SiDB + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 21); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + } + + SECTION("replace the output perturbers by equivalent negatively charged defects") + { + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + defect_layout.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::EMPTY); + defect_layout.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({36, 19, 0}) == layout::technology::EMPTY); + CHECK(defect_layout.get_cell_type({2, 19, 0}) == layout::technology::EMPTY); + + defect_layout.assign_sidb_defect( + {36, 19, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, + params.phys_params.lambda_tf}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 19); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + } } TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") @@ -194,4 +219,28 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") REQUIRE(!found_gate_layouts.empty()); CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); } + + SECTION("Random Generation with defects") + { + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + + defect_layout.assign_sidb_defect( + {15, 10, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect( + {20, 12, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); + REQUIRE(!found_gate_layouts.empty()); + CHECK(found_gate_layouts.front().num_defects() == 2); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + + found_gate_layouts.front().foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::coord_t{15, 10, 0}); + CHECK(cell != siqad::coord_t{20, 12, 0}); + }); + } } diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index 46b4a3218..d167acec0 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -10,7 +10,10 @@ #include #include #include +#include #include +#include +#include using namespace fiction; @@ -402,13 +405,13 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la } } -TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layout]") +TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layout]") { SECTION("empty parameters") { - const generate_random_sidb_layout_params params{}; + const generate_random_sidb_layout_params params{}; - const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -417,9 +420,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given two identical coordinates") { - const generate_random_sidb_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; + const generate_random_sidb_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -433,9 +436,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given corner coordinates") { - const generate_random_sidb_layout_params params{{{1, 1, 0}, {5, 7, 1}}}; + const generate_random_sidb_layout_params params{{{1, 1, 0}, {5, 7, 1}}}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -449,9 +452,9 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given corner coordinates and number of placed SiDBs") { - const generate_random_sidb_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; + const generate_random_sidb_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -467,12 +470,12 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given corner coordinates and number of placed SiDBs, and allow positive charges") { - const generate_random_sidb_layout_params params{ + const generate_random_sidb_layout_params params{ {{0, 0, 0}, {90, 90, 0}}, 100, - generate_random_sidb_layout_params::positive_charges::ALLOWED}; + generate_random_sidb_layout_params::positive_charges::ALLOWED}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -485,12 +488,12 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given corner coordinates and number of placed SiDBs, and forbid positive charges") { - const generate_random_sidb_layout_params params{ + const generate_random_sidb_layout_params params{ {{0, 0, 0}, {90, 90, 0}}, 10, - generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; + generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -509,7 +512,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo { if (cell_one != cell_two) { - CHECK(euclidean_distance(result_lyt, cell_one, cell_two) >= 2); + CHECK(euclidean_distance(result_lyt, cell_one, cell_two) >= 2); } }); }); @@ -517,14 +520,15 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo SECTION("given previous layouts") { - const generate_random_sidb_layout_params params{ + const generate_random_sidb_layout_params params{ {{0, 0, 1}, {9, 9, 1}}, 10, - generate_random_sidb_layout_params::positive_charges::FORBIDDEN, + generate_random_sidb_layout_params::positive_charges::FORBIDDEN, 2, static_cast(10E6), 3}; - const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt{}, params); + const auto result_lyts = + generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -541,3 +545,101 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate_random_sidb_layo } } } + +TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-random-sidb-layout]") +{ + + SECTION("given two identical coordinates") + { + const generate_random_sidb_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; + + const auto result_lyt = + generate_random_sidb_layout(sidb_defect_cell_clk_lyt_siqad{}, params); + + CHECK(result_lyt.num_cells() == 1); + result_lyt.foreach_cell( + [](const auto& cell) + { + CHECK(cell.x == 5); + CHECK(cell.y == 5); + CHECK(cell.z == 1); + }); + } + + SECTION("region including only one cell and there is a defect") + { + // it is not possible to generate a random layout since the position where a SiDB could be placed is occupied by + // a defect. + const generate_random_sidb_layout_params params{ + {{2, 1, 1}, {2, 1, 1}}, + 1, + generate_random_sidb_layout_params::positive_charges::FORBIDDEN, + 2, + 5u}; + + auto defect_layout = sidb_defect_cell_clk_lyt_siqad{}; + defect_layout.assign_sidb_defect({2, 1, 1}, sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + + CHECK(result_lyt.num_cells() == 0); + CHECK(result_lyt.num_defects() == 1); + } + + SECTION("region including only one cell and there is no defect") + { + // it is not possible to generate a random layout since the position where a SiDB could be placed is occupied by + // a defect. + const generate_random_sidb_layout_params params{ + {{2, 1, 1}, {2, 1, 1}}, + 1, + generate_random_sidb_layout_params::positive_charges::FORBIDDEN, + 2, + 5u}; + + auto defect_layout = sidb_defect_cell_clk_lyt_siqad{}; + defect_layout.assign_sidb_defect({3, 1, 1}, sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + defect_layout.assign_sidb_defect({4, 1, 1}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); + + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + + CHECK(result_lyt.num_cells() == 1); + CHECK(result_lyt.num_defects() == 2); + + CHECK(result_lyt.get_cell_type({2, 1, 1}) == sidb_defect_cell_clk_lyt_siqad::technology::cell_type::NORMAL); + CHECK(result_lyt.get_sidb_defect({3, 1, 1}) == sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + CHECK(result_lyt.get_sidb_defect({4, 1, 1}) == sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); + } + + SECTION("given corner coordinates and number of placed SiDBs, and allow positive charges") + { + const generate_random_sidb_layout_params params{ + {{0, 0, 0}, {10, 2, 0}}, + 10, + generate_random_sidb_layout_params::positive_charges::ALLOWED, + 2}; + + auto defect_layout = sidb_defect_cell_clk_lyt_siqad{}; + defect_layout.assign_sidb_defect({2, 2, 0}, sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + defect_layout.assign_sidb_defect({4, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); + defect_layout.assign_sidb_defect({5, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 9}); + defect_layout.assign_sidb_defect({7, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 2.6, 7}); + defect_layout.assign_sidb_defect({2, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 4}); + + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + + CHECK(result_lyt.num_cells() == 10); + CHECK(result_lyt.num_defects() == 5); + + // check if all cells are not closer than two cells (Euclidean distance). + result_lyt.foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::coord_t{2, 2, 0}); + CHECK(cell != siqad::coord_t{4, 1, 0}); + CHECK(cell != siqad::coord_t{5, 1, 0}); + CHECK(cell != siqad::coord_t{7, 1, 0}); + CHECK(cell != siqad::coord_t{2, 1, 0}); + }); + } +} From 8dd7ebf1de9aa27744c7dd4c73e8a2f891e001d5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 21 Sep 2023 09:45:20 +0200 Subject: [PATCH 014/191] :art: update docu. --- .../simulation/sidb/random_sidb_layout_generator.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index 42f4724cc..5a7d0d82b 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -131,7 +131,7 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s }); } - // check if a defect does not already occupy random coordinate. + // check if a defect does not yet occupy random coordinate. if constexpr (has_get_sidb_defect_v) { lyt.foreach_sidb_defect( @@ -145,7 +145,8 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s }); } - // if the constraint that no positive SiDBs occur is satisfied, the SiDB is added to the layout + // if the constraints that no positive SiDBs occur and the cell is not yet occupied by a defect are satisfied, + // the SiDB is added to the layout if (!constraint_violation_positive_sidbs && !identical_wih_defect) { lyt.assign_cell_type(random_coord, Lyt::cell_type::NORMAL); From 6306a97a181747ef369720147f9a3cd9e893533f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 21 Sep 2023 09:48:13 +0200 Subject: [PATCH 015/191] :art: delete redundant line. --- .../simulation/sidb/random_sidb_layout_generator.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index 5a7d0d82b..b80f53c04 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -115,7 +115,7 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s const auto random_coord = random_coordinate(params.coordinate_pair.first, params.coordinate_pair.second); bool constraint_violation_positive_sidbs = false; - bool identical_wih_defect = false; + bool random_cell_is_identical_wih_defect = false; if (params.positive_sidbs == generate_random_sidb_layout_params::positive_charges::FORBIDDEN) { @@ -130,24 +130,23 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s } }); } - // check if a defect does not yet occupy random coordinate. if constexpr (has_get_sidb_defect_v) { lyt.foreach_sidb_defect( - [&identical_wih_defect, &random_coord](const auto& cd) + [&random_cell_is_identical_wih_defect, &random_coord](const auto& cd) { const auto& [cell, defect] = cd; if (cell == random_coord) { - identical_wih_defect = true; + random_cell_is_identical_wih_defect = true; } }); } // if the constraints that no positive SiDBs occur and the cell is not yet occupied by a defect are satisfied, // the SiDB is added to the layout - if (!constraint_violation_positive_sidbs && !identical_wih_defect) + if (!constraint_violation_positive_sidbs && !random_cell_is_identical_wih_defect) { lyt.assign_cell_type(random_coord, Lyt::cell_type::NORMAL); } From 49c0981e1ea51917ab36b231d3d1deefba095db8 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 21 Sep 2023 13:25:40 +0200 Subject: [PATCH 016/191] :art: implement Marcel's suggestions. --- .../physical_design/design_sidb_gates.hpp | 1 - .../sidb/random_sidb_layout_generator.hpp | 15 ++--- .../physical_design/design_sidb_gates.cpp | 13 +++-- .../sidb/random_sidb_layout_generator.cpp | 56 +++++++++---------- 4 files changed, 38 insertions(+), 47 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index fd40c3e8c..19e9329f9 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -11,7 +11,6 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/coordinates.hpp" -#include "fiction/technology/sidb_surface.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index b80f53c04..427f0a7d0 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -115,7 +115,6 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s const auto random_coord = random_coordinate(params.coordinate_pair.first, params.coordinate_pair.second); bool constraint_violation_positive_sidbs = false; - bool random_cell_is_identical_wih_defect = false; if (params.positive_sidbs == generate_random_sidb_layout_params::positive_charges::FORBIDDEN) { @@ -130,25 +129,19 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s } }); } + + bool random_cell_is_identical_wih_defect = false; // check if a defect does not yet occupy random coordinate. if constexpr (has_get_sidb_defect_v) { - lyt.foreach_sidb_defect( - [&random_cell_is_identical_wih_defect, &random_coord](const auto& cd) - { - const auto& [cell, defect] = cd; - if (cell == random_coord) - { - random_cell_is_identical_wih_defect = true; - } - }); + random_cell_is_identical_wih_defect = (lyt.get_sidb_defect(random_coord).type != sidb_defect_type::NONE); } // if the constraints that no positive SiDBs occur and the cell is not yet occupied by a defect are satisfied, // the SiDB is added to the layout if (!constraint_violation_positive_sidbs && !random_cell_is_identical_wih_defect) { - lyt.assign_cell_type(random_coord, Lyt::cell_type::NORMAL); + lyt.assign_cell_type(random_coord, technology::cell_type::NORMAL); } attempt_counter += 1; } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 896ad40b5..0cc960341 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -140,7 +140,7 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin 1, sidb_simulation_engine::QUICKEXACT}; - SECTION("generate original fo2") + SECTION("generate original FO2") { CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); @@ -156,10 +156,10 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("replace the output perturbers by equivalent negatively charged defects") { sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - defect_layout.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::EMPTY); - defect_layout.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::EMPTY); - CHECK(defect_layout.get_cell_type({36, 19, 0}) == layout::technology::EMPTY); - CHECK(defect_layout.get_cell_type({2, 19, 0}) == layout::technology::EMPTY); + defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); + defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); defect_layout.assign_sidb_defect( {36, 19, 0}, @@ -171,7 +171,8 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin REQUIRE(found_gate_layouts.size() == 1); CHECK(found_gate_layouts[0].num_cells() == 19); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == + technology::cell_type::NORMAL); } } diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index d167acec0..a0f20a00f 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -25,7 +25,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou { const generate_random_sidb_layout_params params{}; - const auto lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -36,7 +36,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou { const generate_random_sidb_layout_params params{{{5, 7, 2}, {-10, -10, 0}}}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -52,7 +52,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou { const generate_random_sidb_layout_params params{{{-10, -10, 0}, {5, 7, 2}}}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -68,7 +68,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou { const generate_random_sidb_layout_params params{{{-10, -10, 1}, {-10, -10, 1}}, 1}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -84,7 +84,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou { const generate_random_sidb_layout_params params{{{-10, -10, 0}, {5, 7, 1}}, 10}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -106,7 +106,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou 100, generate_random_sidb_layout_params::positive_charges::ALLOWED}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -124,7 +124,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou 100, generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); + const auto result_lyt = generate_random_sidb_layout(cube_layout{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -182,7 +182,7 @@ TEST_CASE("Random cube::coord_t layout generation", "[generate-random-sidb-layou 2, static_cast(10E6), 2}; - const auto result_lyts = generate_multiple_random_sidb_layouts(cube_layout{}, params); + const auto result_lyts = generate_multiple_random_sidb_layouts(cube_layout{}, params); REQUIRE(result_lyts.size() == 2); const auto& first_lyt = result_lyts.front(); @@ -211,7 +211,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la { const generate_random_sidb_layout_params params{}; - const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -222,7 +222,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la { const generate_random_sidb_layout_params params{{{1, 1, 0}, {5, 7, 2}}}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -238,7 +238,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la { const generate_random_sidb_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -254,7 +254,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la { const generate_random_sidb_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -276,7 +276,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la 100, generate_random_sidb_layout_params::positive_charges::ALLOWED}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -294,7 +294,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la 100, generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -327,7 +327,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la 2, static_cast(10E6), 3}; - const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt{}, params); + const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -350,7 +350,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la 2, static_cast(10E6), 2}; - const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt{}, params); + const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt{}, params); REQUIRE(result_lyts.size() == 2); const auto& first_lyt = result_lyts.front(); @@ -379,7 +379,7 @@ TEST_CASE("Random offset::ucoord_t layout generation", "[generate-random-sidb-la skeleton_layout.assign_cell_type({0, 0}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({9, 1}, sidb_cell_clk_lyt::technology::NORMAL); skeleton_layout.assign_cell_type({5, 0}, sidb_cell_clk_lyt::technology::NORMAL); - const auto result_lyt = generate_random_sidb_layout(skeleton_layout, params); + const auto result_lyt = generate_random_sidb_layout(skeleton_layout, params); CHECK(result_lyt.num_cells() == 13); } @@ -411,7 +411,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo { const generate_random_sidb_layout_params params{}; - const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); + const auto lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(lyt.num_cells() == 0); CHECK(lyt.x() == 0); @@ -438,7 +438,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo { const generate_random_sidb_layout_params params{{{1, 1, 0}, {5, 7, 1}}}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 0); result_lyt.foreach_cell( @@ -454,7 +454,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo { const generate_random_sidb_layout_params params{{{1, 1, 0}, {50, 7, 1}}, 10}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -475,7 +475,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo 100, generate_random_sidb_layout_params::positive_charges::ALLOWED}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 100); result_lyt.foreach_cell( @@ -493,7 +493,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo 10, generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; - const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 10); result_lyt.foreach_cell( @@ -527,8 +527,7 @@ TEST_CASE("Random siqad::coord_t layout generation", "[generate-random-sidb-layo 2, static_cast(10E6), 3}; - const auto result_lyts = - generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt_siqad{}, params); + const auto result_lyts = generate_multiple_random_sidb_layouts(sidb_cell_clk_lyt_siqad{}, params); CHECK(result_lyts.size() == 3); for (const auto& lyt : result_lyts) @@ -553,8 +552,7 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran { const generate_random_sidb_layout_params params{{{5, 5, 1}, {5, 5, 1}}, 1}; - const auto result_lyt = - generate_random_sidb_layout(sidb_defect_cell_clk_lyt_siqad{}, params); + const auto result_lyt = generate_random_sidb_layout(sidb_defect_cell_clk_lyt_siqad{}, params); CHECK(result_lyt.num_cells() == 1); result_lyt.foreach_cell( @@ -580,7 +578,7 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran auto defect_layout = sidb_defect_cell_clk_lyt_siqad{}; defect_layout.assign_sidb_defect({2, 1, 1}, sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); - const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); CHECK(result_lyt.num_cells() == 0); CHECK(result_lyt.num_defects() == 1); @@ -601,7 +599,7 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran defect_layout.assign_sidb_defect({3, 1, 1}, sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); defect_layout.assign_sidb_defect({4, 1, 1}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); - const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); CHECK(result_lyt.num_cells() == 1); CHECK(result_lyt.num_defects() == 2); @@ -626,7 +624,7 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran defect_layout.assign_sidb_defect({7, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 2.6, 7}); defect_layout.assign_sidb_defect({2, 1, 0}, sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 4}); - const auto result_lyt = generate_random_sidb_layout(defect_layout, params); + const auto result_lyt = generate_random_sidb_layout(defect_layout, params); CHECK(result_lyt.num_cells() == 10); CHECK(result_lyt.num_defects() == 5); From e47e060ca70b68cebd4f95f43c5569b6a275c3ab Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 27 Sep 2023 17:44:13 +0200 Subject: [PATCH 017/191] :rocket: P&R and gate on the fly works. --- experiments/bestagon.json | 390 +++++++++ .../defect_aware_physical_design.cpp | 2 +- .../generate_defective_surface.py | 38 +- .../dynamic_gate_design.cpp | 65 +- ...inputsdbp_1i1o_diagonal.sqd => 1i1o_d.sqd} | 0 ...inputsdbp_1i1o_straight.sqd => 1i1o_s.sqd} | 0 ...eleton_hex_inputsdbp_1i2o.sqd => 1i2o.sqd} | 12 - ...eleton_hex_inputsdbp_2i1o.sqd => 2i1o.sqd} | 12 - ...eleton_hex_inputsdbp_2i2o.sqd => 2i2o.sqd} | 0 .../technology_mapping.hpp | 2 +- .../physical_design/apply_gate_library.hpp | 12 +- .../physical_design/design_sidb_gates.hpp | 25 +- .../algorithms/simulation/sidb/quickexact.hpp | 7 +- include/fiction/io/print_layout.hpp | 24 +- include/fiction/layouts/gate_level_layout.hpp | 27 +- include/fiction/technology/sidb_defects.hpp | 6 +- .../technology/sidb_dynamic_gate_library.hpp | 549 ++++++++++++- .../sidb_skeleton_bestagon_library.hpp | 774 ++++++++++++++++++ 18 files changed, 1859 insertions(+), 86 deletions(-) rename experiments/skeleton_bestagons_with_tags/{skeleton_hex_inputsdbp_1i1o_diagonal.sqd => 1i1o_d.sqd} (100%) rename experiments/skeleton_bestagons_with_tags/{skeleton_hex_inputsdbp_1i1o_straight.sqd => 1i1o_s.sqd} (100%) rename experiments/skeleton_bestagons_with_tags/{skeleton_hex_inputsdbp_1i2o.sqd => 1i2o.sqd} (93%) rename experiments/skeleton_bestagons_with_tags/{skeleton_hex_inputsdbp_2i1o.sqd => 2i1o.sqd} (93%) rename experiments/skeleton_bestagons_with_tags/{skeleton_hex_inputsdbp_2i2o.sqd => 2i2o.sqd} (100%) create mode 100644 include/fiction/technology/sidb_skeleton_bestagon_library.hpp diff --git a/experiments/bestagon.json b/experiments/bestagon.json index afcaa7d7d..c625e1658 100644 --- a/experiments/bestagon.json +++ b/experiments/bestagon.json @@ -421,5 +421,395 @@ } ], "version": "4926a76" + }, + { + "entries": [ + { + "SiDB dots": 196, + "benchmark": "fontes18/xor5Maj", + "critical path": 6, + "equivalent": true, + "gates": 4, + "initial depth": 12, + "initial nodes": 30, + "inputs": 5, + "layout area (in tiles)": 30, + "layout area in nm²": 12124.5696, + "layout height (in tiles)": 6, + "layout width (in tiles)": 5, + "optimized depth": 3, + "optimized nodes": 4, + "outputs": 1, + "runtime (in sec)": 0.054599833, + "throughput": 1, + "wires": 11 + } + ], + "version": "36639cd7" + }, + { + "entries": [ + { + "SiDB dots": 136, + "benchmark": "trindade16/mux21", + "critical path": 5, + "equivalent": true, + "gates": 3, + "initial depth": 2, + "initial nodes": 3, + "inputs": 3, + "layout area (in tiles)": 70, + "layout area in nm²": 28330.868736, + "layout height (in tiles)": 5, + "layout width (in tiles)": 14, + "optimized depth": 2, + "optimized nodes": 3, + "outputs": 1, + "runtime (in sec)": 1.402220665, + "throughput": 1, + "wires": 7 + }, + { + "SiDB dots": 52, + "benchmark": "trindade16/xor2", + "critical path": 3, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 36, + "layout area in nm²": 14524.858368000001, + "layout height (in tiles)": 3, + "layout width (in tiles)": 12, + "optimized depth": 1, + "optimized nodes": 1, + "outputs": 1, + "runtime (in sec)": 0.32591325, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 52, + "benchmark": "trindade16/xnor2", + "critical path": 3, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 36, + "layout area in nm²": 14524.858368000001, + "layout height (in tiles)": 3, + "layout width (in tiles)": 12, + "optimized depth": 1, + "optimized nodes": 1, + "outputs": 1, + "runtime (in sec)": 0.330557, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 92, + "benchmark": "trindade16/par_gen", + "critical path": 4, + "equivalent": true, + "gates": 2, + "initial depth": 4, + "initial nodes": 6, + "inputs": 3, + "layout area (in tiles)": 48, + "layout area in nm²": 19401.818112, + "layout height (in tiles)": 4, + "layout width (in tiles)": 12, + "optimized depth": 2, + "optimized nodes": 2, + "outputs": 1, + "runtime (in sec)": 0.491098289, + "throughput": 1, + "wires": 5 + }, + { + "SiDB dots": 380, + "benchmark": "trindade16/FA", + "critical path": 9, + "equivalent": true, + "gates": 5, + "initial depth": 3, + "initial nodes": 5, + "inputs": 3, + "layout area (in tiles)": 135, + "layout area in nm²": 54748.49587200001, + "layout height (in tiles)": 9, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 5, + "outputs": 2, + "runtime (in sec)": 12.750889498, + "throughput": 1, + "wires": 25 + }, + { + "SiDB dots": 208, + "benchmark": "trindade16/par_check", + "critical path": 6, + "equivalent": true, + "gates": 5, + "initial depth": 4, + "initial nodes": 9, + "inputs": 4, + "layout area (in tiles)": 90, + "layout area in nm²": 36454.8096, + "layout height (in tiles)": 6, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 5, + "outputs": 1, + "runtime (in sec)": 3.033809333, + "throughput": 1, + "wires": 10 + }, + { + "SiDB dots": 52, + "benchmark": "fontes18/xor", + "critical path": 3, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 36, + "layout area in nm²": 14524.858368000001, + "layout height (in tiles)": 3, + "layout width (in tiles)": 12, + "optimized depth": 1, + "optimized nodes": 1, + "outputs": 1, + "runtime (in sec)": 0.341874165, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 396, + "benchmark": "fontes18/1bitAdderAOIG", + "critical path": 9, + "equivalent": true, + "gates": 5, + "initial depth": 4, + "initial nodes": 7, + "inputs": 3, + "layout area (in tiles)": 135, + "layout area in nm²": 54748.49587200001, + "layout height (in tiles)": 9, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 5, + "outputs": 2, + "runtime (in sec)": 13.597326004, + "throughput": 1, + "wires": 27 + }, + { + "SiDB dots": 380, + "benchmark": "fontes18/t", + "critical path": 8, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 120, + "layout area in nm²": 48650.600448, + "layout height (in tiles)": 8, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 6, + "outputs": 2, + "runtime (in sec)": 5.860524459, + "throughput": 1, + "wires": 24 + }, + { + "SiDB dots": 388, + "benchmark": "fontes18/t_5", + "critical path": 8, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 120, + "layout area in nm²": 48650.600448, + "layout height (in tiles)": 8, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 6, + "outputs": 2, + "runtime (in sec)": 6.858638375, + "throughput": 1, + "wires": 25 + }, + { + "SiDB dots": 376, + "benchmark": "fontes18/c17", + "critical path": 8, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 120, + "layout area in nm²": 48650.600448, + "layout height (in tiles)": 8, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 6, + "outputs": 2, + "runtime (in sec)": 4.34392021, + "throughput": 1, + "wires": 23 + }, + { + "SiDB dots": 564, + "benchmark": "fontes18/majority", + "critical path": 11, + "equivalent": true, + "gates": 8, + "initial depth": 5, + "initial nodes": 8, + "inputs": 5, + "layout area (in tiles)": 176, + "layout area in nm²": 71412.20352000001, + "layout height (in tiles)": 11, + "layout width (in tiles)": 16, + "optimized depth": 5, + "optimized nodes": 8, + "outputs": 1, + "runtime (in sec)": 26.79160612, + "throughput": 1, + "wires": 38 + }, + { + "SiDB dots": 632, + "benchmark": "fontes18/majority_5_r1", + "critical path": 12, + "equivalent": true, + "gates": 9, + "initial depth": 4, + "initial nodes": 8, + "inputs": 5, + "layout area (in tiles)": 192, + "layout area in nm²": 77917.077504, + "layout height (in tiles)": 12, + "layout width (in tiles)": 16, + "optimized depth": 6, + "optimized nodes": 9, + "outputs": 1, + "runtime (in sec)": 31.680806616, + "throughput": 1, + "wires": 43 + }, + { + "SiDB dots": 612, + "benchmark": "fontes18/newtag", + "critical path": 10, + "equivalent": true, + "gates": 9, + "initial depth": 5, + "initial nodes": 9, + "inputs": 8, + "layout area (in tiles)": 180, + "layout area in nm²": 73029.206016, + "layout height (in tiles)": 10, + "layout width (in tiles)": 18, + "optimized depth": 6, + "optimized nodes": 9, + "outputs": 1, + "runtime (in sec)": 18.590638953, + "throughput": 1, + "wires": 40 + }, + { + "SiDB dots": 196, + "benchmark": "fontes18/xor5_r1", + "critical path": 6, + "equivalent": true, + "gates": 4, + "initial depth": 6, + "initial nodes": 12, + "inputs": 5, + "layout area (in tiles)": 90, + "layout area in nm²": 36454.8096, + "layout height (in tiles)": 6, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 4, + "outputs": 1, + "runtime (in sec)": 1.996412958, + "throughput": 1, + "wires": 11 + }, + { + "SiDB dots": 236, + "benchmark": "fontes18/1bitAdderMaj", + "critical path": 7, + "equivalent": true, + "gates": 4, + "initial depth": 9, + "initial nodes": 14, + "inputs": 3, + "layout area (in tiles)": 105, + "layout area in nm²": 42552.705024, + "layout height (in tiles)": 7, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 4, + "outputs": 1, + "runtime (in sec)": 4.64513558, + "throughput": 1, + "wires": 14 + }, + { + "SiDB dots": 1092, + "benchmark": "fontes18/cm82a_5", + "critical path": 13, + "equivalent": true, + "gates": 12, + "initial depth": 5, + "initial nodes": 20, + "inputs": 5, + "layout area (in tiles)": 234, + "layout area in nm²": 94985.69932800002, + "layout height (in tiles)": 13, + "layout width (in tiles)": 18, + "optimized depth": 5, + "optimized nodes": 12, + "outputs": 3, + "runtime (in sec)": 636.640190954, + "throughput": 1, + "wires": 78 + }, + { + "SiDB dots": 216, + "benchmark": "fontes18/xor5Maj", + "critical path": 6, + "equivalent": true, + "gates": 4, + "initial depth": 12, + "initial nodes": 30, + "inputs": 5, + "layout area (in tiles)": 90, + "layout area in nm²": 36454.8096, + "layout height (in tiles)": 6, + "layout width (in tiles)": 15, + "optimized depth": 3, + "optimized nodes": 4, + "outputs": 1, + "runtime (in sec)": 2.399298334, + "throughput": 1, + "wires": 13 + } + ], + "version": "cff1b1ac" } ] diff --git a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp index b04ea2413..e0e8b3437 100644 --- a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp +++ b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp @@ -118,7 +118,7 @@ int main() // NOLINT // read surface scan lattice data const auto surface_lattice = fiction::read_sidb_surface_defects( - "../../experiments/defect_aware_physical_design/py_test_surface.txt", "py_test_surface"); + "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); // fiction::read_sqd_layout(surface_lattice, surface_data_path); const auto lattice_tiling = gate_lyt{{11, 30}}; // our surface data is 12 x 31 Bestagon tiles diff --git a/experiments/defect_aware_physical_design/generate_defective_surface.py b/experiments/defect_aware_physical_design/generate_defective_surface.py index c1e67cdee..e1ad8343c 100644 --- a/experiments/defect_aware_physical_design/generate_defective_surface.py +++ b/experiments/defect_aware_physical_design/generate_defective_surface.py @@ -55,7 +55,7 @@ def add_defects(self, coverage=0.05): [4, 1, 2, 0.05], # single_dihydride [5, 4, 2, 0.05], # onebyone [6, 4, 4, 0.05], # threebyone - [7, 1, 2, 0.1], # siloxane + [7, 1, 2, 0.3], # siloxane [8, 1, 2, 0.1], # raised_si [9, 3, 2, 0.05], # etch pit [10, 1, 2, 0.05] # missing_dimer @@ -97,17 +97,10 @@ def add_defects(self, coverage=0.05): i = i - 1 pass - def draw_panels(self): # DB_panels,DB_pattern_extended, pattern): - # draws the DB_pattern_extended with rectangles to show each pannel - + def draw_panels(self): width_nm = self.a1 * self.surface_width height_nm = self.a2 * self.surface_height - # print(height_nm,width_nm) - # lattice_points = np.where(self.surface_lattice>=-1) - # DB_top_points = np.where(self.surface_lattice==0) - # DB_bottom_points = np.where(self.surface_lattice==1) - # print(lattice_points) - fig = plt.figure(figsize=((width_nm + 1) / 10, (height_nm + 1) / 10), dpi=100) + fig = plt.figure() ax = fig.add_subplot(1, 1, 1) plt.gca().invert_yaxis() @@ -136,19 +129,30 @@ def draw_panels(self): # DB_panels,DB_pattern_extended, pattern): plt.xticks([]) plt.yticks([]) plt.legend() - # print(self.DB_pattern_extended.shape) - plt.show() def save_to_file(self, filename='test.txt'): - np.savetxt(filename, self.surface_lattice) - print('file_saved') + with open(filename, 'w') as file: + for row in self.surface_lattice: + # Write an opening bracket + file.write('[') + + # Loop through the elements in the row and write them with commas and spaces + for i, element in enumerate(row): + file.write(str(element)) + + # If it's not the last element, write a comma and space + if i < len(row) - 1: + file.write(' ') + + # Write a closing bracket and a newline character for the next row + file.write(']\n') surface_width = 740 surface_height = 1090 -coverage = 0.005 +coverage = 0.1 surface = defect_surface(surface_width=surface_width, surface_height=surface_height) surface.add_defects(coverage=coverage) print(surface.surface_lattice) -# surface.draw_panels() -# surface.save_to_file('test.txt') +#surface.draw_panels() +surface.save_to_file('test.txt') diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index b2775595f..b75b2e96d 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -9,15 +9,19 @@ #include // technology mapping #include // layout conversion to cell-level #include // SMT-based physical design of FCN layouts +#include #include // critical path and throughput calculations +#include // reader for simulated SiDB surfaces #include // reader for SiQAD files -#include // writer for SiQAD files (physical simulation) -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations -#include // a dynamic SiDB gate library -#include // SiDB surface with support for atomic defects -#include // pre-defined types suitable for the FCN domain +#include // writer for SiQAD files (physical simulation) +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations +#include // a dynamic SiDB gate library +#include +#include // SiDB surface with support for atomic defects +#include +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -41,8 +45,9 @@ int main() // NOLINT using cell_lyt = fiction::sidb_cell_clk_lyt; static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - static const std::string surface_data_path = - fmt::format("{}/dynamic_gate_design/PATH-TO-SURFACE-DATA.sqd", EXPERIMENTS_PATH); + const auto surface_lattice = fiction::read_sidb_surface_defects( + "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); + // const auto surface_lattice = fiction::sidb_surface{}; experiments::experiment @@ -70,8 +75,16 @@ int main() // NOLINT const fiction::sidb_surface_params surface_params{ std::unordered_set{fiction::sidb_defect_type::DB}}; - fiction::sidb_surface surface_lattice{surface_params}; - fiction::read_sqd_layout(surface_lattice, surface_data_path); +// static const std::string surface_data_path = +// fmt::format("{}/defect_aware_physical_design/defects_full56_Oct.xml", EXPERIMENTS_PATH); +// fiction::sidb_surface surface_lattice{surface_params}; +// std::cout << surface_lattice.num_defects() << std::endl; +// fiction::read_sqd_layout(surface_lattice, surface_data_path); + const auto number_defects = surface_lattice.num_defects(); + std::cout << number_defects << std::endl; + + // fiction::sidb_surface surface_lattice{surface_params}; + // fiction::read_sqd_layout(surface_lattice, surface_data_path); // instantiate a complete XAG NPN database for node re-synthesis const mockturtle::xag_npn_resynthesis(lattice_tiling, surface_lattice); + // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); @@ -93,11 +111,16 @@ int main() // NOLINT exact_params.desynchronize = true; exact_params.timeout = 3'600'000; // 1h in ms fiction::exact_physical_design_stats exact_stats{}; + exact_params.black_list = black_list; + + fiction::orthogonal_physical_design_stats stats{}; + + constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & + ~fiction_experiments::two_bit_add_maj & ~fiction_experiments::b1_r2 & + ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl & ~fiction_experiments::half_adder; - static constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::b1_r2 & - ~fiction_experiments::clpl & ~fiction_experiments::two_bit_add_maj & - ~fiction_experiments::parity & ~fiction_experiments::iscas85 & - ~fiction_experiments::epfl; +// constexpr const uint64_t bench_select = fiction_experiments::t; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { @@ -121,6 +144,9 @@ int main() // NOLINT // perform layout generation with an SMT-based exact algorithm const auto gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); + // + // const auto gate_level_layout = fiction::orthogonal(mapped_network, + // fiction::orthogonal_physical_design_params{}, &stats); if (gate_level_layout.has_value()) { @@ -137,16 +163,19 @@ int main() // NOLINT // TODO this can be achieved by implementing an in-place version of apply_gate_library // apply gate library - const auto cell_level_layout = - fiction::apply_gate_library(*gate_level_layout); + const auto cell_level_layout = fiction::apply_gate_library( + *gate_level_layout, surface_lattice); // compute area fiction::area_stats area_stats{}; fiction::area_params area_ps{}; fiction::area(cell_level_layout, area_ps, &area_stats); + fiction::sidb_surface defect_surface{cell_level_layout}; + surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) + { defect_surface.assign_sidb_defect(defect.first, defect.second); }); // write a SiQAD simulation file - fiction::write_sqd_layout(cell_level_layout, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); + fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); // log results bestagon_exp( diff --git a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i1o_diagonal.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd similarity index 100% rename from experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i1o_diagonal.sqd rename to experiments/skeleton_bestagons_with_tags/1i1o_d.sqd diff --git a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i1o_straight.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd similarity index 100% rename from experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i1o_straight.sqd rename to experiments/skeleton_bestagons_with_tags/1i1o_s.sqd diff --git a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i2o.sqd b/experiments/skeleton_bestagons_with_tags/1i2o.sqd similarity index 93% rename from experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i2o.sqd rename to experiments/skeleton_bestagons_with_tags/1i2o.sqd index 7730a4afd..34731113f 100644 --- a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_1i2o.sqd +++ b/experiments/skeleton_bestagons_with_tags/1i2o.sqd @@ -169,18 +169,6 @@ #ffc8c8c8 - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - diff --git a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_2i1o.sqd b/experiments/skeleton_bestagons_with_tags/2i1o.sqd similarity index 93% rename from experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_2i1o.sqd rename to experiments/skeleton_bestagons_with_tags/2i1o.sqd index c5e13527c..1deeb0b1e 100644 --- a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_2i1o.sqd +++ b/experiments/skeleton_bestagons_with_tags/2i1o.sqd @@ -169,18 +169,6 @@ #ffc8c8c8 - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - 2 diff --git a/experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_2i2o.sqd b/experiments/skeleton_bestagons_with_tags/2i2o.sqd similarity index 100% rename from experiments/skeleton_bestagons_with_tags/skeleton_hex_inputsdbp_2i2o.sqd rename to experiments/skeleton_bestagons_with_tags/2i2o.sqd diff --git a/include/fiction/algorithms/network_transformation/technology_mapping.hpp b/include/fiction/algorithms/network_transformation/technology_mapping.hpp index e499b6262..a390f4f86 100644 --- a/include/fiction/algorithms/network_transformation/technology_mapping.hpp +++ b/include/fiction/algorithms/network_transformation/technology_mapping.hpp @@ -172,7 +172,7 @@ struct technology_mapping_params return params; } /** - * Auxiliary function to create technology mapping parameters for AND, OR, NAND, NOR, XOR, XNOR, IMPL, REPL, ANB, BNA, + * Auxiliary function to create technology mapping parameters for AND, OR, NAND, NOR, XOR, XNOR, LE, GE, LT, GT, * and NOT gates. * * @return Technology mapping parameters. diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index ed7266bae..79bce656d 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -35,11 +35,12 @@ template class apply_gate_library_impl { public: - explicit apply_gate_library_impl(const GateLyt& lyt) : + explicit apply_gate_library_impl(const GateLyt& lyt, const sidb_surface& defect_surface) : gate_lyt{lyt}, cell_lyt{aspect_ratio{((gate_lyt.x() + 1) * GateLibrary::gate_x_size()) - 1, ((gate_lyt.y() + 1) * GateLibrary::gate_y_size()) - 1, gate_lyt.z()}, - gate_lyt.get_clocking_scheme(), "", GateLibrary::gate_x_size(), GateLibrary::gate_y_size()} + gate_lyt.get_clocking_scheme(), "", GateLibrary::gate_x_size(), GateLibrary::gate_y_size()}, + sidb_surface{defect_surface} {} CellLyt run() @@ -60,7 +61,7 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t, sidb_surface), n); } #if (PROGRESS_BARS) // update progress @@ -85,6 +86,7 @@ class apply_gate_library_impl private: GateLyt gate_lyt; CellLyt cell_lyt; + sidb_surface sidb_surface; void assign_gate(const cell& c, const typename GateLibrary::fcn_gate& g, const mockturtle::node& n) @@ -133,7 +135,7 @@ class apply_gate_library_impl * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -CellLyt apply_gate_library(const GateLyt& lyt) +CellLyt apply_gate_library(const GateLyt& lyt, const sidb_surface &defect_surface) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -144,7 +146,7 @@ CellLyt apply_gate_library(const GateLyt& lyt) static_assert(std::is_same_v, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt}; + detail::apply_gate_library_impl p{lyt, defect_surface}; auto result = p.run(); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 19e9329f9..6beb0066f 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -185,12 +185,35 @@ class design_sidb_gates_impl { while (!gate_layout_is_found) { - const auto result_lyt = generate_random_sidb_layout(skeleton_layout, parameter); + auto result_lyt = generate_random_sidb_layout(skeleton_layout, parameter); + if constexpr (has_get_sidb_defect_v) + { + result_lyt.foreach_sidb_defect( + [&result_lyt](const auto& cd) + { + if (is_neutrally_charged_defect(result_lyt.get_sidb_defect(cd.first))) + { + result_lyt.assign_sidb_defect(cd.first, sidb_defect{sidb_defect_type::NONE}); + } + }); + } + const auto defects = result_lyt.num_defects(); if (const auto [status, sim_calls] = is_operational(result_lyt, truth_table, params_is_operational); status == operational_status::OPERATIONAL) { const std::lock_guard lock{mutex_to_protect_designed_gate_layouts}; + if constexpr (has_get_sidb_defect_v) + { + skeleton_layout.foreach_sidb_defect( + [this, &result_lyt](const auto& cd) + { + if (is_neutrally_charged_defect(skeleton_layout.get_sidb_defect(cd.first))) + { + result_lyt.assign_sidb_defect(cd.first, cd.second); + } + }); + } randomly_designed_gate_layouts.push_back(result_lyt); gate_layout_is_found = true; break; diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 7e4423ecb..e3cfc5373 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -119,8 +119,11 @@ class quickexact_impl { for (const auto& [cell, defect] : real_placed_defects) { - charge_lyt_with_assigned_dependent_cell.add_sidb_defect_to_potential_landscape(cell, - defect); + if (defect.charge != 0) + { + charge_lyt_with_assigned_dependent_cell.add_sidb_defect_to_potential_landscape(cell, + defect); + } } } diff --git a/include/fiction/io/print_layout.hpp b/include/fiction/io/print_layout.hpp index 7e9dfffb9..8f715ab92 100644 --- a/include/fiction/io/print_layout.hpp +++ b/include/fiction/io/print_layout.hpp @@ -389,12 +389,24 @@ void print_sidb_layout(std::ostream& os, const Lyt& lyt, const bool cs_color = t std::sort(defects.begin(), defects.end()); - min_nw = min_nw > defects.front() ? - defects.front() : - min_nw; // if a defect is more north-west than nw, this position is used as min - max_se = max_se < defects.back() ? - defects.back() : - max_se; // if a defect is more south-east than se, this position is used as max + if (min_nw.x > defects.front().x) + { + min_nw.x = defects.front().x; + } + else if (min_nw.y > defects.front().y) + { + min_nw.y = defects.front().y; + } + + if (max_se.x < defects.back().x) + { + max_se.x = defects.back().x; + } + else if (max_se.y < defects.back().y) + { + max_se.y = defects.back().y; + } + // if a defect is more south-east than se, this position is used as max } } diff --git a/include/fiction/layouts/gate_level_layout.hpp b/include/fiction/layouts/gate_level_layout.hpp index e6604c791..b7ddcd190 100644 --- a/include/fiction/layouts/gate_level_layout.hpp +++ b/include/fiction/layouts/gate_level_layout.hpp @@ -864,6 +864,26 @@ class gate_level_layout : public ClockedLayout { return strg->nodes[n].data[1].h1 == 10; } + + [[nodiscard]] bool is_lt(const node n) const noexcept + { + return strg->nodes[n].data[1].h1 == 11; + } + + [[nodiscard]] bool is_gt(const node n) const noexcept + { + return strg->nodes[n].data[1].h1 == 12; + } + + [[nodiscard]] bool is_ge(const node n) const noexcept + { + return strg->nodes[n].data[1].h1 == 13; + } + + [[nodiscard]] bool is_le(const node n) const noexcept + { + return strg->nodes[n].data[1].h1 == 14; + } /** * Returns whether `n` is a wire and has multiple outputs, thereby, acting as a fanout gate. Note that a fanout will * return `true` for both `is_wire` and `is_fanout`. @@ -1545,12 +1565,17 @@ class gate_level_layout : public ClockedLayout strg->data.fn_cache.insert(tt); }; - static constexpr const uint64_t lit_not = 0x1, lit_and = 0x8, lit_or = 0xe, lit_xor = 0x6, lit_maj = 0xe8; + static constexpr const uint64_t lit_not = 0x1, lit_and = 0x8, lit_or = 0xe, lit_xor = 0x6, lit_maj = 0xe8, + lit_lt = 0x2, lit_gt = 0x4, lit_ge = 0x13, lit_le = 0x11; create_and_cache(lit_not, 1); // since NOT is not normal, its complement, i.e., the identity, is stored create_and_cache(lit_and, 2); create_and_cache(lit_or, 2); create_and_cache(lit_xor, 2); + create_and_cache(lit_lt, 2); + create_and_cache(lit_gt, 2); + create_and_cache(lit_ge, 2); + create_and_cache(lit_le, 2); create_and_cache(lit_maj, 3); } diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 52ea6fbc9..32b80bdeb 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -150,12 +150,12 @@ struct sidb_defect * Horizontal distance to keep from charged SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING = 26u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING = 1u; /** * Vertical distance to keep from charged SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING = 13u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING = 1u; /** * Horizontal distance to keep from neutral SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. @@ -165,7 +165,7 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING = 1u; * Vertical distance to keep from neutral SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; +inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 1u; /** * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the * `NONE` defect type, `{0, 0}` is returned. diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index d40dfc118..0f5397eb4 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -5,9 +5,16 @@ #ifndef FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP #define FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP +#include "fiction/algorithms/path_finding/distance.hpp" +#include "fiction/algorithms/physical_design/design_sidb_gates.hpp" +#include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" +#include "fiction/technology/sidb_surface.hpp" #include "fiction/traits.hpp" +#include "fiction/utils/layout_utils.hpp" + +#include namespace fiction { @@ -17,23 +24,446 @@ class sidb_dynamic_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t) + template + [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, + const sidb_surface& sidb_surface) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); + static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); const auto p = determine_port_routing(lyt, t); - // TODO implement on-the-fly gate design here and return an fcn_gate object - return fcn_gate{}; + const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{15, 7, 0}, {25, 13, 0}}, + 4, + sidb_simulation_engine::QUICKEXACT}; + + auto absolut_cell = cell{t.x * 45, t.y * (60 * 3 / 4), t.z}; + auto absolut_cell_siqad = fiction::siqad::to_siqad_coord(absolut_cell); + + auto layout = sidb_defect_cell_clk_lyt_siqad{}; + auto update_layout = [&layout, &absolut_cell, &absolut_cell_siqad](const auto& cd) + { + if (euclidean_distance(CellLyt{}, cd.first, absolut_cell) < 30) + { + + auto defect_pos_siqad = fiction::siqad::to_siqad_coord(cd.first); + auto shifted_defect_cell = defect_pos_siqad - absolut_cell_siqad; + if (is_charged_defect(cd.second)) + { + if (cd.second.type == sidb_defect_type::DB) + { + layout.assign_sidb_defect(shifted_defect_cell, + sidb_defect{sidb_defect_type::DB, -1, 10.6, 5.9}); + } + else if (cd.second.type == sidb_defect_type::SI_VACANCY) + { + layout.assign_sidb_defect(shifted_defect_cell, + sidb_defect{sidb_defect_type::SI_VACANCY, 1, 9.7, 2.1}); + } + } + else + { + layout.assign_sidb_defect(shifted_defect_cell, cd.second); + } + } + }; + + std::string path = " "; + try + { + if constexpr (fiction::has_is_fanout_v) + { + if (lyt.is_fanout(n)) + { + if (lyt.fanout_size(n) == 2) + { + path = FANOUT_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + // erase defects + sidb_surface.foreach_sidb_defect(update_layout); + const auto found_gate_layouts = design_sidb_gates(layout, create_fan_out_tt(), params); + std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + } + if constexpr (fiction::has_is_buf_v) + { + if (lyt.is_buf(n)) + { + if (lyt.is_ground_layer(t)) + { + // crossing case + if (const auto at = lyt.above(t); (t != at) && lyt.is_wire_tile(at)) + { + // two possible options: actual crossover and (parallel) hourglass wire + const auto pa = determine_port_routing(lyt, at); + + path = CROSSING_MAP.at({p, pa}); + if (path == "2o2o_hour.sqd") + { + path = "2i2o.sqd"; + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" + "skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + const auto found_gate_layouts = + design_sidb_gates(layout, create_double_wire_tt(), params); + std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) + << std::endl; + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished hourglass" << std::endl; + return cell_list_to_gate(list); + } + else if (path == "2o2o_cx.sqd") + { + path = "2i2o.sqd"; + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" + "skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + const auto found_gate_layouts = + design_sidb_gates(layout, create_crossing_wire_tt(), params); + std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) + << std::endl; + fiction::write_sqd_layout( + found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + std::cout << "finished crossing" << std::endl; + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + return cell_list_to_gate(list); + } + } - // if the gate type is unknown, throw an exception - throw unsupported_gate_type_exception(t); + path = WIRE_MAP.at(p); + if (path == "empty") + { + return EMPTY_GATE; + } + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + return EMPTY_GATE; + } + } + if constexpr (fiction::has_is_inv_v) + { + if (lyt.is_inv(n)) + { + path = INVERTER_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (mockturtle::has_is_and_v) + { + if (lyt.is_and(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (mockturtle::has_is_or_v) + { + if (lyt.is_or(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_nand_v) + { + if (lyt.is_nand(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_nor_v) + { + if (lyt.is_nor(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (mockturtle::has_is_xor_v) + { + if (lyt.is_xor(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_xnor_v) + { + if (lyt.is_xnor(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_ge_v) + { + if (lyt.is_ge(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_le_v) + { + if (lyt.is_le(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_gt_v) + { + if (lyt.is_gt(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + if constexpr (fiction::has_is_lt_v) + { + if (lyt.is_lt(n)) + { + path = CONJUNCTION_MAP.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout( + "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + + path); + sidb_surface.foreach_sidb_defect(update_layout); + std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + fiction::write_sqd_layout(found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + std::cout << "finished" << std::endl; + return cell_list_to_gate(list); + } + } + } + catch (const std::out_of_range&) + { + throw unsupported_gate_orientation_exception(t, p); + } } private: + template + static std::array, 46> cell_level_layout_to_list(const Lyt& lyt) + { + uint64_t counter = 0; + std::array, 46> empty_array{}; + const auto all_cell = all_sidbs_in_spanned_area({-10, -1, 0}, {49, 21, 1}); + for (auto i = 0u; i < 46; i++) + { + std::array inner_array{}; + for (auto j = 0u; j < 60; j++) + { + if ((lyt.get_cell_type(all_cell[counter]) == Lyt::technology::cell_type::NORMAL) || + (lyt.get_cell_type(all_cell[counter]) == Lyt::technology::cell_type::OUTPUT)) + { + if (all_cell[counter].y != 19 || all_cell[counter].z != 0) + { + inner_array[j] = 'x'; + } + else + { + inner_array[j] = ' '; + } + } + else + { + inner_array[j] = ' '; + } + counter += 1; + } + empty_array[i] = inner_array; + } + return empty_array; + } + template [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept { @@ -87,7 +517,112 @@ class sidb_dynamic_gate_library : public fcn_gate_library, std::string>; + using double_port_gate_map = + phmap::flat_hash_map, port_list>, std::string>; + + /** + * Lookup table for wire mirroring. Maps ports to corresponding wires. + */ + static inline const port_gate_map WIRE_MAP = { + // primary inputs + {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, "1i1o_s.sqd"}, + {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, "1i1o_d.sqd"}, + // primary outputs + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, "1i1o_d.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, "1i1o_sm.sqd"}, + // straight wire + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i1o_s.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + "1i1o_sm.sqd"}, + // diagonal wire + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + "1i1o_d.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i1o_dm.sqd"}, + // empty gate (for crossing layer) + {{{}, {}}, "empty"}, + }; + /** + * Lookup table for wire crossings and hourglass wires. Maps ports to corresponding crossovers. + */ + static inline const double_port_gate_map CROSSING_MAP = { + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + {{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, + "2o2o_hour.sqd"}, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + {{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, + "2o2o_hour.sqd"}, + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + {{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, + "2o2o_cx.sqd"}, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + {{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, + "2o2o_cx.sqd"}, + }; + /** + * Lookup table for inverter mirroring. Maps ports to corresponding inverters. + */ + static inline const port_gate_map INVERTER_MAP = { + // straight inverters + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i1o_s.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + "1i1o_sm.sqd"}, + // diagonal inverters + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + "1i1o_d.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i1o_dm.sqd"}, + // without inputs + {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, "1i1o_s.sqd"}, + {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, "1i1o_d.sqd"}, + // without outputs + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, "1i1o_d.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, "1i1o_sm.sqd"}}; + /** + * Lookup table for conjunction mirroring. Maps ports to corresponding AND gates. + */ + static inline const port_gate_map CONJUNCTION_MAP = { + {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + "2i1o.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "2i1o_m.sqd"}}; + /** + * Lookup table for negated disjunction mirroring. Maps ports to corresponding NOR gates. + */ + + /** + * Lookup table for fanout mirroring. Maps ports to corresponding fan-out gates. + */ + static inline const port_gate_map FANOUT_MAP = { + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i2o.sqd"}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, + "1i2o_m.sqd"}}; }; } // namespace fiction diff --git a/include/fiction/technology/sidb_skeleton_bestagon_library.hpp b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp new file mode 100644 index 000000000..cf8b1bbb8 --- /dev/null +++ b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp @@ -0,0 +1,774 @@ +// +// Created by Jan Drewniok on 26.09.23. +// + +#ifndef FICTION_SIDB_SKELETON_BESTAGON_LIBRARY_HPP +#define FICTION_SIDB_SKELETON_BESTAGON_LIBRARY_HPP + +#include "fiction/technology/cell_ports.hpp" +#include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/fcn_gate_library.hpp" +#include "fiction/traits.hpp" +#include "fiction/utils/array_utils.hpp" +#include "fiction/utils/hash.hpp" +#include "fiction/utils/truth_table_utils.hpp" + +#include +#include + +#include + +namespace fiction +{ + +/** + * A gate library for the SiDB technology that is based on Y-shaped gates in hexagonal tiles. Y-shaped gates have been + * first introduced in \"Binary Atomic Silicon Logic\" by Taleana Huff, Hatem Labidi, Mohammad Rashidi, Lucian Livadaru, + * Thomas Dienel, Roshan Achal, Wyatt Vine, Jason Pitters, and Robert A. Wolkow in Nature Electronics 2018. The Bestagon + * library was later proposed in \"Hexagons are the Bestagons: Design Automation for Silicon Dangling Bond Logic\" by + * Marcel Walter, Samuel Sze Hang Ng, Konrad Walus, and Robert Wille in Design Automation Conference 2022. The goal of + * the Bestagon library is to be as close to physically realizable SiDB circuits as possible by taking fabrication + * limitations of, e.g., clocking electrodes into account while also relying on established gate shape. Thus, the + * hexagonal tiles in the Bestagon library are quite large with a lot of free space to avoid unwanted gate interactions. + * The Bestagon library is intended for hexagonal, pointy-top layouts that are clocked with a row-based clocking scheme, + * i.e., where the information flow direction is north to south. + */ +class sidb_skeleton_bestagon_library : public fcn_gate_library // width and height of a hexagon +{ + public: + explicit sidb_skeleton_bestagon_library() = delete; + + /** + * Returns a map of all gate functions supported by the library and their respectively possible implementations. + * + * This is an optional interface function that is required by some algorithms. + * + * @return Map of all gate functions supported by the library and their respective implementations as Bestagon + * gates. + */ + static gate_functions get_functional_implementations() noexcept + { + static const gate_functions implementations{ + {{create_id_tt(), + {STRAIGHT_WIRE, MIRRORED_STRAIGHT_WIRE, DIAGONAL_WIRE, MIRRORED_DIAGONAL_WIRE, FANOUT_1_2, MIRRORED_FANOUT_1_2, TWO_IN_TWO_OUT}}, + {create_not_tt(), + {STRAIGHT_WIRE, MIRRORED_STRAIGHT_WIRE, DIAGONAL_WIRE, MIRRORED_DIAGONAL_WIRE}}, + {create_and_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_or_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_nand_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_nor_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_xor_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_xnor_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_le_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_ge_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_lt_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}}, + {create_gt_tt(), {TWO_IN_ONE_OUT, MIRRORED_TWO_IN_ONE_OUT}} + }}; + return implementations; + } + /** + * Returns a map of all different gate implementations and their respective port information. + * + * This is an optional interface function that is required by some algorithms. + * + * @return Map of all different gate implementations and their respective port information. + */ + static gate_ports get_gate_ports() noexcept + { + static const gate_ports ports{{// wires + {STRAIGHT_WIRE, + {{{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}}, + {MIRRORED_STRAIGHT_WIRE, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}}}}, + {DIAGONAL_WIRE, + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}}}}, + {MIRRORED_DIAGONAL_WIRE, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}, + {TWO_IN_TWO_OUT, + {{{{port_direction(port_direction::cardinal::NORTH_WEST), + port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), + port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}, + {TWO_IN_ONE_OUT, + {{{{port_direction(port_direction::cardinal::NORTH_WEST), + port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}}}, + {MIRRORED_TWO_IN_ONE_OUT, + {{{{port_direction(port_direction::cardinal::NORTH_WEST), + port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}, + {FANOUT_1_2, + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), + port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}, + {MIRRORED_FANOUT_1_2, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), + port_direction(port_direction::cardinal::SOUTH_WEST)}}}}} + }}; + + return ports; + } + + private: + template + [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept + { + port_list p{}; + + // determine incoming connector ports + if (lyt.has_north_eastern_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_EAST); + } + if (lyt.has_north_western_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + } + + // determine outgoing connector ports + if (lyt.has_south_eastern_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + if (lyt.has_south_western_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_WEST); + } + + // gates without connector ports + + // 1-input functions + if (const auto n = lyt.get_node(t); lyt.is_pi(n) || lyt.is_po(n) || lyt.is_buf(n) || lyt.is_inv(n)) + { + if (lyt.has_no_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + } + if (lyt.has_no_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + } + else // 2-input functions + { + if (lyt.has_no_incoming_signal(t)) + { + p.inp.emplace(port_direction::cardinal::NORTH_WEST); + p.inp.emplace(port_direction::cardinal::NORTH_EAST); + } + if (lyt.has_no_outgoing_signal(t)) + { + p.out.emplace(port_direction::cardinal::SOUTH_EAST); + } + } + + return p; + } + + // clang-format off + + static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + // clang-format on + + using port_gate_map = phmap::flat_hash_map, fcn_gate>; + using double_port_gate_map = + phmap::flat_hash_map, port_list>, fcn_gate>; + /** + * Lookup table for wire mirroring. Maps ports to corresponding wires. + */ +// static inline const port_gate_map WIRE_MAP = { +// // primary inputs +// {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, STRAIGHT_WIRE}, +// {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, DIAGONAL_WIRE}, +// // primary outputs +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, DIAGONAL_WIRE}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, MIRRORED_STRAIGHT_WIRE}, +// // straight wire +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// STRAIGHT_WIRE}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// MIRRORED_STRAIGHT_WIRE}, +// // diagonal wire +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// DIAGONAL_WIRE}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_DIAGONAL_WIRE}, +// // empty gate (for crossing layer) +// {{{}, {}}, EMPTY_GATE}, +// }; +// /** +// * Lookup table for wire crossings and hourglass wires. Maps ports to corresponding crossovers. +// */ +//// static inline const double_port_gate_map CROSSING_MAP = { +//// {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, +//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +//// {{port_direction(port_direction::cardinal::NORTH_EAST)}, +//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, +//// HOURGLASS_DOUBLE_WIRE}, +//// {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, +//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +//// {{port_direction(port_direction::cardinal::NORTH_WEST)}, +//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, +//// HOURGLASS_DOUBLE_WIRE}, +//// {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, +//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +//// {{port_direction(port_direction::cardinal::NORTH_EAST)}, +//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, +//// CROSSING_WIRE}, +//// {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, +//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +//// {{port_direction(port_direction::cardinal::NORTH_WEST)}, +//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, +//// CROSSING_WIRE}, +//// }; +// /** +// * Lookup table for inverter mirroring. Maps ports to corresponding inverters. +// */ +// static inline const port_gate_map INVERTER_MAP = { +// // straight inverters +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// STRAIGHT_INVERTER}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// MIRRORED_STRAIGHT_INVERTER}, +// // diagonal inverters +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// DIAGONAL_INVERTER}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_DIAGONAL_INVERTER}, +// // without inputs +// {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, STRAIGHT_INVERTER}, +// {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, DIAGONAL_INVERTER}, +// // without outputs +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, DIAGONAL_INVERTER}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, MIRRORED_STRAIGHT_INVERTER}}; +// /** +// * Lookup table for conjunction mirroring. Maps ports to corresponding AND gates. +// */ +// static inline const port_gate_map CONJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// CONJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_CONJUNCTION}}; +// /** +// * Lookup table for disjunction mirroring. Maps ports to corresponding OR gates. +// */ +// static inline const port_gate_map DISJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// DISJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_DISJUNCTION}}; +// /** +// * Lookup table for negated conjunction mirroring. Maps ports to corresponding NAND gates. +// */ +// static inline const port_gate_map NEGATED_CONJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// NEGATED_CONJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_NEGATED_CONJUNCTION}}; +// /** +// * Lookup table for negated disjunction mirroring. Maps ports to corresponding NOR gates. +// */ +// static inline const port_gate_map NEGATED_DISJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// NEGATED_DISJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_NEGATED_DISJUNCTION}}; +// /** +// * Lookup table for exclusive disjunction mirroring. Maps ports to corresponding XOR gates. +// */ +// static inline const port_gate_map EXCLUSIVE_DISJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// EXCLUSIVE_DISJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_EXCLUSIVE_DISJUNCTION}}; +// /** +// * Lookup table for negated exclusive disjunction mirroring. Maps ports to corresponding XNOR gates. +// */ +// static inline const port_gate_map NEGATED_EXCLUSIVE_DISJUNCTION_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, +// NEGATED_EXCLUSIVE_DISJUNCTION}, +// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_NEGATED_EXCLUSIVE_DISJUNCTION}}; +// /** +// * Lookup table for fanout mirroring. Maps ports to corresponding fan-out gates. +// */ +// static inline const port_gate_map FANOUT_MAP = { +// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// FANOUT_1_2}, +// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, +// {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, +// MIRRORED_FANOUT_1_2}}; +}; + +} // namespace fiction + +#endif // FICTION_SIDB_SKELETON_BESTAGON_LIBRARY_HPP From 06c5657a21659eeff0a440cec1873c408bd82424 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 11:53:31 +0200 Subject: [PATCH 018/191] :art: shift skeletons to have same position as the bestagon gates --- .../skeleton_bestagons_with_tags/1i1o_d.sqd | 144 ------------ .../skeleton_bestagons_with_tags/1i1o_s.sqd | 144 ------------ .../skeleton_bestagons_with_tags/1i2o.sqd | 176 -------------- .../skeleton_bestagons_with_tags/2i1o.sqd | 182 --------------- .../skeleton_bestagons_with_tags/2i2o.sqd | 214 ------------------ 5 files changed, 860 deletions(-) delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_d.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_s.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i2o.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/2i1o.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/2i2o.sqd diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd deleted file mode 100644 index 85c1e66d0..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd +++ /dev/null @@ -1,144 +0,0 @@ - - - - - save - 0.3.3 - 2023-06-19 17:01:14 - - - - 0.0295301 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - - - - diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd deleted file mode 100644 index 57880001d..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd +++ /dev/null @@ -1,144 +0,0 @@ - - - - - save - 0.3.3 - 2023-06-19 16:11:47 - - - - 0.0289076 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - diff --git a/experiments/skeleton_bestagons_with_tags/1i2o.sqd b/experiments/skeleton_bestagons_with_tags/1i2o.sqd deleted file mode 100644 index 34731113f..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i2o.sqd +++ /dev/null @@ -1,176 +0,0 @@ - - - - - save - 0.3.3 - 2023-06-19 16:16:48 - - - - 0.0206949 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - diff --git a/experiments/skeleton_bestagons_with_tags/2i1o.sqd b/experiments/skeleton_bestagons_with_tags/2i1o.sqd deleted file mode 100644 index 1deeb0b1e..000000000 --- a/experiments/skeleton_bestagons_with_tags/2i1o.sqd +++ /dev/null @@ -1,182 +0,0 @@ - - - - - save - 0.3.3 - 2023-06-08 10:22:27 - - - - 0.0257652 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - - - - diff --git a/experiments/skeleton_bestagons_with_tags/2i2o.sqd b/experiments/skeleton_bestagons_with_tags/2i2o.sqd deleted file mode 100644 index f4c8e7ed6..000000000 --- a/experiments/skeleton_bestagons_with_tags/2i2o.sqd +++ /dev/null @@ -1,214 +0,0 @@ - - - - - save - 0.3.3 - 2023-06-05 13:30:47 - - - - 0.0240178 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - From 697f65bf7430a3016c78fb80149f0833c2822277 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 12:35:21 +0200 Subject: [PATCH 019/191] :art: add skeletons --- .../skeleton_bestagons_with_tags/1i1o_d.sqd | 148 ++++++++++++ .../skeleton_bestagons_with_tags/1i1o_dm.sqd | 144 ++++++++++++ .../skeleton_bestagons_with_tags/1i1o_s.sqd | 144 ++++++++++++ .../skeleton_bestagons_with_tags/1i1o_sm.sqd | 144 ++++++++++++ .../skeleton_bestagons_with_tags/1i2o.sqd | 176 ++++++++++++++ .../skeleton_bestagons_with_tags/1i2o_m.sqd | 176 ++++++++++++++ .../skeleton_bestagons_with_tags/2i1o.sqd | 182 +++++++++++++++ .../skeleton_bestagons_with_tags/2i1o_m.sqd | 182 +++++++++++++++ .../skeleton_bestagons_with_tags/2i2o.sqd | 214 ++++++++++++++++++ 9 files changed, 1510 insertions(+) create mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_d.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_s.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/1i2o.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/1i2o_m.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/2i1o.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/2i1o_m.sqd create mode 100644 experiments/skeleton_bestagons_with_tags/2i2o.sqd diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd new file mode 100644 index 000000000..3ccf13edf --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd @@ -0,0 +1,148 @@ + + + + + save + 0.3.3 + 2023-09-28 10:22:11 + + + + 0.0643349 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + input + + + #ffc8c8c8 + + + 2 + + input + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd new file mode 100644 index 000000000..fa2ac58eb --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd @@ -0,0 +1,144 @@ + + + + + save + 0.3.3 + 2023-09-28 10:22:59 + + + + 0.0845673 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd new file mode 100644 index 000000000..9397b3fb2 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd @@ -0,0 +1,144 @@ + + + + + save + 0.3.3 + 2023-09-28 10:23:25 + + + + 0.0611291 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd new file mode 100644 index 000000000..1e7c01d06 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd @@ -0,0 +1,144 @@ + + + + + save + 0.3.3 + 2023-09-28 10:24:01 + + + + 0.0721963 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i2o.sqd b/experiments/skeleton_bestagons_with_tags/1i2o.sqd new file mode 100644 index 000000000..17b55ba44 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i2o.sqd @@ -0,0 +1,176 @@ + + + + + save + 0.3.3 + 2023-09-28 10:24:27 + + + + 0.0767521 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd b/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd new file mode 100644 index 000000000..02dad04d4 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd @@ -0,0 +1,176 @@ + + + + + save + 0.3.3 + 2023-09-28 10:25:06 + + + + 0.0648703 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i1o.sqd b/experiments/skeleton_bestagons_with_tags/2i1o.sqd new file mode 100644 index 000000000..945eb5d0d --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/2i1o.sqd @@ -0,0 +1,182 @@ + + + + + save + 0.3.3 + 2023-09-28 10:25:42 + + + + 0.020305 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd b/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd new file mode 100644 index 000000000..5a1833317 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd @@ -0,0 +1,182 @@ + + + + + save + 0.3.3 + 2023-09-28 10:26:18 + + + + 0.0297765 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + + + + \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i2o.sqd b/experiments/skeleton_bestagons_with_tags/2i2o.sqd new file mode 100644 index 000000000..17f0e9876 --- /dev/null +++ b/experiments/skeleton_bestagons_with_tags/2i2o.sqd @@ -0,0 +1,214 @@ + + + + + save + 0.3.3 + 2023-09-28 10:21:38 + + + + 0.0836732 + + + + + + + + Lattice + Lattice + Design + 0 + 0 + 1 + 0 + + + + 2 + + + + + + Screenshot Overlay + Misc + Overlay + 0 + 0 + 1 + 0 + + + Surface + DB + Design + 0 + 0 + 1 + 0 + + + Metal + Electrode + Design + 1000 + 100 + 1 + 0 + + + + + + + + + + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + input + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + + #ffc8c8c8 + + + 2 + + output + + #ffc8c8c8 + + + + + + \ No newline at end of file From 3d6d8341ce612cdda95ec83669676832c8d2e817 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 12:36:06 +0200 Subject: [PATCH 020/191] :art: delete redundant code. --- .../sidb_skeleton_bestagon_library.hpp | 180 +----------------- 1 file changed, 10 insertions(+), 170 deletions(-) diff --git a/include/fiction/technology/sidb_skeleton_bestagon_library.hpp b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp index cf8b1bbb8..ba23d17dc 100644 --- a/include/fiction/technology/sidb_skeleton_bestagon_library.hpp +++ b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp @@ -22,18 +22,10 @@ namespace fiction { /** - * A gate library for the SiDB technology that is based on Y-shaped gates in hexagonal tiles. Y-shaped gates have been - * first introduced in \"Binary Atomic Silicon Logic\" by Taleana Huff, Hatem Labidi, Mohammad Rashidi, Lucian Livadaru, - * Thomas Dienel, Roshan Achal, Wyatt Vine, Jason Pitters, and Robert A. Wolkow in Nature Electronics 2018. The Bestagon - * library was later proposed in \"Hexagons are the Bestagons: Design Automation for Silicon Dangling Bond Logic\" by - * Marcel Walter, Samuel Sze Hang Ng, Konrad Walus, and Robert Wille in Design Automation Conference 2022. The goal of - * the Bestagon library is to be as close to physically realizable SiDB circuits as possible by taking fabrication - * limitations of, e.g., clocking electrodes into account while also relying on established gate shape. Thus, the - * hexagonal tiles in the Bestagon library are quite large with a lot of free space to avoid unwanted gate interactions. - * The Bestagon library is intended for hexagonal, pointy-top layouts that are clocked with a row-based clocking scheme, - * i.e., where the information flow direction is north to south. + * A SiDB skeleton gate library for all two input Boolean functions */ -class sidb_skeleton_bestagon_library : public fcn_gate_library // width and height of a hexagon +class sidb_skeleton_bestagon_library + : public fcn_gate_library // width and height of a hexagon { public: explicit sidb_skeleton_bestagon_library() = delete; @@ -44,15 +36,15 @@ class sidb_skeleton_bestagon_library : public fcn_gate_library get_gate_ports() noexcept { - static const gate_ports ports{{// wires - {STRAIGHT_WIRE, + static const gate_ports ports{{{STRAIGHT_WIRE, {{{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}}}}}, @@ -111,8 +101,7 @@ class sidb_skeleton_bestagon_library : public fcn_gate_library, fcn_gate>; - using double_port_gate_map = - phmap::flat_hash_map, port_list>, fcn_gate>; - /** - * Lookup table for wire mirroring. Maps ports to corresponding wires. - */ -// static inline const port_gate_map WIRE_MAP = { -// // primary inputs -// {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, STRAIGHT_WIRE}, -// {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, DIAGONAL_WIRE}, -// // primary outputs -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, DIAGONAL_WIRE}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, MIRRORED_STRAIGHT_WIRE}, -// // straight wire -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// STRAIGHT_WIRE}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// MIRRORED_STRAIGHT_WIRE}, -// // diagonal wire -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// DIAGONAL_WIRE}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_DIAGONAL_WIRE}, -// // empty gate (for crossing layer) -// {{{}, {}}, EMPTY_GATE}, -// }; -// /** -// * Lookup table for wire crossings and hourglass wires. Maps ports to corresponding crossovers. -// */ -//// static inline const double_port_gate_map CROSSING_MAP = { -//// {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, -//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -//// {{port_direction(port_direction::cardinal::NORTH_EAST)}, -//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, -//// HOURGLASS_DOUBLE_WIRE}, -//// {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, -//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -//// {{port_direction(port_direction::cardinal::NORTH_WEST)}, -//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, -//// HOURGLASS_DOUBLE_WIRE}, -//// {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, -//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -//// {{port_direction(port_direction::cardinal::NORTH_EAST)}, -//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, -//// CROSSING_WIRE}, -//// {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, -//// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -//// {{port_direction(port_direction::cardinal::NORTH_WEST)}, -//// {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, -//// CROSSING_WIRE}, -//// }; -// /** -// * Lookup table for inverter mirroring. Maps ports to corresponding inverters. -// */ -// static inline const port_gate_map INVERTER_MAP = { -// // straight inverters -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// STRAIGHT_INVERTER}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// MIRRORED_STRAIGHT_INVERTER}, -// // diagonal inverters -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// DIAGONAL_INVERTER}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_DIAGONAL_INVERTER}, -// // without inputs -// {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, STRAIGHT_INVERTER}, -// {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, DIAGONAL_INVERTER}, -// // without outputs -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, DIAGONAL_INVERTER}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, MIRRORED_STRAIGHT_INVERTER}}; -// /** -// * Lookup table for conjunction mirroring. Maps ports to corresponding AND gates. -// */ -// static inline const port_gate_map CONJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// CONJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_CONJUNCTION}}; -// /** -// * Lookup table for disjunction mirroring. Maps ports to corresponding OR gates. -// */ -// static inline const port_gate_map DISJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// DISJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_DISJUNCTION}}; -// /** -// * Lookup table for negated conjunction mirroring. Maps ports to corresponding NAND gates. -// */ -// static inline const port_gate_map NEGATED_CONJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// NEGATED_CONJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_NEGATED_CONJUNCTION}}; -// /** -// * Lookup table for negated disjunction mirroring. Maps ports to corresponding NOR gates. -// */ -// static inline const port_gate_map NEGATED_DISJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// NEGATED_DISJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_NEGATED_DISJUNCTION}}; -// /** -// * Lookup table for exclusive disjunction mirroring. Maps ports to corresponding XOR gates. -// */ -// static inline const port_gate_map EXCLUSIVE_DISJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// EXCLUSIVE_DISJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_EXCLUSIVE_DISJUNCTION}}; -// /** -// * Lookup table for negated exclusive disjunction mirroring. Maps ports to corresponding XNOR gates. -// */ -// static inline const port_gate_map NEGATED_EXCLUSIVE_DISJUNCTION_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST)}}, -// NEGATED_EXCLUSIVE_DISJUNCTION}, -// {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_NEGATED_EXCLUSIVE_DISJUNCTION}}; -// /** -// * Lookup table for fanout mirroring. Maps ports to corresponding fan-out gates. -// */ -// static inline const port_gate_map FANOUT_MAP = { -// {{{port_direction(port_direction::cardinal::NORTH_WEST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// FANOUT_1_2}, -// {{{port_direction(port_direction::cardinal::NORTH_EAST)}, -// {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, -// MIRRORED_FANOUT_1_2}}; }; } // namespace fiction From 20bdee556a84d42223ce329ce08fd54f6b5065c5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 15:16:06 +0200 Subject: [PATCH 021/191] :art: choose correct order --- include/fiction/layouts/gate_level_layout.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/layouts/gate_level_layout.hpp b/include/fiction/layouts/gate_level_layout.hpp index b7ddcd190..23e6e8fbc 100644 --- a/include/fiction/layouts/gate_level_layout.hpp +++ b/include/fiction/layouts/gate_level_layout.hpp @@ -1572,11 +1572,11 @@ class gate_level_layout : public ClockedLayout create_and_cache(lit_and, 2); create_and_cache(lit_or, 2); create_and_cache(lit_xor, 2); + create_and_cache(lit_maj, 3); create_and_cache(lit_lt, 2); create_and_cache(lit_gt, 2); create_and_cache(lit_ge, 2); create_and_cache(lit_le, 2); - create_and_cache(lit_maj, 3); } void assign_node(const tile& t, const node n) From d22abafda408b38682685b699fdbff9a2f1ca852 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 15:16:29 +0200 Subject: [PATCH 022/191] :art: add mode to use for gate design --- include/fiction/technology/sidb_defects.hpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 32b80bdeb..9cfb4c04f 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -150,12 +150,12 @@ struct sidb_defect * Horizontal distance to keep from charged SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING = 1u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING = 26u; /** * Vertical distance to keep from charged SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING = 1u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING = 13u; /** * Horizontal distance to keep from neutral SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. @@ -165,18 +165,25 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING = 1u; * Vertical distance to keep from neutral SiDB defects. The value is to be understood as the number of DB positions * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 1u; +inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; /** * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the * `NONE` defect type, `{0, 0}` is returned. * * @param defect Defect type to evaluate. + * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, + * `false`otherwise. * @return Number of horizontal and vertical SiDBs that are affected by the given defect type. */ -[[nodiscard]] static constexpr std::pair defect_extent(const sidb_defect& defect) noexcept +[[nodiscard]] static constexpr std::pair +defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false) noexcept { if (is_charged_defect(defect)) { + if (incorporate_defect_into_gate_design) + { + return {SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING, SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING}; + } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } if (is_neutral_defect(defect)) From f430f81802e78aa45d3b3bc0f3fb3d5b4709f5d7 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 15:39:41 +0200 Subject: [PATCH 023/191] :art: add check to ensure that placed SiDBs have the specified distance to neutral defects. --- .../sidb/random_sidb_layout_generator.hpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index 427f0a7d0..128782a4e 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -102,6 +102,13 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s 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"); + std::unordered_set sidbs_affected_by_defects = {}; + + if constexpr (has_get_sidb_defect_v) + { + sidbs_affected_by_defects = lyt_skeleton.all_affected_sidbs(true); + } + const uint64_t number_of_sidbs_of_final_layout = lyt_skeleton.num_cells() + params.number_of_sidbs; Lyt lyt{lyt_skeleton.clone()}; @@ -113,8 +120,8 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s { // random coordinate within given area const auto random_coord = random_coordinate(params.coordinate_pair.first, params.coordinate_pair.second); - - bool constraint_violation_positive_sidbs = false; + bool next_to_neutral_defect = false; + bool constraint_violation_positive_sidbs = false; if (params.positive_sidbs == generate_random_sidb_layout_params::positive_charges::FORBIDDEN) { @@ -130,6 +137,11 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s }); } + if (sidbs_affected_by_defects.count(random_coord) > 0) + { + next_to_neutral_defect = true; + } + bool random_cell_is_identical_wih_defect = false; // check if a defect does not yet occupy random coordinate. if constexpr (has_get_sidb_defect_v) @@ -139,7 +151,7 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s // if the constraints that no positive SiDBs occur and the cell is not yet occupied by a defect are satisfied, // the SiDB is added to the layout - if (!constraint_violation_positive_sidbs && !random_cell_is_identical_wih_defect) + if (!constraint_violation_positive_sidbs && !random_cell_is_identical_wih_defect && !next_to_neutral_defect) { lyt.assign_cell_type(random_coord, technology::cell_type::NORMAL); } From df9471306b03c70bfe96ab9e2a14e7e9531c6559 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 29 Sep 2023 16:21:43 +0200 Subject: [PATCH 024/191] :art: code cleanup --- .../dynamic_gate_design.cpp | 52 ++- .../physical_design/apply_gate_library.hpp | 103 +++++- .../physical_design/design_sidb_gates.hpp | 1 - .../technology/sidb_dynamic_gate_library.hpp | 312 +++++++----------- include/fiction/technology/sidb_surface.hpp | 15 +- .../technology/sidb_surface_analysis.hpp | 14 +- test/io/write_sqd_sim_result.cpp | 4 +- 7 files changed, 265 insertions(+), 236 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index b75b2e96d..eea066ee2 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -44,10 +44,12 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt; - static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - const auto surface_lattice = fiction::read_sidb_surface_defects( - "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); - // const auto surface_lattice = fiction::sidb_surface{}; + static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); +// const auto surface_lattice = fiction::read_sidb_surface_defects( +// "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); +// const auto lattice_tiling = gate_lyt{{11, 30}}; + + // const auto surface_lattice = fiction::sidb_surface{}; experiments::experiment @@ -75,13 +77,14 @@ int main() // NOLINT const fiction::sidb_surface_params surface_params{ std::unordered_set{fiction::sidb_defect_type::DB}}; -// static const std::string surface_data_path = -// fmt::format("{}/defect_aware_physical_design/defects_full56_Oct.xml", EXPERIMENTS_PATH); -// fiction::sidb_surface surface_lattice{surface_params}; -// std::cout << surface_lattice.num_defects() << std::endl; -// fiction::read_sqd_layout(surface_lattice, surface_data_path); - const auto number_defects = surface_lattice.num_defects(); - std::cout << number_defects << std::endl; + static const std::string surface_data_path = + fmt::format("{}/defect_aware_physical_design/defects_full70.xml", EXPERIMENTS_PATH); + fiction::sidb_surface surface_lattice{surface_params}; + std::cout << surface_lattice.num_defects() << std::endl; + fiction::read_sqd_layout(surface_lattice, surface_data_path); + const auto number_defects = surface_lattice.num_defects(); + std::cout << number_defects << std::endl; + const auto lattice_tiling = gate_lyt{{11, 17}}; // fiction::sidb_surface surface_lattice{surface_params}; // fiction::read_sqd_layout(surface_lattice, surface_data_path); @@ -98,8 +101,6 @@ int main() // NOLINT const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); - const auto lattice_tiling = gate_lyt{{12, 17}}; - const auto black_list = fiction::sidb_surface_analysis(lattice_tiling, surface_lattice); @@ -113,14 +114,12 @@ int main() // NOLINT fiction::exact_physical_design_stats exact_stats{}; exact_params.black_list = black_list; - fiction::orthogonal_physical_design_stats stats{}; - - constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & - ~fiction_experiments::two_bit_add_maj & ~fiction_experiments::b1_r2 & - ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & - ~fiction_experiments::epfl & ~fiction_experiments::half_adder; - -// constexpr const uint64_t bench_select = fiction_experiments::t; +// constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & +// ~fiction_experiments::two_bit_add_maj & ~fiction_experiments::b1_r2 & +// ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & +// ~fiction_experiments::epfl & ~fiction_experiments::half_adder; +// + constexpr const uint64_t bench_select = fiction_experiments::t; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { @@ -144,9 +143,6 @@ int main() // NOLINT // perform layout generation with an SMT-based exact algorithm const auto gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); - // - // const auto gate_level_layout = fiction::orthogonal(mapped_network, - // fiction::orthogonal_physical_design_params{}, &stats); if (gate_level_layout.has_value()) { @@ -159,12 +155,10 @@ int main() // NOLINT fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); - // TODO incorporate surface_lattice into apply_gate_library - // TODO this can be achieved by implementing an in-place version of apply_gate_library - // apply gate library - const auto cell_level_layout = fiction::apply_gate_library( - *gate_level_layout, surface_lattice); + const auto cell_level_layout = + fiction::apply_gate_library_dynamic_gates( + *gate_level_layout, surface_lattice); // compute area fiction::area_stats area_stats{}; diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 79bce656d..58a4cd431 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -35,14 +35,72 @@ template class apply_gate_library_impl { public: - explicit apply_gate_library_impl(const GateLyt& lyt, const sidb_surface& defect_surface) : + explicit apply_gate_library_impl(const GateLyt& lyt) : gate_lyt{lyt}, cell_lyt{aspect_ratio{((gate_lyt.x() + 1) * GateLibrary::gate_x_size()) - 1, ((gate_lyt.y() + 1) * GateLibrary::gate_y_size()) - 1, gate_lyt.z()}, - gate_lyt.get_clocking_scheme(), "", GateLibrary::gate_x_size(), GateLibrary::gate_y_size()}, - sidb_surface{defect_surface} + gate_lyt.get_clocking_scheme(), "", GateLibrary::gate_x_size(), GateLibrary::gate_y_size()} {} + /** + * This function dynamically designs gates based on the provided atomic defects and gate types defined in `lyt`. + * It creates a cell-level layout by adapting a gate-level layout on-the-fly to implement the gate types using + * building blocks from the `GateLibrary`. Atomic defects are incorporated into the gate designs during this + * process. + * + * @param defect_surface Defect surface with atomic defects. + * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. + */ + CellLyt run_dynamic_gates(const sidb_surface& defect_surface) + { +#if (PROGRESS_BARS) + // initialize a progress bar + mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; +#endif + gate_lyt.foreach_node( + [&, this](const auto& n, [[maybe_unused]] auto i) + { + if (!gate_lyt.is_constant(n)) + { + const auto t = gate_lyt.get_tile(n); + + // retrieve the top-leftmost cell in tile t + const auto c = + relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); + + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t, defect_surface), n); + } +#if (PROGRESS_BARS) + // update progress + bar(i); +#endif + }); + + // perform post-layout optimization if necessary + if constexpr (has_post_layout_optimization_v) + { + GateLibrary::post_layout_optimization(cell_lyt); + } + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) + { + cell_lyt.set_layout_name(gate_lyt.get_layout_name()); + } + + return cell_lyt; + } + + /** + * Run the cell layout generation process. + * + * This function performs the cell layout generation process based on the gate library and the gate-level layout + * information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the gate-level layout and + * assigns gates to cells based on their corresponding positions and types. Optionally, it performs post-layout + * optimization and sets the layout name if certain conditions are met. + * + * @return A `CellLyt` object representing the generated cell layout. + */ CellLyt run() { #if (PROGRESS_BARS) @@ -61,7 +119,7 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t, sidb_surface), n); + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); } #if (PROGRESS_BARS) // update progress @@ -86,7 +144,6 @@ class apply_gate_library_impl private: GateLyt gate_lyt; CellLyt cell_lyt; - sidb_surface sidb_surface; void assign_gate(const cell& c, const typename GateLibrary::fcn_gate& g, const mockturtle::node& n) @@ -135,7 +192,7 @@ class apply_gate_library_impl * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -CellLyt apply_gate_library(const GateLyt& lyt, const sidb_surface &defect_surface) +CellLyt apply_gate_library(const GateLyt& lyt) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -146,12 +203,44 @@ CellLyt apply_gate_library(const GateLyt& lyt, const sidb_surface &defe static_assert(std::is_same_v, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt, defect_surface}; + detail::apply_gate_library_impl p{lyt}; auto result = p.run(); return result; } +/** + * Applies a dynamic gate library (i.e., gate are designed on the fly by respecting atomic defects) to a given + * gate-level layout and, thereby, creates and returns a cell-level layout. + * + * May pass through, and thereby throw, an `unsupported_gate_type_exception` or an + * `unsupported_gate_orientation_exception`. + * + * @tparam CellLyt Type of the returned cell-level layout. + * @tparam GateLibrary Type of the gate library to apply. + * @tparam GateLyt Type of the gate-level layout to apply the library to. + * @param lyt The gate-level layout. + * @param defect_surface Defect surface with all atomic defects. + * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. + */ +template +CellLyt apply_gate_library_dynamic_gates(const GateLyt& lyt, const sidb_surface& defect_surface) +{ + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(mockturtle::has_is_constant_v, "GateLyt does not implement the is_constant function"); + static_assert(mockturtle::has_foreach_node_v, "GateLyt does not implement the foreach_node function"); + + static_assert(std::is_same_v, technology>, + "CellLyt and GateLibrary must implement the same technology"); + + detail::apply_gate_library_impl p{lyt}; + + auto result = p.run_dynamic_gates(defect_surface); + + return result; +} } // namespace fiction diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 6beb0066f..e59616706 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -197,7 +197,6 @@ class design_sidb_gates_impl } }); } - const auto defects = result_lyt.num_defects(); if (const auto [status, sim_calls] = is_operational(result_lyt, truth_table, params_is_operational); status == operational_status::OPERATIONAL) diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 0f5397eb4..9f8d763cc 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -18,6 +18,17 @@ namespace fiction { +/** + * This struct stores the parameter to design gates on the fly. + */ +struct sidb_dynamic_gate_library_params +{ + design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{25, 8, 0}, {35, 14, 0}}, + 4, + sidb_simulation_engine::QUICKEXACT}; +}; class sidb_dynamic_gate_library : public fcn_gate_library // width and height of a hexagon { @@ -26,7 +37,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, - const sidb_surface& sidb_surface) + const sidb_surface& sidb_surface, + const sidb_dynamic_gate_library_params parameter = {}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); @@ -35,23 +47,23 @@ class sidb_dynamic_gate_library : public fcn_gate_library{t.x * 45, t.y * (60 * 3 / 4), t.z}; - auto absolut_cell_siqad = fiction::siqad::to_siqad_coord(absolut_cell); + // center cell of the bestagon tile + auto center_cell = relative_to_absolute_cell_position( + lyt, t, cell{gate_x_size() / 2, gate_y_size() / 2}); + // center cell of the current tile + auto absolute_cell = relative_to_absolute_cell_position( + lyt, t, cell{0, 0}); + auto absolute_cell_siqad = fiction::siqad::to_siqad_coord(absolute_cell); + auto center_cell_siqad = fiction::siqad::to_siqad_coord(center_cell); auto layout = sidb_defect_cell_clk_lyt_siqad{}; - auto update_layout = [&layout, &absolut_cell, &absolut_cell_siqad](const auto& cd) + auto update_layout = [&layout, ¢er_cell, ¢er_cell_siqad, &absolute_cell_siqad](const auto& cd) { - if (euclidean_distance(CellLyt{}, cd.first, absolut_cell) < 30) + // all defects (charged) in a distance of 60 from the center are taken into account. + if (euclidean_distance(CellLyt{}, cd.first, center_cell) < 60) { - auto defect_pos_siqad = fiction::siqad::to_siqad_coord(cd.first); - auto shifted_defect_cell = defect_pos_siqad - absolut_cell_siqad; + auto shifted_defect_cell = defect_pos_siqad - absolute_cell_siqad; if (is_charged_defect(cd.second)) { if (cd.second.type == sidb_defect_type::DB) @@ -72,7 +84,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library) @@ -81,14 +94,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + ONE_IN_TWO_OUT.at(p)); // erase defects sidb_surface.foreach_sidb_defect(update_layout); - const auto found_gate_layouts = design_sidb_gates(layout, create_fan_out_tt(), params); + const auto found_gate_layouts = + design_sidb_gates(layout, create_fan_out_tt(), parameter.params); std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", @@ -113,40 +123,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" - "skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + "2i2o.sqd"); sidb_surface.foreach_sidb_defect(update_layout); const auto found_gate_layouts = - design_sidb_gates(layout, create_double_wire_tt(), params); - std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) - << std::endl; - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished hourglass" << std::endl; - return cell_list_to_gate(list); - } - else if (path == "2o2o_cx.sqd") - { - path = "2i2o.sqd"; - std::cout << path << std::endl; - layout = read_sqd_layout( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" - "skeleton_bestagons_with_tags/" + - path); - sidb_surface.foreach_sidb_defect(update_layout); - const auto found_gate_layouts = - design_sidb_gates(layout, create_crossing_wire_tt(), params); + design_sidb_gates(layout, create_double_wire_tt(), parameter.params); std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; fiction::write_sqd_layout( @@ -155,24 +138,37 @@ class sidb_dynamic_gate_library : public fcn_gate_library(list); } + + layout = read_sqd_layout(skeleton_path + "2i2o.sqd"); + sidb_surface.foreach_sidb_defect(update_layout); + const auto found_gate_layouts = + design_sidb_gates(layout, create_crossing_wire_tt(), parameter.params); + std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; + fiction::write_sqd_layout( + found_gate_layouts[0], + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + std::cout << "finished crossing" << std::endl; + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + return cell_list_to_gate(list); } - path = WIRE_MAP.at(p); + auto path = ONE_INPUT_ONE_OUTPUT.at(p); if (path == "empty") { return EMPTY_GATE; } std::cout << path << std::endl; - layout = read_sqd_layout( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", @@ -189,20 +185,17 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = + read_sqd_layout(skeleton_path + ONE_INPUT_ONE_OUTPUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -211,20 +204,16 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + TWO_IN_ONE_OUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -233,20 +222,16 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + TWO_IN_ONE_OUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -255,14 +240,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + TWO_IN_ONE_OUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" @@ -277,20 +258,16 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + TWO_IN_ONE_OUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -299,20 +276,16 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + TWO_IN_ONE_OUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -321,14 +294,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -338,20 +309,18 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -360,20 +329,18 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" "experiments/defect_aware_physical_design/single_gates", n)); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -382,14 +349,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" @@ -404,14 +369,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/skeleton_bestagons_with_tags/" + - path); + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, params); + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", "/Users/jandrewniok/CLionProjects/fiction_fork/" @@ -430,40 +393,47 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static std::array, 46> cell_level_layout_to_list(const Lyt& lyt) + static std::array, gate_y_size()> cell_level_layout_to_list(const Lyt& lyt) { - uint64_t counter = 0; - std::array, 46> empty_array{}; - const auto all_cell = all_sidbs_in_spanned_area({-10, -1, 0}, {49, 21, 1}); - for (auto i = 0u; i < 46; i++) + + std::array, gate_y_size()> result{}; + const auto all_cell = + all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); + uint64_t counter = 0; + + for (auto& row : result) { - std::array inner_array{}; - for (auto j = 0u; j < 60; j++) + for (auto& cell : row) { - if ((lyt.get_cell_type(all_cell[counter]) == Lyt::technology::cell_type::NORMAL) || - (lyt.get_cell_type(all_cell[counter]) == Lyt::technology::cell_type::OUTPUT)) - { - if (all_cell[counter].y != 19 || all_cell[counter].z != 0) - { - inner_array[j] = 'x'; - } - else - { - inner_array[j] = ' '; - } - } - else - { - inner_array[j] = ' '; - } - counter += 1; + const auto cell_type = lyt.get_cell_type(all_cell[counter]); + cell = (cell_type == Lyt::technology::cell_type::NORMAL || + cell_type == Lyt::technology::cell_type::OUTPUT) ? + (all_cell[counter].y != 20 || all_cell[counter].z != 0) ? 'x' : ' ' : + ' '; + counter++; } - empty_array[i] = inner_array; } - return empty_array; + + return result; } + /** + * This function determines the port routing for a specific tile within a layout represented by the object `lyt` of + * type `Lyt`. It examines the tile's characteristics and connectivity to determine the appropriate incoming and + * outgoing connector ports and populates them in a `port_list` object. + * + * @param lyt A reference to an object of type `Lyt` representing the layout. + * @param t The tile for which port routing is being determined. + * @return A `port_list` object containing the determined port directions for incoming and outgoing signals. + */ template [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept { @@ -524,9 +494,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library, port_list>, std::string>; /** - * Lookup table for wire mirroring. Maps ports to corresponding wires. + * Lookup table for one input Boolean functions. */ - static inline const port_gate_map WIRE_MAP = { + static inline const port_gate_map ONE_INPUT_ONE_OUTPUT = { // primary inputs {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, "1i1o_s.sqd"}, {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, "1i1o_d.sqd"}, @@ -551,7 +521,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library : public Lyt * If the given coordinate is defect-free, the empty set is returned. * * @param c Coordinate whose defect extent is to be determined. + * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, + * `false`otherwise. * @return All SiDB positions affected by the defect at coordinate c. */ [[nodiscard]] std::unordered_set - affected_sidbs(const typename Lyt::coordinate& c) const noexcept + affected_sidbs(const typename Lyt::coordinate& c, const bool incorporate_defect_into_gate_design = false) const noexcept { std::unordered_set influenced_sidbs{}; if (const auto d = get_sidb_defect(c); d.type != sidb_defect_type::NONE) { - const auto [horizontal_extent, vertical_extent] = defect_extent(d); + const auto [horizontal_extent, vertical_extent] = defect_extent(d, incorporate_defect_into_gate_design); for (auto y = static_cast(c.y - vertical_extent); y <= static_cast(c.y + vertical_extent); ++y) @@ -211,14 +213,17 @@ class sidb_surface : public Lyt * * If the given surface is defect-free, the empty set is returned. * + * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, + * `false`otherwise. * @return All SiDB positions affected by any defect on the surface. */ - [[nodiscard]] std::unordered_set all_affected_sidbs() const noexcept + [[nodiscard]] std::unordered_set + all_affected_sidbs(const bool incorporate_defect_into_gate_design = false) const noexcept { std::unordered_set influenced_sidbs{}; - foreach_sidb_defect([&influenced_sidbs, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first)); }); + foreach_sidb_defect([&influenced_sidbs, &incorporate_defect_into_gate_design, this](const auto& it) + { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design)); }); return influenced_sidbs; } diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index d90465b0d..fc9d14a2c 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -54,7 +54,8 @@ using surface_black_list = * @return A black list of gate functions associated with tiles. */ template -[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface) noexcept +[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, + const bool incorporate_defect_into_gate_design = false) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -71,7 +72,7 @@ template surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(); + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(incorporate_defect_into_gate_design); const auto gate_implementations = GateLibrary::get_functional_implementations(); const auto gate_ports = GateLibrary::get_gate_ports(); @@ -110,8 +111,6 @@ template { black_list[t][fun].push_back(port); } - - return; // skip to next gate } } } @@ -124,9 +123,10 @@ template [&](const auto& t) constexpr { // for each gate in the library - std::for_each(gate_implementations.cbegin(), gate_implementations.cend(), - // analyze the defect impact - std::bind(analyze_gate, std::placeholders::_1, t)); + for (const auto& it : gate_implementations) + { + analyze_gate(it, t); + } }); return black_list; diff --git a/test/io/write_sqd_sim_result.cpp b/test/io/write_sqd_sim_result.cpp index f05a5b4cd..590120b85 100644 --- a/test/io/write_sqd_sim_result.cpp +++ b/test/io/write_sqd_sim_result.cpp @@ -171,7 +171,7 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") " {}\n" " 0\n" " {}\n" - " 42.0\n" + " 42\n" " \n" " \n" " {}\n" @@ -202,7 +202,7 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") " {}\n" " 0\n" " {}\n" - " 42.0\n" + " 42\n" " \n" " \n" " {}\n" From d5bae811b38913a7d10e28da5a68a97de6502562 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 6 Oct 2023 09:18:33 +0200 Subject: [PATCH 025/191] :construction: latest version. --- .../dynamic_gate_design.cpp | 80 +++++---- .../skeleton_bestagons_with_tags/1i1o_s.sqd | 8 - .../physical_design/apply_gate_library.hpp | 2 +- .../physical_design/design_sidb_gates.hpp | 20 ++- .../technology/sidb_bestagon_library.hpp | 1 - include/fiction/technology/sidb_defects.hpp | 15 +- .../technology/sidb_dynamic_gate_library.hpp | 160 ++++++++++++++++-- .../technology/sidb_surface_analysis.hpp | 1 + 8 files changed, 226 insertions(+), 61 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index eea066ee2..19025f13c 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,12 +13,13 @@ #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces #include // reader for SiQAD files -#include // writer for SiQAD files (physical simulation) -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations -#include // a dynamic SiDB gate library +#include // writer for SiQAD files (physical simulation) +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations +#include // a dynamic SiDB gate library #include +#include #include // SiDB surface with support for atomic defects #include #include // pre-defined types suitable for the FCN domain @@ -44,12 +45,13 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt; - static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); -// const auto surface_lattice = fiction::read_sidb_surface_defects( -// "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); -// const auto lattice_tiling = gate_lyt{{11, 30}}; + static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - // const auto surface_lattice = fiction::sidb_surface{}; + const auto surface_lattice = fiction::read_sidb_surface_defects( + fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 1), + "py_test_surface"); + + const auto lattice_tiling = gate_lyt{{11, 30}}; experiments::experiment @@ -73,18 +75,20 @@ int main() // NOLINT "SiDB dots", "layout area in nm²"}; - // parameterize the H-Si(100) 2x1 surface to ignore certain defect types - const fiction::sidb_surface_params surface_params{ - std::unordered_set{fiction::sidb_defect_type::DB}}; - static const std::string surface_data_path = - fmt::format("{}/defect_aware_physical_design/defects_full70.xml", EXPERIMENTS_PATH); - fiction::sidb_surface surface_lattice{surface_params}; - std::cout << surface_lattice.num_defects() << std::endl; - fiction::read_sqd_layout(surface_lattice, surface_data_path); - const auto number_defects = surface_lattice.num_defects(); - std::cout << number_defects << std::endl; - const auto lattice_tiling = gate_lyt{{11, 17}}; +// // parameterize the H-Si(100) 2x1 surface to ignore certain defect types +// const fiction::sidb_surface_params surface_params{ +// std::unordered_set{fiction::sidb_defect_type::DB}}; + + // const fiction::sidb_surface_params surface_params{}; + // static const std::string surface_data_path = + // fmt::format("{}/defect_aware_physical_design/defects_full56_Oct.xml", EXPERIMENTS_PATH); + // fiction::sidb_surface surface_lattice{surface_params}; + // std::cout << surface_lattice.num_defects() << std::endl; + // fiction::read_sqd_layout(surface_lattice, surface_data_path); + // const auto number_defects = surface_lattice.num_defects(); + // std::cout << number_defects << std::endl; + // const auto lattice_tiling = gate_lyt{{13, 14}}; // fiction::sidb_surface surface_lattice{surface_params}; // fiction::read_sqd_layout(surface_lattice, surface_data_path); @@ -102,23 +106,28 @@ int main() // NOLINT const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); const auto black_list = - fiction::sidb_surface_analysis(lattice_tiling, surface_lattice); + fiction::sidb_surface_analysis(lattice_tiling, surface_lattice, true); // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); exact_params.crossings = true; - exact_params.border_io = true; - exact_params.desynchronize = true; + exact_params.border_io = false; + exact_params.desynchronize = false; exact_params.timeout = 3'600'000; // 1h in ms + exact_params.upper_bound_x = 11; + exact_params.upper_bound_y = 30; fiction::exact_physical_design_stats exact_stats{}; exact_params.black_list = black_list; -// constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & -// ~fiction_experiments::two_bit_add_maj & ~fiction_experiments::b1_r2 & -// ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & -// ~fiction_experiments::epfl & ~fiction_experiments::half_adder; -// + // constexpr const uint64_t bench_select = + // fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & + // ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + // ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & + // ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & + // ~fiction_experiments::cm82a_5; + // // + constexpr const uint64_t bench_select = fiction_experiments::t; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) @@ -155,10 +164,15 @@ int main() // NOLINT fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); - // apply gate library + // apply Bestagon gate library const auto cell_level_layout = - fiction::apply_gate_library_dynamic_gates( - *gate_level_layout, surface_lattice); + fiction::apply_gate_library(*gate_level_layout); + + // apply dynamic gate library + // const auto cell_level_layout = + // fiction::apply_dynamic_gate_library( + // *gate_level_layout, surface_lattice); // compute area fiction::area_stats area_stats{}; @@ -169,7 +183,7 @@ int main() // NOLINT surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) { defect_surface.assign_sidb_defect(defect.first, defect.second); }); // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); + fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_bestagon_gates_applied.sqd", layouts_folder, benchmark)); // log results bestagon_exp( diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd index 9397b3fb2..d449e5cea 100644 --- a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd +++ b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd @@ -6,14 +6,6 @@ 0.3.3 2023-09-28 10:23:25 - - - 0.0611291 - - - - - Lattice diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 58a4cd431..3f9acd0e2 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -224,7 +224,7 @@ CellLyt apply_gate_library(const GateLyt& lyt) * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -CellLyt apply_gate_library_dynamic_gates(const GateLyt& lyt, const sidb_surface& defect_surface) +CellLyt apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index e59616706..ffeab3524 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -191,7 +191,7 @@ class design_sidb_gates_impl result_lyt.foreach_sidb_defect( [&result_lyt](const auto& cd) { - if (is_neutrally_charged_defect(result_lyt.get_sidb_defect(cd.first))) + if (is_neutrally_charged_defect(cd.second)) { result_lyt.assign_sidb_defect(cd.first, sidb_defect{sidb_defect_type::NONE}); } @@ -207,7 +207,7 @@ class design_sidb_gates_impl skeleton_layout.foreach_sidb_defect( [this, &result_lyt](const auto& cd) { - if (is_neutrally_charged_defect(skeleton_layout.get_sidb_defect(cd.first))) + if (is_neutrally_charged_defect(cd.second)) { result_lyt.assign_sidb_defect(cd.first, cd.second); } @@ -217,6 +217,10 @@ class design_sidb_gates_impl gate_layout_is_found = true; break; } +// { +// const std::lock_guard lock{mutex_to_protect_designed_gate_layouts}; +// counter += 1; +// } } }); } @@ -388,7 +392,17 @@ template return p.run_exhaustive_design(); } - return p.run_random_design(); + std::vector found_lyts{}; + while (found_lyts.empty()) + { + design_sidb_gates_params parameter{params}; + detail::design_sidb_gates_impl p_random{skeleton, spec, parameter}; + const auto result = p.run_random_design(); + found_lyts = result; + parameter.number_of_sidbs +=1; + std::cout << "increase number of SiDBs" << std::endl; + } + return found_lyts; } } // namespace fiction diff --git a/include/fiction/technology/sidb_bestagon_library.hpp b/include/fiction/technology/sidb_bestagon_library.hpp index 951760bec..e7be73467 100644 --- a/include/fiction/technology/sidb_bestagon_library.hpp +++ b/include/fiction/technology/sidb_bestagon_library.hpp @@ -294,7 +294,6 @@ class sidb_bestagon_library : public fcn_gate_library return ports; } - private: template [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept { diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 9cfb4c04f..511733c9b 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -166,6 +166,18 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING = 1u; * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; +/** + * Horizontal distance to avoid charged SiDB defects while the defect is incorporated into the SiDB gate design process. + * The value is to be understood as the number of DB positions rather than the number of dimers. + * This is true even though each defect always affects the entire dimer. + */ +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN = 4u; +/** + * Vertical distance to avoid charged SiDB defects while the defect is incorporated into the SiDB gate design process. + * The value is to be understood as the number of DB positions rather than the number of dimers. + * This is true even though each defect always affects the entire dimer. + */ +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN = 4u; /** * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the * `NONE` defect type, `{0, 0}` is returned. @@ -182,7 +194,8 @@ defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_desig { if (incorporate_defect_into_gate_design) { - return {SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING, SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING}; + return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN, + SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN}; } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 9f8d763cc..42f9c69a5 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -10,6 +10,8 @@ #include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" +#include "fiction/technology/sidb_bestagon_library.hpp" +#include "fiction/technology/sidb_skeleton_bestagon_library_optimized.hpp" #include "fiction/technology/sidb_surface.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" @@ -25,8 +27,8 @@ struct sidb_dynamic_gate_library_params { design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{25, 8, 0}, {35, 14, 0}}, - 4, + {{22, 7, 1}, {34, 15, 0}}, + 5, sidb_simulation_engine::QUICKEXACT}; }; @@ -57,10 +59,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + ONE_IN_TWO_OUT.at(p)); + auto path = ONE_IN_TWO_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); // erase defects sidb_surface.foreach_sidb_defect(update_layout); + const auto found_gate_layouts = design_sidb_gates(layout, create_fan_out_tt(), parameter.params); std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; @@ -124,10 +129,40 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + "2i2o.sqd"); sidb_surface.foreach_sidb_defect(update_layout); + + bool bestagon_can_be_used = true; + layout.foreach_sidb_defect( + [&layout, &bestagon_can_be_used, ¶meter](const auto& cd) + { + if (is_charged_defect(cd.second)) + { + std::cout << "charged defects" << std::endl; + bestagon_can_be_used = false; + return; + } + if (cd.first >= siqad::coord_t{24, 6, 0} && + cd.first <= siqad::coord_t{34, 16, 0}) + { + // bestagon_can_be_used = false; + // return; + } + }); + + if (bestagon_can_be_used) + { + return sidb_skeleton_bestagon_library_optimized::DOUBLE_WIRE; + } + + fiction::write_sqd_layout( + layout, fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); const auto found_gate_layouts = design_sidb_gates(layout, create_double_wire_tt(), parameter.params); std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) @@ -145,8 +180,37 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + "2i2o.sqd"); sidb_surface.foreach_sidb_defect(update_layout); + + bool bestagon_can_be_used = true; + layout.foreach_sidb_defect( + [&layout, &bestagon_can_be_used, ¶meter](const auto& cd) + { + if (is_charged_defect(cd.second)) + { + std::cout << "charged defects" << std::endl; + bestagon_can_be_used = false; + return; + } + if (cd.first >= siqad::coord_t{24, 6, 0} && cd.first <= siqad::coord_t{34, 16, 0}) + { + // bestagon_can_be_used = false; + // return; + } + }); + + if (bestagon_can_be_used) + { + return sidb_skeleton_bestagon_library_optimized::CROSSING; + } + + fiction::write_sqd_layout( + layout, fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); const auto found_gate_layouts = design_sidb_gates(layout, create_crossing_wire_tt(), parameter.params); + std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; fiction::write_sqd_layout( found_gate_layouts[0], @@ -166,7 +230,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + std::cout << fmt::format("{} : cells", layout.num_cells()) << std::endl; sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); @@ -185,6 +255,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + ONE_INPUT_ONE_OUTPUT.at(p)); sidb_surface.foreach_sidb_defect(update_layout); @@ -204,8 +276,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + TWO_IN_ONE_OUT.at(p)); + auto path = TWO_IN_ONE_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -222,8 +301,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + TWO_IN_ONE_OUT.at(p)); + auto path = TWO_IN_ONE_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -240,8 +326,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + TWO_IN_ONE_OUT.at(p)); + auto path = TWO_IN_ONE_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -258,8 +351,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + TWO_IN_ONE_OUT.at(p)); + auto path = TWO_IN_ONE_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -276,8 +376,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + TWO_IN_ONE_OUT.at(p)); + auto path = TWO_IN_ONE_OUT.at(p); + std::cout << path << std::endl; + layout = read_sqd_layout(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -298,6 +405,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); @@ -312,6 +424,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); sidb_surface.foreach_sidb_defect(update_layout); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); @@ -333,6 +450,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -353,6 +475,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], @@ -373,6 +500,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout(layout, + fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index fc9d14a2c..df090ac17 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -111,6 +111,7 @@ template { black_list[t][fun].push_back(port); } + return; } } } From 47f32a8d1be4108783ec21f304c57e54d85110cd Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 12 Oct 2023 16:24:06 +0200 Subject: [PATCH 026/191] :art: commit before architectural change --- .../dynamic_gate_design.cpp | 52 +- .../physical_design/design_sidb_gates.hpp | 1 - include/fiction/technology/sidb_defects.hpp | 4 +- .../technology/sidb_dynamic_gate_library.hpp | 444 +++++++++++++++++- .../technology/sidb_surface_analysis.hpp | 2 +- 5 files changed, 472 insertions(+), 31 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 19025f13c..d1e8f4d84 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -47,11 +47,11 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - const auto surface_lattice = fiction::read_sidb_surface_defects( - fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 1), - "py_test_surface"); + const auto surface_lattice = fiction::read_sidb_surface_defects( + fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 0.5), + "py_test_surface"); - const auto lattice_tiling = gate_lyt{{11, 30}}; + const auto lattice_tiling = gate_lyt{{11, 30}}; experiments::experiment @@ -75,10 +75,9 @@ int main() // NOLINT "SiDB dots", "layout area in nm²"}; - -// // parameterize the H-Si(100) 2x1 surface to ignore certain defect types -// const fiction::sidb_surface_params surface_params{ -// std::unordered_set{fiction::sidb_defect_type::DB}}; + // // parameterize the H-Si(100) 2x1 surface to ignore certain defect types + // const fiction::sidb_surface_params surface_params{ + // std::unordered_set{fiction::sidb_defect_type::DB}}; // const fiction::sidb_surface_params surface_params{}; // static const std::string surface_data_path = @@ -105,8 +104,9 @@ int main() // NOLINT const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); - const auto black_list = - fiction::sidb_surface_analysis(lattice_tiling, surface_lattice, true); + const auto black_list = + fiction::sidb_surface_analysis(lattice_tiling, + surface_lattice, true); // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; @@ -120,15 +120,15 @@ int main() // NOLINT fiction::exact_physical_design_stats exact_stats{}; exact_params.black_list = black_list; - // constexpr const uint64_t bench_select = - // fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & - // ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & - // ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & - // ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & - // ~fiction_experiments::cm82a_5; + constexpr const uint64_t bench_select = + fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & + ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & + ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & + ~fiction_experiments::cm82a_5; // // - constexpr const uint64_t bench_select = fiction_experiments::t; +// constexpr const uint64_t bench_select = fiction_experiments::xor5_r1; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { @@ -165,14 +165,13 @@ int main() // NOLINT fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); // apply Bestagon gate library - const auto cell_level_layout = - fiction::apply_gate_library(*gate_level_layout); + // const auto cell_level_layout = + // fiction::apply_gate_library(*gate_level_layout); // apply dynamic gate library - // const auto cell_level_layout = - // fiction::apply_dynamic_gate_library( - // *gate_level_layout, surface_lattice); + const auto cell_level_layout = + fiction::apply_dynamic_gate_library( + *gate_level_layout, surface_lattice); // compute area fiction::area_stats area_stats{}; @@ -180,10 +179,11 @@ int main() // NOLINT fiction::area(cell_level_layout, area_ps, &area_stats); fiction::sidb_surface defect_surface{cell_level_layout}; - surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) - { defect_surface.assign_sidb_defect(defect.first, defect.second); }); + surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) + { defect_surface.assign_sidb_defect(defect.first, + defect.second); }); // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_bestagon_gates_applied.sqd", layouts_folder, benchmark)); + fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_wo_blacklist.sqd", layouts_folder, benchmark)); // log results bestagon_exp( diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index ffeab3524..02399585e 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -400,7 +400,6 @@ template const auto result = p.run_random_design(); found_lyts = result; parameter.number_of_sidbs +=1; - std::cout << "increase number of SiDBs" << std::endl; } return found_lyts; } diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 511733c9b..e410fb6f8 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -171,13 +171,13 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; * The value is to be understood as the number of DB positions rather than the number of dimers. * This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN = 4u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN = 5u; /** * Vertical distance to avoid charged SiDB defects while the defect is incorporated into the SiDB gate design process. * The value is to be understood as the number of DB positions rather than the number of dimers. * This is true even though each defect always affects the entire dimer. */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN = 4u; +inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN = 5u; /** * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the * `NONE` defect type, `{0, 0}` is returned. diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 42f9c69a5..dde67e3cc 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -86,7 +86,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + }; } // namespace fiction diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index df090ac17..6e1ccfbae 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -111,7 +111,7 @@ template { black_list[t][fun].push_back(port); } - return; + break; } } } From 0e11175e257d800af8623f9c86f82db3abd811ec Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 13 Oct 2023 11:23:01 +0200 Subject: [PATCH 027/191] :art: architectural change --- .../dynamic_gate_design.cpp | 40 +- .../technology/sidb_bestagon_library.hpp | 1 + .../technology/sidb_dynamic_gate_library.hpp | 715 +++++++++--------- 3 files changed, 374 insertions(+), 382 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index d1e8f4d84..7862a8938 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -47,11 +47,11 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - const auto surface_lattice = fiction::read_sidb_surface_defects( - fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 0.5), - "py_test_surface"); + const auto surface_lattice = fiction::read_sidb_surface_defects( + fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 1), + "py_test_surface"); - const auto lattice_tiling = gate_lyt{{11, 30}}; + const auto lattice_tiling = gate_lyt{{11, 30}}; experiments::experiment @@ -104,9 +104,8 @@ int main() // NOLINT const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); - const auto black_list = - fiction::sidb_surface_analysis(lattice_tiling, - surface_lattice, true); + const auto black_list = + fiction::sidb_surface_analysis(lattice_tiling, surface_lattice, true); // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; @@ -120,15 +119,14 @@ int main() // NOLINT fiction::exact_physical_design_stats exact_stats{}; exact_params.black_list = black_list; - constexpr const uint64_t bench_select = - fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & - ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & - ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & - ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & - ~fiction_experiments::cm82a_5; - // // + constexpr const uint64_t bench_select = + fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & + ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & + ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & ~fiction_experiments::cm82a_5; + // -// constexpr const uint64_t bench_select = fiction_experiments::xor5_r1; + // constexpr const uint64_t bench_select = fiction_experiments::t; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { @@ -170,8 +168,8 @@ int main() // NOLINT // apply dynamic gate library const auto cell_level_layout = - fiction::apply_dynamic_gate_library( - *gate_level_layout, surface_lattice); + fiction::apply_dynamic_gate_library(*gate_level_layout, + surface_lattice); // compute area fiction::area_stats area_stats{}; @@ -179,11 +177,11 @@ int main() // NOLINT fiction::area(cell_level_layout, area_ps, &area_stats); fiction::sidb_surface defect_surface{cell_level_layout}; - surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) - { defect_surface.assign_sidb_defect(defect.first, - defect.second); }); + surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) + { defect_surface.assign_sidb_defect(defect.first, defect.second); }); // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_wo_blacklist.sqd", layouts_folder, benchmark)); + fiction::write_sqd_layout(defect_surface, + fmt::format("{}/{}_after_huge_change.sqd", layouts_folder, benchmark)); // log results bestagon_exp( diff --git a/include/fiction/technology/sidb_bestagon_library.hpp b/include/fiction/technology/sidb_bestagon_library.hpp index e7be73467..951760bec 100644 --- a/include/fiction/technology/sidb_bestagon_library.hpp +++ b/include/fiction/technology/sidb_bestagon_library.hpp @@ -294,6 +294,7 @@ class sidb_bestagon_library : public fcn_gate_library return ports; } + private: template [[nodiscard]] static port_list determine_port_routing(const Lyt& lyt, const tile& t) noexcept { diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index dde67e3cc..0ec897813 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -38,9 +38,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, + static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, - const sidb_dynamic_gate_library_params parameter = {}) + const sidb_dynamic_gate_library_params& parameter = {}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); @@ -86,8 +86,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library) @@ -96,20 +94,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)); // erase defects sidb_surface.foreach_sidb_defect(update_layout); const auto found_gate_layouts = design_sidb_gates(layout, create_fan_out_tt(), parameter.params); - std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -128,123 +118,54 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + "2i2o.sqd"); + layout = cell_list_to_cell_level_layout(cell_list); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - bool bestagon_can_be_used = true; - layout.foreach_sidb_defect( - [&layout, &bestagon_can_be_used, ¶meter](const auto& cd) - { - if (is_charged_defect(cd.second)) - { - std::cout << "charged defects" << std::endl; - bestagon_can_be_used = false; - return; - } - if (cd.first >= siqad::coord_t{24, 6, 0} && - cd.first <= siqad::coord_t{34, 16, 0}) - { - // bestagon_can_be_used = false; - // return; - } - }); - - if (bestagon_can_be_used) + if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(DOUBLE_WIRE), layout)) { - return sidb_skeleton_bestagon_library_optimized::DOUBLE_WIRE; + return DOUBLE_WIRE; } - fiction::write_sqd_layout( - layout, fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); const auto found_gate_layouts = design_sidb_gates(layout, create_double_wire_tt(), parameter.params); - std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) - << std::endl; - fiction::write_sqd_layout( - found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished hourglass" << std::endl; return cell_list_to_gate(list); } - layout = read_sqd_layout(skeleton_path + "2i2o.sqd"); + layout = cell_list_to_cell_level_layout(cell_list); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - bool bestagon_can_be_used = true; - layout.foreach_sidb_defect( - [&layout, &bestagon_can_be_used, ¶meter](const auto& cd) - { - if (is_charged_defect(cd.second)) - { - std::cout << "charged defects" << std::endl; - bestagon_can_be_used = false; - return; - } - if (cd.first >= siqad::coord_t{24, 6, 0} && cd.first <= siqad::coord_t{34, 16, 0}) - { - // bestagon_can_be_used = false; - // return; - } - }); - - if (bestagon_can_be_used) + if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(CROSSING), layout)) { - return sidb_skeleton_bestagon_library_optimized::CROSSING; + return CROSSING; } - fiction::write_sqd_layout( - layout, fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); const auto found_gate_layouts = design_sidb_gates(layout, create_crossing_wire_tt(), parameter.params); - std::cout << fmt::format("{} : defects", found_gate_layouts[0].num_defects()) << std::endl; - fiction::write_sqd_layout( - found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << "finished crossing" << std::endl; const auto list = cell_level_layout_to_list(found_gate_layouts.front()); return cell_list_to_gate(list); } - auto path = ONE_INPUT_ONE_OUTPUT.at(p); - if (path == "empty") + auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); + if (cell_list == EMPTY_GATE) { return EMPTY_GATE; } - std::cout << path << std::endl; - layout = read_sqd_layout(skeleton_path + path); - std::cout << fmt::format("{} : cells", layout.num_cells()) << std::endl; + layout = cell_list_to_cell_level_layout(cell_list); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -255,18 +176,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + ONE_INPUT_ONE_OUTPUT.at(p)); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -276,22 +191,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -301,22 +206,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -326,24 +221,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; + return cell_list_to_gate(list); } } @@ -351,22 +236,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -376,22 +251,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -401,16 +266,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; @@ -421,22 +280,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects + sidb_surface.foreach_sidb_defect(update_layout); + sidb_surface.foreach_sidb_defect(update_layout); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -446,22 +297,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -471,22 +312,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -496,16 +327,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library(skeleton_path + path); + layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); + // erase defects sidb_surface.foreach_sidb_defect(update_layout); - fiction::write_sqd_layout(layout, - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - std::cout << fmt::format("{} : defects", layout.num_defects()) << std::endl; + const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); fiction::write_sqd_layout(found_gate_layouts[0], fmt::format("{}/{}.sqd", @@ -525,6 +350,32 @@ class sidb_dynamic_gate_library : public fcn_gate_library + static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt,const sidb_surface &defect_lyt) + { + defect_lyt.foreach_sidb_defect( + [&bestagon_lyt](const auto& cd) + { + if (is_charged_defect(cd.second)) + { + std::cout << "charged defects" << std::endl; + return false; + } + bestagon_lyt.foreach_cell( + [&cd](const auto& c) + { + if (c.x <= cd.first.x + SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING || + (c.x >= cd.first.x - SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING && + c.y == cd.first.y)) + { + return false; + } + }); + }); + return true; + } + /** * Generates a cell-level layout as a 2D array of characters based on the provided cell layout information. * @@ -535,7 +386,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library static std::array, gate_y_size()> cell_level_layout_to_list(const Lyt& lyt) { - std::array, gate_y_size()> result{}; const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); @@ -557,6 +407,51 @@ class sidb_dynamic_gate_library : public fcn_gate_library + static Lyt cell_list_to_cell_level_layout(const fcn_gate& cell_list) noexcept + { + Lyt lyt{}; + + const auto all_cell = + all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); + uint64_t counter = 0; + + for (size_t i = 0; i < gate_y_size(); ++i) + { + for (size_t j = 0; j < gate_x_size(); ++j) + { + const auto cell = cell_list[i][j]; + + switch (cell) + { + case 'x': // normal cell + lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::NORMAL); + break; + + case 'i': // input cell + lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::INPUT); + break; + + case 'o': // output cell + lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::OUTPUT); + break; + + case ' ': break; + } + counter += 1; + } + } + return lyt; + } + /** * This function determines the port routing for a specific tile within a layout represented by the object `lyt` of * type `Lyt`. It examines the tile's characteristics and connectivity to determine the appropriate incoming and @@ -621,89 +516,111 @@ class sidb_dynamic_gate_library : public fcn_gate_library, std::string>; - using double_port_gate_map = - phmap::flat_hash_map, port_list>, std::string>; - - /** - * Lookup table for one input Boolean functions. - */ - static inline const port_gate_map ONE_INPUT_ONE_OUTPUT = { - // primary inputs - {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, "1i1o_s.sqd"}, - {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, "1i1o_d.sqd"}, - // primary outputs - {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, "1i1o_d.sqd"}, - {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, "1i1o_sm.sqd"}, - // straight wire - {{{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}, - "1i1o_s.sqd"}, - {{{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}, - "1i1o_sm.sqd"}, - // diagonal wire - {{{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}, - "1i1o_d.sqd"}, - {{{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}, - "1i1o_dm.sqd"}, - // empty gate (for crossing layer) - {{{}, {}}, "empty"}, - }; - /** - * Lookup table for wire crossings and hourglass wires. - */ - static inline const double_port_gate_map CROSSING_MAP = { - {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}, - {{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, - "2o2o_hour.sqd"}, - {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}, - {{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, - "2o2o_hour.sqd"}, - {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}, - {{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, - "2o2o_cx.sqd"}, - {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}, - {{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, - "2o2o_cx.sqd"}, - }; - /** - * Lookup table for two input Boolean function (e.g., AND, OR, ...). - */ - static inline const port_gate_map TWO_IN_ONE_OUT = { - {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST)}}, - "2i1o.sqd"}, - {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_WEST)}}, - "2i1o_m.sqd"}}; - /** - * Lookup table for fan-out. - */ - static inline const port_gate_map ONE_IN_TWO_OUT = { - {{{port_direction(port_direction::cardinal::NORTH_WEST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, - "1i2o.sqd"}, - {{{port_direction(port_direction::cardinal::NORTH_EAST)}, - {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, - "1i2o_m.sqd"}}; + static constexpr const fcn_gate CROSSING{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; - static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate({{ + static constexpr const fcn_gate DOUBLE_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + + static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -735,11 +652,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -784,11 +701,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -833,11 +750,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -882,11 +799,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -931,11 +848,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -980,11 +897,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -1029,11 +946,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -1078,11 +995,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, @@ -1127,11 +1044,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library, fcn_gate>; + using double_port_gate_map = + phmap::flat_hash_map, port_list>, fcn_gate>; + /** + * Lookup table for one input Boolean functions. + */ + static inline const port_gate_map ONE_IN_ONE_OUT_MAP = { + // primary inputs + {{{}, {port_direction(port_direction::cardinal::SOUTH_WEST)}}, STRAIGHT_WIRE}, + {{{}, {port_direction(port_direction::cardinal::SOUTH_EAST)}}, DIAGONAL_WIRE}, + // primary outputs + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, {}}, DIAGONAL_WIRE}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, {}}, MIRRORED_STRAIGHT_WIRE}, + // straight wire + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + STRAIGHT_WIRE}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + MIRRORED_STRAIGHT_WIRE}, + // diagonal wire + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + DIAGONAL_WIRE}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + MIRRORED_DIAGONAL_WIRE}, + // empty gate (for crossing layer) + {{{}, {}}, EMPTY_GATE}, + }; + /** + * Lookup table for wire crossings and hourglass wires. + */ + static inline const double_port_gate_map TWO_IN_TWO_OUT_MAP = { + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + {{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, + DOUBLE_WIRE}, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + {{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, + DOUBLE_WIRE}, + {{{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + {{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}}, + CROSSING}, + {{{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + {{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}}, + CROSSING}, + }; + /** + * Lookup table for two input Boolean function (e.g., AND, OR, ...). + */ + static inline const port_gate_map TWO_IN_ONE_OUT_MAP = { + {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST)}}, + TWO_IN_ONE_OUT}, + {{{port_direction(port_direction::cardinal::NORTH_WEST), port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_WEST)}}, + MIRRORED_TWO_IN_ONE_OUT}}; + /** + * Lookup table for fan-out. + */ + static inline const port_gate_map ONE_IN_TWO_OUT_MAP = { + {{{port_direction(port_direction::cardinal::NORTH_WEST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, + FANOUT_1_2}, + {{{port_direction(port_direction::cardinal::NORTH_EAST)}, + {port_direction(port_direction::cardinal::SOUTH_EAST), port_direction(port_direction::cardinal::SOUTH_WEST)}}, + MIRRORED_FANOUT_1_2}}; + }; } // namespace fiction From 3d1babc74a286399b7e4a03dedaa15ce0b32a6ed Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 17 Oct 2023 14:14:49 +0200 Subject: [PATCH 028/191] :art: architectural change and update blacklist. --- .../dynamic_gate_design.cpp | 242 +- .../physical_design/apply_gate_library.hpp | 46 +- .../physical_design/design_sidb_gates.hpp | 163 +- .../fiction/technology/fcn_gate_library.hpp | 3 + include/fiction/technology/sidb_defects.hpp | 17 +- .../technology/sidb_dynamic_gate_library.hpp | 2298 ++++++++++++----- include/fiction/technology/sidb_surface.hpp | 10 +- .../technology/sidb_surface_analysis.hpp | 4 +- 8 files changed, 2005 insertions(+), 778 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 7862a8938..bffeb4e3a 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -6,14 +6,17 @@ #include "fiction_experiments.hpp" +#include #include // technology mapping #include // layout conversion to cell-level +#include #include // SMT-based physical design of FCN layouts #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces #include // reader for SiQAD files #include // writer for SiQAD files (physical simulation) +#include #include // technology-mapped network type #include // area requirement calculations #include // cell implementations @@ -47,112 +50,114 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - const auto surface_lattice = fiction::read_sidb_surface_defects( - fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", 1), - "py_test_surface"); - - const auto lattice_tiling = gate_lyt{{11, 30}}; - - experiments::experiment - bestagon_exp{"bestagon", - "benchmark", - "inputs", - "outputs", - "initial nodes", - "initial depth", - "optimized nodes", - "optimized depth", - "layout width (in tiles)", - "layout height (in tiles)", - "layout area (in tiles)", - "gates", - "wires", - "critical path", - "throughput", - "runtime (in sec)", - "equivalent", - "SiDB dots", - "layout area in nm²"}; - - // // parameterize the H-Si(100) 2x1 surface to ignore certain defect types - // const fiction::sidb_surface_params surface_params{ - // std::unordered_set{fiction::sidb_defect_type::DB}}; - - // const fiction::sidb_surface_params surface_params{}; - // static const std::string surface_data_path = - // fmt::format("{}/defect_aware_physical_design/defects_full56_Oct.xml", EXPERIMENTS_PATH); - // fiction::sidb_surface surface_lattice{surface_params}; - // std::cout << surface_lattice.num_defects() << std::endl; - // fiction::read_sqd_layout(surface_lattice, surface_data_path); - // const auto number_defects = surface_lattice.num_defects(); - // std::cout << number_defects << std::endl; - // const auto lattice_tiling = gate_lyt{{13, 14}}; - - // fiction::sidb_surface surface_lattice{surface_params}; - // fiction::read_sqd_layout(surface_lattice, surface_data_path); - - // instantiate a complete XAG NPN database for node re-synthesis - const mockturtle::xag_npn_resynthesis // the kind of database to use - resynthesis_function{}; - - // parameters for cut rewriting - mockturtle::cut_rewriting_params cut_params{}; - cut_params.cut_enumeration_ps.cut_size = 4; - - const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); - - const auto black_list = - fiction::sidb_surface_analysis(lattice_tiling, surface_lattice, true); - - // parameters for SMT-based physical design - fiction::exact_physical_design_params exact_params{}; - exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); - exact_params.crossings = true; - exact_params.border_io = false; - exact_params.desynchronize = false; - exact_params.timeout = 3'600'000; // 1h in ms - exact_params.upper_bound_x = 11; - exact_params.upper_bound_y = 30; - fiction::exact_physical_design_stats exact_stats{}; - exact_params.black_list = black_list; - - constexpr const uint64_t bench_select = - fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & - ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & - ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & - ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & ~fiction_experiments::cm82a_5; - // - - // constexpr const uint64_t bench_select = fiction_experiments::t; - - for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) - { - fmt::print("[i] processing {}\n", benchmark); - mockturtle::xag_network xag{}; - - const auto read_verilog_result = - lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); - assert(read_verilog_result == lorina::return_code::success); - - // compute depth - const mockturtle::depth_view depth_xag{xag}; - - // rewrite network cuts using the given re-synthesis function - const auto cut_xag = mockturtle::cut_rewriting(xag, resynthesis_function, cut_params); + std::vector defct_conc = {1}; - // perform technology mapping - const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); - // compute depth - const mockturtle::depth_view depth_mapped_network{mapped_network}; - - // perform layout generation with an SMT-based exact algorithm - const auto gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); - - if (gate_level_layout.has_value()) + for (const auto& conc : defct_conc) + { + std::cout << conc << std::endl; + const auto surface_lattice = fiction::read_sidb_surface_defects( + fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", conc), + "py_test_surface"); + + const auto lattice_tiling = gate_lyt{{11, 30}}; + + experiments::experiment + bestagon_exp{"bestagon", + "benchmark", + "inputs", + "outputs", + "initial nodes", + "initial depth", + "optimized nodes", + "optimized depth", + "layout width (in tiles)", + "layout height (in tiles)", + "layout area (in tiles)", + "gates", + "wires", + "critical path", + "throughput", + "runtime (in sec)", + "equivalent", + "SiDB dots", + "layout area in nm²"}; + +// constexpr const uint64_t bench_select = +// fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & +// ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & +// ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & +// ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & ~fiction_experiments::cm82a_5; + + constexpr const uint64_t bench_select = fiction_experiments::majority_5_r1; + + for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { + fmt::print("[i] processing {}\n", benchmark); + mockturtle::xag_network xag{}; + + const auto read_verilog_result = + lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); + assert(read_verilog_result == lorina::return_code::success); + + // compute depth + const mockturtle::depth_view depth_xag{xag}; + + const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); + + // parameters for cut rewriting + mockturtle::cut_rewriting_params cut_params{}; + cut_params.cut_enumeration_ps.cut_size = 4; + + const mockturtle::xag_npn_resynthesis< + mockturtle::xag_network, // the input network type + mockturtle::xag_network, // the database network type + mockturtle::xag_npn_db_kind::xag_complete> // the kind of database to use + resynthesis_function{}; + + // rewrite network cuts using the given re-synthesis function + const auto cut_xag = mockturtle::cut_rewriting(xag, resynthesis_function, cut_params); + + // perform technology mapping + const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); + // compute depth + const mockturtle::depth_view depth_mapped_network{mapped_network}; + + std::optional gate_level_layout = std::nullopt; + cell_lyt cell_level_layout{{}, "fail"}; + + // fiction::aspect_ratio_iterator ari{1}; + std::pair pair = {0, 0}; + + auto black_list = fiction::sidb_surface_analysis( + lattice_tiling, surface_lattice, true, pair); + + while (!gate_level_layout.has_value() || cell_level_layout.get_layout_name() == "fail") + { + std::cout << black_list.size() << std::endl; + gate_level_layout = fiction::run( + layouts_folder, surface_lattice, lattice_tiling, benchmark, pair, black_list); + if (gate_level_layout.has_value()) + { + cell_level_layout = + fiction::apply_dynamic_gate_library( + *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, pair, + black_list); + // pair.first += 1; + // pair.second += 1; + // ari++; + } + else + { + // ari++; + // pair.first += 1; + // pair.second += 1; + } + std::cout << fmt::format("x: {} | y: {}", pair.first, pair.second) << std::endl; + } + // check equivalence const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); const auto eq = mockturtle::equivalence_checking(*miter); @@ -162,14 +167,7 @@ int main() // NOLINT fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); - // apply Bestagon gate library - // const auto cell_level_layout = - // fiction::apply_gate_library(*gate_level_layout); - // apply dynamic gate library - const auto cell_level_layout = - fiction::apply_dynamic_gate_library(*gate_level_layout, - surface_lattice); // compute area fiction::area_stats area_stats{}; @@ -183,24 +181,16 @@ int main() // NOLINT fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_after_huge_change.sqd", layouts_folder, benchmark)); - // log results - bestagon_exp( - benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), mapped_network.num_gates(), - depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1, - (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(), - gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput, - mockturtle::to_seconds(exact_stats.time_total), *eq, cell_level_layout.num_cells(), area_stats.area); - } - else // no layout was obtained - { // log results bestagon_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), - mapped_network.num_gates(), depth_mapped_network.depth(), 0, 0, 0, 0, 0, 0, 0, - mockturtle::to_seconds(exact_stats.time_total), false, 0, 0); + mapped_network.num_gates(), depth_mapped_network.depth(), gate_level_layout->x() + 1, + gate_level_layout->y() + 1, (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), + gate_level_layout->num_gates(), gate_level_layout->num_wires(), + cp_tp_stats.critical_path_length, cp_tp_stats.throughput, 0.0, *eq, + cell_level_layout.num_cells(), area_stats.area); + bestagon_exp.save(); + bestagon_exp.table(); } - - bestagon_exp.save(); - bestagon_exp.table(); } return EXIT_SUCCESS; diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 3f9acd0e2..106611662 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -8,6 +8,7 @@ #include "fiction/technology/inml_topolinano_library.hpp" #include "fiction/technology/qca_one_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" +#include "fiction/technology/sidb_dynamic_gate_library.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" @@ -31,7 +32,7 @@ namespace fiction namespace detail { -template +template class apply_gate_library_impl { public: @@ -51,7 +52,11 @@ class apply_gate_library_impl * @param defect_surface Defect surface with atomic defects. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ - CellLyt run_dynamic_gates(const sidb_surface& defect_surface) + CellLyt run_dynamic_gates( + const sidb_surface& defect_surface, + const sidb_dynamic_gate_library_params& params = sidb_dynamic_gate_library_params{}, + const std::pair& distance = {0, 0}, + surface_black_list& black_list = {}) { #if (PROGRESS_BARS) // initialize a progress bar @@ -60,6 +65,10 @@ class apply_gate_library_impl gate_lyt.foreach_node( [&, this](const auto& n, [[maybe_unused]] auto i) { + if (cell_lyt.get_layout_name() == "fail") + { + return; + } if (!gate_lyt.is_constant(n)) { const auto t = gate_lyt.get_tile(n); @@ -69,7 +78,16 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t, defect_surface), n); + const auto gate = GateLibrary::template set_up_gate(gate_lyt, t, defect_surface, params, distance, black_list); + if (gate == + fiction::create_array( + fiction::create_array(CellLyt::technology::cell_type::NORMAL))) + { + std::cout << "fail lyt" << std::endl; + cell_lyt = CellLyt{{}, "fail"}; + return; + } + assign_gate(c, gate, n); } #if (PROGRESS_BARS) // update progress @@ -82,11 +100,6 @@ class apply_gate_library_impl { GateLibrary::post_layout_optimization(cell_lyt); } - // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) - { - cell_lyt.set_layout_name(gate_lyt.get_layout_name()); - } return cell_lyt; } @@ -191,7 +204,7 @@ class apply_gate_library_impl * @param lyt The gate-level layout. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ -template +template CellLyt apply_gate_library(const GateLyt& lyt) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -203,7 +216,7 @@ CellLyt apply_gate_library(const GateLyt& lyt) static_assert(std::is_same_v, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt}; + detail::apply_gate_library_impl p{lyt}; auto result = p.run(); @@ -223,8 +236,13 @@ CellLyt apply_gate_library(const GateLyt& lyt) * @param defect_surface Defect surface with all atomic defects. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ -template -CellLyt apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface) +template +CellLyt apply_dynamic_gate_library( + const GateLyt& lyt, const sidb_surface& defect_surface, + const sidb_dynamic_gate_library_params& params = sidb_dynamic_gate_library_params{}, + const std::pair& distance = {0, 0}, + surface_black_list + &black_list = {}) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -235,9 +253,9 @@ CellLyt apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt}; + detail::apply_gate_library_impl p{lyt}; - auto result = p.run_dynamic_gates(defect_surface); + auto result = p.run_dynamic_gates(defect_surface, params, distance, black_list); return result; } diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 02399585e..bbe0b5838 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -109,48 +109,140 @@ class design_sidb_gates_impl [[nodiscard]] std::vector run_exhaustive_design() noexcept { const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; + auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); - const auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); + std::unordered_set sidbs_affected_by_defects = {}; - std::vector designed_gate_layouts = {}; + if constexpr (has_get_sidb_defect_v) + { + sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(true); + } + + std::vector designed_gate_layouts = {}; + std::mutex mutex_to_protect_designer_gate_layouts; + std::atomic solutionFound = false; + std::atomic global_iteration_counter(0); - std::mutex mutex_to_protect_designer_gate_layouts; // Mutex for protecting shared resources + const auto total_comb = binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs); const auto add_combination_to_layout_and_check_operation = - [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, - &designed_gate_layouts](const auto& combination) noexcept + [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, + &sidbs_affected_by_defects, &solutionFound, &global_iteration_counter, + &total_comb](const auto& combination) noexcept { - if (!are_sidbs_too_close(combination)) + for (const auto& comb : combination) { - auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(combination); - if (const auto [status, sim_calls] = - is_operational(layout_with_added_cells, truth_table, params_is_operational); - status == operational_status::OPERATIONAL) + global_iteration_counter++; + if (!solutionFound && !are_sidbs_too_close(comb, sidbs_affected_by_defects)) { - const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; // Lock the mutex - designed_gate_layouts.push_back(layout_with_added_cells); + auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); + + if constexpr (has_get_sidb_defect_v) + { + layout_with_added_cells.foreach_sidb_defect( + [&layout_with_added_cells](const auto& cd) + { + if (is_neutrally_charged_defect(cd.second)) + { + layout_with_added_cells.assign_sidb_defect(cd.first, + sidb_defect{sidb_defect_type::NONE}); + } + }); + } + + if (!solutionFound) + { + if (const auto [status, sim_calls] = + is_operational(layout_with_added_cells, truth_table, params_is_operational); + status == operational_status::OPERATIONAL) + { + { + const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; + designed_gate_layouts.push_back(layout_with_added_cells); + } + solutionFound = true; + + // Optionally, signal all threads to exit + // Uncomment the following line to signal all threads to exit + // solutionFound.store(true, std::memory_order_relaxed); + } + } } } }; - std::vector> futures{}; - futures.reserve(all_combinations.size()); + const unsigned int num_threads = std::thread::hardware_concurrency(); + const size_t chunk_size = all_combinations.size() / num_threads; - // Start asynchronous tasks to process combinations in parallel - for (const auto& combination : all_combinations) + std::vector threads; + threads.reserve(num_threads); + + for (unsigned int i = 0; i < num_threads; ++i) { - futures.emplace_back( - std::async(std::launch::async, add_combination_to_layout_and_check_operation, combination)); + size_t start = i * chunk_size; + size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; + std::vector> chunk_combinations(all_combinations.begin() + start, + all_combinations.begin() + end); + threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); } - // Wait for all tasks to finish - for (auto& future : futures) + for (auto& thread : threads) { - future.wait(); + thread.join(); } return designed_gate_layouts; } + // [[nodiscard]] std::vector run_exhaustive_design() noexcept + // { + // const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; + // auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); + // + // std::unordered_set sidbs_affected_by_defects = {}; + // + // if constexpr (has_get_sidb_defect_v) + // { + // sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(true); + // } + // + // std::vector designed_gate_layouts = {}; + // + // // Shuffle the vector randomly + // std::random_device rd; + // std::mt19937 g(rd()); + // std::shuffle(all_combinations.begin(), all_combinations.end(), g); + // + // for (const auto& combination : all_combinations) + // { + // if (!are_sidbs_too_close(combination, sidbs_affected_by_defects)) + // { + // auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(combination); + // + // if constexpr (has_get_sidb_defect_v) + // { + // layout_with_added_cells.foreach_sidb_defect( + // [&layout_with_added_cells](const auto& cd) + // { + // if (is_neutrally_charged_defect(cd.second)) + // { + // layout_with_added_cells.assign_sidb_defect(cd.first, + // sidb_defect{sidb_defect_type::NONE}); + // } + // }); + // } + // + // if (const auto [status, sim_calls] = + // is_operational(layout_with_added_cells, truth_table, params_is_operational); + // status == operational_status::OPERATIONAL) + // { + // designed_gate_layouts.push_back(layout_with_added_cells); + // break; // Stop after finding the first solution + // } + // } + // } + // + // return designed_gate_layouts; + // } /** * Design gates randomly and in parallel. @@ -217,10 +309,10 @@ class design_sidb_gates_impl gate_layout_is_found = true; break; } -// { -// const std::lock_guard lock{mutex_to_protect_designed_gate_layouts}; -// counter += 1; -// } + // { + // const std::lock_guard + // lock{mutex_to_protect_designed_gate_layouts}; counter += 1; + // } } }); } @@ -299,7 +391,8 @@ class design_sidb_gates_impl * @param cell_indices A vector of cell indices to check for SiDB proximity. * @return `true` if any SiDBs are too close; otherwise, `false`. */ - [[nodiscard]] bool are_sidbs_too_close(const std::vector& cell_indices) noexcept + [[nodiscard]] bool are_sidbs_too_close(const std::vector& cell_indices, + const std::unordered_set& affected_cells = {}) noexcept { for (std::size_t i = 0; i < cell_indices.size(); i++) { @@ -307,7 +400,8 @@ class design_sidb_gates_impl { if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5) + all_sidbs_in_cavas[cell_indices[j]]) < 0.5 || + affected_cells.count(all_sidbs_in_cavas[cell_indices[i]]) > 0) { return true; } @@ -389,17 +483,22 @@ template if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) { - return p.run_exhaustive_design(); + const auto exhaustive = p.run_exhaustive_design(); + if (exhaustive.empty()) + { + std::cout << "no result" << std::endl; + } + return exhaustive; } std::vector found_lyts{}; while (found_lyts.empty()) { - design_sidb_gates_params parameter{params}; + design_sidb_gates_params parameter{params}; detail::design_sidb_gates_impl p_random{skeleton, spec, parameter}; - const auto result = p.run_random_design(); - found_lyts = result; - parameter.number_of_sidbs +=1; + const auto result = p.run_random_design(); + found_lyts = result; + parameter.number_of_sidbs += 1; } return found_lyts; } diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index 5750cc2a3..62d10e5f5 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -317,6 +317,9 @@ class fcn_gate_library */ static constexpr const fcn_gate EMPTY_GATE = fiction::create_array(fiction::create_array(Technology::cell_type::EMPTY)); + + static constexpr const fcn_gate ERROR = + fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); }; } // namespace fiction diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index e410fb6f8..27431d4e8 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -166,18 +166,6 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING = 1u; * rather than the number of dimers. This is true even though each defect always affects the entire dimer. */ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; -/** - * Horizontal distance to avoid charged SiDB defects while the defect is incorporated into the SiDB gate design process. - * The value is to be understood as the number of DB positions rather than the number of dimers. - * This is true even though each defect always affects the entire dimer. - */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN = 5u; -/** - * Vertical distance to avoid charged SiDB defects while the defect is incorporated into the SiDB gate design process. - * The value is to be understood as the number of DB positions rather than the number of dimers. - * This is true even though each defect always affects the entire dimer. - */ -inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN = 5u; /** * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the * `NONE` defect type, `{0, 0}` is returned. @@ -188,14 +176,13 @@ inline constexpr const uint16_t SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_ * @return Number of horizontal and vertical SiDBs that are affected by the given defect type. */ [[nodiscard]] static constexpr std::pair -defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false) noexcept +defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) noexcept { if (is_charged_defect(defect)) { if (incorporate_defect_into_gate_design) { - return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING_ON_THE_FLY_DESIGN, - SIDB_CHARGED_DEFECT_VERTICAL_SPACING_ON_THE_FLY_DESIGN}; + return distance; } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 0ec897813..99d7d74b3 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -13,6 +13,7 @@ #include "fiction/technology/sidb_bestagon_library.hpp" #include "fiction/technology/sidb_skeleton_bestagon_library_optimized.hpp" #include "fiction/technology/sidb_surface.hpp" +#include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" @@ -26,9 +27,9 @@ namespace fiction struct sidb_dynamic_gate_library_params { design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{22, 7, 1}, {34, 15, 0}}, - 5, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{24, 8, 1}, {34, 14, 0}}, + 3, sidb_simulation_engine::QUICKEXACT}; }; @@ -37,10 +38,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, - const sidb_surface& sidb_surface, - const sidb_dynamic_gate_library_params& parameter = {}) + template + static fcn_gate set_up_gate( + const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, + const sidb_dynamic_gate_library_params& parameter = sidb_dynamic_gate_library_params{}, + const std::pair& distance = {0, 0}, + surface_black_list& + black_list = {}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); @@ -94,12 +99,20 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)); + layout = + cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)); // erase defects sidb_surface.foreach_sidb_defect(update_layout); const auto found_gate_layouts = design_sidb_gates(layout, create_fan_out_tt(), parameter.params); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -126,14 +139,34 @@ class sidb_dynamic_gate_library : public fcn_gate_library(DOUBLE_WIRE), layout)) + if (is_bestagon_gate_applicable( + cell_list_to_cell_level_layout(DOUBLE_WIRE), layout, + parameter.params, create_double_wire_tt())) { return DOUBLE_WIRE; } - const auto found_gate_layouts = - design_sidb_gates(layout, create_double_wire_tt(), parameter.params); + layout = cell_list_to_cell_level_layout(cell_list); + // erase defects + sidb_surface.foreach_sidb_defect(update_layout); + + fiction::write_sqd_layout( + layout, fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + auto complex_gate_param = parameter; + complex_gate_param.params.number_of_sidbs = 4; + const auto found_gate_layouts = + design_sidb_gates(layout, create_double_wire_tt(), complex_gate_param.params); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished hourglass" << std::endl; return cell_list_to_gate(list); @@ -143,14 +176,35 @@ class sidb_dynamic_gate_library : public fcn_gate_library(CROSSING), layout)) + if (is_bestagon_gate_applicable( + cell_list_to_cell_level_layout(CROSSING), layout, + parameter.params, create_crossing_wire_tt())) { return CROSSING; } - const auto found_gate_layouts = - design_sidb_gates(layout, create_crossing_wire_tt(), parameter.params); + layout = cell_list_to_cell_level_layout(cell_list); + // erase defects + sidb_surface.foreach_sidb_defect(update_layout); + fiction::write_sqd_layout( + layout, fmt::format("{}/{}.sqd", + "/Users/jandrewniok/CLionProjects/fiction_fork/" + "experiments/defect_aware_physical_design/single_gates", + n)); + + auto complex_gate_param = parameter; + complex_gate_param.params.number_of_sidbs = 4; + const auto found_gate_layouts = + design_sidb_gates(layout, create_crossing_wire_tt(), complex_gate_param.params); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } + std::cout << "finished crossing" << std::endl; const auto list = cell_level_layout_to_list(found_gate_layouts.front()); return cell_list_to_gate(list); } @@ -165,7 +219,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -176,12 +237,18 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)); + layout = cell_list_to_cell_level_layout(ONE_IN_ONE_OUT_MAP.at(p)); // erase defects sidb_surface.foreach_sidb_defect(update_layout); const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -196,7 +263,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -211,7 +284,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -226,7 +305,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); return cell_list_to_gate(list); @@ -241,7 +326,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -256,7 +347,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -271,7 +368,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } + const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); } @@ -287,7 +391,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -317,7 +427,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -332,11 +448,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library{f}, parameter.params); - fiction::write_sqd_layout(found_gate_layouts[0], - fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); + if (found_gate_layouts.empty()) + { + std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; + black_list[t][f].push_back(p); + std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; + return ERROR; + } const auto list = cell_level_layout_to_list(found_gate_layouts.front()); std::cout << "finished" << std::endl; return cell_list_to_gate(list); @@ -350,30 +468,42 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt,const sidb_surface &defect_lyt) + static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, sidb_surface defect_lyt, + const design_sidb_gates_params& parameter, + const std::vector& truth_table) { + bool is_bestagon_gate_applicable = true; defect_lyt.foreach_sidb_defect( - [&bestagon_lyt](const auto& cd) + [&bestagon_lyt, &is_bestagon_gate_applicable](const auto& cd) { if (is_charged_defect(cd.second)) { std::cout << "charged defects" << std::endl; - return false; + is_bestagon_gate_applicable = false; + return; } bestagon_lyt.foreach_cell( - [&cd](const auto& c) + [&cd, &is_bestagon_gate_applicable](const auto& c) { if (c.x <= cd.first.x + SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING || - (c.x >= cd.first.x - SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING && - c.y == cd.first.y)) + (c.x >= cd.first.x - SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING && c.y == cd.first.y)) { - return false; + is_bestagon_gate_applicable = false; + return; } }); }); - return true; + if (is_bestagon_gate_applicable) + { + return is_bestagon_gate_applicable; + } + bestagon_lyt.foreach_cell([&defect_lyt, &bestagon_lyt](const auto& c) + { defect_lyt.assign_cell_type(c, bestagon_lyt.get_cell_type(c)); }); + const auto status = + is_operational(defect_lyt, truth_table, is_operational_params{parameter.phys_params, parameter.sim_engine}) + .first; + return static_cast(status == operational_status::OPERATIONAL); } /** @@ -516,545 +646,1545 @@ class sidb_dynamic_gate_library : public fcn_gate_library({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate DOUBLE_WIRE{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - - static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; - - static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate({{ - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} - }})}; + static constexpr const fcn_gate CROSSING{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate DOUBLE_WIRE{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + + static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate( + {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; using port_gate_map = phmap::flat_hash_map, fcn_gate>; using double_port_gate_map = @@ -1086,6 +2216,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library : public Lyt * @return All SiDB positions affected by the defect at coordinate c. */ [[nodiscard]] std::unordered_set - affected_sidbs(const typename Lyt::coordinate& c, const bool incorporate_defect_into_gate_design = false) const noexcept + affected_sidbs(const typename Lyt::coordinate& c, const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) const noexcept { std::unordered_set influenced_sidbs{}; if (const auto d = get_sidb_defect(c); d.type != sidb_defect_type::NONE) { - const auto [horizontal_extent, vertical_extent] = defect_extent(d, incorporate_defect_into_gate_design); + const auto [horizontal_extent, vertical_extent] = defect_extent(d, incorporate_defect_into_gate_design, distance); for (auto y = static_cast(c.y - vertical_extent); y <= static_cast(c.y + vertical_extent); ++y) @@ -218,12 +218,12 @@ class sidb_surface : public Lyt * @return All SiDB positions affected by any defect on the surface. */ [[nodiscard]] std::unordered_set - all_affected_sidbs(const bool incorporate_defect_into_gate_design = false) const noexcept + all_affected_sidbs(const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) const noexcept { std::unordered_set influenced_sidbs{}; - foreach_sidb_defect([&influenced_sidbs, &incorporate_defect_into_gate_design, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design)); }); + foreach_sidb_defect([&influenced_sidbs, &incorporate_defect_into_gate_design, &distance, this](const auto& it) + { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design, distance)); }); return influenced_sidbs; } diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index 6e1ccfbae..9524d2737 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -55,7 +55,7 @@ using surface_black_list = */ template [[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, - const bool incorporate_defect_into_gate_design = false) noexcept + const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -72,7 +72,7 @@ template surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(incorporate_defect_into_gate_design); + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(incorporate_defect_into_gate_design, distance); const auto gate_implementations = GateLibrary::get_functional_implementations(); const auto gate_ports = GateLibrary::get_gate_ports(); From f29a8c3f00e7a36b40189a06b84be9917053f88e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 24 Oct 2023 15:23:34 +0200 Subject: [PATCH 029/191] :sparkles: defect-aware SiDB circuit designer with on-the-fly gate design. --- docs/algorithms/apply_gate_library.rst | 1 + docs/technology/gate_libraries.rst | 10 + .../dynamic_gate_design.cpp | 131 +- .../physical_design/apply_gate_library.hpp | 51 +- .../physical_design/design_sidb_gates.hpp | 88 +- .../fiction/technology/fcn_gate_library.hpp | 3 - include/fiction/technology/sidb_defects.hpp | 10 +- .../technology/sidb_dynamic_gate_library.hpp | 2579 +++++------------ .../sidb_skeleton_bestagon_library.hpp | 3 +- include/fiction/technology/sidb_surface.hpp | 19 +- .../technology/sidb_surface_analysis.hpp | 5 +- test/technology/sidb_dynamic_gate_library.cpp | 19 + .../sidb_skeleton_bestagon_library.cpp | 21 + test/technology/sidb_surface.cpp | 76 + 14 files changed, 1042 insertions(+), 1974 deletions(-) create mode 100644 test/technology/sidb_dynamic_gate_library.cpp create mode 100644 test/technology/sidb_skeleton_bestagon_library.cpp diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index dc0fae9c2..66067eb4a 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,3 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) +.. doxygenfunction:: fiction::apply_dynamic_gate_library diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index e58349406..4e21a0d64 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -58,3 +58,13 @@ SiDB Bestagon Library .. doxygenclass:: fiction::sidb_bestagon_library :members: + +Dynamic SiDB Bestagon Library +--------------------- + +**Header:** ``fiction/technology/sidb_dynamic_gate_library.hpp`` + +.. doxygenstruct:: fiction::sidb_dynamic_gate_library_params + :members: +.. doxygenclass:: fiction::sidb_dynamic_gate_library + :members: diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index bffeb4e3a..1ca818d44 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -9,20 +9,18 @@ #include #include // technology mapping #include // layout conversion to cell-level -#include #include // SMT-based physical design of FCN layouts #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // reader for SiQAD files -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations -#include // a dynamic SiDB gate library +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations +#include +#include // a dynamic SiDB gate library #include -#include #include // SiDB surface with support for atomic defects #include #include // pre-defined types suitable for the FCN domain @@ -43,6 +41,9 @@ #include #include +// This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SDB +// circuits can be designed in the presence of atomic defects. + int main() // NOLINT { using gate_lyt = fiction::hex_even_row_gate_clk_lyt; @@ -50,15 +51,35 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - std::vector defct_conc = {1}; + const std::vector defect_concentrations = {1, 0.5, 5}; - for (const auto& conc : defct_conc) + for (const auto& concentration : defect_concentrations) { - std::cout << conc << std::endl; - const auto surface_lattice = fiction::read_sidb_surface_defects( - fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", conc), + std::cout << fmt::format("--------------- defect concentration: {} % --------------- ", concentration) + << std::endl; + auto surface_lattice = fiction::read_sidb_surface_defects( + fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", + concentration), "py_test_surface"); + surface_lattice.foreach_sidb_defect( + [&surface_lattice](const auto& cd) + { + if (is_charged_defect(cd.second)) + { + if (cd.second.type == fiction::sidb_defect_type::DB) + { + surface_lattice.assign_sidb_defect( + cd.first, fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}); + } + else if (cd.second.type == fiction::sidb_defect_type::SI_VACANCY) + { + surface_lattice.assign_sidb_defect( + cd.first, fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}); + } + } + }); + const auto lattice_tiling = gate_lyt{{11, 30}}; experiments::experiment exact_params{}; + exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); + exact_params.crossings = false; + exact_params.border_io = false; + exact_params.desynchronize = true; + exact_params.upper_bound_x = 11; // 12 x 31 tiles + exact_params.upper_bound_y = 30; // 12 x 31 tiles + exact_params.timeout = 3'600'000; // 1h in ms + + constexpr const uint64_t bench_select = + fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & + ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & + ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { - fmt::print("[i] processing {}\n", benchmark); + fmt::print("[attempts] processing {}\n", benchmark); mockturtle::xag_network xag{}; const auto read_verilog_result = @@ -127,35 +156,41 @@ int main() // NOLINT std::optional gate_level_layout = std::nullopt; cell_lyt cell_level_layout{{}, "fail"}; - // fiction::aspect_ratio_iterator ari{1}; - std::pair pair = {0, 0}; - auto black_list = fiction::sidb_surface_analysis( - lattice_tiling, surface_lattice, true, pair); + lattice_tiling, surface_lattice, true); + + uint64_t attempts = 0; + + mockturtle::stopwatch<>::duration time_counter{}; - while (!gate_level_layout.has_value() || cell_level_layout.get_layout_name() == "fail") { - std::cout << black_list.size() << std::endl; - gate_level_layout = fiction::run( - layouts_folder, surface_lattice, lattice_tiling, benchmark, pair, black_list); - if (gate_level_layout.has_value()) - { - cell_level_layout = - fiction::apply_dynamic_gate_library( - *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, pair, - black_list); - // pair.first += 1; - // pair.second += 1; - // ari++; - } - else + const mockturtle::stopwatch stop{time_counter}; + + while (!gate_level_layout.has_value() || cell_level_layout.get_layout_name() == "fail") { - // ari++; - // pair.first += 1; - // pair.second += 1; + exact_params.black_list = black_list; + fiction::exact_physical_design_stats exact_stats{}; + if (!gate_level_layout.has_value() && attempts > 0) + { + break; + } + std::cout << black_list.size() << std::endl; + gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); + if (gate_level_layout.has_value()) + { + cell_level_layout = + fiction::apply_dynamic_gate_library( + *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, + black_list); + } + attempts++; } - std::cout << fmt::format("x: {} | y: {}", pair.first, pair.second) << std::endl; + } + + if (!gate_level_layout.has_value()) + { + continue; } // check equivalence @@ -179,15 +214,15 @@ int main() // NOLINT { defect_surface.assign_sidb_defect(defect.first, defect.second); }); // write a SiQAD simulation file fiction::write_sqd_layout(defect_surface, - fmt::format("{}/{}_after_huge_change.sqd", layouts_folder, benchmark)); + fmt::format("{}/{}_{}_percent.sqd", layouts_folder, benchmark, concentration)); // log results bestagon_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), mapped_network.num_gates(), depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1, (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(), gate_level_layout->num_wires(), - cp_tp_stats.critical_path_length, cp_tp_stats.throughput, 0.0, *eq, - cell_level_layout.num_cells(), area_stats.area); + cp_tp_stats.critical_path_length, cp_tp_stats.throughput, mockturtle::to_seconds(time_counter), + *eq, cell_level_layout.num_cells(), area_stats.area); bestagon_exp.save(); bestagon_exp.table(); } diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 106611662..0dba82dec 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -5,6 +5,7 @@ #ifndef FICTION_APPLY_GATE_LIBRARY_HPP #define FICTION_APPLY_GATE_LIBRARY_HPP +#include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/inml_topolinano_library.hpp" #include "fiction/technology/qca_one_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" @@ -32,7 +33,7 @@ namespace fiction namespace detail { -template +template class apply_gate_library_impl { public: @@ -49,14 +50,18 @@ class apply_gate_library_impl * building blocks from the `GateLibrary`. Atomic defects are incorporated into the gate designs during this * process. * + * @tparam GateLibraryblack Type of the gate-level layout used to generate the blacklist. * @param defect_surface Defect surface with atomic defects. + * @param params Parameter for the dynamic gate library. + * @param black_list Blacklist. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ + template CellLyt run_dynamic_gates( - const sidb_surface& defect_surface, - const sidb_dynamic_gate_library_params& params = sidb_dynamic_gate_library_params{}, - const std::pair& distance = {0, 0}, - surface_black_list& black_list = {}) + const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, + surface_black_list& + black_list) { #if (PROGRESS_BARS) // initialize a progress bar @@ -78,12 +83,10 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate(gate_lyt, t, defect_surface, params, distance, black_list); - if (gate == - fiction::create_array( - fiction::create_array(CellLyt::technology::cell_type::NORMAL))) + const auto gate = GateLibrary::template set_up_gate( + gate_lyt, t, defect_surface, params, black_list); + if (gate == GateLibrary::template ERROR) { - std::cout << "fail lyt" << std::endl; cell_lyt = CellLyt{{}, "fail"}; return; } @@ -101,6 +104,15 @@ class apply_gate_library_impl GateLibrary::post_layout_optimization(cell_lyt); } + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) + { + if (cell_lyt.get_layout_name() != "fail") + { + cell_lyt.set_layout_name(gate_lyt.get_layout_name()); + } + } + return cell_lyt; } @@ -204,7 +216,7 @@ class apply_gate_library_impl * @param lyt The gate-level layout. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ -template +template CellLyt apply_gate_library(const GateLyt& lyt) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -216,7 +228,7 @@ CellLyt apply_gate_library(const GateLyt& lyt) static_assert(std::is_same_v, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt}; + detail::apply_gate_library_impl p{lyt}; auto result = p.run(); @@ -232,17 +244,18 @@ CellLyt apply_gate_library(const GateLyt& lyt) * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. + * @tparam GateLibraryblack Type of the gate-level layout used to generate the blacklist. * @param lyt The gate-level layout. * @param defect_surface Defect surface with all atomic defects. + * @param params Parameter for the dynamic gate library. + * @param black_list Blacklist. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template CellLyt apply_dynamic_gate_library( - const GateLyt& lyt, const sidb_surface& defect_surface, - const sidb_dynamic_gate_library_params& params = sidb_dynamic_gate_library_params{}, - const std::pair& distance = {0, 0}, - surface_black_list - &black_list = {}) + const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, + surface_black_list< + GateLyt, typename decltype(GateLibraryblack::get_gate_ports())::mapped_type::value_type::port_type>& black_list) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -253,9 +266,9 @@ CellLyt apply_dynamic_gate_library( static_assert(std::is_same_v, technology>, "CellLyt and GateLibrary must implement the same technology"); - detail::apply_gate_library_impl p{lyt}; + detail::apply_gate_library_impl p{lyt}; - auto result = p.run_dynamic_gates(defect_surface, params, distance, black_list); + auto result = p.template run_dynamic_gates(defect_surface, params, black_list); return result; } diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index bbe0b5838..1a0100e6e 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -193,57 +193,6 @@ class design_sidb_gates_impl return designed_gate_layouts; } - // [[nodiscard]] std::vector run_exhaustive_design() noexcept - // { - // const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; - // auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); - // - // std::unordered_set sidbs_affected_by_defects = {}; - // - // if constexpr (has_get_sidb_defect_v) - // { - // sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(true); - // } - // - // std::vector designed_gate_layouts = {}; - // - // // Shuffle the vector randomly - // std::random_device rd; - // std::mt19937 g(rd()); - // std::shuffle(all_combinations.begin(), all_combinations.end(), g); - // - // for (const auto& combination : all_combinations) - // { - // if (!are_sidbs_too_close(combination, sidbs_affected_by_defects)) - // { - // auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(combination); - // - // if constexpr (has_get_sidb_defect_v) - // { - // layout_with_added_cells.foreach_sidb_defect( - // [&layout_with_added_cells](const auto& cd) - // { - // if (is_neutrally_charged_defect(cd.second)) - // { - // layout_with_added_cells.assign_sidb_defect(cd.first, - // sidb_defect{sidb_defect_type::NONE}); - // } - // }); - // } - // - // if (const auto [status, sim_calls] = - // is_operational(layout_with_added_cells, truth_table, params_is_operational); - // status == operational_status::OPERATIONAL) - // { - // designed_gate_layouts.push_back(layout_with_added_cells); - // break; // Stop after finding the first solution - // } - // } - // } - // - // return designed_gate_layouts; - // } - /** * Design gates randomly and in parallel. * @@ -309,10 +258,6 @@ class design_sidb_gates_impl gate_layout_is_found = true; break; } - // { - // const std::lock_guard - // lock{mutex_to_protect_designed_gate_layouts}; counter += 1; - // } } }); } @@ -396,12 +341,22 @@ class design_sidb_gates_impl { for (std::size_t i = 0; i < cell_indices.size(); i++) { + if constexpr (has_get_sidb_defect_v) + { + if (skeleton_layout.get_sidb_defect(all_sidbs_in_cavas[cell_indices[i]]).type != sidb_defect_type::NONE) + { + return true; + } + } + if (affected_cells.count(all_sidbs_in_cavas[cell_indices[i]]) > 0) + { + return true; + } for (std::size_t j = i + 1; j < cell_indices.size(); j++) { if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5 || - affected_cells.count(all_sidbs_in_cavas[cell_indices[i]]) > 0) + all_sidbs_in_cavas[cell_indices[j]]) < 0.5) { return true; } @@ -483,24 +438,11 @@ template if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) { - const auto exhaustive = p.run_exhaustive_design(); - if (exhaustive.empty()) - { - std::cout << "no result" << std::endl; - } - return exhaustive; + return p.run_exhaustive_design(); } - std::vector found_lyts{}; - while (found_lyts.empty()) - { - design_sidb_gates_params parameter{params}; - detail::design_sidb_gates_impl p_random{skeleton, spec, parameter}; - const auto result = p.run_random_design(); - found_lyts = result; - parameter.number_of_sidbs += 1; - } - return found_lyts; + detail::design_sidb_gates_impl p_random{skeleton, spec, params}; + return p.run_random_design(); } } // namespace fiction diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index 62d10e5f5..5750cc2a3 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -317,9 +317,6 @@ class fcn_gate_library */ static constexpr const fcn_gate EMPTY_GATE = fiction::create_array(fiction::create_array(Technology::cell_type::EMPTY)); - - static constexpr const fcn_gate ERROR = - fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); }; } // namespace fiction diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 27431d4e8..8775877f8 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -171,18 +171,20 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; * `NONE` defect type, `{0, 0}` is returned. * * @param defect Defect type to evaluate. - * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, - * `false`otherwise. + * @param incorporate_defect_into_gate_design If set to `true`, the influence of charged atomic defects on SiDBs + * is given by the input `charged_defect_spacing`. If set to `false`, default values are used. + * @param charged_defect_spacing Influence of charged atomic defects on SiDBs. * @return Number of horizontal and vertical SiDBs that are affected by the given defect type. */ [[nodiscard]] static constexpr std::pair -defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) noexcept +defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false, + const std::pair& charged_defect_spacing = {0, 0}) noexcept { if (is_charged_defect(defect)) { if (incorporate_defect_into_gate_design) { - return distance; + return charged_defect_spacing; } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 99d7d74b3..37c897269 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -1,5 +1,5 @@ // -// Created by marcel on 15.09.23. +// Created by Jan Drewniok 20.09.23. // #ifndef FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP @@ -11,7 +11,6 @@ #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" -#include "fiction/technology/sidb_skeleton_bestagon_library_optimized.hpp" #include "fiction/technology/sidb_surface.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" @@ -31,20 +30,42 @@ struct sidb_dynamic_gate_library_params {{24, 8, 1}, {34, 14, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; + + uint64_t canvas_sidb_complex_gates = 4; + + double influence_radius_charged_defects = 15; }; +/** + * An on-the-fly gate library for SiDB technology. It allows the design of SiDB gates tailored to given atomic defects, + * thus enabling the design of SiDB circuits in the presence of atomic defects. + */ class sidb_dynamic_gate_library : public fcn_gate_library // width and height of a hexagon { public: explicit sidb_dynamic_gate_library() = delete; - template + /** + * Overrides the corresponding function in fcn_gate_library. Given a tile `t`, this function takes all necessary + * information from the stored grid into account to design the correct fcn_gate representation for that tile. In + * case there is no possible SiDB design, the blacklist is updated and an error fcn gate is returned. + * + * @tparam GateLyt Pointy-top hexagonal gate-level layout type. + * @tparam CellLyt The type of the cell-level layout. + * @tparam GateLibraryblack Type of the gate-level layout used to generate the blacklist. + * @param lyt Layout that hosts tile `t`. + * @param t Tile to be realized as a Bestagon gate. + * @param sidb_surface SiDB durface which stores all atomic defects. + * @param parameter Parameter to design SiDB gates on-the-fly. + * @param black_list A blacklist to avoid gate placements on certain ports. + * @return Bestagon gate representation of `t` including mirroring. + */ + template static fcn_gate set_up_gate( const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, const sidb_dynamic_gate_library_params& parameter = sidb_dynamic_gate_library_params{}, - const std::pair& distance = {0, 0}, surface_black_list& + typename decltype(GateLibraryblack::get_gate_ports())::mapped_type::value_type::port_type>& black_list = {}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); @@ -60,36 +81,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library( lyt, t, cell{0, 0}); - auto absolute_cell_siqad = fiction::siqad::to_siqad_coord(absolute_cell); - auto center_cell_siqad = fiction::siqad::to_siqad_coord(center_cell); - - auto layout = sidb_defect_cell_clk_lyt_siqad{}; - auto update_layout = [&layout, ¢er_cell_siqad, &absolute_cell_siqad](const auto& cd) - { - // all defects (charged) in a distance of 60 from the center are taken into account. - if (sidb_nanometer_distance(sidb_cell_clk_lyt_siqad{}, fiction::siqad::to_siqad_coord(cd.first), - center_cell_siqad) < 15) - { - auto defect_pos_siqad = fiction::siqad::to_siqad_coord(cd.first); - auto shifted_defect_cell = defect_pos_siqad - absolute_cell_siqad; - if (is_charged_defect(cd.second)) - { - if (cd.second.type == sidb_defect_type::DB) - { - layout.assign_sidb_defect(shifted_defect_cell, sidb_defect{sidb_defect_type::DB, -1, 4.1, 1.8}); - } - else if (cd.second.type == sidb_defect_type::SI_VACANCY) - { - layout.assign_sidb_defect(shifted_defect_cell, - sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}); - } - } - else - { - layout.assign_sidb_defect(shifted_defect_cell, cd.second); - } - } - }; + const auto absolute_cell_siqad = fiction::siqad::to_siqad_coord(absolute_cell); + const auto center_cell_siqad = fiction::siqad::to_siqad_coord(center_cell); try { @@ -99,23 +92,14 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - const auto found_gate_layouts = - design_sidb_gates(layout, create_fan_out_tt(), parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); + + return design_gate( + layout, create_fan_out_tt(), parameter.params, black_list, p, t); } } } @@ -135,9 +119,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(cell_list), + center_cell_siqad, absolute_cell_siqad, parameter); if (is_bestagon_gate_applicable( cell_list_to_cell_level_layout(DOUBLE_WIRE), layout, @@ -146,35 +131,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - fiction::write_sqd_layout( - layout, fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - auto complex_gate_param = parameter; - complex_gate_param.params.number_of_sidbs = 4; - const auto found_gate_layouts = - design_sidb_gates(layout, create_double_wire_tt(), complex_gate_param.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished hourglass" << std::endl; - return cell_list_to_gate(list); + complex_gate_param.params.number_of_sidbs = parameter.canvas_sidb_complex_gates; + return design_gate( + layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); } - layout = cell_list_to_cell_level_layout(cell_list); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, cell_list_to_cell_level_layout(cell_list), + center_cell_siqad, absolute_cell_siqad, parameter); if (is_bestagon_gate_applicable( cell_list_to_cell_level_layout(CROSSING), layout, @@ -183,30 +148,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - fiction::write_sqd_layout( - layout, fmt::format("{}/{}.sqd", - "/Users/jandrewniok/CLionProjects/fiction_fork/" - "experiments/defect_aware_physical_design/single_gates", - n)); - auto complex_gate_param = parameter; - complex_gate_param.params.number_of_sidbs = 4; - const auto found_gate_layouts = - design_sidb_gates(layout, create_crossing_wire_tt(), complex_gate_param.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - std::cout << "finished crossing" << std::endl; - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - return cell_list_to_gate(list); + complex_gate_param.params.number_of_sidbs = parameter.canvas_sidb_complex_gates; + return design_gate( + layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); } auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); @@ -214,21 +159,12 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, cell_list_to_cell_level_layout(cell_list), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } return EMPTY_GATE; } @@ -237,227 +173,143 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(ONE_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_and_v) { if (lyt.is_and(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_or_v) { if (lyt.is_or(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_nand_v) { if (lyt.is_nand(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_nor_v) { if (lyt.is_nor(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_xor_v) { if (lyt.is_xor(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_xnor_v) { if (lyt.is_xnor(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_ge_v) { if (lyt.is_ge(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_le_v) { if (lyt.is_le(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); - - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_gt_v) { if (lyt.is_gt(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_lt_v) { if (lyt.is_lt(n)) { - layout = cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)); - // erase defects - sidb_surface.foreach_sidb_defect(update_layout); + const auto layout = add_defect_in_the_surrounding_to_layout( + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell_siqad, absolute_cell_siqad, parameter); - const auto found_gate_layouts = design_sidb_gates(layout, std::vector{f}, parameter.params); - if (found_gate_layouts.empty()) - { - std::cout << fmt::format("old: {}", black_list[t][f].size()) << std::endl; - black_list[t][f].push_back(p); - std::cout << fmt::format("new: {}", black_list[t][f].size()) << std::endl; - return ERROR; - } - const auto list = cell_level_layout_to_list(found_gate_layouts.front()); - std::cout << "finished" << std::endl; - return cell_list_to_gate(list); + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } } @@ -467,11 +319,32 @@ class sidb_dynamic_gate_library : public fcn_gate_library + static constexpr const fcn_gate ERROR = + fiction::create_array(fiction::create_array(CellLyt::cell_type::NORMAL)); + private: + /** + * This function evaluates whether a Bestagon gate can be applied to the given node by considering + * various conditions, including the presence of defects and spacing requirements. + * + * @tparam Lyt The type of the cell-level layout. + * @param bestagon_lyt The Bestagon gate which is to be applied. + * @param defect_lyt The layout with defects that may affect gate applicability. + * @param parameter Parameters for the gate design and simulation. + * @param truth_table The truth table representing the gate's logic function. + * @return `true` if the Bestagon gate is applicable to the layout, considering the provided conditions; + * otherwise, returns `false`. + */ template - static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, sidb_surface defect_lyt, - const design_sidb_gates_params& parameter, - const std::vector& truth_table) + [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, sidb_surface defect_lyt, + const design_sidb_gates_params& parameter, + const std::vector& truth_table) { bool is_bestagon_gate_applicable = true; defect_lyt.foreach_sidb_defect( @@ -479,7 +352,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static std::array, gate_y_size()> cell_level_layout_to_list(const Lyt& lyt) + [[nodiscard]] static std::array, gate_y_size()> + cell_level_layout_to_list(const Lyt& lyt) { std::array, gate_y_size()> result{}; const auto all_cell = @@ -533,22 +406,52 @@ class sidb_dynamic_gate_library : public fcn_gate_library + [[nodiscard]] static fcn_gate design_gate( + const Lyt& skeleton, const std::vector& t, const design_sidb_gates_params& params, + surface_black_list< + GateLyt, typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type>& black_list, + const port_list& p, const tile& tile) + { + const auto found_gate_layouts = design_sidb_gates(skeleton, std::vector{t}, params); + if (found_gate_layouts.empty()) + { + black_list[tile][t.front()].push_back(p); + return ERROR; + } + + return cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + } /** - * The function generates a layout (lyt) where each cell is assigned a specific - * cell type according to the characters in the cell list /input grid. + * The function generates a layout where each cell is assigned a specific + * cell type according to the characters in the cell list/input grid. * * @tparam Lyt The type of the cell-level layout to be generated. * @param cell_list A 2D grid representing the cells and their types. * @return The cell-level layout with assigned cell types. */ template - static Lyt cell_list_to_cell_level_layout(const fcn_gate& cell_list) noexcept + [[nodiscard]] static Lyt cell_list_to_cell_level_layout(const fcn_gate& cell_list) noexcept { - Lyt lyt{}; + Lyt lyt{aspect_ratio{gate_x_size(), gate_y_size()}}; const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); @@ -582,6 +485,44 @@ class sidb_dynamic_gate_library : public fcn_gate_library + [[nodiscard]] static LytSkeleton add_defect_in_the_surrounding_to_layout( + const sidb_surface& defect_surface, const LytSkeleton& skeleton, const siqad::coord_t& center_cell_siqad, + const siqad::coord_t& absolute_cell_siqad, const sidb_dynamic_gate_library_params& params) + { + static_assert(!has_siqad_coord_v, "Lyt has SiQAD coordinates."); + static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates."); + auto lyt_copy = LytSkeleton{skeleton.clone()}; + defect_surface.foreach_sidb_defect( + [&defect_surface, &lyt_copy, &skeleton, ¢er_cell_siqad, &absolute_cell_siqad, ¶ms](const auto& cd) + { + // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken + // into account. + if (sidb_nanometer_distance(sidb_cell_clk_lyt_siqad{}, fiction::siqad::to_siqad_coord(cd.first), + center_cell_siqad) < params.influence_radius_charged_defects) + { + const auto defect_position_in_siqad_coordinate = fiction::siqad::to_siqad_coord(cd.first); + const auto relative_cell = defect_position_in_siqad_coordinate - absolute_cell_siqad; + lyt_copy.assign_sidb_defect(relative_cell, cd.second); + } + }); + return lyt_copy; + } + /** * This function determines the port routing for a specific tile within a layout represented by the object `lyt` of * type `Lyt`. It examines the tile's characteristics and connectivity to determine the appropriate incoming and @@ -646,1545 +587,549 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate DOUBLE_WIRE{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; - - static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate( - {{{' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, - {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', - ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}}})}; + // clang-format off + + static constexpr const fcn_gate CROSSING{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate DOUBLE_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + + static constexpr const fcn_gate STRAIGHT_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_STRAIGHT_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_DIAGONAL_WIRE{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_TWO_IN_ONE_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate MIRRORED_FANOUT_1_2{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + static constexpr const fcn_gate TWO_IN_TWO_OUT{cell_list_to_gate({{ + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'i', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}, + {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '} + }})}; + + // clang-format on using port_gate_map = phmap::flat_hash_map, fcn_gate>; using double_port_gate_map = diff --git a/include/fiction/technology/sidb_skeleton_bestagon_library.hpp b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp index ba23d17dc..c802afb8f 100644 --- a/include/fiction/technology/sidb_skeleton_bestagon_library.hpp +++ b/include/fiction/technology/sidb_skeleton_bestagon_library.hpp @@ -22,7 +22,7 @@ namespace fiction { /** - * A SiDB skeleton gate library for all two input Boolean functions + * A Bestagon SiDB skeleton gate library for all two input Boolean functions. */ class sidb_skeleton_bestagon_library : public fcn_gate_library // width and height of a hexagon @@ -606,7 +606,6 @@ class sidb_skeleton_bestagon_library }})}; // clang-format on - }; } // namespace fiction diff --git a/include/fiction/technology/sidb_surface.hpp b/include/fiction/technology/sidb_surface.hpp index a32484a50..aac2d9502 100644 --- a/include/fiction/technology/sidb_surface.hpp +++ b/include/fiction/technology/sidb_surface.hpp @@ -178,18 +178,21 @@ class sidb_surface : public Lyt * If the given coordinate is defect-free, the empty set is returned. * * @param c Coordinate whose defect extent is to be determined. - * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, - * `false`otherwise. + * @param user_defined_spacing_charged_defects If set to `true`, the influence of charged atomic defects on SiDBs + * is given by the input `charged_defect_spacing`. If set to `false`, default values are used. + * @param charged_defect_spacing Influence of charged atomic defects on SiDBs. * @return All SiDB positions affected by the defect at coordinate c. */ [[nodiscard]] std::unordered_set - affected_sidbs(const typename Lyt::coordinate& c, const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) const noexcept + affected_sidbs(const typename Lyt::coordinate& c, const bool user_defined_spacing_charged_defects = false, + const std::pair& charged_defect_spacing = {0, 0}) const noexcept { std::unordered_set influenced_sidbs{}; if (const auto d = get_sidb_defect(c); d.type != sidb_defect_type::NONE) { - const auto [horizontal_extent, vertical_extent] = defect_extent(d, incorporate_defect_into_gate_design, distance); + const auto [horizontal_extent, vertical_extent] = + defect_extent(d, user_defined_spacing_charged_defects, charged_defect_spacing); for (auto y = static_cast(c.y - vertical_extent); y <= static_cast(c.y + vertical_extent); ++y) @@ -218,12 +221,14 @@ class sidb_surface : public Lyt * @return All SiDB positions affected by any defect on the surface. */ [[nodiscard]] std::unordered_set - all_affected_sidbs(const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) const noexcept + all_affected_sidbs(const bool incorporate_defect_into_gate_design = false, + const std::pair& distance = {0, 0}) const noexcept { std::unordered_set influenced_sidbs{}; - foreach_sidb_defect([&influenced_sidbs, &incorporate_defect_into_gate_design, &distance, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design, distance)); }); + foreach_sidb_defect( + [&influenced_sidbs, &incorporate_defect_into_gate_design, &distance, this](const auto& it) + { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design, distance)); }); return influenced_sidbs; } diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index 9524d2737..8e08d3801 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -51,11 +51,14 @@ using surface_black_list = * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. * @param surface SiDB surface that instantiates the defects. + * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, + * `false`otherwise. * @return A black list of gate functions associated with tiles. */ template [[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, - const bool incorporate_defect_into_gate_design = false, const std::pair &distance = {0,0}) noexcept + const bool incorporate_defect_into_gate_design = false, + const std::pair& distance = {0, 0}) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); diff --git a/test/technology/sidb_dynamic_gate_library.cpp b/test/technology/sidb_dynamic_gate_library.cpp new file mode 100644 index 000000000..ea27cf0bd --- /dev/null +++ b/test/technology/sidb_dynamic_gate_library.cpp @@ -0,0 +1,19 @@ +// +// Created by Jan Drewniok on 24.10.23. +// + +#include + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Bestagon traits", "[sidb-dynamic-gate-library]") +{ + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); +} diff --git a/test/technology/sidb_skeleton_bestagon_library.cpp b/test/technology/sidb_skeleton_bestagon_library.cpp new file mode 100644 index 000000000..246193810 --- /dev/null +++ b/test/technology/sidb_skeleton_bestagon_library.cpp @@ -0,0 +1,21 @@ +// +// Created by Jan Drewniok on 24.10.23. +// + +#include + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Bestagon traits", "[sidb-dynamic-gate-library]") +{ + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(has_get_functional_implementations_v); + CHECK(has_get_gate_ports_v); +} diff --git a/test/technology/sidb_surface.cpp b/test/technology/sidb_surface.cpp index b83c80142..11f16d16c 100644 --- a/test/technology/sidb_surface.cpp +++ b/test/technology/sidb_surface.cpp @@ -240,6 +240,82 @@ TEMPLATE_TEST_CASE( {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); } + + SECTION("charged defects, user_defined_spacing_charged_defects is true, (26,13) as charged_defect_spacing") + { + // assign defects + defect_layout.assign_sidb_defect({5, 4}, sidb_defect{sidb_defect_type::SI_VACANCY}); + defect_layout.assign_sidb_defect({5, 5}, sidb_defect{sidb_defect_type::SI_VACANCY}); + + CHECK(defect_layout.num_defects() == 2); + + CHECK(defect_layout.affected_sidbs({5, 4}, true, {26, 13}) == + decltype(defect_layout.affected_sidbs({5, 4})){ + {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, + {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}, {8, 2}, {9, 2}, {10, 2}, {11, 2}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {8, 3}, {9, 3}, {10, 3}, {11, 3}, + {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, + {0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, + {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {10, 6}, {11, 6}, + {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, + {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, + {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); + + CHECK(defect_layout.affected_sidbs({5, 5}, true, {26, 13}) == + decltype(defect_layout.affected_sidbs({5, 5})){ + {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, + {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}, {8, 2}, {9, 2}, {10, 2}, {11, 2}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {8, 3}, {9, 3}, {10, 3}, {11, 3}, + {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, + {0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, + {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {10, 6}, {11, 6}, + {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, + {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, + {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); + + CHECK(defect_layout.all_affected_sidbs(true, {26, 13}) == + decltype(defect_layout.all_affected_sidbs()){ + {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, + {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, + {0, 2}, {1, 2}, {2, 2}, {3, 2}, {4, 2}, {5, 2}, {6, 2}, {7, 2}, {8, 2}, {9, 2}, {10, 2}, {11, 2}, + {0, 3}, {1, 3}, {2, 3}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {8, 3}, {9, 3}, {10, 3}, {11, 3}, + {0, 4}, {1, 4}, {2, 4}, {3, 4}, {4, 4}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, + {0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5}, {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, + {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {10, 6}, {11, 6}, + {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, + {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, + {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); + } + + SECTION("charged defects, user_defined_spacing_charged_defects is true, (0,0) as charged_defect_spacing") + { + // assign defects + defect_layout.assign_sidb_defect({5, 4}, sidb_defect{sidb_defect_type::SI_VACANCY}); + defect_layout.assign_sidb_defect({5, 5}, sidb_defect{sidb_defect_type::SI_VACANCY}); + + CHECK(defect_layout.num_defects() == 2); + + CHECK(defect_layout.affected_sidbs({5, 4}, true) == decltype(defect_layout.affected_sidbs({5, 4})){{{5, 4}}}); + + CHECK(defect_layout.affected_sidbs({5, 4}, true, {2, 1}) == + decltype(defect_layout.affected_sidbs({5, 4})){{{3, 3}, + {4, 3}, + {5, 3}, + {6, 3}, + {7, 3}, + {3, 4}, + {4, 4}, + {5, 4}, + {6, 4}, + {7, 4}, + {3, 5}, + {4, 5}, + {5, 5}, + {6, 5}, + {7, 5}}}); + } SECTION("neutral defects") { // assign defects From e9ee1e19d1cbbd1a40a8bd052a6aed7a180daa29 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 24 Oct 2023 15:32:50 +0200 Subject: [PATCH 030/191] :art: small fix. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 2 +- include/fiction/technology/sidb_dynamic_gate_library.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 0dba82dec..9445fd300 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -133,7 +133,7 @@ class apply_gate_library_impl mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif gate_lyt.foreach_node( - [&, this](const auto& n, [[maybe_unused]] auto i) + [this, &bar](const auto& n, [[maybe_unused]] auto i) { if (!gate_lyt.is_constant(n)) { diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 37c897269..b8f2ac849 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -33,7 +33,7 @@ struct sidb_dynamic_gate_library_params uint64_t canvas_sidb_complex_gates = 4; - double influence_radius_charged_defects = 15; + double influence_radius_charged_defects = 15; // (unit: nm) }; /** From 9078a51b9cd3167df32f688bf17a32a1ba8e6b2d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 24 Oct 2023 15:42:13 +0200 Subject: [PATCH 031/191] :fire: delete bestagon.json --- experiments/bestagon.json | 815 -------------------------------------- 1 file changed, 815 deletions(-) delete mode 100644 experiments/bestagon.json diff --git a/experiments/bestagon.json b/experiments/bestagon.json deleted file mode 100644 index c625e1658..000000000 --- a/experiments/bestagon.json +++ /dev/null @@ -1,815 +0,0 @@ -[ - { - "entries": [ - { - "SiDB dots": 196, - "benchmark": "trindade16/mux21", - "critical path": 6, - "depth after mapping": 3, - "depth after optimization": 2, - "equivalent": true, - "gates": 4, - "initial depth": 2, - "initial nodes": 3, - "inputs": 3, - "layout area (in tiles)": 18, - "layout area in nm²": 7258.521600000001, - "layout height (in tiles)": 6, - "layout width (in tiles)": 3, - "nodes after mapping": 4, - "nodes after optimization": 3, - "outputs": 1, - "runtime (in sec)": 0.030918402, - "throughput": 1, - "wires": 10 - }, - { - "SiDB dots": 58, - "benchmark": "trindade16/xor2", - "critical path": 3, - "depth after mapping": 1, - "depth after optimization": 2, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 6, - "layout area in nm²": 2403.975168, - "layout height (in tiles)": 3, - "layout width (in tiles)": 2, - "nodes after mapping": 1, - "nodes after optimization": 3, - "outputs": 1, - "runtime (in sec)": 0.004286501, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 58, - "benchmark": "trindade16/xnor2", - "critical path": 3, - "depth after mapping": 1, - "depth after optimization": 2, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 6, - "layout area in nm²": 2403.975168, - "layout height (in tiles)": 3, - "layout width (in tiles)": 2, - "nodes after mapping": 1, - "nodes after optimization": 3, - "outputs": 1, - "runtime (in sec)": 0.004211561, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 103, - "benchmark": "trindade16/par_gen", - "critical path": 4, - "depth after mapping": 2, - "depth after optimization": 3, - "equivalent": true, - "gates": 2, - "initial depth": 4, - "initial nodes": 6, - "inputs": 3, - "layout area (in tiles)": 12, - "layout area in nm²": 4830.216192000001, - "layout height (in tiles)": 4, - "layout width (in tiles)": 3, - "nodes after mapping": 2, - "nodes after optimization": 4, - "outputs": 1, - "runtime (in sec)": 0.007178205, - "throughput": 1, - "wires": 5 - }, - { - "SiDB dots": 173, - "benchmark": "trindade16/HA", - "critical path": 5, - "depth after mapping": 1, - "depth after optimization": 2, - "equivalent": true, - "gates": 2, - "initial depth": 2, - "initial nodes": 4, - "inputs": 2, - "layout area (in tiles)": 15, - "layout area in nm²": 6044.368896000001, - "layout height (in tiles)": 5, - "layout width (in tiles)": 3, - "nodes after mapping": 2, - "nodes after optimization": 4, - "outputs": 2, - "runtime (in sec)": 0.027165767, - "throughput": 1, - "wires": 10 - }, - { - "SiDB dots": 404, - "benchmark": "trindade16/FA", - "critical path": 9, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 5, - "initial depth": 3, - "initial nodes": 5, - "inputs": 3, - "layout area (in tiles)": 27, - "layout area in nm²": 10900.979712000002, - "layout height (in tiles)": 9, - "layout width (in tiles)": 3, - "nodes after mapping": 5, - "nodes after optimization": 5, - "outputs": 2, - "runtime (in sec)": 0.0423338, - "throughput": 1, - "wires": 24 - }, - { - "SiDB dots": 284, - "benchmark": "trindade16/par_check", - "critical path": 7, - "depth after mapping": 4, - "depth after optimization": 3, - "equivalent": true, - "gates": 6, - "initial depth": 4, - "initial nodes": 9, - "inputs": 4, - "layout area (in tiles)": 28, - "layout area in nm²": 11312.676864, - "layout height (in tiles)": 7, - "layout width (in tiles)": 4, - "nodes after mapping": 6, - "nodes after optimization": 7, - "outputs": 1, - "runtime (in sec)": 0.029391255, - "throughput": 1, - "wires": 13 - }, - { - "SiDB dots": 58, - "benchmark": "fontes18/xor", - "critical path": 3, - "depth after mapping": 1, - "depth after optimization": 2, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 6, - "layout area in nm²": 2403.975168, - "layout height (in tiles)": 3, - "layout width (in tiles)": 2, - "nodes after mapping": 1, - "nodes after optimization": 3, - "outputs": 1, - "runtime (in sec)": 0.004887973, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 404, - "benchmark": "fontes18/1bitAdderAOIG", - "critical path": 9, - "depth after mapping": 3, - "depth after optimization": 4, - "equivalent": true, - "gates": 5, - "initial depth": 4, - "initial nodes": 7, - "inputs": 3, - "layout area (in tiles)": 27, - "layout area in nm²": 10900.979712000002, - "layout height (in tiles)": 9, - "layout width (in tiles)": 3, - "nodes after mapping": 5, - "nodes after optimization": 6, - "outputs": 2, - "runtime (in sec)": 0.04309465, - "throughput": 1, - "wires": 24 - }, - { - "SiDB dots": 426, - "benchmark": "fontes18/t", - "critical path": 8, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 40, - "layout area in nm²": 16180.789248, - "layout height (in tiles)": 8, - "layout width (in tiles)": 5, - "nodes after mapping": 6, - "nodes after optimization": 6, - "outputs": 2, - "runtime (in sec)": 0.059703367, - "throughput": 1, - "wires": 24 - }, - { - "SiDB dots": 448, - "benchmark": "fontes18/t_5", - "critical path": 8, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 40, - "layout area in nm²": 16180.789248, - "layout height (in tiles)": 8, - "layout width (in tiles)": 5, - "nodes after mapping": 6, - "nodes after optimization": 6, - "outputs": 2, - "runtime (in sec)": 0.058928829, - "throughput": 1, - "wires": 26 - }, - { - "SiDB dots": 396, - "benchmark": "fontes18/c17", - "critical path": 8, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 40, - "layout area in nm²": 16180.789248, - "layout height (in tiles)": 8, - "layout width (in tiles)": 5, - "nodes after mapping": 6, - "nodes after optimization": 6, - "outputs": 2, - "runtime (in sec)": 0.05108846, - "throughput": 1, - "wires": 22 - }, - { - "SiDB dots": 651, - "benchmark": "fontes18/majority", - "critical path": 11, - "depth after mapping": 5, - "depth after optimization": 5, - "equivalent": true, - "gates": 11, - "initial depth": 5, - "initial nodes": 8, - "inputs": 5, - "layout area (in tiles)": 55, - "layout area in nm²": 22265.118720000002, - "layout height (in tiles)": 11, - "layout width (in tiles)": 5, - "nodes after mapping": 11, - "nodes after optimization": 8, - "outputs": 1, - "runtime (in sec)": 0.278753251, - "throughput": 1, - "wires": 36 - }, - { - "SiDB dots": 737, - "benchmark": "fontes18/majority_5_r1", - "critical path": 12, - "depth after mapping": 6, - "depth after optimization": 6, - "equivalent": true, - "gates": 10, - "initial depth": 4, - "initial nodes": 8, - "inputs": 5, - "layout area (in tiles)": 60, - "layout area in nm²": 24293.228544, - "layout height (in tiles)": 12, - "layout width (in tiles)": 5, - "nodes after mapping": 10, - "nodes after optimization": 8, - "outputs": 1, - "runtime (in sec)": 0.154010165, - "throughput": 1, - "wires": 44 - }, - { - "SiDB dots": 651, - "benchmark": "fontes18/newtag", - "critical path": 10, - "depth after mapping": 6, - "depth after optimization": 6, - "equivalent": true, - "gates": 11, - "initial depth": 5, - "initial nodes": 9, - "inputs": 8, - "layout area (in tiles)": 80, - "layout area in nm²": 32419.823616, - "layout height (in tiles)": 10, - "layout width (in tiles)": 8, - "nodes after mapping": 11, - "nodes after optimization": 9, - "outputs": 1, - "runtime (in sec)": 0.18991355, - "throughput": 1, - "wires": 34 - }, - { - "SiDB dots": 232, - "benchmark": "fontes18/xor5_r1", - "critical path": 6, - "depth after mapping": 3, - "depth after optimization": 4, - "equivalent": true, - "gates": 4, - "initial depth": 6, - "initial nodes": 12, - "inputs": 5, - "layout area (in tiles)": 30, - "layout area in nm²": 12124.5696, - "layout height (in tiles)": 6, - "layout width (in tiles)": 5, - "nodes after mapping": 4, - "nodes after optimization": 8, - "outputs": 1, - "runtime (in sec)": 0.026982434, - "throughput": 1, - "wires": 12 - }, - { - "SiDB dots": 255, - "benchmark": "fontes18/1bitAdderMaj", - "critical path": 7, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 5, - "initial depth": 9, - "initial nodes": 14, - "inputs": 3, - "layout area (in tiles)": 21, - "layout area in nm²": 8472.674304, - "layout height (in tiles)": 7, - "layout width (in tiles)": 3, - "nodes after mapping": 5, - "nodes after optimization": 4, - "outputs": 1, - "runtime (in sec)": 0.022231768, - "throughput": 1, - "wires": 13 - }, - { - "SiDB dots": 1211, - "benchmark": "fontes18/cm82a_5", - "critical path": 15, - "depth after mapping": 5, - "depth after optimization": 5, - "equivalent": true, - "gates": 12, - "initial depth": 5, - "initial nodes": 20, - "inputs": 5, - "layout area (in tiles)": 75, - "layout area in nm²": 30377.558016000003, - "layout height (in tiles)": 15, - "layout width (in tiles)": 5, - "nodes after mapping": 12, - "nodes after optimization": 16, - "outputs": 3, - "runtime (in sec)": 704.005429589, - "throughput": 1, - "wires": 78 - }, - { - "SiDB dots": 244, - "benchmark": "fontes18/xor5Maj", - "critical path": 6, - "depth after mapping": 3, - "depth after optimization": 3, - "equivalent": true, - "gates": 4, - "initial depth": 12, - "initial nodes": 30, - "inputs": 5, - "layout area (in tiles)": 30, - "layout area in nm²": 12124.5696, - "layout height (in tiles)": 6, - "layout width (in tiles)": 5, - "nodes after mapping": 4, - "nodes after optimization": 4, - "outputs": 1, - "runtime (in sec)": 0.028480768, - "throughput": 1, - "wires": 13 - } - ], - "version": "4926a76" - }, - { - "entries": [ - { - "SiDB dots": 196, - "benchmark": "fontes18/xor5Maj", - "critical path": 6, - "equivalent": true, - "gates": 4, - "initial depth": 12, - "initial nodes": 30, - "inputs": 5, - "layout area (in tiles)": 30, - "layout area in nm²": 12124.5696, - "layout height (in tiles)": 6, - "layout width (in tiles)": 5, - "optimized depth": 3, - "optimized nodes": 4, - "outputs": 1, - "runtime (in sec)": 0.054599833, - "throughput": 1, - "wires": 11 - } - ], - "version": "36639cd7" - }, - { - "entries": [ - { - "SiDB dots": 136, - "benchmark": "trindade16/mux21", - "critical path": 5, - "equivalent": true, - "gates": 3, - "initial depth": 2, - "initial nodes": 3, - "inputs": 3, - "layout area (in tiles)": 70, - "layout area in nm²": 28330.868736, - "layout height (in tiles)": 5, - "layout width (in tiles)": 14, - "optimized depth": 2, - "optimized nodes": 3, - "outputs": 1, - "runtime (in sec)": 1.402220665, - "throughput": 1, - "wires": 7 - }, - { - "SiDB dots": 52, - "benchmark": "trindade16/xor2", - "critical path": 3, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 36, - "layout area in nm²": 14524.858368000001, - "layout height (in tiles)": 3, - "layout width (in tiles)": 12, - "optimized depth": 1, - "optimized nodes": 1, - "outputs": 1, - "runtime (in sec)": 0.32591325, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 52, - "benchmark": "trindade16/xnor2", - "critical path": 3, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 36, - "layout area in nm²": 14524.858368000001, - "layout height (in tiles)": 3, - "layout width (in tiles)": 12, - "optimized depth": 1, - "optimized nodes": 1, - "outputs": 1, - "runtime (in sec)": 0.330557, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 92, - "benchmark": "trindade16/par_gen", - "critical path": 4, - "equivalent": true, - "gates": 2, - "initial depth": 4, - "initial nodes": 6, - "inputs": 3, - "layout area (in tiles)": 48, - "layout area in nm²": 19401.818112, - "layout height (in tiles)": 4, - "layout width (in tiles)": 12, - "optimized depth": 2, - "optimized nodes": 2, - "outputs": 1, - "runtime (in sec)": 0.491098289, - "throughput": 1, - "wires": 5 - }, - { - "SiDB dots": 380, - "benchmark": "trindade16/FA", - "critical path": 9, - "equivalent": true, - "gates": 5, - "initial depth": 3, - "initial nodes": 5, - "inputs": 3, - "layout area (in tiles)": 135, - "layout area in nm²": 54748.49587200001, - "layout height (in tiles)": 9, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 5, - "outputs": 2, - "runtime (in sec)": 12.750889498, - "throughput": 1, - "wires": 25 - }, - { - "SiDB dots": 208, - "benchmark": "trindade16/par_check", - "critical path": 6, - "equivalent": true, - "gates": 5, - "initial depth": 4, - "initial nodes": 9, - "inputs": 4, - "layout area (in tiles)": 90, - "layout area in nm²": 36454.8096, - "layout height (in tiles)": 6, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 5, - "outputs": 1, - "runtime (in sec)": 3.033809333, - "throughput": 1, - "wires": 10 - }, - { - "SiDB dots": 52, - "benchmark": "fontes18/xor", - "critical path": 3, - "equivalent": true, - "gates": 1, - "initial depth": 2, - "initial nodes": 3, - "inputs": 2, - "layout area (in tiles)": 36, - "layout area in nm²": 14524.858368000001, - "layout height (in tiles)": 3, - "layout width (in tiles)": 12, - "optimized depth": 1, - "optimized nodes": 1, - "outputs": 1, - "runtime (in sec)": 0.341874165, - "throughput": 1, - "wires": 3 - }, - { - "SiDB dots": 396, - "benchmark": "fontes18/1bitAdderAOIG", - "critical path": 9, - "equivalent": true, - "gates": 5, - "initial depth": 4, - "initial nodes": 7, - "inputs": 3, - "layout area (in tiles)": 135, - "layout area in nm²": 54748.49587200001, - "layout height (in tiles)": 9, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 5, - "outputs": 2, - "runtime (in sec)": 13.597326004, - "throughput": 1, - "wires": 27 - }, - { - "SiDB dots": 380, - "benchmark": "fontes18/t", - "critical path": 8, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 120, - "layout area in nm²": 48650.600448, - "layout height (in tiles)": 8, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 6, - "outputs": 2, - "runtime (in sec)": 5.860524459, - "throughput": 1, - "wires": 24 - }, - { - "SiDB dots": 388, - "benchmark": "fontes18/t_5", - "critical path": 8, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 120, - "layout area in nm²": 48650.600448, - "layout height (in tiles)": 8, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 6, - "outputs": 2, - "runtime (in sec)": 6.858638375, - "throughput": 1, - "wires": 25 - }, - { - "SiDB dots": 376, - "benchmark": "fontes18/c17", - "critical path": 8, - "equivalent": true, - "gates": 6, - "initial depth": 3, - "initial nodes": 6, - "inputs": 5, - "layout area (in tiles)": 120, - "layout area in nm²": 48650.600448, - "layout height (in tiles)": 8, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 6, - "outputs": 2, - "runtime (in sec)": 4.34392021, - "throughput": 1, - "wires": 23 - }, - { - "SiDB dots": 564, - "benchmark": "fontes18/majority", - "critical path": 11, - "equivalent": true, - "gates": 8, - "initial depth": 5, - "initial nodes": 8, - "inputs": 5, - "layout area (in tiles)": 176, - "layout area in nm²": 71412.20352000001, - "layout height (in tiles)": 11, - "layout width (in tiles)": 16, - "optimized depth": 5, - "optimized nodes": 8, - "outputs": 1, - "runtime (in sec)": 26.79160612, - "throughput": 1, - "wires": 38 - }, - { - "SiDB dots": 632, - "benchmark": "fontes18/majority_5_r1", - "critical path": 12, - "equivalent": true, - "gates": 9, - "initial depth": 4, - "initial nodes": 8, - "inputs": 5, - "layout area (in tiles)": 192, - "layout area in nm²": 77917.077504, - "layout height (in tiles)": 12, - "layout width (in tiles)": 16, - "optimized depth": 6, - "optimized nodes": 9, - "outputs": 1, - "runtime (in sec)": 31.680806616, - "throughput": 1, - "wires": 43 - }, - { - "SiDB dots": 612, - "benchmark": "fontes18/newtag", - "critical path": 10, - "equivalent": true, - "gates": 9, - "initial depth": 5, - "initial nodes": 9, - "inputs": 8, - "layout area (in tiles)": 180, - "layout area in nm²": 73029.206016, - "layout height (in tiles)": 10, - "layout width (in tiles)": 18, - "optimized depth": 6, - "optimized nodes": 9, - "outputs": 1, - "runtime (in sec)": 18.590638953, - "throughput": 1, - "wires": 40 - }, - { - "SiDB dots": 196, - "benchmark": "fontes18/xor5_r1", - "critical path": 6, - "equivalent": true, - "gates": 4, - "initial depth": 6, - "initial nodes": 12, - "inputs": 5, - "layout area (in tiles)": 90, - "layout area in nm²": 36454.8096, - "layout height (in tiles)": 6, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 4, - "outputs": 1, - "runtime (in sec)": 1.996412958, - "throughput": 1, - "wires": 11 - }, - { - "SiDB dots": 236, - "benchmark": "fontes18/1bitAdderMaj", - "critical path": 7, - "equivalent": true, - "gates": 4, - "initial depth": 9, - "initial nodes": 14, - "inputs": 3, - "layout area (in tiles)": 105, - "layout area in nm²": 42552.705024, - "layout height (in tiles)": 7, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 4, - "outputs": 1, - "runtime (in sec)": 4.64513558, - "throughput": 1, - "wires": 14 - }, - { - "SiDB dots": 1092, - "benchmark": "fontes18/cm82a_5", - "critical path": 13, - "equivalent": true, - "gates": 12, - "initial depth": 5, - "initial nodes": 20, - "inputs": 5, - "layout area (in tiles)": 234, - "layout area in nm²": 94985.69932800002, - "layout height (in tiles)": 13, - "layout width (in tiles)": 18, - "optimized depth": 5, - "optimized nodes": 12, - "outputs": 3, - "runtime (in sec)": 636.640190954, - "throughput": 1, - "wires": 78 - }, - { - "SiDB dots": 216, - "benchmark": "fontes18/xor5Maj", - "critical path": 6, - "equivalent": true, - "gates": 4, - "initial depth": 12, - "initial nodes": 30, - "inputs": 5, - "layout area (in tiles)": 90, - "layout area in nm²": 36454.8096, - "layout height (in tiles)": 6, - "layout width (in tiles)": 15, - "optimized depth": 3, - "optimized nodes": 4, - "outputs": 1, - "runtime (in sec)": 2.399298334, - "throughput": 1, - "wires": 13 - } - ], - "version": "cff1b1ac" - } -] From 44290cd4a3465fe4e7f74df210588c873e8a40ba Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 24 Oct 2023 15:44:48 +0200 Subject: [PATCH 032/191] :art: add previous bestagon.json file --- experiments/bestagon.json | 425 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 experiments/bestagon.json diff --git a/experiments/bestagon.json b/experiments/bestagon.json new file mode 100644 index 000000000..afcaa7d7d --- /dev/null +++ b/experiments/bestagon.json @@ -0,0 +1,425 @@ +[ + { + "entries": [ + { + "SiDB dots": 196, + "benchmark": "trindade16/mux21", + "critical path": 6, + "depth after mapping": 3, + "depth after optimization": 2, + "equivalent": true, + "gates": 4, + "initial depth": 2, + "initial nodes": 3, + "inputs": 3, + "layout area (in tiles)": 18, + "layout area in nm²": 7258.521600000001, + "layout height (in tiles)": 6, + "layout width (in tiles)": 3, + "nodes after mapping": 4, + "nodes after optimization": 3, + "outputs": 1, + "runtime (in sec)": 0.030918402, + "throughput": 1, + "wires": 10 + }, + { + "SiDB dots": 58, + "benchmark": "trindade16/xor2", + "critical path": 3, + "depth after mapping": 1, + "depth after optimization": 2, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 6, + "layout area in nm²": 2403.975168, + "layout height (in tiles)": 3, + "layout width (in tiles)": 2, + "nodes after mapping": 1, + "nodes after optimization": 3, + "outputs": 1, + "runtime (in sec)": 0.004286501, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 58, + "benchmark": "trindade16/xnor2", + "critical path": 3, + "depth after mapping": 1, + "depth after optimization": 2, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 6, + "layout area in nm²": 2403.975168, + "layout height (in tiles)": 3, + "layout width (in tiles)": 2, + "nodes after mapping": 1, + "nodes after optimization": 3, + "outputs": 1, + "runtime (in sec)": 0.004211561, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 103, + "benchmark": "trindade16/par_gen", + "critical path": 4, + "depth after mapping": 2, + "depth after optimization": 3, + "equivalent": true, + "gates": 2, + "initial depth": 4, + "initial nodes": 6, + "inputs": 3, + "layout area (in tiles)": 12, + "layout area in nm²": 4830.216192000001, + "layout height (in tiles)": 4, + "layout width (in tiles)": 3, + "nodes after mapping": 2, + "nodes after optimization": 4, + "outputs": 1, + "runtime (in sec)": 0.007178205, + "throughput": 1, + "wires": 5 + }, + { + "SiDB dots": 173, + "benchmark": "trindade16/HA", + "critical path": 5, + "depth after mapping": 1, + "depth after optimization": 2, + "equivalent": true, + "gates": 2, + "initial depth": 2, + "initial nodes": 4, + "inputs": 2, + "layout area (in tiles)": 15, + "layout area in nm²": 6044.368896000001, + "layout height (in tiles)": 5, + "layout width (in tiles)": 3, + "nodes after mapping": 2, + "nodes after optimization": 4, + "outputs": 2, + "runtime (in sec)": 0.027165767, + "throughput": 1, + "wires": 10 + }, + { + "SiDB dots": 404, + "benchmark": "trindade16/FA", + "critical path": 9, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 5, + "initial depth": 3, + "initial nodes": 5, + "inputs": 3, + "layout area (in tiles)": 27, + "layout area in nm²": 10900.979712000002, + "layout height (in tiles)": 9, + "layout width (in tiles)": 3, + "nodes after mapping": 5, + "nodes after optimization": 5, + "outputs": 2, + "runtime (in sec)": 0.0423338, + "throughput": 1, + "wires": 24 + }, + { + "SiDB dots": 284, + "benchmark": "trindade16/par_check", + "critical path": 7, + "depth after mapping": 4, + "depth after optimization": 3, + "equivalent": true, + "gates": 6, + "initial depth": 4, + "initial nodes": 9, + "inputs": 4, + "layout area (in tiles)": 28, + "layout area in nm²": 11312.676864, + "layout height (in tiles)": 7, + "layout width (in tiles)": 4, + "nodes after mapping": 6, + "nodes after optimization": 7, + "outputs": 1, + "runtime (in sec)": 0.029391255, + "throughput": 1, + "wires": 13 + }, + { + "SiDB dots": 58, + "benchmark": "fontes18/xor", + "critical path": 3, + "depth after mapping": 1, + "depth after optimization": 2, + "equivalent": true, + "gates": 1, + "initial depth": 2, + "initial nodes": 3, + "inputs": 2, + "layout area (in tiles)": 6, + "layout area in nm²": 2403.975168, + "layout height (in tiles)": 3, + "layout width (in tiles)": 2, + "nodes after mapping": 1, + "nodes after optimization": 3, + "outputs": 1, + "runtime (in sec)": 0.004887973, + "throughput": 1, + "wires": 3 + }, + { + "SiDB dots": 404, + "benchmark": "fontes18/1bitAdderAOIG", + "critical path": 9, + "depth after mapping": 3, + "depth after optimization": 4, + "equivalent": true, + "gates": 5, + "initial depth": 4, + "initial nodes": 7, + "inputs": 3, + "layout area (in tiles)": 27, + "layout area in nm²": 10900.979712000002, + "layout height (in tiles)": 9, + "layout width (in tiles)": 3, + "nodes after mapping": 5, + "nodes after optimization": 6, + "outputs": 2, + "runtime (in sec)": 0.04309465, + "throughput": 1, + "wires": 24 + }, + { + "SiDB dots": 426, + "benchmark": "fontes18/t", + "critical path": 8, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 40, + "layout area in nm²": 16180.789248, + "layout height (in tiles)": 8, + "layout width (in tiles)": 5, + "nodes after mapping": 6, + "nodes after optimization": 6, + "outputs": 2, + "runtime (in sec)": 0.059703367, + "throughput": 1, + "wires": 24 + }, + { + "SiDB dots": 448, + "benchmark": "fontes18/t_5", + "critical path": 8, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 40, + "layout area in nm²": 16180.789248, + "layout height (in tiles)": 8, + "layout width (in tiles)": 5, + "nodes after mapping": 6, + "nodes after optimization": 6, + "outputs": 2, + "runtime (in sec)": 0.058928829, + "throughput": 1, + "wires": 26 + }, + { + "SiDB dots": 396, + "benchmark": "fontes18/c17", + "critical path": 8, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 6, + "initial depth": 3, + "initial nodes": 6, + "inputs": 5, + "layout area (in tiles)": 40, + "layout area in nm²": 16180.789248, + "layout height (in tiles)": 8, + "layout width (in tiles)": 5, + "nodes after mapping": 6, + "nodes after optimization": 6, + "outputs": 2, + "runtime (in sec)": 0.05108846, + "throughput": 1, + "wires": 22 + }, + { + "SiDB dots": 651, + "benchmark": "fontes18/majority", + "critical path": 11, + "depth after mapping": 5, + "depth after optimization": 5, + "equivalent": true, + "gates": 11, + "initial depth": 5, + "initial nodes": 8, + "inputs": 5, + "layout area (in tiles)": 55, + "layout area in nm²": 22265.118720000002, + "layout height (in tiles)": 11, + "layout width (in tiles)": 5, + "nodes after mapping": 11, + "nodes after optimization": 8, + "outputs": 1, + "runtime (in sec)": 0.278753251, + "throughput": 1, + "wires": 36 + }, + { + "SiDB dots": 737, + "benchmark": "fontes18/majority_5_r1", + "critical path": 12, + "depth after mapping": 6, + "depth after optimization": 6, + "equivalent": true, + "gates": 10, + "initial depth": 4, + "initial nodes": 8, + "inputs": 5, + "layout area (in tiles)": 60, + "layout area in nm²": 24293.228544, + "layout height (in tiles)": 12, + "layout width (in tiles)": 5, + "nodes after mapping": 10, + "nodes after optimization": 8, + "outputs": 1, + "runtime (in sec)": 0.154010165, + "throughput": 1, + "wires": 44 + }, + { + "SiDB dots": 651, + "benchmark": "fontes18/newtag", + "critical path": 10, + "depth after mapping": 6, + "depth after optimization": 6, + "equivalent": true, + "gates": 11, + "initial depth": 5, + "initial nodes": 9, + "inputs": 8, + "layout area (in tiles)": 80, + "layout area in nm²": 32419.823616, + "layout height (in tiles)": 10, + "layout width (in tiles)": 8, + "nodes after mapping": 11, + "nodes after optimization": 9, + "outputs": 1, + "runtime (in sec)": 0.18991355, + "throughput": 1, + "wires": 34 + }, + { + "SiDB dots": 232, + "benchmark": "fontes18/xor5_r1", + "critical path": 6, + "depth after mapping": 3, + "depth after optimization": 4, + "equivalent": true, + "gates": 4, + "initial depth": 6, + "initial nodes": 12, + "inputs": 5, + "layout area (in tiles)": 30, + "layout area in nm²": 12124.5696, + "layout height (in tiles)": 6, + "layout width (in tiles)": 5, + "nodes after mapping": 4, + "nodes after optimization": 8, + "outputs": 1, + "runtime (in sec)": 0.026982434, + "throughput": 1, + "wires": 12 + }, + { + "SiDB dots": 255, + "benchmark": "fontes18/1bitAdderMaj", + "critical path": 7, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 5, + "initial depth": 9, + "initial nodes": 14, + "inputs": 3, + "layout area (in tiles)": 21, + "layout area in nm²": 8472.674304, + "layout height (in tiles)": 7, + "layout width (in tiles)": 3, + "nodes after mapping": 5, + "nodes after optimization": 4, + "outputs": 1, + "runtime (in sec)": 0.022231768, + "throughput": 1, + "wires": 13 + }, + { + "SiDB dots": 1211, + "benchmark": "fontes18/cm82a_5", + "critical path": 15, + "depth after mapping": 5, + "depth after optimization": 5, + "equivalent": true, + "gates": 12, + "initial depth": 5, + "initial nodes": 20, + "inputs": 5, + "layout area (in tiles)": 75, + "layout area in nm²": 30377.558016000003, + "layout height (in tiles)": 15, + "layout width (in tiles)": 5, + "nodes after mapping": 12, + "nodes after optimization": 16, + "outputs": 3, + "runtime (in sec)": 704.005429589, + "throughput": 1, + "wires": 78 + }, + { + "SiDB dots": 244, + "benchmark": "fontes18/xor5Maj", + "critical path": 6, + "depth after mapping": 3, + "depth after optimization": 3, + "equivalent": true, + "gates": 4, + "initial depth": 12, + "initial nodes": 30, + "inputs": 5, + "layout area (in tiles)": 30, + "layout area in nm²": 12124.5696, + "layout height (in tiles)": 6, + "layout width (in tiles)": 5, + "nodes after mapping": 4, + "nodes after optimization": 4, + "outputs": 1, + "runtime (in sec)": 0.028480768, + "throughput": 1, + "wires": 13 + } + ], + "version": "4926a76" + } +] From 64e34fb862e1148303f2ef407571c931aea08445 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:40:17 +0200 Subject: [PATCH 033/191] :art: add additional parameter ``influence_radius_charged_defects`` --- .../physical_design/design_sidb_gates.hpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 1a0100e6e..7dea7398a 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -75,6 +75,10 @@ struct design_sidb_gates_params * The simulation engine to be used for the operational domain computation. */ sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; + /** + * The percentage of all combinations that are tested before the design process is canceled. + */ + std::size_t procentual_maximum_attemps = 1; }; namespace detail @@ -125,6 +129,10 @@ class design_sidb_gates_impl const auto total_comb = binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs); + // Shuffle the combinations before dividing them among threads + std::shuffle(all_combinations.begin(), all_combinations.end(), + std::default_random_engine(std::random_device()())); + const auto add_combination_to_layout_and_check_operation = [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, &sidbs_affected_by_defects, &solutionFound, &global_iteration_counter, @@ -133,7 +141,8 @@ class design_sidb_gates_impl for (const auto& comb : combination) { global_iteration_counter++; - if (!solutionFound && !are_sidbs_too_close(comb, sidbs_affected_by_defects)) + if (!solutionFound && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && + global_iteration_counter < static_cast(params.procentual_maximum_attemps * total_comb)) { auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -161,10 +170,6 @@ class design_sidb_gates_impl designed_gate_layouts.push_back(layout_with_added_cells); } solutionFound = true; - - // Optionally, signal all threads to exit - // Uncomment the following line to signal all threads to exit - // solutionFound.store(true, std::memory_order_relaxed); } } } From a5bfa7bb908d76a4857c3a31a8d6bbc845ad3a0b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:40:43 +0200 Subject: [PATCH 034/191] :bug: fix smaller bugs. --- .../technology/sidb_dynamic_gate_library.hpp | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index b8f2ac849..8a905a562 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -10,7 +10,6 @@ #include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" -#include "fiction/technology/sidb_bestagon_library.hpp" #include "fiction/technology/sidb_surface.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" @@ -31,9 +30,9 @@ struct sidb_dynamic_gate_library_params 3, sidb_simulation_engine::QUICKEXACT}; - uint64_t canvas_sidb_complex_gates = 4; + uint64_t canvas_sidb_complex_gates = 3; - double influence_radius_charged_defects = 15; // (unit: nm) + double influence_radius_charged_defects = 15; // (unit: nm) }; /** @@ -115,13 +114,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list), + cell_list_to_cell_level_layout(TWO_IN_TWO_OUT), center_cell_siqad, absolute_cell_siqad, parameter); if (is_bestagon_gate_applicable( @@ -138,7 +135,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list), + sidb_surface, + cell_list_to_cell_level_layout(TWO_IN_TWO_OUT), center_cell_siqad, absolute_cell_siqad, parameter); if (is_bestagon_gate_applicable( @@ -154,7 +152,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library - [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, sidb_surface defect_lyt, + [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, const sidb_surface& defect_lyt, const design_sidb_gates_params& parameter, const std::vector& truth_table) { + auto defect_copy = defect_lyt.clone(); + const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(true); + bool is_bestagon_gate_applicable = true; - defect_lyt.foreach_sidb_defect( - [&bestagon_lyt, &is_bestagon_gate_applicable](const auto& cd) + defect_copy.foreach_sidb_defect( + [&bestagon_lyt, &is_bestagon_gate_applicable, &sidbs_affected_by_defects](const auto& cd) { if (is_charged_defect(cd.second)) { @@ -356,10 +357,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library= cd.first.x - SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING && c.y == cd.first.y)) + if (sidbs_affected_by_defects.count(c)) { is_bestagon_gate_applicable = false; return; @@ -370,10 +370,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library(status == operational_status::OPERATIONAL); } @@ -437,7 +437,24 @@ class sidb_dynamic_gate_library : public fcn_gate_library; } - return cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + if (t == create_crossing_wire_tt()) + { + auto lyt_found = found_gate_layouts.front(); + skeleton.foreach_sidb_defect([&lyt_found](const auto& defect) + { lyt_found.assign_sidb_defect(defect.first, defect.second); }); + fiction::write_sqd_layout(lyt_found, "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" + "defect_aware_physical_design/single_gates/cx.sqd"); + } + if (t == create_double_wire_tt()) + { + auto lyt_found = found_gate_layouts.front(); + skeleton.foreach_sidb_defect([&lyt_found](const auto& defect) + { lyt_found.assign_sidb_defect(defect.first, defect.second); }); + fiction::write_sqd_layout(lyt_found, "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" + "defect_aware_physical_design/single_gates/db.sqd"); + } + return lyt; } /** @@ -451,7 +468,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library [[nodiscard]] static Lyt cell_list_to_cell_level_layout(const fcn_gate& cell_list) noexcept { - Lyt lyt{aspect_ratio{gate_x_size(), gate_y_size()}}; + Lyt lyt{{std::numeric_limits::max(), std::numeric_limits::max()}}; const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); @@ -512,10 +529,11 @@ class sidb_dynamic_gate_library : public fcn_gate_library Date: Wed, 25 Oct 2023 10:41:19 +0200 Subject: [PATCH 035/191] :art: update evaluation script. --- .../dynamic_gate_design.cpp | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 1ca818d44..d6ecb5253 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -51,32 +51,36 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); - const std::vector defect_concentrations = {1, 0.5, 5}; + const std::vector defect_concentrations = {1}; for (const auto& concentration : defect_concentrations) { std::cout << fmt::format("--------------- defect concentration: {} % --------------- ", concentration) << std::endl; - auto surface_lattice = fiction::read_sidb_surface_defects( + auto surface_lattice_initial = fiction::read_sidb_surface_defects( fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", concentration), "py_test_surface"); - surface_lattice.foreach_sidb_defect( + fiction::sidb_surface surface_lattice{ + {std::numeric_limits::max(), std::numeric_limits::max()}}; + + surface_lattice_initial.foreach_sidb_defect( [&surface_lattice](const auto& cd) { - if (is_charged_defect(cd.second)) + if (cd.second.type == fiction::sidb_defect_type::DB) { - if (cd.second.type == fiction::sidb_defect_type::DB) - { - surface_lattice.assign_sidb_defect( - cd.first, fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}); - } - else if (cd.second.type == fiction::sidb_defect_type::SI_VACANCY) - { - surface_lattice.assign_sidb_defect( - cd.first, fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}); - } + surface_lattice.assign_sidb_defect( + cd.first, fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}); + } + else if (cd.second.type == fiction::sidb_defect_type::SI_VACANCY) + { + surface_lattice.assign_sidb_defect( + cd.first, fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}); + } + else + { + surface_lattice.assign_sidb_defect(cd.first, cd.second); } }); From 4aa58a2b92be90d8dcd707708c2db4063c815e25 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:51:15 +0200 Subject: [PATCH 036/191] :art: small fix. --- .../fiction/algorithms/physical_design/design_sidb_gates.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 7dea7398a..0c513a5f6 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -140,7 +140,6 @@ class design_sidb_gates_impl { for (const auto& comb : combination) { - global_iteration_counter++; if (!solutionFound && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && global_iteration_counter < static_cast(params.procentual_maximum_attemps * total_comb)) { @@ -173,6 +172,7 @@ class design_sidb_gates_impl } } } + global_iteration_counter++; } }; From 2fe77ce60450972597bc6f9565c42530bbc8f6b9 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:52:54 +0200 Subject: [PATCH 037/191] :fire: delete skeletons. --- .../skeleton_bestagons_with_tags/1i1o_d.sqd | 148 ------------ .../skeleton_bestagons_with_tags/1i1o_dm.sqd | 144 ------------ .../skeleton_bestagons_with_tags/1i1o_s.sqd | 136 ----------- .../skeleton_bestagons_with_tags/1i1o_sm.sqd | 144 ------------ .../skeleton_bestagons_with_tags/1i2o.sqd | 176 -------------- .../skeleton_bestagons_with_tags/1i2o_m.sqd | 176 -------------- .../skeleton_bestagons_with_tags/2i1o.sqd | 182 --------------- .../skeleton_bestagons_with_tags/2i1o_m.sqd | 182 --------------- .../skeleton_bestagons_with_tags/2i2o.sqd | 214 ------------------ 9 files changed, 1502 deletions(-) delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_d.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_s.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i2o.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/1i2o_m.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/2i1o.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/2i1o_m.sqd delete mode 100644 experiments/skeleton_bestagons_with_tags/2i2o.sqd diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd deleted file mode 100644 index 3ccf13edf..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_d.sqd +++ /dev/null @@ -1,148 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:22:11 - - - - 0.0643349 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - - #ffc8c8c8 - - - 2 - - input - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd deleted file mode 100644 index fa2ac58eb..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_dm.sqd +++ /dev/null @@ -1,144 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:22:59 - - - - 0.0845673 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd deleted file mode 100644 index d449e5cea..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_s.sqd +++ /dev/null @@ -1,136 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:23:25 - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd b/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd deleted file mode 100644 index 1e7c01d06..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i1o_sm.sqd +++ /dev/null @@ -1,144 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:24:01 - - - - 0.0721963 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i2o.sqd b/experiments/skeleton_bestagons_with_tags/1i2o.sqd deleted file mode 100644 index 17b55ba44..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i2o.sqd +++ /dev/null @@ -1,176 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:24:27 - - - - 0.0767521 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd b/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd deleted file mode 100644 index 02dad04d4..000000000 --- a/experiments/skeleton_bestagons_with_tags/1i2o_m.sqd +++ /dev/null @@ -1,176 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:25:06 - - - - 0.0648703 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i1o.sqd b/experiments/skeleton_bestagons_with_tags/2i1o.sqd deleted file mode 100644 index 945eb5d0d..000000000 --- a/experiments/skeleton_bestagons_with_tags/2i1o.sqd +++ /dev/null @@ -1,182 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:25:42 - - - - 0.020305 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd b/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd deleted file mode 100644 index 5a1833317..000000000 --- a/experiments/skeleton_bestagons_with_tags/2i1o_m.sqd +++ /dev/null @@ -1,182 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:26:18 - - - - 0.0297765 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - - - - \ No newline at end of file diff --git a/experiments/skeleton_bestagons_with_tags/2i2o.sqd b/experiments/skeleton_bestagons_with_tags/2i2o.sqd deleted file mode 100644 index 17f0e9876..000000000 --- a/experiments/skeleton_bestagons_with_tags/2i2o.sqd +++ /dev/null @@ -1,214 +0,0 @@ - - - - - save - 0.3.3 - 2023-09-28 10:21:38 - - - - 0.0836732 - - - - - - - - Lattice - Lattice - Design - 0 - 0 - 1 - 0 - - - - 2 - - - - - - Screenshot Overlay - Misc - Overlay - 0 - 0 - 1 - 0 - - - Surface - DB - Design - 0 - 0 - 1 - 0 - - - Metal - Electrode - Design - 1000 - 100 - 1 - 0 - - - - - - - - - - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - input - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - - #ffc8c8c8 - - - 2 - - output - - #ffc8c8c8 - - - - - - \ No newline at end of file From 39f640cdc2df10e912089aad1f001016efa466c6 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:54:29 +0200 Subject: [PATCH 038/191] :fire: delete .gitkeep. --- experiments/dynamic_gate_design/layouts/.gitkeep | 0 experiments/dynamic_gate_design/layouts/fontes18/.gitkeep | 0 experiments/dynamic_gate_design/layouts/trindade16/.gitkeep | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 experiments/dynamic_gate_design/layouts/.gitkeep delete mode 100644 experiments/dynamic_gate_design/layouts/fontes18/.gitkeep delete mode 100644 experiments/dynamic_gate_design/layouts/trindade16/.gitkeep diff --git a/experiments/dynamic_gate_design/layouts/.gitkeep b/experiments/dynamic_gate_design/layouts/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/experiments/dynamic_gate_design/layouts/fontes18/.gitkeep b/experiments/dynamic_gate_design/layouts/fontes18/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/experiments/dynamic_gate_design/layouts/trindade16/.gitkeep b/experiments/dynamic_gate_design/layouts/trindade16/.gitkeep deleted file mode 100644 index e69de29bb..000000000 From 514de494fd66cba580c954c54078885cb78beee3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 10:57:12 +0200 Subject: [PATCH 039/191] :art: take original generate_defective_surface.py file --- .../generate_defective_surface.py | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/experiments/defect_aware_physical_design/generate_defective_surface.py b/experiments/defect_aware_physical_design/generate_defective_surface.py index e1ad8343c..c1e67cdee 100644 --- a/experiments/defect_aware_physical_design/generate_defective_surface.py +++ b/experiments/defect_aware_physical_design/generate_defective_surface.py @@ -55,7 +55,7 @@ def add_defects(self, coverage=0.05): [4, 1, 2, 0.05], # single_dihydride [5, 4, 2, 0.05], # onebyone [6, 4, 4, 0.05], # threebyone - [7, 1, 2, 0.3], # siloxane + [7, 1, 2, 0.1], # siloxane [8, 1, 2, 0.1], # raised_si [9, 3, 2, 0.05], # etch pit [10, 1, 2, 0.05] # missing_dimer @@ -97,10 +97,17 @@ def add_defects(self, coverage=0.05): i = i - 1 pass - def draw_panels(self): + def draw_panels(self): # DB_panels,DB_pattern_extended, pattern): + # draws the DB_pattern_extended with rectangles to show each pannel + width_nm = self.a1 * self.surface_width height_nm = self.a2 * self.surface_height - fig = plt.figure() + # print(height_nm,width_nm) + # lattice_points = np.where(self.surface_lattice>=-1) + # DB_top_points = np.where(self.surface_lattice==0) + # DB_bottom_points = np.where(self.surface_lattice==1) + # print(lattice_points) + fig = plt.figure(figsize=((width_nm + 1) / 10, (height_nm + 1) / 10), dpi=100) ax = fig.add_subplot(1, 1, 1) plt.gca().invert_yaxis() @@ -129,30 +136,19 @@ def draw_panels(self): plt.xticks([]) plt.yticks([]) plt.legend() + # print(self.DB_pattern_extended.shape) + plt.show() def save_to_file(self, filename='test.txt'): - with open(filename, 'w') as file: - for row in self.surface_lattice: - # Write an opening bracket - file.write('[') - - # Loop through the elements in the row and write them with commas and spaces - for i, element in enumerate(row): - file.write(str(element)) - - # If it's not the last element, write a comma and space - if i < len(row) - 1: - file.write(' ') - - # Write a closing bracket and a newline character for the next row - file.write(']\n') + np.savetxt(filename, self.surface_lattice) + print('file_saved') surface_width = 740 surface_height = 1090 -coverage = 0.1 +coverage = 0.005 surface = defect_surface(surface_width=surface_width, surface_height=surface_height) surface.add_defects(coverage=coverage) print(surface.surface_lattice) -#surface.draw_panels() -surface.save_to_file('test.txt') +# surface.draw_panels() +# surface.save_to_file('test.txt') From b3dbe95306fc6e03373d4231348a239dddf4d825 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Wed, 25 Oct 2023 09:09:49 +0000 Subject: [PATCH 040/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../dynamic_gate_design/dynamic_gate_design.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index d6ecb5253..113aec2d7 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,17 +13,17 @@ #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include -#include // SiDB surface with support for atomic defects +#include // SiDB surface with support for atomic defects #include -#include // pre-defined types suitable for the FCN domain +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing From 8429ab574160f4ed33e40e06dfaeaf995e7b1faf Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 11:15:52 +0200 Subject: [PATCH 041/191] :bug: fix docu issue. --- docs/algorithms/apply_gate_library.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 66067eb4a..2a1437401 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_dynamic_gate_library +.. doxygenfunction:: fiction::apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, surface_black_list& black_list) From 8630f505aee6bfaf50c3d70e1d4a51064aa827ed Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 11:20:55 +0200 Subject: [PATCH 042/191] :art: update lambda expression. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 9445fd300..0dba82dec 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -133,7 +133,7 @@ class apply_gate_library_impl mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif gate_lyt.foreach_node( - [this, &bar](const auto& n, [[maybe_unused]] auto i) + [&, this](const auto& n, [[maybe_unused]] auto i) { if (!gate_lyt.is_constant(n)) { From 09797cb04f6d0ae6d1c6bd439de53e2c995c46dd Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 11:21:08 +0200 Subject: [PATCH 043/191] :art: update docu. --- docs/algorithms/apply_gate_library.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 2a1437401..0410dffec 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, surface_black_list& black_list) +.. doxygenfunction:: fiction::apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface) From 7df16521174bb12bef4dee91e0143b7c638ba915 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 11:49:44 +0200 Subject: [PATCH 044/191] :bug: add runtime digit. --- test/io/write_sqd_sim_result.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/io/write_sqd_sim_result.cpp b/test/io/write_sqd_sim_result.cpp index 590120b85..f05a5b4cd 100644 --- a/test/io/write_sqd_sim_result.cpp +++ b/test/io/write_sqd_sim_result.cpp @@ -171,7 +171,7 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") " {}\n" " 0\n" " {}\n" - " 42\n" + " 42.0\n" " \n" " \n" " {}\n" @@ -202,7 +202,7 @@ TEST_CASE("Write empty simulation result", "[sqd-sim-result]") " {}\n" " 0\n" " {}\n" - " 42\n" + " 42.0\n" " \n" " \n" " {}\n" From 8a3bcf199d0a8eb301f5d33d8a4eed4d4ab93c1f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 12:52:35 +0200 Subject: [PATCH 045/191] :art: delete ``const`` --- include/fiction/technology/sidb_dynamic_gate_library.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 8a905a562..b6f40688d 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -323,7 +323,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static constexpr const fcn_gate ERROR = + static constexpr fcn_gate ERROR = fiction::create_array(fiction::create_array(CellLyt::cell_type::NORMAL)); private: From 5bd209cb0ac8e52f021460e7589ff41a7a86d3d8 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 13:23:12 +0200 Subject: [PATCH 046/191] :art: define error gate in fcn_gate_library.hpp --- include/fiction/technology/fcn_gate_library.hpp | 6 ++++++ .../fiction/technology/sidb_dynamic_gate_library.hpp | 11 +---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index 5750cc2a3..edc20f55e 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -317,6 +317,12 @@ class fcn_gate_library */ static constexpr const fcn_gate EMPTY_GATE = fiction::create_array(fiction::create_array(Technology::cell_type::EMPTY)); + /** + * Single error gate in given technology and tile size. + * + */ + static constexpr const fcn_gate ERROR = + fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); }; } // namespace fiction diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index b6f40688d..d95ff3eeb 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -317,15 +317,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library - static constexpr fcn_gate ERROR = - fiction::create_array(fiction::create_array(CellLyt::cell_type::NORMAL)); - private: /** * This function evaluates whether a Bestagon gate can be applied to the given node by considering @@ -434,7 +425,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library; + return ERROR; } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); From 4f97f83aa3e1d73d01b17813c81b8b38e2dc51ea Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 14:16:06 +0200 Subject: [PATCH 047/191] :bug: fix small issue. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 0dba82dec..0fef23e10 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -85,7 +85,7 @@ class apply_gate_library_impl const auto gate = GateLibrary::template set_up_gate( gate_lyt, t, defect_surface, params, black_list); - if (gate == GateLibrary::template ERROR) + if (gate == GateLibrary::ERROR) { cell_lyt = CellLyt{{}, "fail"}; return; From c0bf4f15248b3043c5d42f25e9ebccc74bc08a25 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 18:21:25 +0200 Subject: [PATCH 048/191] :sparkles: function to check if gate design is impossible due to defects --- .../sidb/is_gate_design_impossible.hpp | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp diff --git a/include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp b/include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp new file mode 100644 index 000000000..fc6a2f8c6 --- /dev/null +++ b/include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp @@ -0,0 +1,80 @@ +// +// Created by Jan Drewniok on 25.10.23. +// + +#ifndef FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#define FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP + +#include "fiction/algorithms/iter/bdl_input_iterator.hpp" +#include "fiction/algorithms/simulation/sidb/is_operational.hpp" +#include "fiction/layouts/cell_level_layout.hpp" +#include "fiction/technology/charge_distribution_surface.hpp" +#include "fiction/technology/sidb_defects.hpp" +#include "fiction/traits.hpp" +#include "fiction/types.hpp" +#include "fiction/utils/truth_table_utils.hpp" + +namespace fiction +{ + +/** + * This function assesses whether it is impossible to design a gate for a given truth table in the provided layout due + * to atomic defects. + * + * @tparam Lyt The type of the layout. + * @tparam TT The type of the truth table. + * @param layout The layout for which gate design feasibility is being checked. + * @param spec A vector of truth tables representing the gate's functionality. + * @param params Parameter for the simulation. + * @return `true` if gate design is impossible, `false` otherwise. + * + */ +template +bool gate_design_impossible(const Lyt& layout, const std::vector& spec, const is_operational_params& params = {}) +{ + 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"); + + assert(layout.num_pis() > 0 && "lyt needs input cells"); + assert(layout.num_pos() > 0 && "lyt needs output cells"); + + const auto bdl_pairs = detect_bdl_pairs(layout, sidb_technology::cell_type::OUTPUT, params.bdl_params); + + auto bdl_iter = bdl_input_iterator{layout, params.bdl_params}; + + for (auto i = 0u; i < spec.front().num_bits(); ++i, ++bdl_iter) + { + auto charge_lyt = charge_distribution_surface{layout, params.simulation_parameter}; + charge_lyt.assign_all_charge_states(sidb_charge_state::NEUTRAL); + charge_lyt.update_after_charge_change(); + + layout.foreach_sidb_defect( + [&charge_lyt](const auto& cd) + { + if (is_charged_defect(cd.second)) + { + charge_lyt.add_sidb_defect_to_potential_landscape(cd.first, cd.second); + } + }); + + for (const auto& bdl : bdl_pairs) + { + if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.simulation_parameter.mu_minus) > + -physical_constants::POP_STABILITY_ERR) + { + return true; + } + if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.simulation_parameter.mu_minus) > + -physical_constants::POP_STABILITY_ERR) + { + return true; + } + } + } + return false; +} + +} // namespace fiction + +#endif // FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP From 8ea1700554fb12d93dee697d8a62a5c5bcc44d83 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 18:21:47 +0200 Subject: [PATCH 049/191] :white_check_mark: add test. --- .../sidb/is_gate_design_impossible.cpp | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 test/algorithms/simulation/sidb/is_gate_design_impossible.cpp diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp new file mode 100644 index 000000000..15f58a7b1 --- /dev/null +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -0,0 +1,112 @@ +// +// Created by Jan Drewniok on 25.10.23. +// + +#include + +#include +#include +#include +#include +#include + +using namespace fiction; + +TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-operational]") +{ + using layout = sidb_defect_cell_clk_lyt_siqad; + + layout 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); + + lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({19, 1, 1}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); + + SECTION("without defect") + { + CHECK(!gate_design_impossible(lyt, std::vector{create_and_tt()}, + is_operational_params{sidb_simulation_parameters{2, -0.28}})); + } + + SECTION("with defect") + { + lyt.assign_sidb_defect({12,6,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); + lyt.assign_sidb_defect({11,6,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); + CHECK(gate_design_impossible(lyt, std::vector{create_and_tt()}, + is_operational_params{sidb_simulation_parameters{2, -0.28}})); + } +} + +TEST_CASE("Bestagon CROSSING gate", "[is-operational]") +{ + using layout = sidb_defect_cell_clk_lyt_siqad; + + layout 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); + + lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({20, 12, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 11, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({14, 9, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({18, 9, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({24, 13, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({16, 13, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({20, 8, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); + + SECTION("without defect") + { + CHECK(!gate_design_impossible(lyt, create_crossing_wire_tt(), + is_operational_params{sidb_simulation_parameters{2, -0.32}})); + } + + SECTION("with defect") + { + lyt.assign_sidb_defect({34,18,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); + lyt.assign_sidb_defect({34,18,1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); + CHECK(gate_design_impossible(lyt, create_crossing_wire_tt(), + is_operational_params{sidb_simulation_parameters{2, -0.32}})); + } +} From 7a83a58eafe3a416b0757a1ed472e6d829fe3ac6 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 25 Oct 2023 18:23:22 +0200 Subject: [PATCH 050/191] :art: small adaptations. --- .../dynamic_gate_design.cpp | 3 + .../physical_design/design_sidb_gates.hpp | 2 +- .../fiction/technology/fcn_gate_library.hpp | 13 +++-- .../technology/sidb_dynamic_gate_library.hpp | 58 ++++++++++++------- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 113aec2d7..47992d875 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -125,6 +125,9 @@ int main() // NOLINT ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; +// constexpr const uint64_t bench_select = +// fiction_experiments::t; + for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { fmt::print("[attempts] processing {}\n", benchmark); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 0c513a5f6..a4aada004 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -78,7 +78,7 @@ struct design_sidb_gates_params /** * The percentage of all combinations that are tested before the design process is canceled. */ - std::size_t procentual_maximum_attemps = 1; + double procentual_maximum_attemps = 1.0; }; namespace detail diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index edc20f55e..c119ce0bc 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -261,6 +261,13 @@ class fcn_gate_library return GateSizeY; } + /** + * Single error gate in given technology and tile size. + * + */ + static constexpr const fcn_gate ERROR = + fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); + protected: /** * Transposes the given `fcn_gate` at compile time. @@ -317,12 +324,6 @@ class fcn_gate_library */ static constexpr const fcn_gate EMPTY_GATE = fiction::create_array(fiction::create_array(Technology::cell_type::EMPTY)); - /** - * Single error gate in given technology and tile size. - * - */ - static constexpr const fcn_gate ERROR = - fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); }; } // namespace fiction diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index d95ff3eeb..9d8ab6de6 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -7,6 +7,8 @@ #include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" +#include "fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp" +#include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" @@ -28,7 +30,7 @@ struct sidb_dynamic_gate_library_params design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{24, 8, 1}, {34, 14, 0}}, 3, - sidb_simulation_engine::QUICKEXACT}; + sidb_simulation_engine::QUICKEXACT, 1}; uint64_t canvas_sidb_complex_gates = 3; @@ -421,31 +423,43 @@ class sidb_dynamic_gate_library : public fcn_gate_library& black_list, const port_list& p, const tile& tile) { - const auto found_gate_layouts = design_sidb_gates(skeleton, std::vector{t}, params); - if (found_gate_layouts.empty()) + if (t == create_crossing_wire_tt() || t==create_double_wire_tt()) { - black_list[tile][t.front()].push_back(p); - return ERROR; - } - - const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); - if (t == create_crossing_wire_tt()) - { - auto lyt_found = found_gate_layouts.front(); - skeleton.foreach_sidb_defect([&lyt_found](const auto& defect) - { lyt_found.assign_sidb_defect(defect.first, defect.second); }); - fiction::write_sqd_layout(lyt_found, "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" - "defect_aware_physical_design/single_gates/cx.sqd"); + if (gate_design_impossible(skeleton, t, + is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) + { + black_list[tile][create_id_tt()].push_back(p); + return ERROR; + } + const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); + if (found_gate_layouts.empty()) + { + black_list[tile][create_id_tt()].push_back(p); + return ERROR; + } + const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + return lyt; } - if (t == create_double_wire_tt()) + else { - auto lyt_found = found_gate_layouts.front(); - skeleton.foreach_sidb_defect([&lyt_found](const auto& defect) - { lyt_found.assign_sidb_defect(defect.first, defect.second); }); - fiction::write_sqd_layout(lyt_found, "/Users/jandrewniok/CLionProjects/fiction_fork/experiments/" - "defect_aware_physical_design/single_gates/db.sqd"); + if (gate_design_impossible(skeleton, t, + is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) + { + black_list[tile][t.front()].push_back(p); + return ERROR; + } + const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); + if (found_gate_layouts.empty()) + { + black_list[tile][t.front()].push_back(p); + return ERROR; + } + const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + return lyt; } - return lyt; + + + } /** From 9cb8733df982230a8a099b6a20e4ebdd61926441 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Wed, 25 Oct 2023 16:25:43 +0000 Subject: [PATCH 051/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../dynamic_gate_design.cpp | 4 ++-- .../physical_design/design_sidb_gates.hpp | 2 +- .../technology/sidb_dynamic_gate_library.hpp | 8 +++----- .../sidb/is_gate_design_impossible.cpp | 20 +++++++++---------- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 47992d875..83265aaae 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -125,8 +125,8 @@ int main() // NOLINT ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; -// constexpr const uint64_t bench_select = -// fiction_experiments::t; + // constexpr const uint64_t bench_select = + // fiction_experiments::t; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index a4aada004..77c312671 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -78,7 +78,7 @@ struct design_sidb_gates_params /** * The percentage of all combinations that are tested before the design process is canceled. */ - double procentual_maximum_attemps = 1.0; + double procentual_maximum_attemps = 1.0; }; namespace detail diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 9d8ab6de6..53e26ec97 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -30,7 +30,8 @@ struct sidb_dynamic_gate_library_params design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{24, 8, 1}, {34, 14, 0}}, 3, - sidb_simulation_engine::QUICKEXACT, 1}; + sidb_simulation_engine::QUICKEXACT, + 1}; uint64_t canvas_sidb_complex_gates = 3; @@ -423,7 +424,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library& black_list, const port_list& p, const tile& tile) { - if (t == create_crossing_wire_tt() || t==create_double_wire_tt()) + if (t == create_crossing_wire_tt() || t == create_double_wire_tt()) { if (gate_design_impossible(skeleton, t, is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) @@ -457,9 +458,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; } - - - } /** diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index 15f58a7b1..c5ff63eee 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -5,10 +5,10 @@ #include #include -#include -#include #include #include +#include +#include using namespace fiction; @@ -38,15 +38,15 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-operat SECTION("without defect") { CHECK(!gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + is_operational_params{sidb_simulation_parameters{2, -0.28}})); } SECTION("with defect") { - lyt.assign_sidb_defect({12,6,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); - lyt.assign_sidb_defect({11,6,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); + lyt.assign_sidb_defect({12, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); + lyt.assign_sidb_defect({11, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); CHECK(gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + is_operational_params{sidb_simulation_parameters{2, -0.28}})); } } @@ -99,14 +99,14 @@ TEST_CASE("Bestagon CROSSING gate", "[is-operational]") SECTION("without defect") { CHECK(!gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + is_operational_params{sidb_simulation_parameters{2, -0.32}})); } SECTION("with defect") { - lyt.assign_sidb_defect({34,18,0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); - lyt.assign_sidb_defect({34,18,1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); + lyt.assign_sidb_defect({34, 18, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); + lyt.assign_sidb_defect({34, 18, 1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); CHECK(gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + is_operational_params{sidb_simulation_parameters{2, -0.32}})); } } From 77160f3a38f5fe647b7add750c70ba57c59236bd Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 30 Oct 2023 11:21:00 +0100 Subject: [PATCH 052/191] :art: small adaptations. --- docs/algorithms/design_sidb_gates.rst | 13 ++++++- .../physical_design/design_sidb_gates.hpp | 10 +++--- .../is_gate_design_impossible.hpp | 2 +- .../technology/sidb_dynamic_gate_library.hpp | 34 +++++++++---------- .../sidb/is_gate_design_impossible.cpp | 19 ++++++----- 5 files changed, 44 insertions(+), 34 deletions(-) rename include/fiction/algorithms/{simulation/sidb => physical_design}/is_gate_design_impossible.hpp (95%) diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index c468d96ec..08293afd6 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -1,8 +1,19 @@ +SiDB Gate Design +---------------- + SiDB Gate Designer ------------------- +################## **Header:** ``fiction/algorithms/physical_design/design_sidb_gates.hpp`` .. doxygenstruct:: fiction::design_sidb_gates_params :members: .. doxygenfunction:: fiction::design_sidb_gates + + +Utility Functions +################# + +**Header:** ``fiction/algorithms/physical_design/is_gate_design_impossible.hpp`` + +.. doxygenfunction:: fiction::is_gate_design_impossible diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 77c312671..2e876f1e0 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -124,7 +124,7 @@ class design_sidb_gates_impl std::vector designed_gate_layouts = {}; std::mutex mutex_to_protect_designer_gate_layouts; - std::atomic solutionFound = false; + std::atomic solution_found = false; std::atomic global_iteration_counter(0); const auto total_comb = binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs); @@ -135,12 +135,12 @@ class design_sidb_gates_impl const auto add_combination_to_layout_and_check_operation = [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, - &sidbs_affected_by_defects, &solutionFound, &global_iteration_counter, + &sidbs_affected_by_defects, &solution_found, &global_iteration_counter, &total_comb](const auto& combination) noexcept { for (const auto& comb : combination) { - if (!solutionFound && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && + if (!solution_found && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && global_iteration_counter < static_cast(params.procentual_maximum_attemps * total_comb)) { auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -158,7 +158,7 @@ class design_sidb_gates_impl }); } - if (!solutionFound) + if (!solution_found) { if (const auto [status, sim_calls] = is_operational(layout_with_added_cells, truth_table, params_is_operational); @@ -168,7 +168,7 @@ class design_sidb_gates_impl const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; designed_gate_layouts.push_back(layout_with_added_cells); } - solutionFound = true; + solution_found = true; } } } diff --git a/include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp similarity index 95% rename from include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp rename to include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp index fc6a2f8c6..341698723 100644 --- a/include/fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp +++ b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp @@ -30,7 +30,7 @@ namespace fiction * */ template -bool gate_design_impossible(const Lyt& layout, const std::vector& spec, const is_operational_params& params = {}) +bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, const is_operational_params& params = {}) { 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"); diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 53e26ec97..d3d5433f2 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -7,7 +7,7 @@ #include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" -#include "fiction/algorithms/simulation/sidb/is_gate_design_impossible.hpp" +#include "fiction/algorithms/physical_design/is_gate_design_impossible.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" @@ -426,8 +426,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; } - else + + if (is_gate_design_impossible(skeleton, t, + is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) { - if (gate_design_impossible(skeleton, t, - is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) - { - black_list[tile][t.front()].push_back(p); - return ERROR; - } - const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); - if (found_gate_layouts.empty()) - { - black_list[tile][t.front()].push_back(p); - return ERROR; - } - const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); - return lyt; + black_list[tile][t.front()].push_back(p); + return ERROR; } + const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); + if (found_gate_layouts.empty()) + { + black_list[tile][t.front()].push_back(p); + return ERROR; + } + const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + return lyt; } /** diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index c5ff63eee..763c37c94 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -2,9 +2,10 @@ // Created by Jan Drewniok on 25.10.23. // +#include "fiction/algorithms/physical_design/is_gate_design_impossible.hpp" + #include -#include #include #include #include @@ -37,16 +38,16 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-operat SECTION("without defect") { - CHECK(!gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + CHECK(!is_gate_design_impossible(lyt, std::vector{create_and_tt()}, + is_operational_params{sidb_simulation_parameters{2, -0.28}})); } SECTION("with defect") { lyt.assign_sidb_defect({12, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); lyt.assign_sidb_defect({11, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); - CHECK(gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + CHECK(is_gate_design_impossible(lyt, std::vector{create_and_tt()}, + is_operational_params{sidb_simulation_parameters{2, -0.28}})); } } @@ -98,15 +99,15 @@ TEST_CASE("Bestagon CROSSING gate", "[is-operational]") SECTION("without defect") { - CHECK(!gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + CHECK(!is_gate_design_impossible(lyt, create_crossing_wire_tt(), + is_operational_params{sidb_simulation_parameters{2, -0.32}})); } SECTION("with defect") { lyt.assign_sidb_defect({34, 18, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); lyt.assign_sidb_defect({34, 18, 1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); - CHECK(gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + CHECK(is_gate_design_impossible(lyt, create_crossing_wire_tt(), + is_operational_params{sidb_simulation_parameters{2, -0.32}})); } } From 2a31019bb72c0b96d2d6c7795616af1285ef1913 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 30 Oct 2023 11:49:50 +0100 Subject: [PATCH 053/191] :art: add note. --- .../algorithms/physical_design/is_gate_design_impossible.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp index 341698723..f668bb114 100644 --- a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp +++ b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp @@ -21,6 +21,8 @@ namespace fiction * This function assesses whether it is impossible to design a gate for a given truth table in the provided layout due * to atomic defects. * + * @note If the function returns `false`, it does not imply that it is possible to design a SiDB gate for given parameters. + * * @tparam Lyt The type of the layout. * @tparam TT The type of the truth table. * @param layout The layout for which gate design feasibility is being checked. From c152ace572b331eef4cfb6aa3702aa0eadef5403 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 30 Oct 2023 12:11:22 +0100 Subject: [PATCH 054/191] :art: remove ``const``. --- include/fiction/technology/fcn_gate_library.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index c119ce0bc..26b084c32 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -265,8 +265,8 @@ class fcn_gate_library * Single error gate in given technology and tile size. * */ - static constexpr const fcn_gate ERROR = - fiction::create_array(fiction::create_array(Technology::cell_type::NORMAL)); + static constexpr fcn_gate ERROR = + fiction::create_array(fiction::create_array(Technology::cell_type::INPUT)); protected: /** From d9989a8f7a06d37f488ba57af67e900285e27b74 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Mon, 30 Oct 2023 11:13:00 +0000 Subject: [PATCH 055/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../algorithms/physical_design/is_gate_design_impossible.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp index f668bb114..79b157130 100644 --- a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp +++ b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp @@ -21,7 +21,8 @@ namespace fiction * This function assesses whether it is impossible to design a gate for a given truth table in the provided layout due * to atomic defects. * - * @note If the function returns `false`, it does not imply that it is possible to design a SiDB gate for given parameters. + * @note If the function returns `false`, it does not imply that it is possible to design a SiDB gate for given + * parameters. * * @tparam Lyt The type of the layout. * @tparam TT The type of the truth table. From d14bab88133db0586b34ce2cc0fb1f39c68d1f9f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 30 Oct 2023 13:07:32 +0100 Subject: [PATCH 056/191] :art: treat neutral atomic defects differently in quickexact.hpp. --- .../physical_design/design_sidb_gates.hpp | 14 +------------- .../algorithms/simulation/sidb/quickexact.hpp | 2 +- include/fiction/technology/sidb_defects.hpp | 2 +- .../physical_design/design_sidb_gates.cpp | 3 ++- 4 files changed, 5 insertions(+), 16 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 2e876f1e0..805fc592b 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -143,21 +143,9 @@ class design_sidb_gates_impl if (!solution_found && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && global_iteration_counter < static_cast(params.procentual_maximum_attemps * total_comb)) { + // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); - if constexpr (has_get_sidb_defect_v) - { - layout_with_added_cells.foreach_sidb_defect( - [&layout_with_added_cells](const auto& cd) - { - if (is_neutrally_charged_defect(cd.second)) - { - layout_with_added_cells.assign_sidb_defect(cd.first, - sidb_defect{sidb_defect_type::NONE}); - } - }); - } - if (!solution_found) { if (const auto [status, sim_calls] = diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 2bda96cb7..6a291d0c3 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -529,7 +529,7 @@ class quickexact_impl { const auto& [cell, defect] = cd; - if (defect.type != sidb_defect_type::NONE) + if (defect.type != sidb_defect_type::NONE && is_charged_defect(cd.second)) { charge_lyt.add_sidb_defect_to_potential_landscape(cell, layout.get_sidb_defect(cell)); } diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 8775877f8..f14a0eb9a 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -101,7 +101,7 @@ struct sidb_defect */ [[nodiscard]] static constexpr bool is_charged_defect(const sidb_defect& defect) noexcept { - return defect.type == sidb_defect_type::DB || defect.type == sidb_defect_type::SI_VACANCY; + return defect.charge != 0 || defect.type == sidb_defect_type::DB || defect.type == sidb_defect_type::SI_VACANCY; } /** * Checks whether the given defect is positively charged. diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 0cc960341..0501a85b2 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -231,10 +231,11 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") defect_layout.assign_sidb_defect( {20, 12, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); REQUIRE(!found_gate_layouts.empty()); - CHECK(found_gate_layouts.front().num_defects() == 2); + CHECK(found_gate_layouts.front().num_defects() == 3); CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); found_gate_layouts.front().foreach_cell( From ad692e5df7c53844d9778a69cad60afeff231d43 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 31 Oct 2023 14:40:25 +0100 Subject: [PATCH 057/191] :art: use exceptions instead of ``ERROR`` gate --- .../defect_aware_physical_design.cpp | 2 +- .../dynamic_gate_design.cpp | 36 ++-- .../physical_design/apply_gate_library.hpp | 86 ++++----- .../physical_design/design_sidb_gates.hpp | 13 +- .../fiction/technology/fcn_gate_library.hpp | 7 - .../technology/sidb_dynamic_gate_library.hpp | 176 ++++++++++++++---- 6 files changed, 215 insertions(+), 105 deletions(-) diff --git a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp index e0e8b3437..6f9d3634d 100644 --- a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp +++ b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp @@ -129,7 +129,7 @@ int main() // NOLINT // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); - exact_params.crossings = true; + exact_params.crossings = false; exact_params.border_io = false; exact_params.desynchronize = false; exact_params.upper_bound_x = 11; // 12 x 31 tiles diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 83265aaae..b4d009337 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,17 +13,17 @@ #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include -#include // SiDB surface with support for atomic defects +#include // SiDB surface with support for atomic defects #include -#include // pre-defined types suitable for the FCN domain +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -170,10 +170,12 @@ int main() // NOLINT mockturtle::stopwatch<>::duration time_counter{}; + bool gate_design_failed = true; + { const mockturtle::stopwatch stop{time_counter}; - while (!gate_level_layout.has_value() || cell_level_layout.get_layout_name() == "fail") + while (!gate_level_layout.has_value() || gate_design_failed) { exact_params.black_list = black_list; fiction::exact_physical_design_stats exact_stats{}; @@ -185,11 +187,19 @@ int main() // NOLINT gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); if (gate_level_layout.has_value()) { - cell_level_layout = - fiction::apply_dynamic_gate_library( - *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, - black_list); + try + { + cell_level_layout = + fiction::apply_dynamic_gate_library( + *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, + black_list); + gate_design_failed = false; + } + catch (const std::exception& e) + { + gate_design_failed = true; + } } attempts++; } diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 0fef23e10..2dc19de7c 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -57,7 +57,7 @@ class apply_gate_library_impl * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ template - CellLyt run_dynamic_gates( + [[nodiscard]] CellLyt run_dynamic_gates( const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, surface_black_list& @@ -67,53 +67,49 @@ class apply_gate_library_impl // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif - gate_lyt.foreach_node( - [&, this](const auto& n, [[maybe_unused]] auto i) - { - if (cell_lyt.get_layout_name() == "fail") - { - return; - } - if (!gate_lyt.is_constant(n)) + try + { + gate_lyt.foreach_node( + [&, this](const auto& n, [[maybe_unused]] auto i) { - const auto t = gate_lyt.get_tile(n); + if (!gate_lyt.is_constant(n)) + { + const auto t = gate_lyt.get_tile(n); - // retrieve the top-leftmost cell in tile t - const auto c = - relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); + // retrieve the top-leftmost cell in tile t + const auto c = + relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate( - gate_lyt, t, defect_surface, params, black_list); - if (gate == GateLibrary::ERROR) - { - cell_lyt = CellLyt{{}, "fail"}; - return; + const auto gate = GateLibrary::template set_up_gate( + gate_lyt, t, defect_surface, params, black_list); + + assign_gate(c, gate, n); } - assign_gate(c, gate, n); - } #if (PROGRESS_BARS) - // update progress - bar(i); + // update progress + bar(i); #endif - }); + }); - // perform post-layout optimization if necessary - if constexpr (has_post_layout_optimization_v) - { - GateLibrary::post_layout_optimization(cell_lyt); - } + // perform post-layout optimization if necessary + if constexpr (has_post_layout_optimization_v) + { + GateLibrary::post_layout_optimization(cell_lyt); + } - // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) - { - if (cell_lyt.get_layout_name() != "fail") + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) { cell_lyt.set_layout_name(gate_lyt.get_layout_name()); } - } - return cell_lyt; + return cell_lyt; + } + catch (const std::exception& e) + { + throw; + } } /** @@ -126,7 +122,7 @@ class apply_gate_library_impl * * @return A `CellLyt` object representing the generated cell layout. */ - CellLyt run() + [[nodiscard]] CellLyt run() { #if (PROGRESS_BARS) // initialize a progress bar @@ -217,7 +213,7 @@ class apply_gate_library_impl * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -CellLyt apply_gate_library(const GateLyt& lyt) +[[nodiscard]] CellLyt apply_gate_library(const GateLyt& lyt) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -252,7 +248,7 @@ CellLyt apply_gate_library(const GateLyt& lyt) * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -CellLyt apply_dynamic_gate_library( +[[nodiscard]] CellLyt apply_dynamic_gate_library( const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, surface_black_list< GateLyt, typename decltype(GateLibraryblack::get_gate_ports())::mapped_type::value_type::port_type>& black_list) @@ -268,9 +264,15 @@ CellLyt apply_dynamic_gate_library( detail::apply_gate_library_impl p{lyt}; - auto result = p.template run_dynamic_gates(defect_surface, params, black_list); - - return result; + try + { + auto result = p.template run_dynamic_gates(defect_surface, params, black_list); + return result; + } + catch (const std::exception& e) + { + throw; // Re-throw the exception to propagate it up the call stack. + } } } // namespace fiction diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 805fc592b..2816c0696 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -141,7 +141,8 @@ class design_sidb_gates_impl for (const auto& comb : combination) { if (!solution_found && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && - global_iteration_counter < static_cast(params.procentual_maximum_attemps * total_comb)) + global_iteration_counter < + static_cast(params.procentual_maximum_attemps * static_cast(total_comb))) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -165,15 +166,15 @@ class design_sidb_gates_impl }; const unsigned int num_threads = std::thread::hardware_concurrency(); - const size_t chunk_size = all_combinations.size() / num_threads; + const std::size_t chunk_size = all_combinations.size() / num_threads; std::vector threads; threads.reserve(num_threads); - for (unsigned int i = 0; i < num_threads; ++i) + for (auto i = 0u; i < num_threads; ++i) { - size_t start = i * chunk_size; - size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; + std::size_t start = i * chunk_size; + std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; std::vector> chunk_combinations(all_combinations.begin() + start, all_combinations.begin() + end); threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); @@ -239,7 +240,7 @@ class design_sidb_gates_impl if constexpr (has_get_sidb_defect_v) { skeleton_layout.foreach_sidb_defect( - [this, &result_lyt](const auto& cd) + [&result_lyt](const auto& cd) { if (is_neutrally_charged_defect(cd.second)) { diff --git a/include/fiction/technology/fcn_gate_library.hpp b/include/fiction/technology/fcn_gate_library.hpp index 26b084c32..5750cc2a3 100644 --- a/include/fiction/technology/fcn_gate_library.hpp +++ b/include/fiction/technology/fcn_gate_library.hpp @@ -261,13 +261,6 @@ class fcn_gate_library return GateSizeY; } - /** - * Single error gate in given technology and tile size. - * - */ - static constexpr fcn_gate ERROR = - fiction::create_array(fiction::create_array(Technology::cell_type::INPUT)); - protected: /** * Transposes the given `fcn_gate` at compile time. diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index d3d5433f2..2205d9b72 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -18,6 +18,7 @@ #include "fiction/utils/layout_utils.hpp" #include +#include namespace fiction { @@ -100,8 +101,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, create_fan_out_tt(), parameter.params, black_list, p, t); + try + { + return design_gate( + layout, create_fan_out_tt(), parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } } @@ -133,8 +141,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); + try + { + return design_gate( + layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } const auto layout = add_defect_in_the_surrounding_to_layout( @@ -151,8 +166,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); + try + { + return design_gate( + layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } const auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); @@ -164,8 +186,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } return EMPTY_GATE; } @@ -179,8 +208,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (mockturtle::has_is_and_v) @@ -191,9 +227,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (mockturtle::has_is_or_v) @@ -205,8 +247,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_nand_v) @@ -218,8 +267,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_nor_v) @@ -231,8 +287,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (mockturtle::has_is_xor_v) @@ -244,8 +307,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_xnor_v) @@ -257,8 +327,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_ge_v) @@ -270,8 +347,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_le_v) @@ -283,8 +367,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_gt_v) @@ -295,9 +386,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } if constexpr (fiction::has_is_lt_v) @@ -309,8 +406,15 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); + try + { + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); + } + catch (const std::exception& e) + { + throw; + } } } } @@ -430,13 +534,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; @@ -446,13 +550,13 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; From 338959844daf7fa477b050ca638d0cb0d4c1e2be Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Tue, 31 Oct 2023 13:42:54 +0000 Subject: [PATCH 058/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../dynamic_gate_design/dynamic_gate_design.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index b4d009337..6b6bacebd 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,17 +13,17 @@ #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include -#include // SiDB surface with support for atomic defects +#include // SiDB surface with support for atomic defects #include -#include // pre-defined types suitable for the FCN domain +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing From c9c083166ab4e8cd30436c0a372ffc752ca21939 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 31 Oct 2023 15:51:58 +0100 Subject: [PATCH 059/191] :art: add more exceptions. --- .../physical_design/apply_gate_library.hpp | 68 +++++++++++-------- .../technology/sidb_dynamic_gate_library.hpp | 9 +++ 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 2dc19de7c..c9fd41016 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -128,38 +128,45 @@ class apply_gate_library_impl // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif - gate_lyt.foreach_node( - [&, this](const auto& n, [[maybe_unused]] auto i) - { - if (!gate_lyt.is_constant(n)) + try + { + gate_lyt.foreach_node( + [&, this](const auto& n, [[maybe_unused]] auto i) { - const auto t = gate_lyt.get_tile(n); + if (!gate_lyt.is_constant(n)) + { + const auto t = gate_lyt.get_tile(n); - // retrieve the top-leftmost cell in tile t - const auto c = - relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); + // retrieve the top-leftmost cell in tile t + const auto c = + relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); - } + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); + } #if (PROGRESS_BARS) - // update progress - bar(i); + // update progress + bar(i); #endif - }); + }); - // perform post-layout optimization if necessary - if constexpr (has_post_layout_optimization_v) - { - GateLibrary::post_layout_optimization(cell_lyt); + // perform post-layout optimization if necessary + if constexpr (has_post_layout_optimization_v) + { + GateLibrary::post_layout_optimization(cell_lyt); + } + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) + { + cell_lyt.set_layout_name(gate_lyt.get_layout_name()); + } + + return cell_lyt; } - // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) + catch (const std::exception& e) { - cell_lyt.set_layout_name(gate_lyt.get_layout_name()); + throw; } - - return cell_lyt; } private: @@ -226,9 +233,14 @@ template detail::apply_gate_library_impl p{lyt}; - auto result = p.run(); - - return result; + try + { + return p.run(); + } + catch (const std::exception& e) + { + throw; + } } /** * Applies a dynamic gate library (i.e., gate are designed on the fly by respecting atomic defects) to a given @@ -266,8 +278,8 @@ template (defect_surface, params, black_list); - return result; + return p.template run_dynamic_gates(defect_surface, params, black_list); + } catch (const std::exception& e) { diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 2205d9b72..0a8a36a6f 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -418,10 +418,19 @@ class sidb_dynamic_gate_library : public fcn_gate_library Date: Tue, 31 Oct 2023 14:53:36 +0000 Subject: [PATCH 060/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 1 - include/fiction/technology/sidb_dynamic_gate_library.hpp | 1 - 2 files changed, 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index c9fd41016..ce61f98f3 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -279,7 +279,6 @@ template (defect_surface, params, black_list); - } catch (const std::exception& e) { diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index 0a8a36a6f..fca935a91 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -430,7 +430,6 @@ class sidb_dynamic_gate_library : public fcn_gate_library Date: Tue, 31 Oct 2023 17:19:06 +0100 Subject: [PATCH 061/191] :art: change structure. --- .../technology/sidb_dynamic_gate_library.hpp | 169 ++++-------------- 1 file changed, 34 insertions(+), 135 deletions(-) diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index fca935a91..ea1bac07b 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -101,15 +101,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, create_fan_out_tt(), parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, create_fan_out_tt(), parameter.params, black_list, p, t); } } } @@ -141,15 +134,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + + return design_gate( + layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); } const auto layout = add_defect_in_the_surrounding_to_layout( @@ -166,15 +153,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library( - layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + + return design_gate( + layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); } const auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); @@ -186,15 +167,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } return EMPTY_GATE; } @@ -208,15 +182,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_and_v) @@ -227,15 +194,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_or_v) @@ -247,15 +208,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_nand_v) @@ -267,15 +221,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_nor_v) @@ -287,15 +234,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (mockturtle::has_is_xor_v) @@ -307,15 +247,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_xnor_v) @@ -327,15 +260,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_ge_v) @@ -347,15 +273,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_le_v) @@ -367,15 +286,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_gt_v) @@ -386,15 +298,9 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } if constexpr (fiction::has_is_lt_v) @@ -406,15 +312,8 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); - try - { - return design_gate( - layout, std::vector{f}, parameter.params, black_list, p, t); - } - catch (const std::exception& e) - { - throw; - } + return design_gate( + layout, std::vector{f}, parameter.params, black_list, p, t); } } } From 113c88744d61106e42f603f39b65800d69213466 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 31 Oct 2023 20:10:58 +0100 Subject: [PATCH 062/191] :art: implement clang-tidy suggestion. --- .../fiction/algorithms/physical_design/design_sidb_gates.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 2816c0696..31003f4d8 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -175,8 +175,8 @@ class design_sidb_gates_impl { std::size_t start = i * chunk_size; std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; - std::vector> chunk_combinations(all_combinations.begin() + start, - all_combinations.begin() + end); + std::vector> chunk_combinations( + all_combinations.begin() + start, all_combinations.begin() + static_cast(end)); threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); } From 7da1df6ef25b0819384c4b92620897de7d395c3b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 2 Nov 2023 10:13:04 +0100 Subject: [PATCH 063/191] :art: smaller changes here and there. --- docs/algorithms/apply_gate_library.rst | 2 +- docs/technology/defects.rst | 2 + .../dynamic_gate_design.cpp | 21 ++++++---- .../physical_design/apply_gate_library.hpp | 2 +- .../physical_design/design_sidb_gates.hpp | 12 +++--- .../is_gate_design_impossible.hpp | 14 ++++--- .../technology/sidb_dynamic_gate_library.hpp | 38 +++++++++---------- include/fiction/technology/sidb_surface.hpp | 10 ++--- 8 files changed, 56 insertions(+), 45 deletions(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 0410dffec..963b1a9fc 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_dynamic_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface) +.. doxygenfunction:: fiction::apply_dynamic_gate_library \ No newline at end of file diff --git a/docs/technology/defects.rst b/docs/technology/defects.rst index ecfb656eb..f28bb03ae 100644 --- a/docs/technology/defects.rst +++ b/docs/technology/defects.rst @@ -29,6 +29,8 @@ SiDB Defect Surface **Header:** ``fiction/technology/sidb_surface.hpp`` +.. doxygenstruct:: fiction::sidb_surface_params + :members: .. doxygenclass:: fiction::sidb_surface :members: .. doxygenclass:: fiction::sidb_surface< Lyt, true > diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 6b6bacebd..98c4d7f63 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,17 +13,17 @@ #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include -#include // SiDB surface with support for atomic defects +#include // SiDB surface with support for atomic defects #include -#include // pre-defined types suitable for the FCN domain +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -196,10 +196,15 @@ int main() // NOLINT black_list); gate_design_failed = false; } - catch (const std::exception& e) + catch (const std::logic_error& e) { gate_design_failed = true; } + + catch (const std::exception& e) + { + std::cerr << "Caught std::exception: " << e.what() << std::endl; + } } attempts++; } diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index ce61f98f3..5921d1e48 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -282,7 +282,7 @@ template threads; threads.reserve(num_threads); for (auto i = 0u; i < num_threads; ++i) { - std::size_t start = i * chunk_size; - std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; - std::vector> chunk_combinations( - all_combinations.begin() + start, all_combinations.begin() + static_cast(end)); + const std::size_t start = i * chunk_size; + const std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; + std::vector> chunk_combinations(all_combinations.begin() + start, + all_combinations.begin() + end); threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); } diff --git a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp index 79b157130..2171b7898 100644 --- a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp +++ b/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp @@ -18,10 +18,10 @@ namespace fiction { /** - * This function assesses whether it is impossible to design a gate for a given truth table in the provided layout due - * to atomic defects. + * This function assesses whether it is impossible to design an SiDB gate for a given truth table in the provided layout + * due to atomic defects. * - * @note If the function returns `false`, it does not imply that it is possible to design a SiDB gate for given + * @note If the function returns `false`, it does not imply that it is possible to design an SiDB gate for given * parameters. * * @tparam Lyt The type of the layout. @@ -61,17 +61,21 @@ bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, c } }); + // this function checks if parts of the bdl pairs are already neutrally charged due to nearby charged atomic + // defects. for (const auto& bdl : bdl_pairs) { if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.simulation_parameter.mu_minus) > -physical_constants::POP_STABILITY_ERR) { - return true; + return true; // the lower part can never be negatively charged. Thus, BDL property is not fulfilled + // anymore } if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.simulation_parameter.mu_minus) > -physical_constants::POP_STABILITY_ERR) { - return true; + return true; // the upper part can never be negatively charged. Thus, BDL property is not fulfilled + // anymore } } } diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_dynamic_gate_library.hpp index ea1bac07b..193230114 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_dynamic_gate_library.hpp @@ -95,8 +95,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library( + const auto layout = add_defect_to_skeleton( sidb_surface, cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -120,7 +119,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_TWO_OUT), center_cell_siqad, absolute_cell_siqad, parameter); @@ -139,7 +138,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_TWO_OUT), center_cell_siqad, absolute_cell_siqad, parameter); @@ -163,7 +162,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(cell_list), center_cell_siqad, absolute_cell_siqad, parameter); @@ -177,7 +176,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -190,7 +189,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -203,7 +202,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -216,7 +215,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -229,7 +228,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -242,7 +241,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -255,7 +254,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -268,7 +267,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -281,7 +280,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -294,7 +293,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -307,7 +306,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell_siqad, absolute_cell_siqad, parameter); @@ -529,9 +528,10 @@ class sidb_dynamic_gate_library : public fcn_gate_library - [[nodiscard]] static LytSkeleton add_defect_in_the_surrounding_to_layout( - const sidb_surface& defect_surface, const LytSkeleton& skeleton, const siqad::coord_t& center_cell_siqad, - const siqad::coord_t& absolute_cell_siqad, const sidb_dynamic_gate_library_params& params) + [[nodiscard]] static LytSkeleton + add_defect_to_skeleton(const sidb_surface& defect_surface, const LytSkeleton& skeleton, + const siqad::coord_t& center_cell_siqad, const siqad::coord_t& absolute_cell_siqad, + const sidb_dynamic_gate_library_params& params) { static_assert(!has_siqad_coord_v, "Lyt has SiQAD coordinates."); static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates."); diff --git a/include/fiction/technology/sidb_surface.hpp b/include/fiction/technology/sidb_surface.hpp index aac2d9502..5aae90690 100644 --- a/include/fiction/technology/sidb_surface.hpp +++ b/include/fiction/technology/sidb_surface.hpp @@ -216,19 +216,19 @@ class sidb_surface : public Lyt * * If the given surface is defect-free, the empty set is returned. * - * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, + * @param user_defined_spacing_charged_defects If set to `true`, charged defects are treated like neutral defects, * `false`otherwise. * @return All SiDB positions affected by any defect on the surface. */ [[nodiscard]] std::unordered_set - all_affected_sidbs(const bool incorporate_defect_into_gate_design = false, - const std::pair& distance = {0, 0}) const noexcept + all_affected_sidbs(const bool user_defined_spacing_charged_defects = false, + const std::pair& distance = {0, 0}) const noexcept { std::unordered_set influenced_sidbs{}; foreach_sidb_defect( - [&influenced_sidbs, &incorporate_defect_into_gate_design, &distance, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first, incorporate_defect_into_gate_design, distance)); }); + [&influenced_sidbs, &user_defined_spacing_charged_defects, &distance, this](const auto& it) + { influenced_sidbs.merge(affected_sidbs(it.first, user_defined_spacing_charged_defects, distance)); }); return influenced_sidbs; } From 55e1486b31a1471613589924b52423f85bb562fd Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Thu, 2 Nov 2023 10:19:33 +0000 Subject: [PATCH 064/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../dynamic_gate_design/dynamic_gate_design.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/dynamic_gate_design/dynamic_gate_design.cpp index 98c4d7f63..e9bb8db8e 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/dynamic_gate_design/dynamic_gate_design.cpp @@ -13,17 +13,17 @@ #include #include // critical path and throughput calculations #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) #include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include -#include // SiDB surface with support for atomic defects +#include // SiDB surface with support for atomic defects #include -#include // pre-defined types suitable for the FCN domain +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing From ff5ebe74f9c8632039fae33ea803f76e5fff3dcd Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 08:37:24 +0100 Subject: [PATCH 065/191] :art: revert changes in experiment script. --- .../defect_aware_physical_design.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp index 6f9d3634d..b04ea2413 100644 --- a/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp +++ b/experiments/defect_aware_physical_design/defect_aware_physical_design.cpp @@ -118,7 +118,7 @@ int main() // NOLINT // read surface scan lattice data const auto surface_lattice = fiction::read_sidb_surface_defects( - "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt", "py_test_surface"); + "../../experiments/defect_aware_physical_design/py_test_surface.txt", "py_test_surface"); // fiction::read_sqd_layout(surface_lattice, surface_data_path); const auto lattice_tiling = gate_lyt{{11, 30}}; // our surface data is 12 x 31 Bestagon tiles @@ -129,7 +129,7 @@ int main() // NOLINT // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); - exact_params.crossings = false; + exact_params.crossings = true; exact_params.border_io = false; exact_params.desynchronize = false; exact_params.upper_bound_x = 11; // 12 x 31 tiles From cad6aa79d47ec87402e332182e93c1667e9e9331 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 12:04:27 +0100 Subject: [PATCH 066/191] :art: implement Marcel's suggestions, first batch. --- docs/algorithms/design_sidb_gates.rst | 3 -- docs/technology/gate_libraries.rst | 10 ++--- ...al_design_with_on_the_fly_gate_design.cpp} | 14 ++++--- .../physical_design/apply_gate_library.hpp | 12 +++--- .../physical_design/design_sidb_gates.hpp | 2 +- .../sidb/random_sidb_layout_generator.hpp | 2 +- include/fiction/technology/sidb_defects.hpp | 23 +++++------ ...y.hpp => sidb_on_the_fly_gate_library.hpp} | 38 ++++++++++++------- .../sidb_skeleton_bestagon_library.hpp | 8 +--- include/fiction/technology/sidb_surface.hpp | 26 ++++++------- .../technology/sidb_surface_analysis.hpp | 9 +++-- .../sidb/is_gate_design_impossible.cpp | 7 ++-- .../technology/sidb_bestagon_gate_library.cpp | 2 +- test/technology/sidb_dynamic_gate_library.cpp | 19 ---------- .../sidb_on_the_fly_gate_library.cpp | 19 ++++++++++ test/technology/sidb_surface.cpp | 12 +++--- 16 files changed, 108 insertions(+), 98 deletions(-) rename experiments/{dynamic_gate_design/dynamic_gate_design.cpp => physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp} (95%) rename include/fiction/technology/{sidb_dynamic_gate_library.hpp => sidb_on_the_fly_gate_library.hpp} (99%) delete mode 100644 test/technology/sidb_dynamic_gate_library.cpp create mode 100644 test/technology/sidb_on_the_fly_gate_library.cpp diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index 08293afd6..c06711197 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -1,9 +1,6 @@ SiDB Gate Design ---------------- -SiDB Gate Designer -################## - **Header:** ``fiction/algorithms/physical_design/design_sidb_gates.hpp`` .. doxygenstruct:: fiction::design_sidb_gates_params diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index 4e21a0d64..f8ee5838e 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -59,12 +59,12 @@ SiDB Bestagon Library .. doxygenclass:: fiction::sidb_bestagon_library :members: -Dynamic SiDB Bestagon Library ---------------------- +On-the-fly SiDB Library +----------------------- -**Header:** ``fiction/technology/sidb_dynamic_gate_library.hpp`` +**Header:** ``fiction/technology/sidb_on_the_fly_gate_library.hpp`` -.. doxygenstruct:: fiction::sidb_dynamic_gate_library_params +.. doxygenstruct:: fiction::sidb_on_the_fly_gate_library_params :members: -.. doxygenclass:: fiction::sidb_dynamic_gate_library +.. doxygenclass:: fiction::sidb_on_the_fly_gate_library :members: diff --git a/experiments/dynamic_gate_design/dynamic_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp similarity index 95% rename from experiments/dynamic_gate_design/dynamic_gate_design.cpp rename to experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index e9bb8db8e..134c0df5c 100644 --- a/experiments/dynamic_gate_design/dynamic_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -19,7 +19,7 @@ #include // area requirement calculations #include // cell implementations #include -#include // a dynamic SiDB gate library +#include // a dynamic SiDB gate library #include #include // SiDB surface with support for atomic defects #include @@ -40,6 +40,7 @@ #include #include #include +#include // This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SDB // circuits can be designed in the presence of atomic defects. @@ -49,7 +50,7 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt; - static const std::string layouts_folder = fmt::format("{}/dynamic_gate_design/layouts", EXPERIMENTS_PATH); + static const std::string layouts_folder = fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); const std::vector defect_concentrations = {1}; @@ -164,7 +165,7 @@ int main() // NOLINT cell_lyt cell_level_layout{{}, "fail"}; auto black_list = fiction::sidb_surface_analysis( - lattice_tiling, surface_lattice, true); + lattice_tiling, surface_lattice, std::make_pair(0,0)); uint64_t attempts = 0; @@ -190,9 +191,10 @@ int main() // NOLINT try { cell_level_layout = - fiction::apply_dynamic_gate_library( - *gate_level_layout, surface_lattice, fiction::sidb_dynamic_gate_library_params{}, + fiction::apply_on_the_fly_gate_library( + *gate_level_layout, surface_lattice, fiction::sidb_on_the_fly_gate_library_params{}, black_list); gate_design_failed = false; } diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 5921d1e48..7878aec73 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -9,7 +9,7 @@ #include "fiction/technology/inml_topolinano_library.hpp" #include "fiction/technology/qca_one_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" -#include "fiction/technology/sidb_dynamic_gate_library.hpp" +#include "fiction/technology/sidb_on_the_fly_gate_library.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" @@ -58,7 +58,7 @@ class apply_gate_library_impl */ template [[nodiscard]] CellLyt run_dynamic_gates( - const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, + const sidb_surface& defect_surface, const sidb_on_the_fly_gate_library_params& params, surface_black_list& black_list) @@ -243,7 +243,7 @@ template } } /** - * Applies a dynamic gate library (i.e., gate are designed on the fly by respecting atomic defects) to a given + * Applies an on-the-fly gate library (i.e., gate are designed on-the-fly by respecting atomic defects) to a given * gate-level layout and, thereby, creates and returns a cell-level layout. * * May pass through, and thereby throw, an `unsupported_gate_type_exception` or an @@ -252,7 +252,7 @@ template * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. - * @tparam GateLibraryblack Type of the gate-level layout used to generate the blacklist. + * @tparam GateLibraryblack Type of the Gate Library to generate the blacklist. * @param lyt The gate-level layout. * @param defect_surface Defect surface with all atomic defects. * @param params Parameter for the dynamic gate library. @@ -260,8 +260,8 @@ template * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -[[nodiscard]] CellLyt apply_dynamic_gate_library( - const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_dynamic_gate_library_params& params, +[[nodiscard]] CellLyt apply_on_the_fly_gate_library( + const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_on_the_fly_gate_library_params& params, surface_black_list< GateLyt, typename decltype(GateLibraryblack::get_gate_ports())::mapped_type::value_type::port_type>& black_list) { diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index c3e16e159..08d146879 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -119,7 +119,7 @@ class design_sidb_gates_impl if constexpr (has_get_sidb_defect_v) { - sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(true); + sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(std::make_pair(0, 0)); } std::vector designed_gate_layouts = {}; diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index 128782a4e..702e6c8cb 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -106,7 +106,7 @@ Lyt generate_random_sidb_layout(const Lyt& lyt_skeleton, const generate_random_s if constexpr (has_get_sidb_defect_v) { - sidbs_affected_by_defects = lyt_skeleton.all_affected_sidbs(true); + sidbs_affected_by_defects = lyt_skeleton.all_affected_sidbs(std::make_pair(0, 0)); } const uint64_t number_of_sidbs_of_final_layout = lyt_skeleton.num_cells() + params.number_of_sidbs; diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index f14a0eb9a..f1eb58c4d 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace fiction @@ -167,24 +168,24 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING = 1u; */ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; /** - * Returns the extent of a defect as a pair of SiDB distances in horizontal and vertical direction. If defect is the - * `NONE` defect type, `{0, 0}` is returned. + * Returns the extent of a defect as a pair of SiDB distances in the horizontal and vertical directions. + * If the defect type is `NONE`, `{0, 0}` is returned. * * @param defect Defect type to evaluate. - * @param incorporate_defect_into_gate_design If set to `true`, the influence of charged atomic defects on SiDBs - * is given by the input `charged_defect_spacing`. If set to `false`, default values are used. - * @param charged_defect_spacing Influence of charged atomic defects on SiDBs. - * @return Number of horizontal and vertical SiDBs that are affected by the given defect type. + * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an optional + * pair of horizontal and vertical spacings. + * @return A pair of uint16_t values representing the number of horizontal and vertical SiDBs affected by the given + * defect type. */ -[[nodiscard]] static constexpr std::pair -defect_extent(const sidb_defect& defect, bool incorporate_defect_into_gate_design = false, - const std::pair& charged_defect_spacing = {0, 0}) noexcept +[[nodiscard]] static constexpr std::pair defect_extent( + const sidb_defect& defect, + const std::optional>& user_defined_spacing_charged_defects = std::nullopt) noexcept { if (is_charged_defect(defect)) { - if (incorporate_defect_into_gate_design) + if (user_defined_spacing_charged_defects.has_value()) { - return charged_defect_spacing; + return user_defined_spacing_charged_defects.value(); } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } diff --git a/include/fiction/technology/sidb_dynamic_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp similarity index 99% rename from include/fiction/technology/sidb_dynamic_gate_library.hpp rename to include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 193230114..a128a6f55 100644 --- a/include/fiction/technology/sidb_dynamic_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -2,14 +2,13 @@ // Created by Jan Drewniok 20.09.23. // -#ifndef FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP -#define FICTION_SIDB_DYNAMIC_GATE_LIBRARY_HPP +#ifndef FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP +#define FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP #include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/physical_design/is_gate_design_impossible.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" -#include "fiction/io/read_sqd_layout.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/sidb_surface.hpp" @@ -18,24 +17,37 @@ #include "fiction/utils/layout_utils.hpp" #include +#include #include +#include +#include namespace fiction { /** - * This struct stores the parameter to design gates on the fly. + * This struct encapsulates parameters for the dynamic gate library. */ -struct sidb_dynamic_gate_library_params +struct sidb_on_the_fly_gate_library_params { + /** + * This struct holds parameters to design SiDB gates on-the-fly. + */ design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{24, 8, 1}, {34, 14, 0}}, 3, sidb_simulation_engine::QUICKEXACT, 1}; - + /** + * This variable defines the number of canvas SiDBs dedicated to complex gates, such as crossing, double wire, + * and half-adder. + */ uint64_t canvas_sidb_complex_gates = 3; + /** + * This variable specifies the radius around the middle of the hexagon where atomic defects are incorporated into + * the gate design. + */ double influence_radius_charged_defects = 15; // (unit: nm) }; @@ -43,10 +55,10 @@ struct sidb_dynamic_gate_library_params * An on-the-fly gate library for SiDB technology. It allows the design of SiDB gates tailored to given atomic defects, * thus enabling the design of SiDB circuits in the presence of atomic defects. */ -class sidb_dynamic_gate_library : public fcn_gate_library // width and height of a hexagon +class sidb_on_the_fly_gate_library : public fcn_gate_library // width and height of a hexagon { public: - explicit sidb_dynamic_gate_library() = delete; + explicit sidb_on_the_fly_gate_library() = delete; /** * Overrides the corresponding function in fcn_gate_library. Given a tile `t`, this function takes all necessary @@ -58,7 +70,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library static fcn_gate set_up_gate( const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, - const sidb_dynamic_gate_library_params& parameter = sidb_dynamic_gate_library_params{}, + const sidb_on_the_fly_gate_library_params& parameter = sidb_on_the_fly_gate_library_params{}, surface_black_list& black_list = {}) @@ -349,7 +361,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library& truth_table) { auto defect_copy = defect_lyt.clone(); - const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(true); + const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(std::pair(0, 0)); bool is_bestagon_gate_applicable = true; defect_copy.foreach_sidb_defect( @@ -531,7 +543,7 @@ class sidb_dynamic_gate_library : public fcn_gate_library& defect_surface, const LytSkeleton& skeleton, const siqad::coord_t& center_cell_siqad, const siqad::coord_t& absolute_cell_siqad, - const sidb_dynamic_gate_library_params& params) + const sidb_on_the_fly_gate_library_params& params) { static_assert(!has_siqad_coord_v, "Lyt has SiQAD coordinates."); static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates."); @@ -1241,4 +1253,4 @@ class sidb_dynamic_gate_library : public fcn_gate_library -#include - -#include - namespace fiction { /** - * A Bestagon SiDB skeleton gate library for all two input Boolean functions. + * This library contains SiDB I/O wires designed for both 1- and 2-input functions. + * Each wire comprises 2 BDL pairs. The library contains all mirrored versions, a double wire and a crossing. */ class sidb_skeleton_bestagon_library : public fcn_gate_library // width and height of a hexagon diff --git a/include/fiction/technology/sidb_surface.hpp b/include/fiction/technology/sidb_surface.hpp index 5aae90690..d2a0dc1b7 100644 --- a/include/fiction/technology/sidb_surface.hpp +++ b/include/fiction/technology/sidb_surface.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -178,21 +179,20 @@ class sidb_surface : public Lyt * If the given coordinate is defect-free, the empty set is returned. * * @param c Coordinate whose defect extent is to be determined. - * @param user_defined_spacing_charged_defects If set to `true`, the influence of charged atomic defects on SiDBs - * is given by the input `charged_defect_spacing`. If set to `false`, default values are used. - * @param charged_defect_spacing Influence of charged atomic defects on SiDBs. + * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an + * optional pair of horizontal and vertical spacings. * @return All SiDB positions affected by the defect at coordinate c. */ [[nodiscard]] std::unordered_set - affected_sidbs(const typename Lyt::coordinate& c, const bool user_defined_spacing_charged_defects = false, - const std::pair& charged_defect_spacing = {0, 0}) const noexcept + affected_sidbs(const typename Lyt::coordinate& c, + const std::optional>& user_defined_spacing_charged_defects = + std::nullopt) const noexcept { std::unordered_set influenced_sidbs{}; if (const auto d = get_sidb_defect(c); d.type != sidb_defect_type::NONE) { - const auto [horizontal_extent, vertical_extent] = - defect_extent(d, user_defined_spacing_charged_defects, charged_defect_spacing); + const auto [horizontal_extent, vertical_extent] = defect_extent(d, user_defined_spacing_charged_defects); for (auto y = static_cast(c.y - vertical_extent); y <= static_cast(c.y + vertical_extent); ++y) @@ -216,19 +216,19 @@ class sidb_surface : public Lyt * * If the given surface is defect-free, the empty set is returned. * - * @param user_defined_spacing_charged_defects If set to `true`, charged defects are treated like neutral defects, - * `false`otherwise. + * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an + * optional pair of horizontal and vertical spacings. * @return All SiDB positions affected by any defect on the surface. */ [[nodiscard]] std::unordered_set - all_affected_sidbs(const bool user_defined_spacing_charged_defects = false, - const std::pair& distance = {0, 0}) const noexcept + all_affected_sidbs(const std::optional>& user_defined_spacing_charged_defects = + std::nullopt) const noexcept { std::unordered_set influenced_sidbs{}; foreach_sidb_defect( - [&influenced_sidbs, &user_defined_spacing_charged_defects, &distance, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first, user_defined_spacing_charged_defects, distance)); }); + [&influenced_sidbs, &user_defined_spacing_charged_defects, this](const auto& it) + { influenced_sidbs.merge(affected_sidbs(it.first, user_defined_spacing_charged_defects)); }); return influenced_sidbs; } diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index 30f3570fc..e74327e2b 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include namespace fiction @@ -54,9 +55,9 @@ using surface_black_list = * @return A black list of gate functions associated with tiles. */ template -[[nodiscard]] auto sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, - const bool incorporate_defect_into_gate_design = false, - const std::pair& distance = {0, 0}) noexcept +[[nodiscard]] auto +sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, + const std::optional>& distance = std::nullopt) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -73,7 +74,7 @@ template surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(incorporate_defect_into_gate_design, distance); + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(distance); const auto gate_implementations = GateLibrary::get_functional_implementations(); const auto gate_ports = GateLibrary::get_gate_ports(); diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index 763c37c94..770eb0874 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -2,10 +2,9 @@ // Created by Jan Drewniok on 25.10.23. // -#include "fiction/algorithms/physical_design/is_gate_design_impossible.hpp" - #include +#include #include #include #include @@ -13,7 +12,7 @@ using namespace fiction; -TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-operational]") +TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-gate-design-impossible]") { using layout = sidb_defect_cell_clk_lyt_siqad; @@ -51,7 +50,7 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-operat } } -TEST_CASE("Bestagon CROSSING gate", "[is-operational]") +TEST_CASE("Bestagon CROSSING gate", "[is-gate-design-impossible]") { using layout = sidb_defect_cell_clk_lyt_siqad; diff --git a/test/technology/sidb_bestagon_gate_library.cpp b/test/technology/sidb_bestagon_gate_library.cpp index 9eb007b50..3da87fc81 100644 --- a/test/technology/sidb_bestagon_gate_library.cpp +++ b/test/technology/sidb_bestagon_gate_library.cpp @@ -10,7 +10,7 @@ using namespace fiction; -TEST_CASE("Bestagon traits", "[sidb-bestagon-library]") +TEST_CASE("traits", "[sidb-bestagon-gate-library]") { CHECK(!has_post_layout_optimization_v); CHECK(!has_post_layout_optimization_v); diff --git a/test/technology/sidb_dynamic_gate_library.cpp b/test/technology/sidb_dynamic_gate_library.cpp deleted file mode 100644 index ea27cf0bd..000000000 --- a/test/technology/sidb_dynamic_gate_library.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by Jan Drewniok on 24.10.23. -// - -#include - -#include -#include -#include - -using namespace fiction; - -TEST_CASE("Bestagon traits", "[sidb-dynamic-gate-library]") -{ - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); -} diff --git a/test/technology/sidb_on_the_fly_gate_library.cpp b/test/technology/sidb_on_the_fly_gate_library.cpp new file mode 100644 index 000000000..2b3090014 --- /dev/null +++ b/test/technology/sidb_on_the_fly_gate_library.cpp @@ -0,0 +1,19 @@ +// +// Created by Jan Drewniok on 24.10.23. +// + +#include + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Layout optimization traits", "[sidb-dynamic-gate-library]") +{ + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); +} diff --git a/test/technology/sidb_surface.cpp b/test/technology/sidb_surface.cpp index 11f16d16c..35bc69cb0 100644 --- a/test/technology/sidb_surface.cpp +++ b/test/technology/sidb_surface.cpp @@ -14,6 +14,7 @@ #include #include +#include using namespace fiction; @@ -249,7 +250,7 @@ TEMPLATE_TEST_CASE( CHECK(defect_layout.num_defects() == 2); - CHECK(defect_layout.affected_sidbs({5, 4}, true, {26, 13}) == + CHECK(defect_layout.affected_sidbs({5, 4}, std::make_pair(26, 13)) == decltype(defect_layout.affected_sidbs({5, 4})){ {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, @@ -262,7 +263,7 @@ TEMPLATE_TEST_CASE( {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); - CHECK(defect_layout.affected_sidbs({5, 5}, true, {26, 13}) == + CHECK(defect_layout.affected_sidbs({5, 5}, std::make_pair(26, 13)) == decltype(defect_layout.affected_sidbs({5, 5})){ {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, @@ -275,7 +276,7 @@ TEMPLATE_TEST_CASE( {0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 9}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}}}); - CHECK(defect_layout.all_affected_sidbs(true, {26, 13}) == + CHECK(defect_layout.all_affected_sidbs(std::make_pair(26, 13)) == decltype(defect_layout.all_affected_sidbs()){ {{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, {10, 0}, {11, 0}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1}, @@ -297,9 +298,10 @@ TEMPLATE_TEST_CASE( CHECK(defect_layout.num_defects() == 2); - CHECK(defect_layout.affected_sidbs({5, 4}, true) == decltype(defect_layout.affected_sidbs({5, 4})){{{5, 4}}}); + CHECK(defect_layout.affected_sidbs({5, 4}, std::make_pair(0, 0)) == + decltype(defect_layout.affected_sidbs({5, 4})){{{5, 4}}}); - CHECK(defect_layout.affected_sidbs({5, 4}, true, {2, 1}) == + CHECK(defect_layout.affected_sidbs({5, 4}, std::make_pair(2, 1)) == decltype(defect_layout.affected_sidbs({5, 4})){{{3, 3}, {4, 3}, {5, 3}, From 0520b2cdaada4973577d17c12a16af2d4497a347 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Mon, 13 Nov 2023 11:05:44 +0000 Subject: [PATCH 067/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../physical_design_with_on_the_fly_gate_design.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 134c0df5c..2c07b39eb 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -50,7 +50,8 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt; - static const std::string layouts_folder = fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); + static const std::string layouts_folder = + fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); const std::vector defect_concentrations = {1}; @@ -165,7 +166,7 @@ int main() // NOLINT cell_lyt cell_level_layout{{}, "fail"}; auto black_list = fiction::sidb_surface_analysis( - lattice_tiling, surface_lattice, std::make_pair(0,0)); + lattice_tiling, surface_lattice, std::make_pair(0, 0)); uint64_t attempts = 0; From 30460dc7b9e58bd4ac909c87dba3f4d4afb4da3a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 12:21:10 +0100 Subject: [PATCH 068/191] :art: rename dynamic to on-the-fly. --- docs/algorithms/apply_gate_library.rst | 2 +- .../physical_design/apply_gate_library.hpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 963b1a9fc..599446b9a 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_dynamic_gate_library \ No newline at end of file +.. doxygenfunction:: fiction::apply_on_the_fly_gate_library \ No newline at end of file diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 7878aec73..52fd91106 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -45,19 +45,19 @@ class apply_gate_library_impl {} /** - * This function dynamically designs gates based on the provided atomic defects and gate types defined in `lyt`. + * This function designs gates on-the-fly based on the provided atomic defects and gate types defined in `lyt`. * It creates a cell-level layout by adapting a gate-level layout on-the-fly to implement the gate types using * building blocks from the `GateLibrary`. Atomic defects are incorporated into the gate designs during this * process. * - * @tparam GateLibraryblack Type of the gate-level layout used to generate the blacklist. + * @tparam GateLibraryblack Type of the gate library used to generate the blacklist. * @param defect_surface Defect surface with atomic defects. - * @param params Parameter for the dynamic gate library. + * @param params Parameter for the gate library. * @param black_list Blacklist. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ template - [[nodiscard]] CellLyt run_dynamic_gates( + [[nodiscard]] CellLyt design_gates_on_the_fly( const sidb_surface& defect_surface, const sidb_on_the_fly_gate_library_params& params, surface_black_list& @@ -255,7 +255,7 @@ template * @tparam GateLibraryblack Type of the Gate Library to generate the blacklist. * @param lyt The gate-level layout. * @param defect_surface Defect surface with all atomic defects. - * @param params Parameter for the dynamic gate library. + * @param params Parameter for the gate library. * @param black_list Blacklist. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ @@ -278,7 +278,7 @@ template (defect_surface, params, black_list); + return p.template design_gates_on_the_fly(defect_surface, params, black_list); } catch (const std::exception& e) { From 34d77bb995a5fe22cc797cb25ab883c736b0b65f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 15:59:09 +0100 Subject: [PATCH 069/191] :art: introduce new exception class. --- ...cal_design_with_on_the_fly_gate_design.cpp | 8 +- .../physical_design/apply_gate_library.hpp | 146 +++++++---------- .../sidb_on_the_fly_gate_library.hpp | 150 +++++++++++++----- 3 files changed, 171 insertions(+), 133 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 2c07b39eb..7064668d0 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -24,6 +24,7 @@ #include // SiDB surface with support for atomic defects #include #include // pre-defined types suitable for the FCN domain +#include #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -195,13 +196,14 @@ int main() // NOLINT fiction::apply_on_the_fly_gate_library( - *gate_level_layout, surface_lattice, fiction::sidb_on_the_fly_gate_library_params{}, - black_list); + *gate_level_layout, surface_lattice, + fiction::sidb_on_the_fly_gate_library_params{}); gate_design_failed = false; } - catch (const std::logic_error& e) + catch (const fiction::gate_design_exception& e) { gate_design_failed = true; + black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); } catch (const std::exception& e) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 52fd91106..71a2c0429 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -53,63 +53,52 @@ class apply_gate_library_impl * @tparam GateLibraryblack Type of the gate library used to generate the blacklist. * @param defect_surface Defect surface with atomic defects. * @param params Parameter for the gate library. - * @param black_list Blacklist. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ template - [[nodiscard]] CellLyt design_gates_on_the_fly( - const sidb_surface& defect_surface, const sidb_on_the_fly_gate_library_params& params, - surface_black_list& - black_list) + [[nodiscard]] CellLyt design_gates_on_the_fly(const sidb_surface& defect_surface, + const sidb_on_the_fly_gate_library_params& params) { #if (PROGRESS_BARS) // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif - try - { - gate_lyt.foreach_node( - [&, this](const auto& n, [[maybe_unused]] auto i) + gate_lyt.foreach_node( + [&, this](const auto& n, [[maybe_unused]] auto i) + { + if (!gate_lyt.is_constant(n)) { - if (!gate_lyt.is_constant(n)) - { - const auto t = gate_lyt.get_tile(n); + const auto t = gate_lyt.get_tile(n); - // retrieve the top-leftmost cell in tile t - const auto c = - relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); + // retrieve the top-leftmost cell in tile t + const auto c = + relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate( - gate_lyt, t, defect_surface, params, black_list); + const auto gate = GateLibrary::template set_up_gate( + gate_lyt, t, defect_surface, params); - assign_gate(c, gate, n); - } + assign_gate(c, gate, n); + } #if (PROGRESS_BARS) - // update progress - bar(i); + // update progress + bar(i); #endif - }); - - // perform post-layout optimization if necessary - if constexpr (has_post_layout_optimization_v) - { - GateLibrary::post_layout_optimization(cell_lyt); - } - - // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) - { - cell_lyt.set_layout_name(gate_lyt.get_layout_name()); - } + }); - return cell_lyt; + // perform post-layout optimization if necessary + if constexpr (has_post_layout_optimization_v) + { + GateLibrary::post_layout_optimization(cell_lyt); } - catch (const std::exception& e) + + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) { - throw; + cell_lyt.set_layout_name(gate_lyt.get_layout_name()); } + + return cell_lyt; } /** @@ -128,45 +117,39 @@ class apply_gate_library_impl // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif - try - { - gate_lyt.foreach_node( - [&, this](const auto& n, [[maybe_unused]] auto i) + + gate_lyt.foreach_node( + [&, this](const auto& n, [[maybe_unused]] auto i) + { + if (!gate_lyt.is_constant(n)) { - if (!gate_lyt.is_constant(n)) - { - const auto t = gate_lyt.get_tile(n); + const auto t = gate_lyt.get_tile(n); - // retrieve the top-leftmost cell in tile t - const auto c = - relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); + // retrieve the top-leftmost cell in tile t + const auto c = + relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); - } + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); + } #if (PROGRESS_BARS) - // update progress - bar(i); + // update progress + bar(i); #endif - }); + }); - // perform post-layout optimization if necessary - if constexpr (has_post_layout_optimization_v) - { - GateLibrary::post_layout_optimization(cell_lyt); - } - // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) - { - cell_lyt.set_layout_name(gate_lyt.get_layout_name()); - } - - return cell_lyt; + // perform post-layout optimization if necessary + if constexpr (has_post_layout_optimization_v) + { + GateLibrary::post_layout_optimization(cell_lyt); } - catch (const std::exception& e) + // if available, recover layout name + if constexpr (has_get_layout_name_v && has_set_layout_name_v) { - throw; + cell_lyt.set_layout_name(gate_lyt.get_layout_name()); } + + return cell_lyt; } private: @@ -233,14 +216,7 @@ template detail::apply_gate_library_impl p{lyt}; - try - { - return p.run(); - } - catch (const std::exception& e) - { - throw; - } + return p.run(); } /** * Applies an on-the-fly gate library (i.e., gate are designed on-the-fly by respecting atomic defects) to a given @@ -256,14 +232,11 @@ template * @param lyt The gate-level layout. * @param defect_surface Defect surface with all atomic defects. * @param params Parameter for the gate library. - * @param black_list Blacklist. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -[[nodiscard]] CellLyt apply_on_the_fly_gate_library( - const GateLyt& lyt, const sidb_surface& defect_surface, const sidb_on_the_fly_gate_library_params& params, - surface_black_list< - GateLyt, typename decltype(GateLibraryblack::get_gate_ports())::mapped_type::value_type::port_type>& black_list) +[[nodiscard]] CellLyt apply_on_the_fly_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface, + const sidb_on_the_fly_gate_library_params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); @@ -276,14 +249,7 @@ template p{lyt}; - try - { - return p.template design_gates_on_the_fly(defect_surface, params, black_list); - } - catch (const std::exception& e) - { - throw; - } + return p.template design_gates_on_the_fly(defect_surface, params); } } // namespace fiction diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index a128a6f55..9f71fedf7 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -24,6 +24,84 @@ namespace fiction { + +/** + * This exception is thrown when an error occurs during the design of an SiDB gate. + * It provides information about the tile, truth table, and port list associated with the error. + * + * @tparam TT The type representing the truth table. + * @tparam GateLyt The type representing the gate-level layout. + */ +template +class gate_design_exception : public std::exception +{ + public: + /** + * @brief Constructor for the gate_design_exception class. + * + * @param ti The tile associated with the error. + * @param spec The truth table associated with the error. + * @param portlist The port list associated with the error. + */ + explicit gate_design_exception(const tile& ti, const TT& spec, + const port_list& portlist) noexcept : + std::exception(), + tile{ti}, + truth_table{spec}, + p{portlist} + {} + + /** + * Get the tile associated with the exception. + * + * @return The tile associated with the error. + */ + [[nodiscard]] tile which_tile() const noexcept + { + return tile; + } + + /** + * Get the truth table associated with the exception. + * + * @return The truth table associated with the error. + */ + [[nodiscard]] TT which_truth_table() const noexcept + { + return truth_table; + } + + /** + * Get the port list associated with the exception. + * + * @return The port list associated with the error. + */ + [[nodiscard]] port_list which_port_list() const noexcept + { + return p; + } + + private: + /** + * The tile associated with the error. + * + * @return The tile associated with the error. + */ + const tile tile{}; + /** + * The truth table associated with the error. + * + * @return The port list associated with the error. + */ + const TT truth_table{}; + /** + * The port list associated with the error. + * + * @return The port list associated with the error. + */ + const port_list p; +}; + /** * This struct encapsulates parameters for the dynamic gate library. */ @@ -72,16 +150,12 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - static fcn_gate set_up_gate( - const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, - const sidb_on_the_fly_gate_library_params& parameter = sidb_on_the_fly_gate_library_params{}, - surface_black_list& - black_list = {}) + static fcn_gate + set_up_gate(const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, + const sidb_on_the_fly_gate_library_params& parameter = sidb_on_the_fly_gate_library_params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); @@ -113,7 +187,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, create_fan_out_tt(), parameter.params, black_list, p, t); + layout, create_fan_out_tt(), parameter.params, p, t); } } } @@ -147,7 +221,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, create_double_wire_tt(), complex_gate_param.params, black_list, p, t); + layout, create_double_wire_tt(), complex_gate_param.params, p, t); } const auto layout = add_defect_to_skeleton( @@ -166,7 +240,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, create_crossing_wire_tt(), complex_gate_param.params, black_list, p, t); + layout, create_crossing_wire_tt(), complex_gate_param.params, p, t); } const auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); @@ -179,7 +253,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } return EMPTY_GATE; } @@ -194,7 +268,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (mockturtle::has_is_and_v) @@ -207,7 +281,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (mockturtle::has_is_or_v) @@ -220,7 +294,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_nand_v) @@ -233,7 +307,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_nor_v) @@ -246,7 +320,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (mockturtle::has_is_xor_v) @@ -259,7 +333,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_xnor_v) @@ -272,7 +346,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_ge_v) @@ -285,7 +359,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_le_v) @@ -298,7 +372,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_gt_v) @@ -311,7 +385,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } if constexpr (fiction::has_is_lt_v) @@ -324,7 +398,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - layout, std::vector{f}, parameter.params, black_list, p, t); + layout, std::vector{f}, parameter.params, p, t); } } } @@ -334,11 +408,6 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate design_gate( - const Lyt& skeleton, const std::vector& t, const design_sidb_gates_params& params, - surface_black_list< - GateLyt, typename decltype(GateLibrary::get_gate_ports())::mapped_type::value_type::port_type>& black_list, - const port_list& p, const tile& tile) + [[nodiscard]] static fcn_gate design_gate(const Lyt& skeleton, const std::vector& t, + const design_sidb_gates_params& params, + const port_list& p, const tile& tile) { if (t == create_crossing_wire_tt() || t == create_double_wire_tt()) { if (is_gate_design_impossible( skeleton, t, is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) { - black_list[tile][create_id_tt()].push_back(p); - throw std::logic_error("Gate cannot be designed."); + throw gate_design_exception(tile, create_id_tt(), p); + // black_list[tile][create_id_tt()].push_back(p); + // throw std::logic_error("Gate cannot be designed."); } const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); if (found_gate_layouts.empty()) { - black_list[tile][create_id_tt()].push_back(p); - throw std::logic_error("Gate cannot be designed."); + throw gate_design_exception(tile, create_id_tt(), p); + // throw std::logic_error("Gate cannot be designed."); } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; @@ -467,14 +535,16 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(tile, t.front(), p); + // throw std::logic_error("Gate cannot be designed."); } const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); if (found_gate_layouts.empty()) { - black_list[tile][t.front()].push_back(p); - throw std::logic_error("Gate cannot be designed."); + // black_list[tile][t.front()].push_back(p); + throw gate_design_exception(tile, t.front(), p); + // throw std::logic_error("Gate cannot be designed."); } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; From b72638c8f57bee5354af51ab1e6ae34478aa8f9d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 16:06:56 +0100 Subject: [PATCH 070/191] :art: rename ``tile`` to ``error_tile``. --- include/fiction/technology/sidb_on_the_fly_gate_library.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 9f71fedf7..4ef91271f 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -46,7 +46,7 @@ class gate_design_exception : public std::exception explicit gate_design_exception(const tile& ti, const TT& spec, const port_list& portlist) noexcept : std::exception(), - tile{ti}, + error_tile{ti}, truth_table{spec}, p{portlist} {} @@ -58,7 +58,7 @@ class gate_design_exception : public std::exception */ [[nodiscard]] tile which_tile() const noexcept { - return tile; + return error_tile; } /** @@ -87,7 +87,7 @@ class gate_design_exception : public std::exception * * @return The tile associated with the error. */ - const tile tile{}; + const tile error_tile{}; /** * The truth table associated with the error. * From a1f09de846e4599e2060209c5f963c7aeb0559c9 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 16:12:00 +0100 Subject: [PATCH 071/191] :art: fix typo. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 71a2c0429..b9fe32226 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -219,7 +219,7 @@ template return p.run(); } /** - * Applies an on-the-fly gate library (i.e., gate are designed on-the-fly by respecting atomic defects) to a given + * Applies an on-the-fly gate library (i.e., gates are designed on-the-fly by respecting atomic defects) to a given * gate-level layout and, thereby, creates and returns a cell-level layout. * * May pass through, and thereby throw, an `unsupported_gate_type_exception` or an From ff748dd2918551f57048aa5b116f47217abd6bfe Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 13 Nov 2023 16:25:36 +0100 Subject: [PATCH 072/191] :art: small fix. --- .../technology/sidb_on_the_fly_gate_library.hpp | 2 +- include/fiction/technology/sidb_surface_analysis.hpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 4ef91271f..9bc704e1c 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -17,8 +17,8 @@ #include "fiction/utils/layout_utils.hpp" #include +#include #include -#include #include #include diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index e74327e2b..b1cdbd4db 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -50,14 +50,14 @@ using surface_black_list = * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. * @param surface SiDB surface that instantiates the defects. - * @param incorporate_defect_into_gate_design If set to `true`, charged defects are treated like neutral defects, - * `false`otherwise. + * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an optional + * pair of horizontal and vertical spacings. * @return A black list of gate functions associated with tiles. */ template -[[nodiscard]] auto -sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surface, - const std::optional>& distance = std::nullopt) noexcept +[[nodiscard]] auto sidb_surface_analysis( + const GateLyt& gate_lyt, const sidb_surface& surface, + const std::optional>& user_defined_spacing_charged_defects = std::nullopt) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -74,7 +74,7 @@ sidb_surface_analysis(const GateLyt& gate_lyt, const sidb_surface& surf surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(distance); + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(user_defined_spacing_charged_defects); const auto gate_implementations = GateLibrary::get_functional_implementations(); const auto gate_ports = GateLibrary::get_gate_ports(); From 1812232599a75336360a386e7e958e255d6a353c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 14 Nov 2023 10:45:16 +0100 Subject: [PATCH 073/191] :art: add reference. --- include/fiction/technology/sidb_on_the_fly_gate_library.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 9bc704e1c..e99648fec 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -87,19 +87,19 @@ class gate_design_exception : public std::exception * * @return The tile associated with the error. */ - const tile error_tile{}; + const tile &error_tile{}; /** * The truth table associated with the error. * * @return The port list associated with the error. */ - const TT truth_table{}; + const TT &truth_table{}; /** * The port list associated with the error. * * @return The port list associated with the error. */ - const port_list p; + const port_list &p; }; /** From 88639a3d2a2020cee0cbbf0bad752ae37875e553 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Tue, 14 Nov 2023 10:20:59 +0000 Subject: [PATCH 074/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- include/fiction/technology/sidb_on_the_fly_gate_library.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index e99648fec..a2cbb144b 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -87,19 +87,19 @@ class gate_design_exception : public std::exception * * @return The tile associated with the error. */ - const tile &error_tile{}; + const tile& error_tile{}; /** * The truth table associated with the error. * * @return The port list associated with the error. */ - const TT &truth_table{}; + const TT& truth_table{}; /** * The port list associated with the error. * * @return The port list associated with the error. */ - const port_list &p; + const port_list& p; }; /** From cb0f2e63d296b76e1e657e1e1e2c91f7c95a457e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 14 Nov 2023 14:33:13 +0100 Subject: [PATCH 075/191] :white_check_mark: update unit test. --- test/io/print_layout.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/io/print_layout.cpp b/test/io/print_layout.cpp index 27fe6212f..b81ab03fd 100644 --- a/test/io/print_layout.cpp +++ b/test/io/print_layout.cpp @@ -429,8 +429,9 @@ TEST_CASE("Print Bestagon OR-gate with defect", "[print-charge-layout]") sidb_simulation_parameters{3, -0.32}, sidb_charge_state::NEGATIVE}; cl.assign_sidb_defect({18, 3, 0}, sidb_defect{sidb_defect_type::UNKNOWN, 1}); - cl.assign_sidb_defect({40, 3, 0}, sidb_defect{sidb_defect_type::UNKNOWN, -1}); + cl.assign_sidb_defect({44, 2, 0}, sidb_defect{sidb_defect_type::UNKNOWN, -1}); cl.assign_sidb_defect({40, 5, 1}, sidb_defect{sidb_defect_type::UNKNOWN, 0}); + cl.assign_sidb_defect({42, 20, 0}, sidb_defect{sidb_defect_type::UNKNOWN, 1}); cl.assign_charge_state({42, 3, 0}, sidb_charge_state::NEGATIVE); @@ -461,7 +462,10 @@ TEST_CASE("Print Bestagon OR-gate with defect", "[print-charge-layout]") " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · ◯ · ⊞ · · · · · · · · · · · · · · · · · · · · · ⊟ · ● · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊟ \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + "\n" + " · · ◯ · ⊞ · · · · · · · · · · · · · · · · · · · · · · · ● · · \n" " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" " · · · · ● · · · · · · · · · · · · · · · · · · · · · ● · · · · \n" @@ -512,6 +516,9 @@ TEST_CASE("Print Bestagon OR-gate with defect", "[print-charge-layout]") " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ● · · \n" " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊞ · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + "\n" " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" From ac96346e434b0ea4ffc6c88dc628fb2130443d1d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 17 Nov 2023 12:29:37 +0100 Subject: [PATCH 076/191] :art: implement Marcel's suggestions. --- .../physical_design/apply_gate_library.hpp | 20 +++++---- include/fiction/technology/sidb_defects.hpp | 17 +++++--- .../sidb_is_gate_design_impossible.hpp} | 6 +-- .../sidb_on_the_fly_gate_library.hpp | 41 +++++++------------ include/fiction/technology/sidb_surface.hpp | 33 ++++++++++----- .../technology/sidb_surface_analysis.hpp | 11 +++-- .../sidb/is_gate_design_impossible.cpp | 2 +- .../algorithms/simulation/sidb/quickexact.cpp | 40 +++++++++++++----- 8 files changed, 101 insertions(+), 69 deletions(-) rename include/fiction/{algorithms/physical_design/is_gate_design_impossible.hpp => technology/sidb_is_gate_design_impossible.hpp} (95%) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index b9fe32226..d76d5f09e 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -51,13 +51,13 @@ class apply_gate_library_impl * process. * * @tparam GateLibraryblack Type of the gate library used to generate the blacklist. + * @tparam Params Type of the parameter used for the on-the-fly gate library. * @param defect_surface Defect surface with atomic defects. * @param params Parameter for the gate library. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ - template - [[nodiscard]] CellLyt design_gates_on_the_fly(const sidb_surface& defect_surface, - const sidb_on_the_fly_gate_library_params& params) + template + [[nodiscard]] CellLyt design_gates_on_the_fly(const sidb_surface& defect_surface, const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar @@ -75,7 +75,7 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate( + const auto gate = GateLibrary::template set_up_gate( gate_lyt, t, defect_surface, params); assign_gate(c, gate, n); @@ -228,19 +228,21 @@ template * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. - * @tparam GateLibraryblack Type of the Gate Library to generate the blacklist. + * @tparam GateLibraryblack Type of the gate library to generate the blacklist. + * @tparam Params Type of the parameter used for the on-the-fly gate library. * @param lyt The gate-level layout. * @param defect_surface Defect surface with all atomic defects. * @param params Parameter for the gate library. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ -template +template [[nodiscard]] CellLyt apply_on_the_fly_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface, - const sidb_on_the_fly_gate_library_params& params) + const Params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); - static_assert(!has_siqad_coord_v, "CellLyt cannot have SiQAD coordinates"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(has_offset_ucoord_v || has_cube_coord_v, + "CellLyt must be either based on cube or offset coordinates"); static_assert(mockturtle::has_is_constant_v, "GateLyt does not implement the is_constant function"); static_assert(mockturtle::has_foreach_node_v, "GateLyt does not implement the foreach_node function"); @@ -249,7 +251,7 @@ template p{lyt}; - return p.template design_gates_on_the_fly(defect_surface, params); + return p.template design_gates_on_the_fly(defect_surface, params); } } // namespace fiction diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index f1eb58c4d..83541ae8a 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -172,25 +172,32 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; * If the defect type is `NONE`, `{0, 0}` is returned. * * @param defect Defect type to evaluate. - * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an optional - * pair of horizontal and vertical spacings. + * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on SiDBs + * with an optional pair of horizontal and vertical distances. + * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on SiDBs +* with an optional pair of horizontal and vertical distances. * @return A pair of uint16_t values representing the number of horizontal and vertical SiDBs affected by the given * defect type. */ [[nodiscard]] static constexpr std::pair defect_extent( const sidb_defect& defect, - const std::optional>& user_defined_spacing_charged_defects = std::nullopt) noexcept + const std::optional>& charged_defect_spacing_overwrite = std::nullopt, + const std::optional>& neutral_defect_spacing_overwrite = std::nullopt) noexcept { if (is_charged_defect(defect)) { - if (user_defined_spacing_charged_defects.has_value()) + if (charged_defect_spacing_overwrite.has_value()) { - return user_defined_spacing_charged_defects.value(); + return charged_defect_spacing_overwrite.value(); } return {SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; } if (is_neutral_defect(defect)) { + if (neutral_defect_spacing_overwrite.has_value()) + { + return neutral_defect_spacing_overwrite.value(); + } return {SIDB_NEUTRAL_DEFECT_HORIZONTAL_SPACING, SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING}; } diff --git a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp b/include/fiction/technology/sidb_is_gate_design_impossible.hpp similarity index 95% rename from include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp rename to include/fiction/technology/sidb_is_gate_design_impossible.hpp index 2171b7898..50f446146 100644 --- a/include/fiction/algorithms/physical_design/is_gate_design_impossible.hpp +++ b/include/fiction/technology/sidb_is_gate_design_impossible.hpp @@ -2,8 +2,8 @@ // Created by Jan Drewniok on 25.10.23. // -#ifndef FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP -#define FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#ifndef FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#define FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP #include "fiction/algorithms/iter/bdl_input_iterator.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" @@ -84,4 +84,4 @@ bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, c } // namespace fiction -#endif // FICTION_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#endif // FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index a2cbb144b..6008b7298 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -7,7 +7,6 @@ #include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" -#include "fiction/algorithms/physical_design/is_gate_design_impossible.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" @@ -15,6 +14,7 @@ #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" +#include "sidb_is_gate_design_impossible.hpp" #include #include @@ -37,7 +37,7 @@ class gate_design_exception : public std::exception { public: /** - * @brief Constructor for the gate_design_exception class. + * Constructor for the gate_design_exception class. * * @param ti The tile associated with the error. * @param spec The truth table associated with the error. @@ -53,8 +53,6 @@ class gate_design_exception : public std::exception /** * Get the tile associated with the exception. - * - * @return The tile associated with the error. */ [[nodiscard]] tile which_tile() const noexcept { @@ -63,8 +61,6 @@ class gate_design_exception : public std::exception /** * Get the truth table associated with the exception. - * - * @return The truth table associated with the error. */ [[nodiscard]] TT which_truth_table() const noexcept { @@ -73,8 +69,6 @@ class gate_design_exception : public std::exception /** * Get the port list associated with the exception. - * - * @return The port list associated with the error. */ [[nodiscard]] port_list which_port_list() const noexcept { @@ -84,26 +78,20 @@ class gate_design_exception : public std::exception private: /** * The tile associated with the error. - * - * @return The tile associated with the error. */ - const tile& error_tile{}; + const tile error_tile{}; /** * The truth table associated with the error. - * - * @return The port list associated with the error. */ - const TT& truth_table{}; + const TT truth_table{}; /** * The port list associated with the error. - * - * @return The port list associated with the error. */ - const port_list& p; + const port_list p; }; /** - * This struct encapsulates parameters for the dynamic gate library. + * This struct encapsulates parameters for the on-the-fly SiDB gate library. */ struct sidb_on_the_fly_gate_library_params { @@ -121,7 +109,6 @@ struct sidb_on_the_fly_gate_library_params * and half-adder. */ uint64_t canvas_sidb_complex_gates = 3; - /** * This variable specifies the radius around the middle of the hexagon where atomic defects are incorporated into * the gate design. @@ -157,8 +144,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library& t, const sidb_surface& sidb_surface, const sidb_on_the_fly_gate_library_params& parameter = sidb_on_the_fly_gate_library_params{}) { - static_assert(is_gate_level_layout_v, "GateLyt must be a gate level layout."); - static_assert(!has_siqad_coord_v, "CellLyt has SiQAD coordinates."); + static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); + static_assert(has_offset_ucoord_v || has_cube_coord_v, + "CellLyt must be either based on cube or offset coordinates"); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); @@ -600,7 +588,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library + template [[nodiscard]] static LytSkeleton - add_defect_to_skeleton(const sidb_surface& defect_surface, const LytSkeleton& skeleton, + add_defect_to_skeleton(const sidb_surface& defect_surface, const LytSkeleton& skeleton, const siqad::coord_t& center_cell_siqad, const siqad::coord_t& absolute_cell_siqad, const sidb_on_the_fly_gate_library_params& params) { - static_assert(!has_siqad_coord_v, "Lyt has SiQAD coordinates."); - static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates."); + static_assert(has_offset_ucoord_v || has_cube_coord_v, + "CellLyt must be either based on cube or offset coordinates"); + static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates"); auto lyt_copy = LytSkeleton{skeleton.clone()}; defect_surface.foreach_sidb_defect( [&defect_surface, &lyt_copy, &skeleton, ¢er_cell_siqad, &absolute_cell_siqad, ¶ms](const auto& cd) diff --git a/include/fiction/technology/sidb_surface.hpp b/include/fiction/technology/sidb_surface.hpp index d2a0dc1b7..8d3cea1aa 100644 --- a/include/fiction/technology/sidb_surface.hpp +++ b/include/fiction/technology/sidb_surface.hpp @@ -179,20 +179,24 @@ class sidb_surface : public Lyt * If the given coordinate is defect-free, the empty set is returned. * * @param c Coordinate whose defect extent is to be determined. - * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an - * optional pair of horizontal and vertical spacings. + * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on + * SiDBs with an optional pair of horizontal and vertical distances. + * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on + * SiDBs with an optional pair of horizontal and vertical distances. * @return All SiDB positions affected by the defect at coordinate c. */ [[nodiscard]] std::unordered_set affected_sidbs(const typename Lyt::coordinate& c, - const std::optional>& user_defined_spacing_charged_defects = + const std::optional>& charged_defect_spacing_overwrite = std::nullopt, + const std::optional>& neutral_defect_spacing_overwrite = std::nullopt) const noexcept { std::unordered_set influenced_sidbs{}; if (const auto d = get_sidb_defect(c); d.type != sidb_defect_type::NONE) { - const auto [horizontal_extent, vertical_extent] = defect_extent(d, user_defined_spacing_charged_defects); + const auto [horizontal_extent, vertical_extent] = + defect_extent(d, charged_defect_spacing_overwrite, neutral_defect_spacing_overwrite); for (auto y = static_cast(c.y - vertical_extent); y <= static_cast(c.y + vertical_extent); ++y) @@ -216,19 +220,26 @@ class sidb_surface : public Lyt * * If the given surface is defect-free, the empty set is returned. * - * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an - * optional pair of horizontal and vertical spacings. + * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on + * SiDBs with an optional pair of horizontal and vertical distances. + * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on + * SiDBs with an optional pair of horizontal and vertical distances. * @return All SiDB positions affected by any defect on the surface. */ - [[nodiscard]] std::unordered_set - all_affected_sidbs(const std::optional>& user_defined_spacing_charged_defects = - std::nullopt) const noexcept + [[nodiscard]] std::unordered_set all_affected_sidbs( + const std::optional>& charged_defect_spacing_overwrite = std::nullopt, + const std::optional>& neutral_defect_spacing_overwrite = + std::nullopt) const noexcept { std::unordered_set influenced_sidbs{}; foreach_sidb_defect( - [&influenced_sidbs, &user_defined_spacing_charged_defects, this](const auto& it) - { influenced_sidbs.merge(affected_sidbs(it.first, user_defined_spacing_charged_defects)); }); + [&influenced_sidbs, &charged_defect_spacing_overwrite, &neutral_defect_spacing_overwrite, + this](const auto& it) + { + influenced_sidbs.merge( + affected_sidbs(it.first, charged_defect_spacing_overwrite, neutral_defect_spacing_overwrite)); + }); return influenced_sidbs; } diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index b1cdbd4db..f411282b4 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -50,14 +50,17 @@ using surface_black_list = * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. * @param surface SiDB surface that instantiates the defects. - * @param user_defined_spacing_charged_defects Influence of charged atomic defects on SiDBs, represented as an optional - * pair of horizontal and vertical spacings. + * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on SiDBs + * with an optional pair of horizontal and vertical distances. + * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on SiDBs + * with an optional pair of horizontal and vertical distances. * @return A black list of gate functions associated with tiles. */ template [[nodiscard]] auto sidb_surface_analysis( const GateLyt& gate_lyt, const sidb_surface& surface, - const std::optional>& user_defined_spacing_charged_defects = std::nullopt) noexcept + const std::optional>& charged_defect_spacing_overwrite = std::nullopt, + const std::optional>& neutral_defect_spacing_overwrite = std::nullopt) noexcept { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); @@ -74,7 +77,7 @@ template surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(user_defined_spacing_charged_defects); + const auto sidbs_affected_by_defects = surface.all_affected_sidbs(charged_defect_spacing_overwrite, neutral_defect_spacing_overwrite); const auto gate_implementations = GateLibrary::get_functional_implementations(); const auto gate_ports = GateLibrary::get_gate_ports(); diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index 770eb0874..f409a4411 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -4,7 +4,7 @@ #include -#include +#include "fiction/technology/sidb_is_gate_design_impossible.hpp" #include #include #include diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 12a120d6c..d5f372be7 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -1052,18 +1052,38 @@ TEMPLATE_TEST_CASE( SECTION("Check if QuickExact is deterministic") { - std::set ground_state{}; - std::set charge_index{}; - for (auto i = 0; i < 100000; i++) + SECTION("Epsilon_r = 8") { - const auto simulation_results = quickexact(lyt, params); - auto& charge_lyt_first = simulation_results.charge_distributions.front(); - ground_state.insert(charge_lyt_first.get_system_energy()); - charge_lyt_first.charge_distribution_to_index_general(); - charge_index.insert(charge_lyt_first.get_charge_index_and_base().first); + params.physical_parameters.epsilon_r = 8; + std::set ground_state{}; + std::set charge_index{}; + for (auto i = 0; i < 10000; i++) + { + const auto simulation_results = quickexact(lyt, params); + auto& charge_lyt_first = simulation_results.charge_distributions.front(); + ground_state.insert(charge_lyt_first.get_system_energy()); + charge_lyt_first.charge_distribution_to_index_general(); + charge_index.insert(charge_lyt_first.get_charge_index_and_base().first); + } + CHECK(ground_state.size() == 1); + CHECK(charge_index.size() == 1); + } + SECTION("Epsilon_r = 2") + { + params.physical_parameters.epsilon_r = 2; + std::set ground_state{}; + std::set charge_index{}; + for (auto i = 0; i < 10000; i++) + { + const auto simulation_results = quickexact(lyt, params); + auto& charge_lyt_first = simulation_results.charge_distributions.front(); + ground_state.insert(charge_lyt_first.get_system_energy()); + charge_lyt_first.charge_distribution_to_index_general(); + charge_index.insert(charge_lyt_first.get_charge_index_and_base().first); + } + CHECK(ground_state.size() == 1); + CHECK(charge_index.size() == 1); } - CHECK(ground_state.size() == 1); - CHECK(charge_index.size() == 1); } SECTION("Standard Physical Parameters") From 5a0a22fd27f0f03d8784441360b90c652054d49f Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Fri, 17 Nov 2023 11:30:54 +0000 Subject: [PATCH 077/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- include/fiction/technology/sidb_defects.hpp | 2 +- include/fiction/technology/sidb_surface_analysis.hpp | 7 ++++--- .../simulation/sidb/is_gate_design_impossible.cpp | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/fiction/technology/sidb_defects.hpp b/include/fiction/technology/sidb_defects.hpp index 83541ae8a..242eeb2e9 100644 --- a/include/fiction/technology/sidb_defects.hpp +++ b/include/fiction/technology/sidb_defects.hpp @@ -175,7 +175,7 @@ inline constexpr const uint16_t SIDB_NEUTRAL_DEFECT_VERTICAL_SPACING = 0u; * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on SiDBs * with an optional pair of horizontal and vertical distances. * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on SiDBs -* with an optional pair of horizontal and vertical distances. + * with an optional pair of horizontal and vertical distances. * @return A pair of uint16_t values representing the number of horizontal and vertical SiDBs affected by the given * defect type. */ diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index f411282b4..629a802fc 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -77,9 +77,10 @@ template surface_black_list black_list{}; - const auto sidbs_affected_by_defects = surface.all_affected_sidbs(charged_defect_spacing_overwrite, neutral_defect_spacing_overwrite); - const auto gate_implementations = GateLibrary::get_functional_implementations(); - const auto gate_ports = GateLibrary::get_gate_ports(); + const auto sidbs_affected_by_defects = + surface.all_affected_sidbs(charged_defect_spacing_overwrite, neutral_defect_spacing_overwrite); + const auto gate_implementations = GateLibrary::get_functional_implementations(); + const auto gate_ports = GateLibrary::get_gate_ports(); // a lambda that analyzes defect impact on a gate at a given layout tile // it had to be extracted from the foreach_tile lambda because its nesting caused an C1001: internal compiler error diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index f409a4411..b76396b20 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -5,6 +5,7 @@ #include #include "fiction/technology/sidb_is_gate_design_impossible.hpp" + #include #include #include From a4e1ee94b3775ccea0b3038d2425bde992ce88fc Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 17 Nov 2023 16:44:15 +0100 Subject: [PATCH 078/191] :art: small fix. --- .../fiction/technology/sidb_on_the_fly_gate_library.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 6008b7298..fbb6bccbf 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -507,14 +507,11 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(tile, create_id_tt(), p); - // black_list[tile][create_id_tt()].push_back(p); - // throw std::logic_error("Gate cannot be designed."); } const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, create_id_tt(), p); - // throw std::logic_error("Gate cannot be designed."); } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; @@ -523,16 +520,12 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(tile, t.front(), p); - // throw std::logic_error("Gate cannot be designed."); } const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); if (found_gate_layouts.empty()) { - // black_list[tile][t.front()].push_back(p); throw gate_design_exception(tile, t.front(), p); - // throw std::logic_error("Gate cannot be designed."); } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; From ad3e93e75fa680795cb2379867b109f7e6e5acb2 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 20 Nov 2023 10:32:20 +0100 Subject: [PATCH 079/191] :art: add parameter as typename. --- .../sidb_on_the_fly_gate_library.hpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index fbb6bccbf..587b9dd44 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -133,16 +133,16 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - static fcn_gate - set_up_gate(const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, - const sidb_on_the_fly_gate_library_params& parameter = sidb_on_the_fly_gate_library_params{}) + template + static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, + const Params& parameter = Params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); static_assert(has_offset_ucoord_v || has_cube_coord_v, @@ -405,6 +405,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library + template [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, const sidb_surface& defect_lyt, - const design_sidb_gates_params& parameter, - const std::vector& truth_table) + const Params& parameter, const std::vector& truth_table) { auto defect_copy = defect_lyt.clone(); const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(std::pair(0, 0)); @@ -484,9 +484,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library + template [[nodiscard]] static fcn_gate design_gate(const Lyt& skeleton, const std::vector& t, const design_sidb_gates_params& params, const port_list& p, const tile& tile) From 10eb70ae40f3c65267b57a8cc45c9096e3235cb5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 21 Nov 2023 22:11:13 +0100 Subject: [PATCH 080/191] :art: allow fiction coordinates for simulation. --- .../algorithms/iter/bdl_input_iterator.hpp | 1 - .../algorithms/path_finding/distance.hpp | 2 +- .../physical_design/design_sidb_gates.hpp | 21 ++- .../assess_physical_population_stability.hpp | 2 +- .../sidb/calculate_energy_and_state_type.hpp | 1 - .../simulation/sidb/detect_bdl_pairs.hpp | 2 - .../simulation/sidb/is_ground_state.hpp | 1 - .../simulation/sidb/is_operational.hpp | 1 - ...defect_influence_position_and_distance.hpp | 115 +++++------- .../simulation/sidb/operational_domain.hpp | 4 - .../algorithms/simulation/sidb/quickexact.hpp | 8 +- include/fiction/layouts/bounding_box.hpp | 2 +- include/fiction/layouts/coordinates.hpp | 10 +- .../charge_distribution_surface.hpp | 4 +- .../fiction/technology/sidb_nm_position.hpp | 22 ++- include/fiction/utils/layout_utils.hpp | 34 ++-- .../physical_design/design_sidb_gates.cpp | 84 ++++++--- .../assess_physical_population_stability.cpp | 164 +++++++++++++++- .../sidb/can_positive_charges_occur.cpp | 72 ++++++- .../exhaustive_ground_state_simulation.cpp | 116 +++++++++++- ...defect_influence_position_and_distance.cpp | 38 +++- .../simulation/sidb/operational_domain.cpp | 121 ++++++++++++ .../algorithms/simulation/sidb/quickexact.cpp | 177 +++++++++++++++++- test/algorithms/simulation/sidb/quicksim.cpp | 102 ++++++++++ .../sidb/random_sidb_layout_generator.cpp | 41 ++++ .../charge_distribution_surface.cpp | 44 +---- test/technology/sidb_nm_position.cpp | 66 ++++++- test/utils/layout_utils.cpp | 58 +++++- 28 files changed, 1107 insertions(+), 206 deletions(-) diff --git a/include/fiction/algorithms/iter/bdl_input_iterator.hpp b/include/fiction/algorithms/iter/bdl_input_iterator.hpp index cd5a40e60..68d25d4e8 100644 --- a/include/fiction/algorithms/iter/bdl_input_iterator.hpp +++ b/include/fiction/algorithms/iter/bdl_input_iterator.hpp @@ -46,7 +46,6 @@ class bdl_input_iterator { 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"); set_all_inputs(); } diff --git a/include/fiction/algorithms/path_finding/distance.hpp b/include/fiction/algorithms/path_finding/distance.hpp index 5b2351a7a..943d42fa9 100644 --- a/include/fiction/algorithms/path_finding/distance.hpp +++ b/include/fiction/algorithms/path_finding/distance.hpp @@ -107,7 +107,7 @@ sidb_nanometer_distance([[maybe_unused]] const Lyt& lyt, const coordinate& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not based on SiDB technology"); - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); const auto pos_c1 = sidb_nm_position(sp, source); const auto pos_c2 = sidb_nm_position(sp, target); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 19e9329f9..4ac214a07 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -39,6 +39,7 @@ namespace fiction * This struct contains parameters and settings to design SiDB gates. * */ +template struct design_sidb_gates_params { /** @@ -66,7 +67,7 @@ struct design_sidb_gates_params /** * Canvas spanned by the northwest and southeast cell. */ - std::pair canvas{}; + std::pair canvas{}; /** * Number of SiDBs placed in the canvas to create a working gate. */ @@ -92,7 +93,7 @@ class design_sidb_gates_impl * @param tt Expected Boolean function of the layout given as a multi-output truth table. * @param ps Parameters and settings for the gate designer. */ - design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, const design_sidb_gates_params& ps) : + design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, const design_sidb_gates_params& ps) : skeleton_layout{skeleton}, truth_table{tt}, params{ps}, @@ -220,11 +221,11 @@ class design_sidb_gates_impl /** * Parameters for the *SiDB Gate Designer*. */ - const design_sidb_gates_params& params; + const design_sidb_gates_params& params; /** * All cells within the canvas. */ - const std::vector all_sidbs_in_cavas; + const std::vector all_sidbs_in_cavas; /** * Calculates all possible combinations of distributing the given number of SiDBs within a canvas * based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in @@ -279,9 +280,8 @@ class design_sidb_gates_impl { for (std::size_t j = i + 1; j < cell_indices.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, - all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5) + if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], + all_sidbs_in_cavas[cell_indices[j]]) < 0.5) { return true; } @@ -344,12 +344,13 @@ class design_sidb_gates_impl */ template [[nodiscard]] std::vector design_sidb_gates(const Lyt& skeleton, const std::vector& spec, - const design_sidb_gates_params& params = {}) noexcept + const design_sidb_gates_params& params = {}) 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(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); + static_assert(!has_offset_ucoord_v, "Lyt cannot be based on offset coordinates"); assert(skeleton.num_pis() > 0 && "skeleton needs input cells"); assert(skeleton.num_pos() > 0 && "skeleton needs output cells"); @@ -361,7 +362,7 @@ template detail::design_sidb_gates_impl p{skeleton, spec, params}; - if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) + if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) { return p.run_exhaustive_design(); } diff --git a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp index 7cf19c96c..bce65fa35 100644 --- a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp +++ b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp @@ -367,7 +367,7 @@ assess_physical_population_stability(const Lyt& lyt, const assess_physical_popul { 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"); + static_assert(!is_charge_distribution_surface_v, "Lyt is a charge distribution surface"); detail::assess_physical_population_stability_impl p{lyt, params}; return p.run(); diff --git a/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp b/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp index da2790e24..63f5e5ac2 100644 --- a/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp +++ b/include/fiction/algorithms/simulation/sidb/calculate_energy_and_state_type.hpp @@ -50,7 +50,6 @@ calculate_energy_and_state_type(const sidb_energy_distribution& { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); assert(!output_bdl_pairs.empty() && "No output cell provided."); diff --git a/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp b/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp index 5169a91ce..f779fe7d3 100644 --- a/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp +++ b/include/fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp @@ -56,7 +56,6 @@ struct bdl_pair { 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"); } }; @@ -96,7 +95,6 @@ std::vector> detect_bdl_pairs(const Lyt& lyt, const typename techn { 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"); // sanity check for parameter settings assert(params.minimum_distance <= params.maximum_distance); diff --git a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp index ddbcd0424..085ef971e 100644 --- a/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_ground_state.hpp @@ -32,7 +32,6 @@ template { 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"); if (exhaustive_results.charge_distributions.empty()) { diff --git a/include/fiction/algorithms/simulation/sidb/is_operational.hpp b/include/fiction/algorithms/simulation/sidb/is_operational.hpp index 4ab337cae..aaa7a9f5f 100644 --- a/include/fiction/algorithms/simulation/sidb/is_operational.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_operational.hpp @@ -272,7 +272,6 @@ is_operational(const Lyt& lyt, const std::vector& spec, const is_operational { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); assert(lyt.num_pis() > 0 && "skeleton needs input cells"); 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 c276479d7..e6f5a5650 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 @@ -98,49 +98,53 @@ class maximum_defect_influence_position_and_distance_impl // simulate the impact of the defect at a given position on the ground state of the SiDB layout const auto process_defect = [&](const auto& defect) noexcept { - sidb_surface lyt_defect{}; + if (layout.get_cell_type(defect) == Lyt::technology::cell_type::EMPTY) + { + sidb_surface lyt_defect{}; - layout.foreach_cell([this, &lyt_defect](const auto& cell) - { lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); }); + layout.foreach_cell([this, &lyt_defect](const auto& cell) + { lyt_defect.assign_cell_type(cell, layout.get_cell_type(cell)); }); - // assign defect to layout - lyt_defect.assign_sidb_defect(defect, params.defect); - // conduct simulation with defect - auto simulation_result_defect = quickexact(lyt_defect, params_defect); + // assign defect to layout + lyt_defect.assign_sidb_defect(defect, params.defect); + // 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); + 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) - { - if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) - - round_to_n_decimal_places(min_energy_defect, 6)) < std::numeric_limits::epsilon()) + // get the charge index of the ground state + for (const auto& lyt_simulation_with_defect : simulation_result_defect.charge_distributions) { - lyt_simulation_with_defect.charge_distribution_to_index_general(); - charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first; - } - } - - // defect changes the ground state, i.e., the charge index is changed compared to the charge - // distribution without placed defect. - if (charge_index_defect_layout != charge_index_layout) - { - auto distance = std::numeric_limits::max(); - layout.foreach_cell( - [this, &defect, &distance](const auto& cell) + if (std::fabs(round_to_n_decimal_places(lyt_simulation_with_defect.get_system_energy(), 6) - + round_to_n_decimal_places(min_energy_defect, 6)) < + std::numeric_limits::epsilon()) { - if (sidb_nanometer_distance(layout, cell, defect) < distance) - { - distance = sidb_nanometer_distance(layout, cell, defect); - } - }); + lyt_simulation_with_defect.charge_distribution_to_index_general(); + charge_index_defect_layout = lyt_simulation_with_defect.get_charge_index_and_base().first; + } + } - // the distance is larger than the current maximum one. - if (distance > avoidance_distance) + // defect changes the ground state, i.e., the charge index is changed compared to the charge + // distribution without placed defect. + if (charge_index_defect_layout != charge_index_layout) { - max_defect_position = defect; - avoidance_distance = distance; + auto distance = std::numeric_limits::max(); + layout.foreach_cell( + [this, &defect, &distance](const auto& cell) + { + if (sidb_nanometer_distance(layout, cell, defect) < distance) + { + distance = sidb_nanometer_distance(layout, cell, defect); + } + }); + + // the distance is larger than the current maximum one. + if (distance > avoidance_distance) + { + max_defect_position = defect; + avoidance_distance = distance; + } } } }; @@ -187,43 +191,7 @@ class maximum_defect_influence_position_and_distance_impl se.x = se.x + params.additional_scanning_area.first; se.y = se.y + params.additional_scanning_area.second; - // start to place the defect at the north-west cell - auto defect_cell = nw; - - // maximum number of placable defects in the given bounding box - const uint64_t max_defect_positions = - static_cast(std::abs(se.x - nw.x) + 1) * static_cast(std::abs(se.y - nw.y) + 1) * 2; - defect_cells.reserve(max_defect_positions); - - // collect all cells in the bounding box area (spanned by the nw and se) going from top to down from left to - // right. - while (defect_cell <= se) - { - // Defect can only be placed at free locations. - if (layout.get_cell_type(defect_cell) == sidb_technology::cell_type::EMPTY) - { - defect_cells.push_back(defect_cell); - } - if (defect_cell.x < se.x) - { - defect_cell.x += 1; - } - else if ((defect_cell.x == se.x) && defect_cell.z == 0) - { - defect_cell.z += 1; - defect_cell.x = nw.x; - } - else if ((defect_cell.x == se.x) && defect_cell.z == 1) - { - defect_cell.x = nw.x; - defect_cell.y += 1; - defect_cell.z = 0; - } - else - { - break; - } - } + defect_cells = all_sidbs_in_spanned_area(nw, se); } }; @@ -249,7 +217,8 @@ maximum_defect_influence_position_and_distance(const Lyt& { 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"); + static_assert(!has_offset_ucoord_v, "Lyt should not be based on offset coordinates"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); detail::maximum_defect_influence_position_and_distance_impl p{lyt, sim_params}; diff --git a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp index f8a56d428..ee6726dcd 100644 --- a/include/fiction/algorithms/simulation/sidb/operational_domain.hpp +++ b/include/fiction/algorithms/simulation/sidb/operational_domain.hpp @@ -973,7 +973,6 @@ operational_domain operational_domain_grid_search(const Lyt& lyt, const std::vec { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1017,7 +1016,6 @@ operational_domain operational_domain_random_sampling(const Lyt& lyt, const std: { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1066,7 +1064,6 @@ operational_domain operational_domain_flood_fill(const Lyt& lyt, const std::vect { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; @@ -1118,7 +1115,6 @@ operational_domain operational_domain_contour_tracing(const Lyt& lyt, const std: { 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"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); operational_domain_stats st{}; diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 15fedafd8..55e37b149 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -125,12 +125,12 @@ class quickexact_impl { if constexpr (has_get_sidb_defect_v) { - charge_distribution_surface charge_layout{static_cast(layout)}; + charge_distribution_surface charge_layout{layout}; conduct_simulation(charge_layout, base_number); } else { - charge_distribution_surface charge_layout{static_cast(layout)}; + charge_distribution_surface charge_layout{layout}; conduct_simulation(charge_layout, base_number); } } @@ -261,7 +261,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); if (base_number == required_simulation_base_number::THREE) @@ -327,7 +326,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); charge_layout.assign_base_number(2); @@ -374,7 +372,6 @@ class quickexact_impl { static_assert(is_cell_level_layout_v, "ChargeLyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "ChargeLyt is not an SiDB layout"); - static_assert(has_siqad_coord_v, "ChargeLyt is not based on SiQAD coordinates"); static_assert(is_charge_distribution_surface_v, "ChargeLyt is not a charge distribution surface"); charge_layout.assign_all_charge_states(sidb_charge_state::NEGATIVE); @@ -583,7 +580,6 @@ template { 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"); detail::quickexact_impl p{lyt, params}; diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index a2c57a368..34a6fed4c 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -67,7 +67,7 @@ class bounding_box_2d int32_t min_y = std::numeric_limits::max(); int32_t max_y = std::numeric_limits::min(); - uint8_t min_z = 0; + uint8_t min_z = 1; uint8_t max_z = 0; layout.foreach_cell( diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 0b6072015..270e5569c 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -780,15 +780,19 @@ struct coord_t * @param coord SiQAD coordinate to convert. * @return Coordinate of type `CoordinateType`. */ -template -constexpr CoordinateType to_fiction_coord(const coord_t& coord) noexcept +template +constexpr CoordinateTypeOutput to_fiction_coord(const CoordinateTypeInput& coord) noexcept { + if constexpr (std::is_same_v) + { + return coord; + } if (!coord.is_dead()) { return {coord.x, coord.y * 2 + coord.z}; } - return CoordinateType{}; + return CoordinateTypeOutput{}; } /** * Converts any coordinate type to SiQAD coordinates. diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index ed27f324b..bdb9270c2 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -242,7 +242,7 @@ class charge_distribution_surface : public Lyt Lyt(), strg{std::make_shared(params)} { - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); 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"); @@ -264,7 +264,7 @@ class charge_distribution_surface : public Lyt Lyt(lyt), strg{std::make_shared(params)} { - static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); + //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); 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"); diff --git a/include/fiction/technology/sidb_nm_position.hpp b/include/fiction/technology/sidb_nm_position.hpp index 076197358..c8259c486 100644 --- a/include/fiction/technology/sidb_nm_position.hpp +++ b/include/fiction/technology/sidb_nm_position.hpp @@ -8,6 +8,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/cell_level_layout.hpp" #include "fiction/traits.hpp" +#include "fiction/layouts/coordinates.hpp" #include @@ -28,12 +29,21 @@ template { 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"); - - const auto x = (c.x * sp.lat_a) * 0.1; - const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * .1; - - return std::make_pair(x, y); + static_assert(has_siqad_coord_v || has_cube_coord_v || has_offset_ucoord_v, "Coordinate type is not supported"); + + if constexpr (has_siqad_coord_v) + { + const auto x = (c.x * sp.lat_a) * 0.1; + const auto y = (c.y * sp.lat_b + c.z * sp.lat_c) * .1; + return std::make_pair(x, y); + } + else + { + const auto cell_in_siqad = siqad::to_siqad_coord(c); + const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; + const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; + return std::make_pair(x, y); + } } } // namespace fiction diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 62071e5dc..b6a5474e8 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -367,10 +367,6 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept template CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coordinate2) noexcept { - static_assert(std::is_same_v || std::is_same_v || - std::is_same_v, - "CoordinateType is unknown"); - static std::mt19937_64 generator(std::random_device{}()); if (coordinate1 > coordinate2) @@ -408,38 +404,40 @@ CoordinateType random_coordinate(CoordinateType coordinate1, CoordinateType coor * @param cell_se The southeast SiQAD cell defining the ending point of the area. * @return A vector containing all cells within the specified area. */ -[[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const siqad::coord_t& cell_nw, - const siqad::coord_t& cell_se) noexcept +template +[[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const CoordinateType& cell_nw, + const CoordinateType& cell_se) noexcept { - const auto c1_cube = siqad::to_fiction_coord(cell_nw); - const auto c2_cube = siqad::to_fiction_coord(cell_se); + const auto c1_cube = siqad::to_fiction_coord(cell_nw); + const auto c2_cube = siqad::to_fiction_coord(cell_se); const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); - std::vector all_cells{}; + std::vector all_cells{}; all_cells.reserve(total_cell_count); - auto current_cell = cell_nw; + auto current_cell = c1_cube; // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to down // from left to right. - while (current_cell <= cell_se) + while (current_cell <= c2_cube) { - all_cells.push_back(current_cell); - if (current_cell.x < cell_se.x) + if constexpr (std::is_same_v) { - current_cell.x += 1; + all_cells.push_back(siqad::to_siqad_coord(current_cell)); + } + else + { + all_cells.push_back(siqad::to_fiction_coord(current_cell)); } - else if ((current_cell.x == cell_se.x) && current_cell.z == 0) + if (current_cell.x < cell_se.x) { - current_cell.z += 1; - current_cell.x = cell_nw.x; + current_cell.x += 1; } else { current_cell.x = cell_nw.x; current_cell.y += 1; - current_cell.z = 0; } } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 0cc960341..e8195ddb0 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -16,7 +16,9 @@ using namespace fiction; TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; + + using layout = sidb_cell_clk_lyt_siqad; + using layout_cube = cell_level_layout>>; layout lyt{}; @@ -42,17 +44,35 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; + const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); REQUIRE(found_gate_layouts.size() == 1); CHECK(found_gate_layouts[0].num_cells() == 14); CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + + // using cube coordinates + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_cube = + design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); + + REQUIRE(found_gate_layouts_cube.size() == 1); + CHECK(found_gate_layouts_cube[0].num_cells() == 14); + CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == + layout::technology::NORMAL); } TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") @@ -78,11 +98,11 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - design_sidb_gates_params params{sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{4, 4, 0}, {14, 5, 1}}, - 1, - sidb_simulation_engine::EXGS}; + design_sidb_gates_params params{sidb_simulation_parameters{2, -0.28}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{4, 4, 0}, {14, 5, 1}}, + 1, + sidb_simulation_engine::EXGS}; SECTION("Exhaustive Generation") { @@ -92,7 +112,7 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ SECTION("Random Generation") { - params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; + params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); CHECK(!found_gate_layouts.empty()); } @@ -134,14 +154,15 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - SECTION("generate original FO2") { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); // generate gate by placing one SiDB @@ -155,6 +176,13 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("replace the output perturbers by equivalent negatively charged defects") { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); @@ -207,15 +235,14 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - // generate gate by placing one SiDB - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - SECTION("Random Generation") { + const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); REQUIRE(!found_gate_layouts.empty()); CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); @@ -225,6 +252,13 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") { sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + defect_layout.assign_sidb_defect( {15, 10, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); diff --git a/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp b/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp index 1a5bc7694..3b25b8161 100644 --- a/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp +++ b/test/algorithms/simulation/sidb/assess_physical_population_stability.cpp @@ -199,7 +199,7 @@ TEST_CASE("Bestagon AND gate", "[assess-physical-population-stability]") } } -TEST_CASE("Bestagon CROSSING gate input 11", "[assess-physical-population-stability]") +TEST_CASE("Bestagon CROSSING gate input 11, using siqad coordinates", "[assess-physical-population-stability]") { layout lyt{}; const auto params = assess_physical_population_stability_params{}; @@ -251,3 +251,165 @@ TEST_CASE("Bestagon CROSSING gate input 11", "[assess-physical-population-stabil REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, Catch::Matchers::WithinAbs(6.88, 1e-5)); } + +TEST_CASE("Bestagon CROSSING gate input 11, using cube coordinates", "[assess-physical-population-stability]") +{ + cell_level_layout>> lyt{}; + + const auto params = assess_physical_population_stability_params{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 1, 0}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 12, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 11, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 4, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 4, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 16, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 16, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 8, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 17, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 18, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 18, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 17, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 19, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 19, 0}), + sidb_technology::cell_type::NORMAL); + + CHECK(lyt.num_cells() == 27); + + const auto result = assess_physical_population_stability(lyt, params); + REQUIRE(result.size() == 20); + const auto& population_stability_detail = result[0]; + CHECK(population_stability_detail.critical_cell == cube::coord_t{14, 18, 0}); + CHECK(population_stability_detail.transition_from_to == transition_type::NEUTRAL_TO_NEGATIVE); + CHECK(population_stability_detail.minimum_potential_difference_to_transition < 0.01); + REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, + Catch::Matchers::WithinAbs(6.88, 1e-5)); +} + +TEST_CASE("Bestagon CROSSING gate input 11, using offset coordinates", "[assess-physical-population-stability]") +{ + cell_level_layout>> lyt{}; + + const auto params = assess_physical_population_stability_params{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 1, 0}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 12, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 11, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 4, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 4, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 15, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 16, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 9, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{26, 16, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{24, 5, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 3, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 13, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 2, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 8, 0}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{30, 17, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 18, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{32, 18, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 17, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 19, 0}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{36, 19, 0}), + sidb_technology::cell_type::NORMAL); + + CHECK(lyt.num_cells() == 27); + + const auto result = assess_physical_population_stability(lyt, params); + REQUIRE(result.size() == 20); + const auto& population_stability_detail = result[0]; + CHECK(population_stability_detail.critical_cell == offset::ucoord_t{14, 18, 0}); + CHECK(population_stability_detail.transition_from_to == transition_type::NEUTRAL_TO_NEGATIVE); + CHECK(population_stability_detail.minimum_potential_difference_to_transition < 0.01); + REQUIRE_THAT(population_stability_detail.distance_corresponding_to_potential, + Catch::Matchers::WithinAbs(6.88, 1e-5)); +} diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index 0a7fa295b..c8326d4cc 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -37,7 +37,7 @@ TEMPLATE_TEST_CASE("One BDL pair with one perturber", "[can-positive-charges-occ } } -TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01", "[can-positive-charges-occur]", +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using siqad coordinates", "[can-positive-charges-occur]", (cell_level_layout>>)) { TestType lyt{{20, 10}}; @@ -71,3 +71,73 @@ TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01", "[can-positive-charges- CHECK(can_positive_charges_occur(lyt, params)); } } + +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using cube coordinates", "[can-positive-charges-occur]", + (cell_level_layout>>)) +{ + TestType lyt{{20, 10}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + SECTION("Default values") + { + const sidb_simulation_parameters params{2, -0.32}; + CHECK(!can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 1") + { + const sidb_simulation_parameters params{2, -0.32, 1, 1}; + CHECK(can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 10") + { + const sidb_simulation_parameters params{2, -0.32, 1, 10}; + CHECK(can_positive_charges_occur(lyt, params)); + } +} + +TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using offset coordinates", "[can-positive-charges-occur]", + (cell_level_layout>>)) +{ + TestType lyt{{20, 10}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + SECTION("Default values") + { + const sidb_simulation_parameters params{2, -0.32}; + CHECK(!can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 1") + { + const sidb_simulation_parameters params{2, -0.32, 1, 1}; + CHECK(can_positive_charges_occur(lyt, params)); + } + + SECTION("epsilon = 1, lambda = 10") + { + const sidb_simulation_parameters params{2, -0.32, 1, 10}; + CHECK(can_positive_charges_occur(lyt, params)); + } +} diff --git a/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp b/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp index 820bc8284..1e39d3f10 100644 --- a/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp +++ b/test/algorithms/simulation/sidb/exhaustive_ground_state_simulation.cpp @@ -65,7 +65,8 @@ TEMPLATE_TEST_CASE( } TEMPLATE_TEST_CASE( - "ExGS simulation of a two-pair BDL wire with one perturber", "[exhaustive-ground-state-simulation]", + "ExGS simulation of a two-pair BDL wire with one perturber, using siqad coordinates", + "[exhaustive-ground-state-simulation]", (cell_level_layout>>), (charge_distribution_surface>>>)) { @@ -109,6 +110,119 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); } +TEMPLATE_TEST_CASE("ExGS simulation of a two-pair BDL wire with one perturber, using offset coordinates", + "[exhaustive-ground-state-simulation]", + (cell_level_layout>>), + (charge_distribution_surface< + cell_level_layout>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0}), + TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); + + const auto size_before = simulation_results.charge_distributions.size(); + + const auto simulation_results_after = exhaustive_ground_state_simulation(lyt, params); + auto size_after = simulation_results_after.charge_distributions.size(); + + CHECK(size_before == 1); + CHECK(size_after == 1); + + REQUIRE(!simulation_results_after.charge_distributions.empty()); + + const auto& charge_lyt_first = simulation_results_after.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); +} + +TEMPLATE_TEST_CASE( + "ExGS simulation of a two-pair BDL wire with one perturber, using cube coordinates", + "[exhaustive-ground-state-simulation]", + (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0}), TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + const auto simulation_results = exhaustive_ground_state_simulation(lyt, params); + + const auto size_before = simulation_results.charge_distributions.size(); + + const auto simulation_results_after = exhaustive_ground_state_simulation(lyt, params); + auto size_after = simulation_results_after.charge_distributions.size(); + + CHECK(size_before == 1); + CHECK(size_after == 1); + + REQUIRE(!simulation_results_after.charge_distributions.empty()); + + const auto& charge_lyt_first = simulation_results_after.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{0, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{5, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{7, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{11, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{13, 0, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{17, 0, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{19, 0, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.2460493219, physical_constants::POP_STABILITY_ERR)); +} + TEMPLATE_TEST_CASE( "ExGS simulation of a Y-shape SiDB arrangement", "[exhaustive-ground-state-simulation]", (cell_level_layout>>), diff --git a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp index 36eef1021..897956f4f 100644 --- a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp +++ b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp @@ -29,7 +29,7 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio { const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, sidb_simulation_parameters{}.lambda_tf}; - const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}, {50, 6}}; + const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}, {2, 2}}; sidb_cell_clk_lyt_siqad lyt{}; lyt.assign_cell_type({0, 0, 0}, sidb_cell_clk_lyt_siqad::cell_type::NORMAL); @@ -103,6 +103,8 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(defect_pos.y == 4); CHECK(defect_pos.z == 1); + CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); + // number of threads given by the hardware const sidb_defect high_screening{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, 1}; const maximum_defect_influence_distance_params sim_params_high_screening{high_screening, @@ -113,4 +115,38 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(distance_high_screeing < distance); } + + SECTION("QuickExact simulation of a Y-shape SiDB OR gate with input 01, using cube coordinate") + { + const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, + sidb_simulation_parameters{}.lambda_tf}; + const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}}; + cell_level_layout>> lyt{{30,30}}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 0, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 1, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 1, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 2, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 4, 0}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 5, 1}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 7, 1}), + sidb_cell_clk_lyt_siqad::cell_type::NORMAL); + + const auto [defect_pos, distance] = maximum_defect_influence_position_and_distance(lyt, sim_params); + CHECK(defect_pos.x == 12); + CHECK(defect_pos.y == 9); + CHECK(defect_pos.z == 0); + + CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); + + } } diff --git a/test/algorithms/simulation/sidb/operational_domain.cpp b/test/algorithms/simulation/sidb/operational_domain.cpp index 3d744ab0b..8e5e33e1b 100644 --- a/test/algorithms/simulation/sidb/operational_domain.cpp +++ b/test/algorithms/simulation/sidb/operational_domain.cpp @@ -513,3 +513,124 @@ TEST_CASE("SiQAD's AND gate operational domain computation", "[operational-domai CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); } } + +TEST_CASE("SiQAD's AND gate operational domain computation, using cube coordinates", "[operational-domain]") +{ + using layout = cell_level_layout>>; + + layout lyt{{20, 10}, "AND gate"}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{0, 0, 1}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{2, 1, 1}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{20, 0, 1}), + sidb_technology::cell_type::INPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{18, 1, 1}), + sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{4, 2, 1}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 3, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 3, 1}), + sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 2, 1}), + sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 0}), + sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 7, 0}), + sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 9, 1}), + sidb_technology::cell_type::NORMAL); + + sidb_simulation_parameters sim_params{}; + sim_params.base = 2; + sim_params.mu_minus = -0.28; + + operational_domain_params op_domain_params{}; + op_domain_params.sim_params = sim_params; + op_domain_params.x_dimension = operational_domain::sweep_parameter::EPSILON_R; + op_domain_params.x_min = 5.1; + op_domain_params.x_max = 6.1; + op_domain_params.x_step = 0.1; + op_domain_params.y_dimension = operational_domain::sweep_parameter::LAMBDA_TF; + op_domain_params.y_min = 4.5; + op_domain_params.y_max = 5.5; + op_domain_params.y_step = 0.1; + + operational_domain_stats op_domain_stats{}; + + SECTION("grid_search") + { + const auto op_domain = + operational_domain_grid_search(lyt, std::vector{create_and_tt()}, op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (10 steps in each dimension) + CHECK(op_domain.operational_values.size() == 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations == 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations == 100); + CHECK(op_domain_stats.num_operational_parameter_combinations == 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("random_sampling") + { + const auto op_domain = operational_domain_random_sampling(lyt, std::vector{create_and_tt()}, 100, + op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (max 10 steps in each dimension) + CHECK(op_domain.operational_values.size() <= 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations <= 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations <= 100); + CHECK(op_domain_stats.num_operational_parameter_combinations <= 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("flood_fill") + { + const auto op_domain = + operational_domain_flood_fill(lyt, std::vector{create_and_tt()}, 1, op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (10 steps in each dimension) + CHECK(op_domain.operational_values.size() == 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations == 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations == 100); + CHECK(op_domain_stats.num_operational_parameter_combinations == 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } + SECTION("contour_tracing") + { + const auto op_domain = operational_domain_contour_tracing(lyt, std::vector{create_and_tt()}, 1, + op_domain_params, &op_domain_stats); + + // check if the operational domain has the correct size (max 10 steps in each dimension) + CHECK(op_domain.operational_values.size() <= 100); + + // for the selected range, all samples should be within the parameters and operational + check_op_domain_params_and_operational_status(op_domain, op_domain_params, operational_status::OPERATIONAL); + + CHECK(mockturtle::to_seconds(op_domain_stats.time_total) > 0.0); + CHECK(op_domain_stats.num_simulator_invocations <= 400); + CHECK(op_domain_stats.num_evaluated_parameter_combinations <= 100); + CHECK(op_domain_stats.num_operational_parameter_combinations <= 100); + CHECK(op_domain_stats.num_non_operational_parameter_combinations == 0); + } +} diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 12a120d6c..fa98c26a0 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -480,8 +480,118 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); } +TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shape SiDB OR gate with input 01, check energy and charge " + "distribution, using offset coordinates", + "[quickexact]", + (cell_level_layout>>), + (charge_distribution_surface< + cell_level_layout>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), + TestType::cell_type::NORMAL); + + const quickexact_params sim_params{sidb_simulation_parameters{2, -0.28}}; + + const auto simulation_results = quickexact(lyt, sim_params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); +} + TEMPLATE_TEST_CASE( - "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber", + "QuickExact simulation of a Y-shape SiDB OR gate with input 01, check energy and charge " + "distribution, using offset coordinates", + "[quickexact]", (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + + const quickexact_params sim_params{sidb_simulation_parameters{2, -0.28}}; + + const auto simulation_results = quickexact(lyt, sim_params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.4662582096, physical_constants::POP_STABILITY_ERR)); +} + +TEMPLATE_TEST_CASE( + "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber, using " + "siqad coordinates", "[quickexact]", (cell_level_layout>>), (charge_distribution_surface>>>)) { @@ -516,6 +626,50 @@ TEMPLATE_TEST_CASE( CHECK(charge_lyt_first.get_charge_state({8, 3, 0}) == sidb_charge_state::NEGATIVE); } +TEMPLATE_TEST_CASE( + "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and local external potential at perturber, using " + "cube coordinates", + "[quickexact]", (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + + quickexact_params params{sidb_simulation_parameters{3, -0.28}}; + params.local_external_potential.insert({{siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), -0.5}}); + + const auto simulation_results = quickexact(lyt, params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0})) == + sidb_charge_state::NEGATIVE); +} + TEMPLATE_TEST_CASE( "QuickExact simulation of a Y-shape SiDB OR gate with input 01 and global external potential", "[quickexact]", (cell_level_layout>>), @@ -613,6 +767,27 @@ TEMPLATE_TEST_CASE( CHECK(charge_lyt_first.get_charge_state({30, 0, 0}) == sidb_charge_state::NEGATIVE); } +TEMPLATE_TEST_CASE( + "QuickExact with one SiDB and one negatively charged defect in proximity", "[quickexact]", + (sidb_surface>>>), + (charge_distribution_surface< + sidb_surface>>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type({0, 0, 0}, TestType::cell_type::NORMAL); + + const quickexact_params params{sidb_simulation_parameters{3, -0.32}}; + lyt.assign_sidb_defect({-1, -1, 1}, sidb_defect{sidb_defect_type::UNKNOWN, -1, params.physical_parameters.epsilon_r, + params.physical_parameters.lambda_tf}); + const auto simulation_results = quickexact(lyt, params); + + REQUIRE(!simulation_results.charge_distributions.empty()); + const auto& charge_lyt_first = simulation_results.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state({0, 0, 0}) == sidb_charge_state::NEUTRAL); +} + TEMPLATE_TEST_CASE( "QuickExact simulation of four SiDBs (far away) with one negatively charged defects in proximity", "[quickexact]", (sidb_surface>>>), diff --git a/test/algorithms/simulation/sidb/quicksim.cpp b/test/algorithms/simulation/sidb/quicksim.cpp index 6d45a45a1..b8de465b7 100644 --- a/test/algorithms/simulation/sidb/quicksim.cpp +++ b/test/algorithms/simulation/sidb/quicksim.cpp @@ -899,3 +899,105 @@ TEMPLATE_TEST_CASE( Catch::Matchers::WithinAbs(0.505173434, physical_constants::POP_STABILITY_ERR)); } } + +TEMPLATE_TEST_CASE( + "QuickSim simulation of a Y-shape SiDB arrangement with varying thread counts, cube coordinates", "[quicksim]", + (cell_level_layout>>), + (charge_distribution_surface>>>)) +{ + TestType lyt{}; + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-11, -2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-10, -1, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-4, -1, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-3, -2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 0, 1}), TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 1, 1}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{-7, 3, 0}), TestType::cell_type::NORMAL); + + const sidb_simulation_parameters params{2, -0.32}; + + quicksim_params quicksim_params{params}; + + REQUIRE(quicksim_params.phys_params.mu_minus == -0.32); + + const auto check_charge_configuration = [](const sidb_simulation_result& stats) noexcept + { + REQUIRE(!stats.charge_distributions.empty()); + + const auto& charge_lyt_first = stats.charge_distributions.front(); + + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-11, -2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-10, -1, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-3, -2, 0})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-4, -1, 0})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 0, 1})) == + sidb_charge_state::NEGATIVE); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 1, 1})) == + sidb_charge_state::NEUTRAL); + CHECK(charge_lyt_first.get_charge_state(siqad::to_fiction_coord(siqad::coord_t{-7, 3, 0})) == + sidb_charge_state::NEGATIVE); + + CHECK_THAT(charge_lyt_first.get_system_energy(), + Catch::Matchers::WithinAbs(0.3191788254, physical_constants::POP_STABILITY_ERR)); + }; + + SECTION("Default settings") + { + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("0 threads") + { + quicksim_params.number_threads = 0; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("1 thread") + { + quicksim_params.number_threads = 1; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("2 threads") + { + quicksim_params.number_threads = 2; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } + SECTION("100 threads") + { + quicksim_params.number_threads = 100; + + const auto simulation_results = quicksim(lyt, quicksim_params); + + check_for_absence_of_positive_charges(simulation_results); + check_for_runtime_measurement(simulation_results); + check_charge_configuration(simulation_results); + } +} diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index a0f20a00f..f73d6b77e 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -641,3 +641,44 @@ TEST_CASE("Random siqad::coord_t layout generation with defects", "[generate-ran }); } } + +TEST_CASE("Random cube::coord_t layout generation with defects", "[generate-random-sidb-layout]") +{ + using lyt = sidb_surface>>>; + + const generate_random_sidb_layout_params params{ + {to_fiction_coord(siqad::coord_t{0, 0, 0}), + to_fiction_coord(siqad::coord_t{10, 2, 0})}, + 10, + generate_random_sidb_layout_params::positive_charges::ALLOWED, + 2}; + + lyt layout{}; + + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{2, 2, 0}), + sidb_defect{sidb_defect_type::DB, -1, 5.6, 5}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{4, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 7}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{5, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 9}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{7, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 2.6, 7}); + layout.assign_sidb_defect(siqad::to_fiction_coord(siqad::coord_t{2, 1, 0}), + sidb_defect{sidb_defect_type::SINGLE_DIHYDRIDE, 1, 7.6, 4}); + + const auto result_lyt = generate_random_sidb_layout(layout, params); + + CHECK(result_lyt.num_cells() == 10); + CHECK(result_lyt.num_defects() == 5); + + // check if all cells are not closer than two cells (Euclidean distance). + result_lyt.foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{2, 2, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{4, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{5, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{7, 1, 0})); + CHECK(cell != siqad::to_fiction_coord(siqad::coord_t{2, 1, 0})); + }); +} diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index f65da827e..13b748991 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -17,21 +17,9 @@ using namespace fiction; -TEMPLATE_TEST_CASE( - "Charge distribution surface traits and construction", "[charge-distribution-surface]", - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) +TEMPLATE_TEST_CASE("Charge distribution surface traits and construction", "[charge-distribution-surface]", + (cell_level_layout>>), + (sidb_surface>>>)) { REQUIRE(is_cell_level_layout_v); CHECK(!has_assign_charge_state_v); @@ -55,13 +43,9 @@ TEMPLATE_TEST_CASE( CHECK(has_get_charge_state_v); } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects", "[charge-distribution-surface]", - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>), - (cell_level_layout>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-distribution-surface]", + (cell_level_layout>>), + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1327,13 +1311,7 @@ TEMPLATE_TEST_CASE( TEMPLATE_TEST_CASE( "Assign and delete charge states without defects, part one", "[charge-distribution-surface]", - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1583,13 +1561,7 @@ TEMPLATE_TEST_CASE( TEMPLATE_TEST_CASE( "Assign and delete charge states without defects, part two", "[charge-distribution-surface]", - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface>>>), - (sidb_surface< - cell_level_layout>>>), - (sidb_surface< - cell_level_layout>>>)) + (sidb_surface>>>)) { TestType lyt{{11, 11}}; diff --git a/test/technology/sidb_nm_position.cpp b/test/technology/sidb_nm_position.cpp index 892d50ad5..ff4324c94 100644 --- a/test/technology/sidb_nm_position.cpp +++ b/test/technology/sidb_nm_position.cpp @@ -12,13 +12,12 @@ using namespace fiction; -TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") +TEST_CASE("SiDB position in nanometer for siqad coordinate", "[sidb_nm_position]") { using namespace Catch::Matchers; SECTION("Default lattice constants, positive cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{}; const auto [pos_x, pos_y] = sidb_nm_position(params, {1, 0, 0}); @@ -48,7 +47,6 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") SECTION("Default lattice constants, negative cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{}; const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0, 0}); @@ -74,7 +72,6 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") SECTION("Special lattice constants, positive and negative cell coordinates") { - const sidb_cell_clk_lyt_siqad layout{}; const sidb_simulation_parameters params{3, -0.32, 5.6, 5.0, 1, 2, 3}; const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0, 0}); @@ -106,3 +103,64 @@ TEST_CASE("SiDB position in nanometer", "[sidb_nm_position]") CHECK_THAT(pos6_y, WithinAbs(-1.7, 1E-5)); } } + +TEST_CASE("SiDB position in nanometer for fiction coordinates", "[sidb_nm_position]") +{ + using namespace Catch::Matchers; + + using sidb_cell_clk_lyt_cube = cell_level_layout>>; + + SECTION("Default lattice constants, positive cell coordinates") + { + const sidb_simulation_parameters params{}; + + const auto [pos_x, pos_y] = sidb_nm_position(params, {1, 0}); + CHECK_THAT(pos_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + + const auto [pos2_x, pos2_y] = sidb_nm_position(params, {0, 2}); + CHECK_THAT(pos2_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos2_y, WithinAbs(params.lat_b * 0.1, 1E-5)); + + const auto [pos3_x, pos3_y] = sidb_nm_position(params, {0, 17}); + CHECK_THAT(pos3_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos3_y, WithinAbs(params.lat_b * 0.8 + params.lat_c * 0.1, 1E-5)); + + const auto [pos4_x, pos4_y] = sidb_nm_position(params, {1, 2}); + CHECK_THAT(pos4_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos4_y, WithinAbs(params.lat_b * 0.1, 1E-5)); + + const auto [pos5_x, pos5_y] = sidb_nm_position(params, {1, 3}); + CHECK_THAT(pos5_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos5_y, WithinAbs(params.lat_b * 0.1 + params.lat_c * 0.1, 1E-5)); + + const auto [pos6_x, pos6_y] = sidb_nm_position(params, {1, 21}); + CHECK_THAT(pos6_x, WithinAbs(params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos6_y, WithinAbs(params.lat_b + params.lat_c * 0.1, 1E-5)); + } + + SECTION("Default lattice constants, negative cell coordinates") + { + const sidb_simulation_parameters params{}; + + const auto [pos_x, pos_y] = sidb_nm_position(params, {-1, 0}); + CHECK_THAT(pos_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos_y, WithinAbs(0.0, 1E-5)); + + const auto [pos2_x, pos2_y] = sidb_nm_position(params, {0, -2}); + CHECK_THAT(pos2_x, WithinAbs(0.0, 1E-5)); + CHECK_THAT(pos2_y, WithinAbs(-params.lat_b * 0.1, 1E-5)); + + const auto [pos3_x, pos3_y] = sidb_nm_position(params, {-5, -10}); + CHECK_THAT(pos3_x, WithinAbs(-params.lat_a * 0.5, 1E-5)); + CHECK_THAT(pos3_y, WithinAbs(-params.lat_b * 0.5, 1E-5)); + + const auto [pos4_x, pos4_y] = sidb_nm_position(params, {-1, -3}); + CHECK_THAT(pos4_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos4_y, WithinAbs(-params.lat_b * 0.1 + params.lat_c * 0.1, 1E-5)); + + const auto [pos5_x, pos5_y] = sidb_nm_position(params, {-1, -21}); + CHECK_THAT(pos5_x, WithinAbs(-params.lat_a * 0.1, 1E-5)); + CHECK_THAT(pos5_y, WithinAbs(-params.lat_b + params.lat_c * 0.1, 1E-5)); + } +} diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 8e268ef9f..663af7e46 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -336,11 +336,11 @@ TEST_CASE("Generate random siqad::coord_t coordinate", "[layout-utils]") } } -TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") +TEST_CASE("Generate all cells in area spanned by two cells, using siqad coordinates", "[layout-utils]") { SECTION("two identical cells") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {-10, -5, 0}); REQUIRE(all_area_cells.size() == 1); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -350,7 +350,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same y and z coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {10, -5, 0}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -5, 0}, {10, -5, 0}); REQUIRE(all_area_cells.size() == 21); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -365,7 +365,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same y coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({-10, 5, 0}, {10, 5, 1}); + const auto all_area_cells = all_sidbs_in_spanned_area({-10, 5, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 42); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == -10); @@ -380,7 +380,7 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") SECTION("two cells at the same x coordinate ") { - const auto all_area_cells = all_sidbs_in_spanned_area({10, 2, 0}, {10, 5, 1}); + const auto all_area_cells = all_sidbs_in_spanned_area({10, 2, 0}, {10, 5, 1}); REQUIRE(all_area_cells.size() == 8); const auto first_cell = all_area_cells.front(); CHECK(first_cell.x == 10); @@ -393,3 +393,51 @@ TEST_CASE("Generate all cells in area spanned by two cells", "[layout-utils]") CHECK(final_cell.z == 1); } } + +TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinates", "[layout-utils]") +{ + SECTION("two identical cells") + { + const auto all_area_cells = all_sidbs_in_spanned_area({-10, -10, 0}, {-10, -10, 0}); + REQUIRE(all_area_cells.size() == 1); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == -10); + CHECK(first_cell.y == -10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == -10); + CHECK(final_cell.y == -10); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same y coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({-10, 10}, {10, 11}); + REQUIRE(all_area_cells.size() == 42); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == -10); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same x coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + REQUIRE(all_area_cells.size() == 8); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 4); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } +} From b8e2160e39129cae32d798ec45532c10de336391 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 21 Nov 2023 22:15:02 +0100 Subject: [PATCH 081/191] :art: remove redundant static_cast. --- include/fiction/technology/charge_distribution_surface.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/fiction/technology/charge_distribution_surface.hpp b/include/fiction/technology/charge_distribution_surface.hpp index bdb9270c2..2d9bd792d 100644 --- a/include/fiction/technology/charge_distribution_surface.hpp +++ b/include/fiction/technology/charge_distribution_surface.hpp @@ -242,7 +242,6 @@ class charge_distribution_surface : public Lyt Lyt(), strg{std::make_shared(params)} { - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); 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"); @@ -264,7 +263,6 @@ class charge_distribution_surface : public Lyt Lyt(lyt), strg{std::make_shared(params)} { - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); 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"); From c22e3e84f65199ec88c7b43e02662e433bc6ff47 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:15:18 +0100 Subject: [PATCH 082/191] :art: add static_cast --- include/fiction/algorithms/simulation/sidb/quickexact.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 55e37b149..138a0e326 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -125,12 +125,12 @@ class quickexact_impl { if constexpr (has_get_sidb_defect_v) { - charge_distribution_surface charge_layout{layout}; + charge_distribution_surface charge_layout{static_cast(layout)}; conduct_simulation(charge_layout, base_number); } else { - charge_distribution_surface charge_layout{layout}; + charge_distribution_surface charge_layout{static_cast(layout)}; conduct_simulation(charge_layout, base_number); } } From 835a19b8ee28e5d8cd957add1f602c455f64e81f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:33:32 +0100 Subject: [PATCH 083/191] :white_check_mark: add further test for bdl input iterator. --- test/algorithms/iter/bdl_input_iterator.cpp | 172 ++++++++++++++------ 1 file changed, 122 insertions(+), 50 deletions(-) diff --git a/test/algorithms/iter/bdl_input_iterator.cpp b/test/algorithms/iter/bdl_input_iterator.cpp index 7aabba41a..4641ef077 100644 --- a/test/algorithms/iter/bdl_input_iterator.cpp +++ b/test/algorithms/iter/bdl_input_iterator.cpp @@ -5,8 +5,10 @@ #include #include +#include #include #include +#include #include #include @@ -226,63 +228,133 @@ TEST_CASE("SiQAD's AND gate iteration", "[bdl-input-iterator]") lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - bdl_input_iterator bii{lyt}; - - for (auto i = 0; bii < 4; ++bii, ++i) + SECTION("siqad coordinates") { - switch (i) - { - case 0: - { - const auto& lyt_0 = *bii; - - CHECK(lyt_0.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_0.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); - - CHECK(lyt_0.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_0.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + bdl_input_iterator bii{lyt}; - break; - } - case 1: - { - const auto& lyt_1 = *bii; - - CHECK(lyt_1.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_1.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); - - CHECK(lyt_1.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_1.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); - - break; - } - case 2: + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) { - const auto& lyt_2 = *bii; - - CHECK(lyt_2.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_2.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); - - CHECK(lyt_2.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); - CHECK(lyt_2.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); - - break; + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } } - case 3: - { - const auto& lyt_3 = *bii; - - CHECK(lyt_3.get_cell_type({0, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_3.get_cell_type({2, 1, 1}) == sidb_technology::cell_type::INPUT); + } + } - CHECK(lyt_3.get_cell_type({20, 0, 1}) == sidb_technology::cell_type::EMPTY); - CHECK(lyt_3.get_cell_type({18, 1, 1}) == sidb_technology::cell_type::INPUT); + SECTION("cube coordinates") + { + const auto layout_cube = convert_to_fiction_coordinates< + cell_level_layout>>>(lyt); + bdl_input_iterator>>> bii{ + layout_cube}; - break; - } - default: + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) { - CHECK(false); + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } } } } From 91f2d1a2fc09cc0390d412ed7aa49a37e94072f4 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 07:36:23 +0100 Subject: [PATCH 084/191] :art: add missing namespace. --- .../simulation/sidb/random_sidb_layout_generator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp index f73d6b77e..747b196d2 100644 --- a/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp +++ b/test/algorithms/simulation/sidb/random_sidb_layout_generator.cpp @@ -647,8 +647,8 @@ TEST_CASE("Random cube::coord_t layout generation with defects", "[generate-rand using lyt = sidb_surface>>>; const generate_random_sidb_layout_params params{ - {to_fiction_coord(siqad::coord_t{0, 0, 0}), - to_fiction_coord(siqad::coord_t{10, 2, 0})}, + {siqad::to_fiction_coord(siqad::coord_t{0, 0, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 2, 0})}, 10, generate_random_sidb_layout_params::positive_charges::ALLOWED, 2}; From 6ccb477b8e8656f1f2ba51166c7b2d3ef9958900 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 08:56:56 +0100 Subject: [PATCH 085/191] :art: allow offset coordinates for gate design --- .../algorithms/path_finding/distance.hpp | 1 - .../physical_design/design_sidb_gates.hpp | 21 +++-- .../assess_physical_population_stability.hpp | 2 +- include/fiction/layouts/coordinates.hpp | 12 +-- .../fiction/technology/sidb_nm_position.hpp | 7 +- include/fiction/utils/layout_utils.hpp | 93 +++++++++++++------ test/algorithms/iter/bdl_input_iterator.cpp | 67 +++++++++++++ .../physical_design/design_sidb_gates.cpp | 23 ++++- test/utils/layout_utils.cpp | 48 ++++++++++ 9 files changed, 220 insertions(+), 54 deletions(-) diff --git a/include/fiction/algorithms/path_finding/distance.hpp b/include/fiction/algorithms/path_finding/distance.hpp index 943d42fa9..7b532eb37 100644 --- a/include/fiction/algorithms/path_finding/distance.hpp +++ b/include/fiction/algorithms/path_finding/distance.hpp @@ -107,7 +107,6 @@ sidb_nanometer_distance([[maybe_unused]] const Lyt& lyt, const coordinate& { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not based on SiDB technology"); - //static_assert(has_siqad_coord_v, "Lyt is not based on SiQAD coordinates"); const auto pos_c1 = sidb_nm_position(sp, source); const auto pos_c2 = sidb_nm_position(sp, target); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 4ac214a07..69d4d43a9 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -38,6 +38,8 @@ namespace fiction /** * This struct contains parameters and settings to design SiDB gates. * + * @tparam Cell-level layout type. + * */ template struct design_sidb_gates_params @@ -97,7 +99,7 @@ class design_sidb_gates_impl skeleton_layout{skeleton}, truth_table{tt}, params{ps}, - all_sidbs_in_cavas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} + all_sidbs_in_canvas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} {} /** * Design gates exhaustively and in parallel. @@ -225,7 +227,7 @@ class design_sidb_gates_impl /** * All cells within the canvas. */ - const std::vector all_sidbs_in_cavas; + const std::vector all_sidbs_in_canvas; /** * Calculates all possible combinations of distributing the given number of SiDBs within a canvas * based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in @@ -237,9 +239,9 @@ class design_sidb_gates_impl [[nodiscard]] std::vector> determine_all_combinations_of_given_sidbs_in_canvas() noexcept { std::vector> all_combinations{}; - all_combinations.reserve(binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs)); + all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs)); - std::vector numbers(all_sidbs_in_cavas.size()); + std::vector numbers(all_sidbs_in_canvas.size()); std::iota(numbers.begin(), numbers.end(), 0); combinations::for_each_combination( @@ -280,8 +282,8 @@ class design_sidb_gates_impl { for (std::size_t j = i + 1; j < cell_indices.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_cavas[cell_indices[i]], - all_sidbs_in_cavas[cell_indices[j]]) < 0.5) + if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_canvas[cell_indices[i]], + all_sidbs_in_canvas[cell_indices[j]]) < 0.5) { return true; } @@ -301,11 +303,11 @@ class design_sidb_gates_impl for (const auto i : cell_indices) { - assert(i < all_sidbs_in_cavas.size() && "cell indices are out-of-range"); + assert(i < all_sidbs_in_canvas.size() && "cell indices are out-of-range"); - if (lyt_copy.get_cell_type(all_sidbs_in_cavas[i]) == sidb_technology::cell_type::EMPTY) + if (lyt_copy.get_cell_type(all_sidbs_in_canvas[i]) == sidb_technology::cell_type::EMPTY) { - lyt_copy.assign_cell_type(all_sidbs_in_cavas[i], sidb_technology::cell_type::NORMAL); + lyt_copy.assign_cell_type(all_sidbs_in_canvas[i], sidb_technology::cell_type::NORMAL); } } @@ -350,7 +352,6 @@ template static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); static_assert(kitty::is_truth_table::value, "TT is not a truth table"); static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); - static_assert(!has_offset_ucoord_v, "Lyt cannot be based on offset coordinates"); assert(skeleton.num_pis() > 0 && "skeleton needs input cells"); assert(skeleton.num_pos() > 0 && "skeleton needs output cells"); diff --git a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp index bce65fa35..f844d694f 100644 --- a/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp +++ b/include/fiction/algorithms/simulation/sidb/assess_physical_population_stability.hpp @@ -367,7 +367,7 @@ assess_physical_population_stability(const Lyt& lyt, const assess_physical_popul { 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(!is_charge_distribution_surface_v, "Lyt is a charge distribution surface"); + static_assert(!is_charge_distribution_surface_v, "Lyt cannot be a charge distribution surface"); detail::assess_physical_population_stability_impl p{lyt, params}; return p.run(); diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 270e5569c..8ac369b88 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -776,23 +776,19 @@ struct coord_t /** * Converts SiQAD coordinates to other coordinates (offset, cube). * - * @tparam CoordinateType Coordinate type to convert to. + * @tparam CoordinateType The wanted coordinate type. * @param coord SiQAD coordinate to convert. * @return Coordinate of type `CoordinateType`. */ -template -constexpr CoordinateTypeOutput to_fiction_coord(const CoordinateTypeInput& coord) noexcept +template +constexpr CoordinateType to_fiction_coord(const siqad::coord_t& coord) noexcept { - if constexpr (std::is_same_v) - { - return coord; - } if (!coord.is_dead()) { return {coord.x, coord.y * 2 + coord.z}; } - return CoordinateTypeOutput{}; + return CoordinateType{}; } /** * Converts any coordinate type to SiQAD coordinates. diff --git a/include/fiction/technology/sidb_nm_position.hpp b/include/fiction/technology/sidb_nm_position.hpp index c8259c486..36e490c4f 100644 --- a/include/fiction/technology/sidb_nm_position.hpp +++ b/include/fiction/technology/sidb_nm_position.hpp @@ -7,8 +7,8 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/cell_level_layout.hpp" -#include "fiction/traits.hpp" #include "fiction/layouts/coordinates.hpp" +#include "fiction/traits.hpp" #include @@ -29,7 +29,6 @@ template { 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 || has_cube_coord_v || has_offset_ucoord_v, "Coordinate type is not supported"); if constexpr (has_siqad_coord_v) { @@ -40,8 +39,8 @@ template else { const auto cell_in_siqad = siqad::to_siqad_coord(c); - const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; - const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; + const auto x = (cell_in_siqad.x * sp.lat_a) * 0.1; + const auto y = (cell_in_siqad.y * sp.lat_b + cell_in_siqad.z * sp.lat_c) * .1; return std::make_pair(x, y); } } diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index b6a5474e8..e56674baf 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -328,6 +328,17 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) 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"); + bool has_negative_coordinates = false; + + lyt.foreach_cell( + [&has_negative_coordinates](const auto& c) + { + if (c.x < 0 || c.y < 0) + { + has_negative_coordinates = true; + } + }); + Lyt lyt_new{{lyt.x(), 2 * lyt.y() + 1}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; const auto assign_coordinates = [&lyt_new](const auto& base_lyt) noexcept @@ -341,7 +352,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept }); }; - if (has_offset_ucoord_v && !lyt.is_empty()) + if (has_offset_ucoord_v && !lyt.is_empty() && has_negative_coordinates) { auto lyt_normalized = normalize_layout_coordinates(lyt); assign_coordinates(lyt_normalized); @@ -408,40 +419,66 @@ template [[nodiscard]] inline std::vector all_sidbs_in_spanned_area(const CoordinateType& cell_nw, const CoordinateType& cell_se) noexcept { - const auto c1_cube = siqad::to_fiction_coord(cell_nw); - const auto c2_cube = siqad::to_fiction_coord(cell_se); - const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * - static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); - - std::vector all_cells{}; - all_cells.reserve(total_cell_count); - - auto current_cell = c1_cube; - - // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to down - // from left to right. - while (current_cell <= c2_cube) + // for siqad coordinates + if constexpr (std::is_same_v) { - if constexpr (std::is_same_v) + const auto c1_cube = siqad::to_fiction_coord(cell_nw); + const auto c2_cube = siqad::to_fiction_coord(cell_se); + const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * + static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); + std::vector all_cells{}; + all_cells.reserve(total_cell_count); + + auto current_cell = c1_cube; + + // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to + // down from left to right. + while (current_cell <= c2_cube) { all_cells.push_back(siqad::to_siqad_coord(current_cell)); + if (current_cell.x < cell_se.x) + { + current_cell.x += 1; + } + else + { + current_cell.x = cell_nw.x; + current_cell.y += 1; + } } - else - { - all_cells.push_back(siqad::to_fiction_coord(current_cell)); - } - if (current_cell.x < cell_se.x) - { - current_cell.x += 1; - } - else + + return all_cells; + } + // for cube and offset coordinates + else + { + const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * + static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + std::vector all_cells{}; + all_cells.reserve(total_cell_count); + + auto current_cell = cell_nw; + + // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to + // down from left to right. + while (current_cell <= cell_se) { - current_cell.x = cell_nw.x; - current_cell.y += 1; + + all_cells.push_back(current_cell); + + if (current_cell.x < cell_se.x) + { + current_cell.x += 1; + } + else + { + current_cell.x = cell_nw.x; + current_cell.y += 1; + } } - } - return all_cells; + return all_cells; + } } } // namespace fiction diff --git a/test/algorithms/iter/bdl_input_iterator.cpp b/test/algorithms/iter/bdl_input_iterator.cpp index 4641ef077..a3ee32971 100644 --- a/test/algorithms/iter/bdl_input_iterator.cpp +++ b/test/algorithms/iter/bdl_input_iterator.cpp @@ -358,4 +358,71 @@ TEST_CASE("SiQAD's AND gate iteration", "[bdl-input-iterator]") } } } + + SECTION("offset coordinates") + { + const auto layout_offset = convert_to_fiction_coordinates< + cell_level_layout>>>(lyt); + bdl_input_iterator>>> bii{ + layout_offset}; + + for (auto i = 0; bii < 4; ++bii, ++i) + { + switch (i) + { + case 0: + { + const auto& lyt_0 = *bii; + + CHECK(lyt_0.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_0.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_0.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 1: + { + const auto& lyt_1 = *bii; + + CHECK(lyt_1.get_cell_type({0, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_1.get_cell_type({2, 3}) == sidb_technology::cell_type::EMPTY); + + CHECK(lyt_1.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_1.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + case 2: + { + const auto& lyt_2 = *bii; + + CHECK(lyt_2.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_2.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_2.get_cell_type({20, 1}) == sidb_technology::cell_type::INPUT); + CHECK(lyt_2.get_cell_type({18, 3}) == sidb_technology::cell_type::EMPTY); + + break; + } + case 3: + { + const auto& lyt_3 = *bii; + + CHECK(lyt_3.get_cell_type({0, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({2, 3}) == sidb_technology::cell_type::INPUT); + + CHECK(lyt_3.get_cell_type({20, 1}) == sidb_technology::cell_type::EMPTY); + CHECK(lyt_3.get_cell_type({18, 3}) == sidb_technology::cell_type::INPUT); + + break; + } + default: + { + CHECK(false); + } + } + } + } } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index e8195ddb0..5f7ee24fb 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -17,8 +17,9 @@ using namespace fiction; TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; - using layout_cube = cell_level_layout>>; + using layout = sidb_cell_clk_lyt_siqad; + using layout_cube = cell_level_layout>>; + using layout_offset = cell_level_layout>>; layout lyt{}; @@ -73,6 +74,24 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_cube[0].num_cells() == 14); CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_offset = + design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); + + REQUIRE(found_gate_layouts_offset.size() == 1); + CHECK(found_gate_layouts_offset[0].num_cells() == 14); + CHECK(found_gate_layouts_offset[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 663af7e46..3a16d0e9d 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -441,3 +441,51 @@ TEST_CASE("Generate all cells in area spanned by two cells, using cube coordinat CHECK(final_cell.z == 0); } } + +TEST_CASE("Generate all cells in area spanned by two cells, using offset coordinates", "[layout-utils]") +{ + SECTION("two identical cells") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 10, 0}, {10, 10, 0}); + REQUIRE(all_area_cells.size() == 1); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 10); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same y coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({0, 10}, {20, 11}); + REQUIRE(all_area_cells.size() == 42); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 0); + CHECK(first_cell.y == 10); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 20); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } + + SECTION("two cells at the same x coordinate ") + { + const auto all_area_cells = all_sidbs_in_spanned_area({10, 4, 0}, {10, 11}); + REQUIRE(all_area_cells.size() == 8); + const auto first_cell = all_area_cells.front(); + CHECK(first_cell.x == 10); + CHECK(first_cell.y == 4); + CHECK(first_cell.z == 0); + + const auto final_cell = all_area_cells.back(); + CHECK(final_cell.x == 10); + CHECK(final_cell.y == 11); + CHECK(final_cell.z == 0); + } +} From 559e1898734257cecc314b4acabf95bc48ed2637 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 09:40:37 +0100 Subject: [PATCH 086/191] :art: reformat code --- include/fiction/utils/layout_utils.hpp | 4 +-- .../sidb/can_positive_charges_occur.cpp | 28 ++++++++++++------- ...defect_influence_position_and_distance.cpp | 3 +- .../algorithms/simulation/sidb/quickexact.cpp | 2 +- .../charge_distribution_surface.cpp | 10 +++---- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index e56674baf..1dc1b640c 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -452,8 +452,8 @@ template // for cube and offset coordinates else { - const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * - static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * + static_cast(std::abs(cell_nw.y - cell_se.y) + 1); std::vector all_cells{}; all_cells.reserve(total_cell_count); diff --git a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp index c8326d4cc..1fd7822d1 100644 --- a/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp +++ b/test/algorithms/simulation/sidb/can_positive_charges_occur.cpp @@ -112,16 +112,24 @@ TEMPLATE_TEST_CASE("Y-shape SiDB OR gate with input 01, using offset coordinates { TestType lyt{{20, 10}}; - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), TestType::cell_type::NORMAL); - - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), TestType::cell_type::NORMAL); - - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), TestType::cell_type::NORMAL); - lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{6, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{8, 3, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{12, 3, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{14, 2, 0}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 5, 0}), + TestType::cell_type::NORMAL); + + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 6, 1}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 8, 1}), + TestType::cell_type::NORMAL); + lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{16, 1, 0}), + TestType::cell_type::NORMAL); SECTION("Default values") { diff --git a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp index 897956f4f..e56265d3d 100644 --- a/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp +++ b/test/algorithms/simulation/sidb/maximum_defect_influence_position_and_distance.cpp @@ -121,7 +121,7 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio const sidb_defect defect{sidb_defect_type::UNKNOWN, -1, sidb_simulation_parameters{}.epsilon_r, sidb_simulation_parameters{}.lambda_tf}; const maximum_defect_influence_distance_params sim_params{defect, sidb_simulation_parameters{}}; - cell_level_layout>> lyt{{30,30}}; + cell_level_layout>> lyt{{30, 30}}; lyt.assign_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 0, 0}), sidb_cell_clk_lyt_siqad::cell_type::NORMAL); @@ -147,6 +147,5 @@ TEST_CASE("Test influence distance function", "[maximum-defect-influence-positio CHECK(defect_pos.z == 0); CHECK_THAT(distance, Catch::Matchers::WithinAbs(2.8999201713, physical_constants::POP_STABILITY_ERR)); - } } diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index fa98c26a0..77517b5fa 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -779,7 +779,7 @@ TEMPLATE_TEST_CASE( const quickexact_params params{sidb_simulation_parameters{3, -0.32}}; lyt.assign_sidb_defect({-1, -1, 1}, sidb_defect{sidb_defect_type::UNKNOWN, -1, params.physical_parameters.epsilon_r, - params.physical_parameters.lambda_tf}); + params.physical_parameters.lambda_tf}); const auto simulation_results = quickexact(lyt, params); REQUIRE(!simulation_results.charge_distributions.empty()); diff --git a/test/technology/charge_distribution_surface.cpp b/test/technology/charge_distribution_surface.cpp index 13b748991..ca961fcc7 100644 --- a/test/technology/charge_distribution_surface.cpp +++ b/test/technology/charge_distribution_surface.cpp @@ -1309,9 +1309,8 @@ TEMPLATE_TEST_CASE("Assign and delete charge states without defects", "[charge-d } } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects, part one", "[charge-distribution-surface]", - (sidb_surface>>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part one", "[charge-distribution-surface]", + (sidb_surface>>>)) { TestType lyt{{11, 11}}; @@ -1559,9 +1558,8 @@ TEMPLATE_TEST_CASE( } } -TEMPLATE_TEST_CASE( - "Assign and delete charge states without defects, part two", "[charge-distribution-surface]", - (sidb_surface>>>)) +TEMPLATE_TEST_CASE("Assign and delete charge states without defects, part two", "[charge-distribution-surface]", + (sidb_surface>>>)) { TestType lyt{{11, 11}}; From e28b1b4833b37709e633dacfab22eb943fec85a3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 22 Nov 2023 12:45:11 +0100 Subject: [PATCH 087/191] :art: small fix. --- include/fiction/utils/layout_utils.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 1dc1b640c..243986cd2 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -452,8 +452,9 @@ template // for cube and offset coordinates else { - const auto total_cell_count = static_cast(std::abs(cell_nw.x - cell_se.x) + 1) * - static_cast(std::abs(cell_nw.y - cell_se.y) + 1); + const auto total_cell_count = + static_cast(std::abs(static_cast(cell_nw.x) - static_cast(cell_se.x)) + 1) * + static_cast(std::abs(static_cast(cell_nw.y) - static_cast(cell_se.y)) + 1); std::vector all_cells{}; all_cells.reserve(total_cell_count); From 2788e87e0c0b80255bd802c3340d6c7e6c1d8818 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 23 Nov 2023 14:31:19 +0100 Subject: [PATCH 088/191] :art: structural changes. --- docs/algorithms/apply_gate_library.rst | 2 +- ...cal_design_with_on_the_fly_gate_design.cpp | 26 +- .../physical_design/apply_gate_library.hpp | 18 +- .../physical_design/design_sidb_gates.hpp | 51 +-- .../simulation/sidb/is_operational.hpp | 12 +- include/fiction/layouts/coordinates.hpp | 19 + .../sidb_is_gate_design_impossible.hpp | 46 ++- .../sidb_on_the_fly_gate_library.hpp | 324 +++++++++--------- include/fiction/types.hpp | 3 + include/fiction/utils/layout_utils.hpp | 35 +- .../physical_design/design_sidb_gates.cpp | 70 ++-- .../sidb/is_gate_design_impossible.cpp | 8 +- test/layouts/coordinates.cpp | 25 ++ test/utils/layout_utils.cpp | 58 ++++ 14 files changed, 421 insertions(+), 276 deletions(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 599446b9a..8bda01d25 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_on_the_fly_gate_library \ No newline at end of file +.. doxygenfunction:: fiction::apply_parameterized_gate_library \ No newline at end of file diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 7064668d0..3dfd36928 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -192,12 +192,22 @@ int main() // NOLINT { try { - cell_level_layout = - fiction::apply_on_the_fly_gate_library( - *gate_level_layout, surface_lattice, - fiction::sidb_on_the_fly_gate_library_params{}); + const fiction::design_sidb_gates_params design_gate_params{ + fiction::sidb_simulation_parameters{2, -0.32}, + fiction::design_sidb_gates_params< + fiction::cube::coord_t>::design_sidb_gates_mode::EXHAUSTIVE, + {{24, 17}, {34, 28}}, + 3, + fiction::sidb_simulation_engine::QUICKEXACT, + 1}; + + auto parameter_gate_library = fiction::sidb_on_the_fly_gate_library_params{ + surface_lattice, design_gate_params}; + + cell_level_layout = fiction::apply_parameterized_gate_library< + cell_lyt, fiction::sidb_on_the_fly_gate_library, gate_lyt, + fiction::sidb_on_the_fly_gate_library_params>(*gate_level_layout, + parameter_gate_library); gate_design_failed = false; } catch (const fiction::gate_design_exception& e) @@ -240,8 +250,8 @@ int main() // NOLINT surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) { defect_surface.assign_sidb_defect(defect.first, defect.second); }); // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, - fmt::format("{}/{}_{}_percent.sqd", layouts_folder, benchmark, concentration)); + fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_{}_percent_after_big_change.sqd", + layouts_folder, benchmark, concentration)); // log results bestagon_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index d76d5f09e..70c8b4b1a 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -50,14 +50,12 @@ class apply_gate_library_impl * building blocks from the `GateLibrary`. Atomic defects are incorporated into the gate designs during this * process. * - * @tparam GateLibraryblack Type of the gate library used to generate the blacklist. * @tparam Params Type of the parameter used for the on-the-fly gate library. - * @param defect_surface Defect surface with atomic defects. * @param params Parameter for the gate library. * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ - template - [[nodiscard]] CellLyt design_gates_on_the_fly(const sidb_surface& defect_surface, const Params& params) + template + [[nodiscard]] CellLyt design_gates_on_the_fly(const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar @@ -75,8 +73,7 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate( - gate_lyt, t, defect_surface, params); + const auto gate = GateLibrary::template set_up_gate(gate_lyt, t, params); assign_gate(c, gate, n); } @@ -228,16 +225,13 @@ template * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. - * @tparam GateLibraryblack Type of the gate library to generate the blacklist. * @tparam Params Type of the parameter used for the on-the-fly gate library. * @param lyt The gate-level layout. - * @param defect_surface Defect surface with all atomic defects. * @param params Parameter for the gate library. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ -template -[[nodiscard]] CellLyt apply_on_the_fly_gate_library(const GateLyt& lyt, const sidb_surface& defect_surface, - const Params& params) +template +[[nodiscard]] CellLyt apply_parameterized_gate_library(const GateLyt& lyt, Params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); @@ -251,7 +245,7 @@ template p{lyt}; - return p.template design_gates_on_the_fly(defect_surface, params); + return p.template design_gates_on_the_fly(params); } } // namespace fiction diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index df1980761..3f0205415 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -38,10 +38,10 @@ namespace fiction /** * This struct contains parameters and settings to design SiDB gates. * - * @tparam Cell-level layout type. + * @tparam CellType Type of the cells used. * */ -template +template struct design_sidb_gates_params { /** @@ -69,7 +69,7 @@ struct design_sidb_gates_params /** * Canvas spanned by the northwest and southeast cell. */ - std::pair canvas{}; + std::pair canvas{}; /** * Number of SiDBs placed in the canvas to create a working gate. */ @@ -96,14 +96,15 @@ class design_sidb_gates_impl * implementation with the provided skeleton layout and configuration parameters. * * @param skeleton The skeleton layout used as a basis for gate design. - * @param tt Expected Boolean function of the layout given as a multi-output truth table. + * @param spec Expected Boolean function of the layout given as a multi-output truth table. * @param ps Parameters and settings for the gate designer. */ - design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, const design_sidb_gates_params& ps) : + design_sidb_gates_impl(const Lyt& skeleton, const std::vector& spec, + const design_sidb_gates_params>& ps) : skeleton_layout{skeleton}, - truth_table{tt}, - params{ps}, - all_sidbs_in_canvas{all_sidbs_in_spanned_area(params.canvas.first, params.canvas.second)} + truth_table{spec}, + parameter{ps}, + all_sidbs_in_canvas{all_sidbs_in_spanned_area(parameter.canvas.first, parameter.canvas.second)} {} /** * Design gates exhaustively and in parallel. @@ -115,7 +116,7 @@ class design_sidb_gates_impl */ [[nodiscard]] std::vector run_exhaustive_design() noexcept { - const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; + const is_operational_params params_is_operational{parameter.phys_params, parameter.sim_engine}; auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); std::unordered_set sidbs_affected_by_defects = {}; @@ -130,7 +131,7 @@ class design_sidb_gates_impl std::atomic solution_found = false; std::atomic global_iteration_counter(0); - const auto total_comb = binomial_coefficient(all_sidbs_in_cavas.size(), params.number_of_sidbs); + const auto total_comb = binomial_coefficient(all_sidbs_in_canvas.size(), parameter.number_of_sidbs); // Shuffle the combinations before dividing them among threads std::shuffle(all_combinations.begin(), all_combinations.end(), @@ -145,7 +146,7 @@ class design_sidb_gates_impl { if (!solution_found && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && global_iteration_counter < - static_cast(params.procentual_maximum_attemps * static_cast(total_comb))) + static_cast(parameter.procentual_maximum_attemps * static_cast(total_comb))) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -202,10 +203,10 @@ class design_sidb_gates_impl { std::vector randomly_designed_gate_layouts = {}; - const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; + const is_operational_params params_is_operational{parameter.phys_params, parameter.sim_engine}; - const generate_random_sidb_layout_params parameter{ - params.canvas, params.number_of_sidbs, + const generate_random_sidb_layout_params parameter_random_layout{ + parameter.canvas, parameter.number_of_sidbs, generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; const std::size_t num_threads = std::thread::hardware_concurrency(); @@ -218,12 +219,12 @@ class design_sidb_gates_impl for (uint64_t z = 0u; z < num_threads; z++) { threads.emplace_back( - [this, &gate_layout_is_found, &mutex_to_protect_designed_gate_layouts, ¶meter, + [this, &gate_layout_is_found, &mutex_to_protect_designed_gate_layouts, ¶meter_random_layout, ¶ms_is_operational, &randomly_designed_gate_layouts] { while (!gate_layout_is_found) { - auto result_lyt = generate_random_sidb_layout(skeleton_layout, parameter); + auto result_lyt = generate_random_sidb_layout(skeleton_layout, parameter_random_layout); if constexpr (has_get_sidb_defect_v) { result_lyt.foreach_sidb_defect( @@ -280,7 +281,7 @@ class design_sidb_gates_impl /** * Parameters for the *SiDB Gate Designer*. */ - const design_sidb_gates_params& params; + const design_sidb_gates_params& parameter; /** * All cells within the canvas. */ @@ -296,19 +297,19 @@ class design_sidb_gates_impl [[nodiscard]] std::vector> determine_all_combinations_of_given_sidbs_in_canvas() noexcept { std::vector> all_combinations{}; - all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs)); + all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), parameter.number_of_sidbs)); std::vector numbers(all_sidbs_in_canvas.size()); std::iota(numbers.begin(), numbers.end(), 0); combinations::for_each_combination( numbers.begin(), - numbers.begin() + static_cast::difference_type>(params.number_of_sidbs), + numbers.begin() + static_cast::difference_type>(parameter.number_of_sidbs), numbers.end(), [this, &all_combinations](const auto begin, const auto end) { std::vector combination{}; - combination.reserve(params.number_of_sidbs); + combination.reserve(parameter.number_of_sidbs); for (auto it = begin; it != end; ++it) { @@ -331,6 +332,7 @@ class design_sidb_gates_impl * otherwise, it returns `false`. * * @param cell_indices A vector of cell indices to check for SiDB proximity. + * @tparam affected_cells All SiDBs that are affected by atomic defects. * @return `true` if any SiDBs are too close; otherwise, `false`. */ [[nodiscard]] bool are_sidbs_too_close(const std::vector& cell_indices, @@ -340,12 +342,13 @@ class design_sidb_gates_impl { if constexpr (has_get_sidb_defect_v) { - if (skeleton_layout.get_sidb_defect(all_sidbs_in_cavas[cell_indices[i]]).type != sidb_defect_type::NONE) + if (skeleton_layout.get_sidb_defect(all_sidbs_in_canvas[cell_indices[i]]).type != + sidb_defect_type::NONE) { return true; } } - if (affected_cells.count(all_sidbs_in_cavas[cell_indices[i]]) > 0) + if (affected_cells.count(all_sidbs_in_canvas[cell_indices[i]]) > 0) { return true; } @@ -415,7 +418,7 @@ class design_sidb_gates_impl */ template [[nodiscard]] std::vector design_sidb_gates(const Lyt& skeleton, const std::vector& spec, - const design_sidb_gates_params& params = {}) noexcept + const design_sidb_gates_params>& params = {}) 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"); @@ -432,7 +435,7 @@ template detail::design_sidb_gates_impl p{skeleton, spec, params}; - if (params.design_mode == design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE) + if (params.design_mode == design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE) { return p.run_exhaustive_design(); } diff --git a/include/fiction/algorithms/simulation/sidb/is_operational.hpp b/include/fiction/algorithms/simulation/sidb/is_operational.hpp index aaa7a9f5f..bc89c75b1 100644 --- a/include/fiction/algorithms/simulation/sidb/is_operational.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_operational.hpp @@ -52,7 +52,7 @@ struct is_operational_params /** * The simulation parameters for the physical simulation of the ground state. */ - sidb_simulation_parameters simulation_parameter{}; + sidb_simulation_parameters phys_params{}; /** * The simulation engine to be used for the operational domain computation. */ @@ -115,7 +115,7 @@ class is_operational_impl ++simulator_invocations; // if positively charged SiDBs can occur, the SiDB layout is considered as non-operational - if (can_positive_charges_occur(*bii, parameters.simulation_parameter)) + if (can_positive_charges_occur(*bii, parameters.phys_params)) { return operational_status::NON_OPERATIONAL; } @@ -223,23 +223,23 @@ class is_operational_impl [[nodiscard]] sidb_simulation_result physical_simulation_of_layout(const bdl_input_iterator& bdl_iterator) noexcept { - assert(parameters.simulation_parameter.base == 2 && "base number is set to 3"); + assert(parameters.phys_params.base == 2 && "base number is set to 3"); if (parameters.sim_engine == sidb_simulation_engine::EXGS) { // perform an exhaustive ground state simulation - return exhaustive_ground_state_simulation(*bdl_iterator, parameters.simulation_parameter); + return exhaustive_ground_state_simulation(*bdl_iterator, parameters.phys_params); } if (parameters.sim_engine == sidb_simulation_engine::QUICKSIM) { // perform a heuristic simulation - const quicksim_params qs_params{parameters.simulation_parameter, 500, 0.6}; + const quicksim_params qs_params{parameters.phys_params, 500, 0.6}; return quicksim(*bdl_iterator, qs_params); } if (parameters.sim_engine == sidb_simulation_engine::QUICKEXACT) { // perform exact simulation const quickexact_params quickexact_params{ - parameters.simulation_parameter, fiction::quickexact_params::automatic_base_number_detection::OFF}; + parameters.phys_params, fiction::quickexact_params::automatic_base_number_detection::OFF}; return quickexact(*bdl_iterator, quickexact_params); } diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 8ac369b88..bf1e21102 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include // data types cannot properly be converted to bit field types @@ -805,6 +806,24 @@ constexpr coord_t to_siqad_coord(const CoordinateType& coord) noexcept } // namespace siqad +/** + * Converts offset coordinates to cube coordinates + * + * @param coord Offset coordinate to convert to a cube coordinate. + * @return Cube coordinate. + */ +constexpr cube::coord_t offset_to_cube_coord(const offset::ucoord_t& coord) noexcept +{ + assert(coord.x <= std::numeric_limits::max() && coord.y <= std::numeric_limits::max() && + coord.z <= std::numeric_limits::max() && "Coordinate is out-of-range and cannot be transformed"); + if (!coord.is_dead()) + { + return {static_cast(coord.x), static_cast(coord.y), static_cast(coord.z)}; + } + + return cube::coord_t{}; +} + /** * Computes the area of a given coordinate assuming its origin is (0, 0, 0). Calculates \f$ (|x| + 1) \cdot (|y| + 1) * \f$ by default. The exception is SiQAD coordinates, for which it computes \f$ (|x| + 1) \cdot (2 \cdot |y| + |z| + 1) diff --git a/include/fiction/technology/sidb_is_gate_design_impossible.hpp b/include/fiction/technology/sidb_is_gate_design_impossible.hpp index 50f446146..85de32bca 100644 --- a/include/fiction/technology/sidb_is_gate_design_impossible.hpp +++ b/include/fiction/technology/sidb_is_gate_design_impossible.hpp @@ -7,6 +7,7 @@ #include "fiction/algorithms/iter/bdl_input_iterator.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" +#include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/layouts/cell_level_layout.hpp" #include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/technology/sidb_defects.hpp" @@ -16,7 +17,17 @@ namespace fiction { - +struct is_gate_design_impossible_params +{ + /** + * All Parameters for physical SiDB simulations. + */ + sidb_simulation_parameters phys_params{}; + /** + * The simulation engine to be used for the operational domain computation. + */ + sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; +}; /** * This function assesses whether it is impossible to design an SiDB gate for a given truth table in the provided layout * due to atomic defects. @@ -33,45 +44,50 @@ namespace fiction * */ template -bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, const is_operational_params& params = {}) +bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, + const is_gate_design_impossible_params& params = {}) { 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"); assert(layout.num_pis() > 0 && "lyt needs input cells"); assert(layout.num_pos() > 0 && "lyt needs output cells"); - const auto bdl_pairs = detect_bdl_pairs(layout, sidb_technology::cell_type::OUTPUT, params.bdl_params); + const auto operation_params = is_operational_params{params.phys_params, params.sim_engine}; + + const auto bdl_pairs = detect_bdl_pairs(layout, sidb_technology::cell_type::OUTPUT, operation_params.bdl_params); - auto bdl_iter = bdl_input_iterator{layout, params.bdl_params}; + auto bdl_iter = bdl_input_iterator{layout, operation_params.bdl_params}; for (auto i = 0u; i < spec.front().num_bits(); ++i, ++bdl_iter) { - auto charge_lyt = charge_distribution_surface{layout, params.simulation_parameter}; + auto charge_lyt = charge_distribution_surface{layout, params.phys_params}; charge_lyt.assign_all_charge_states(sidb_charge_state::NEUTRAL); charge_lyt.update_after_charge_change(); - layout.foreach_sidb_defect( - [&charge_lyt](const auto& cd) - { - if (is_charged_defect(cd.second)) + if constexpr (has_get_sidb_defect_v) + { + layout.foreach_sidb_defect( + [&charge_lyt](const auto& cd) { - charge_lyt.add_sidb_defect_to_potential_landscape(cd.first, cd.second); - } - }); + if (is_charged_defect(cd.second)) + { + charge_lyt.add_sidb_defect_to_potential_landscape(cd.first, cd.second); + } + }); + } // this function checks if parts of the bdl pairs are already neutrally charged due to nearby charged atomic // defects. for (const auto& bdl : bdl_pairs) { - if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.simulation_parameter.mu_minus) > + if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.phys_params.mu_minus) > -physical_constants::POP_STABILITY_ERR) { return true; // the lower part can never be negatively charged. Thus, BDL property is not fulfilled // anymore } - if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.simulation_parameter.mu_minus) > + if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.phys_params.mu_minus) > -physical_constants::POP_STABILITY_ERR) { return true; // the upper part can never be negatively charged. Thus, BDL property is not fulfilled diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 587b9dd44..eb126bf29 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -10,11 +10,12 @@ #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" +#include "fiction/technology/sidb_is_gate_design_impossible.hpp" #include "fiction/technology/sidb_surface.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" +#include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" -#include "sidb_is_gate_design_impossible.hpp" #include #include @@ -92,18 +93,23 @@ class gate_design_exception : public std::exception /** * This struct encapsulates parameters for the on-the-fly SiDB gate library. + * + * @tparam Lyt Cell-level layout type. */ +template struct sidb_on_the_fly_gate_library_params { + sidb_surface defect_surface{}; /** * This struct holds parameters to design SiDB gates on-the-fly. */ - design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{24, 8, 1}, {34, 14, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT, - 1}; + design_sidb_gates_params> design_gate_params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{}, {}}, + 3, + sidb_simulation_engine::QUICKEXACT, + 1}; /** * This variable defines the number of canvas SiDBs dedicated to complex gates, such as crossing, double wire, * and half-adder. @@ -132,21 +138,17 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const sidb_surface& sidb_surface, - const Params& parameter = Params{}) + template + static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const Params& parameter = Params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); - static_assert(has_offset_ucoord_v || has_cube_coord_v, - "CellLyt must be either based on cube or offset coordinates"); + static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); @@ -158,8 +160,6 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( lyt, t, cell{0, 0}); - const auto absolute_cell_siqad = fiction::siqad::to_siqad_coord(absolute_cell); - const auto center_cell_siqad = fiction::siqad::to_siqad_coord(center_cell); try { @@ -169,13 +169,12 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library( - sidb_surface, - cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(ONE_IN_TWO_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, create_fan_out_tt(), parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, create_fan_out_tt(), parameter, p, t); } } } @@ -193,42 +192,39 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_TWO_OUT), - center_cell_siqad, absolute_cell_siqad, parameter); - - if (is_bestagon_gate_applicable( - cell_list_to_cell_level_layout(DOUBLE_WIRE), layout, - parameter.params, create_double_wire_tt())) + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_TWO_OUT), + center_cell, absolute_cell, parameter); + + if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(DOUBLE_WIRE), + create_double_wire_tt(), parameter)) { return DOUBLE_WIRE; } - auto complex_gate_param = parameter; - complex_gate_param.params.number_of_sidbs = parameter.canvas_sidb_complex_gates; + auto complex_gate_param = parameter; + complex_gate_param.design_gate_params.number_of_sidbs = + parameter.canvas_sidb_complex_gates; - return design_gate( - layout, create_double_wire_tt(), complex_gate_param.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, create_double_wire_tt(), complex_gate_param, p, t); } - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_TWO_OUT), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_TWO_OUT), + center_cell, absolute_cell, parameter); - if (is_bestagon_gate_applicable( - cell_list_to_cell_level_layout(CROSSING), layout, - parameter.params, create_crossing_wire_tt())) + if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(CROSSING), + create_crossing_wire_tt(), parameter)) { return CROSSING; } - auto complex_gate_param = parameter; - complex_gate_param.params.number_of_sidbs = parameter.canvas_sidb_complex_gates; + auto complex_gate_param = parameter; + complex_gate_param.design_gate_params.number_of_sidbs = parameter.canvas_sidb_complex_gates; - return design_gate( - layout, create_crossing_wire_tt(), complex_gate_param.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, create_crossing_wire_tt(), complex_gate_param, p, t); } const auto cell_list = ONE_IN_ONE_OUT_MAP.at(p); @@ -236,12 +232,11 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(cell_list), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = add_defect_to_skeleton(cell_list_to_cell_level_layout(cell_list), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } return EMPTY_GATE; } @@ -250,143 +245,132 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(ONE_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (mockturtle::has_is_and_v) { if (lyt.is_and(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (mockturtle::has_is_or_v) { if (lyt.is_or(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_nand_v) { if (lyt.is_nand(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_nor_v) { if (lyt.is_nor(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (mockturtle::has_is_xor_v) { if (lyt.is_xor(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_xnor_v) { if (lyt.is_xnor(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_ge_v) { if (lyt.is_ge(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_le_v) { if (lyt.is_le(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_gt_v) { if (lyt.is_gt(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } if constexpr (fiction::has_is_lt_v) { if (lyt.is_lt(n)) { - const auto layout = add_defect_to_skeleton( - sidb_surface, - cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell_siqad, absolute_cell_siqad, parameter); + const auto layout = + add_defect_to_skeleton(cell_list_to_cell_level_layout(TWO_IN_ONE_OUT_MAP.at(p)), + center_cell, absolute_cell, parameter); - return design_gate( - layout, std::vector{f}, parameter.params, p, t); + return design_gate, tt, CellLyt, GateLyt>( + layout, std::vector{f}, parameter, p, t); } } } @@ -405,6 +389,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, const sidb_surface& defect_lyt, - const Params& parameter, const std::vector& truth_table) + template + [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, const std::vector& truth_table, + const Params& parameter) { - auto defect_copy = defect_lyt.clone(); + auto defect_copy = parameter.defect_surface.clone(); const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(std::pair(0, 0)); bool is_bestagon_gate_applicable = true; @@ -445,9 +430,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(status == operational_status::OPERATIONAL); } @@ -463,9 +449,8 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library, gate_y_size()> result{}; - const auto all_cell = - all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); - uint64_t counter = 0; + const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); + uint64_t counter = 0; for (auto& row : result) { @@ -474,7 +459,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate design_gate(const Lyt& skeleton, const std::vector& t, - const design_sidb_gates_params& params, + template + [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton, const std::vector& spec, + const sidb_on_the_fly_gate_library_params& parameter, const port_list& p, const tile& tile) { - if (t == create_crossing_wire_tt() || t == create_double_wire_tt()) + const auto params = is_gate_design_impossible_params{parameter.design_gate_params.phys_params, + parameter.design_gate_params.sim_engine}; + if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) { - if (is_gate_design_impossible( - skeleton, t, is_operational_params{params.phys_params, sidb_simulation_engine::QUICKEXACT})) + if (is_gate_design_impossible(skeleton, spec, params)) { throw gate_design_exception(tile, create_id_tt(), p); } - const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); + const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameter.design_gate_params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, create_id_tt(), p); @@ -517,15 +503,14 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(tile, t.front(), p); + throw gate_design_exception(tile, spec.front(), p); } - const auto found_gate_layouts = design_sidb_gates(skeleton, t, params); + const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameter.design_gate_params); if (found_gate_layouts.empty()) { - throw gate_design_exception(tile, t.front(), p); + throw gate_design_exception(tile, spec.front(), p); } const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); return lyt; @@ -544,9 +529,8 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library::max(), std::numeric_limits::max()}}; - const auto all_cell = - all_sidbs_in_spanned_area({0, 0, 0}, to_siqad_coord(cell{gate_x_size() - 1, gate_y_size() - 1})); - uint64_t counter = 0; + const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); + uint64_t counter = 0; for (size_t i = 0; i < gate_y_size(); ++i) { @@ -582,39 +566,41 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - [[nodiscard]] static LytSkeleton - add_defect_to_skeleton(const sidb_surface& defect_surface, const LytSkeleton& skeleton, - const siqad::coord_t& center_cell_siqad, const siqad::coord_t& absolute_cell_siqad, - const sidb_on_the_fly_gate_library_params& params) + template + [[nodiscard]] static sidb_surface + add_defect_to_skeleton(const CellLyt& skeleton, const cell& center_cell, + const cell& absolute_cell, const Params& params) { - static_assert(has_offset_ucoord_v || has_cube_coord_v, - "CellLyt must be either based on cube or offset coordinates"); - static_assert(has_siqad_coord_v, "Lyt_skeleton does not have SiQAD coordinates"); - auto lyt_copy = LytSkeleton{skeleton.clone()}; - defect_surface.foreach_sidb_defect( - [&defect_surface, &lyt_copy, &skeleton, ¢er_cell_siqad, &absolute_cell_siqad, ¶ms](const auto& cd) + static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); + + const auto skeleton_in_cube_coordinates = + convert_offset_to_cube_coordinates(skeleton); + auto skeleton_with_defect_in_cube = sidb_surface{skeleton_in_cube_coordinates}; + + const auto center_cell_cube = offset_to_cube_coord(center_cell); + const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); + + params.defect_surface.foreach_sidb_defect( + [&skeleton_with_defect_in_cube, ¢er_cell_cube, &absolute_cell_cube, ¶ms](const auto& cd) { // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken // into account. - const auto defect_in_siqad = fiction::siqad::to_siqad_coord(cd.first); - if (sidb_nanometer_distance(sidb_cell_clk_lyt_siqad{}, defect_in_siqad, center_cell_siqad) < + const auto defect_in_cube = fiction::offset_to_cube_coord(cd.first); + if (sidb_nanometer_distance(sidb_cell_clk_lyt_cube{}, center_cell_cube, defect_in_cube) < params.influence_radius_charged_defects) { - const auto defect_position_in_siqad_coordinate = defect_in_siqad; - const auto relative_cell = defect_position_in_siqad_coordinate - absolute_cell_siqad; - lyt_copy.assign_sidb_defect(relative_cell, cd.second); + const auto relative_cell = defect_in_cube - absolute_cell_cube; + skeleton_with_defect_in_cube.assign_sidb_defect(relative_cell, cd.second); } }); - return lyt_copy; + return skeleton_with_defect_in_cube; } /** diff --git a/include/fiction/types.hpp b/include/fiction/types.hpp index c1e5415fe..3de2bef73 100644 --- a/include/fiction/types.hpp +++ b/include/fiction/types.hpp @@ -152,6 +152,9 @@ 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 sidb_cell_clk_lyt_cube = cell_level_layout>>; +using sidb_cell_clk_lyt_ptr_cube = std::shared_ptr; + using sidb_cell_clk_lyt_siqad = cell_level_layout>>; using sidb_cell_clk_lyt_siqad_ptr = std::shared_ptr; diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 243986cd2..04843612c 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -282,6 +282,36 @@ Lyt normalize_layout_coordinates(const Lyt& lyt) noexcept return lyt_new; } +/** + * Converts the offset coordinates of a given cell-level layout to cube coordinates. A new equivalent layout based on + * cube coordinates is returned. + * + * @tparam LytOffset Cell-level layout type based on`offset::ucoord_t`. + * @tparam LytCube Cell-level layout type based on`cube::coord_t`. + * @param lyt The layout that is to be converted is based on offset coordinates. + * @return A new equivalent layout based on cube coordinates. + */ +template +LytCube convert_offset_to_cube_coordinates(const LytOffset& 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"); + static_assert(has_offset_ucoord_v, "Lyt does not have offset coordinates"); + static_assert(has_cube_coord_v, "Lyt does not have cube coordinates"); + + LytCube lyt_new{{lyt.x(), (lyt.y())}, lyt.get_layout_name(), lyt.get_tile_size_x(), lyt.get_tile_size_y()}; + + lyt.foreach_cell( + [&lyt_new, &lyt](const auto& c) + { + lyt_new.assign_cell_type(offset_to_cube_coord(c), lyt.get_cell_type(c)); + lyt_new.assign_cell_mode(offset_to_cube_coord(c), lyt.get_cell_mode(c)); + lyt_new.assign_cell_name(offset_to_cube_coord(c), lyt.get_cell_name(c)); + }); + + return lyt_new; +} + /** * Converts the coordinates of a given cell-level layout to SiQAD coordinates. A new equivalent layout based on SiQAD * coordinates is returned. @@ -365,6 +395,7 @@ Lyt convert_to_fiction_coordinates(const sidb_cell_clk_lyt_siqad& lyt) noexcept return lyt_new; } + /** * Generates a random coordinate within the region spanned by two given coordinates. The two given coordinates form the * top left corner and the bottom right corner of the spanned region. @@ -453,8 +484,8 @@ template else { const auto total_cell_count = - static_cast(std::abs(static_cast(cell_nw.x) - static_cast(cell_se.x)) + 1) * - static_cast(std::abs(static_cast(cell_nw.y) - static_cast(cell_se.y)) + 1); + static_cast(std::abs(static_cast(cell_se.x) - static_cast(cell_nw.x)) + 1) * + static_cast(std::abs(static_cast(cell_se.y) - static_cast(cell_nw.y)) + 1); std::vector all_cells{}; all_cells.reserve(total_cell_count); diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index a7df7abc0..107cb1208 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -45,11 +46,12 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); @@ -58,14 +60,11 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); // using cube coordinates - const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params params_cube{ + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_cube{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_cube = design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); @@ -77,13 +76,12 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ // using offset coordinates const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params params_offset{ + const design_sidb_gates_params> params_offset{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), + 1, sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_offset = design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); @@ -117,11 +115,12 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - design_sidb_gates_params params{sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{4, 4, 0}, {14, 5, 1}}, - 1, - sidb_simulation_engine::EXGS}; + design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.28}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{4, 4, 0}, {14, 5, 1}}, + 1, + sidb_simulation_engine::EXGS}; SECTION("Exhaustive Generation") { @@ -131,7 +130,7 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ SECTION("Random Generation") { - params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; + params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); CHECK(!found_gate_layouts.empty()); } @@ -175,9 +174,9 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("generate original FO2") { - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{17, 11, 0}, {17, 11, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -195,9 +194,9 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("replace the output perturbers by equivalent negatively charged defects") { - const design_sidb_gates_params params{ + const design_sidb_gates_params params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{17, 11, 0}, {17, 11, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -256,11 +255,12 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") SECTION("Random Generation") { - const design_sidb_gates_params params{sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); REQUIRE(!found_gate_layouts.empty()); @@ -271,9 +271,9 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") { sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - const design_sidb_gates_params params{ + const design_sidb_gates_params params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, {{14, 6, 0}, {24, 12, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp index b76396b20..5723ff091 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp @@ -39,7 +39,7 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-gate-d SECTION("without defect") { CHECK(!is_gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); } SECTION("with defect") @@ -47,7 +47,7 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-gate-d lyt.assign_sidb_defect({12, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); lyt.assign_sidb_defect({11, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); CHECK(is_gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_operational_params{sidb_simulation_parameters{2, -0.28}})); + is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); } } @@ -100,7 +100,7 @@ TEST_CASE("Bestagon CROSSING gate", "[is-gate-design-impossible]") SECTION("without defect") { CHECK(!is_gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); } SECTION("with defect") @@ -108,6 +108,6 @@ TEST_CASE("Bestagon CROSSING gate", "[is-gate-design-impossible]") lyt.assign_sidb_defect({34, 18, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); lyt.assign_sidb_defect({34, 18, 1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); CHECK(is_gate_design_impossible(lyt, create_crossing_wire_tt(), - is_operational_params{sidb_simulation_parameters{2, -0.32}})); + is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); } } diff --git a/test/layouts/coordinates.cpp b/test/layouts/coordinates.cpp index 87a4c7038..a6eca327b 100644 --- a/test/layouts/coordinates.cpp +++ b/test/layouts/coordinates.cpp @@ -129,6 +129,31 @@ TEST_CASE("SiQAD coordinate conversion", "[coordinates]") CHECK(t5_fiction.y == -3); } +TEST_CASE("Offset to cube coordinate conversion", "[coordinates]") +{ + using offset = offset::ucoord_t; + + auto t = offset{}; + CHECK(t.is_dead()); + auto fiction_d = offset_to_cube_coord(t); + CHECK(fiction_d.is_dead()); + + auto t0 = offset{0, 0, 0}; + auto fiction_0 = offset_to_cube_coord(t0); + CHECK(!fiction_0.is_dead()); + + auto t1 = offset{1, 3, 1}; + auto t1_cube = offset_to_cube_coord(t1); + CHECK(t1_cube.x == t1.x); + CHECK(t1_cube.y == 3); + + auto t2 = offset{1, 2}; + auto t2_cube = offset_to_cube_coord(t2); + CHECK(t2_cube.x == t2.x); + CHECK(t2_cube.y == 2); + CHECK(t2_cube.z == 0); +} + TEMPLATE_TEST_CASE("Coordinate iteration", "[coordinates]", offset::ucoord_t, cube::coord_t, siqad::coord_t) { using lyt_t = cartesian_layout; diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 3a16d0e9d..ca5cec5e3 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -66,6 +66,64 @@ inline auto area_with_padding(const uint64_t& area, const T1& x, const T2& y) no return area + (static_cast(x) + 1) * ((static_cast(y) + 1) % 2ul); } +TEST_CASE("Convert offset::ucoord_t layout to cube::coord_t layout", "[layout-utils]") +{ + SECTION("empty layout") + { + const auto x = 10, y = 10; + + sidb_cell_clk_lyt lyt{{x, y}, "test"}; + + auto lyt_transformed = convert_offset_to_cube_coordinates(lyt); + + CHECK(lyt_transformed.is_empty()); + CHECK(lyt_transformed.area() == lyt.area()); + CHECK(lyt_transformed.get_layout_name() == lyt.get_layout_name()); + } + + SECTION("layout with one normal and one input cell") + { + const auto x = 5, y = 3; + + sidb_cell_clk_lyt lyt{{x, y}}; + + lyt.assign_cell_type({5, 3}, sidb_cell_clk_lyt::cell_type::NORMAL); + lyt.assign_cell_type({5, 1}, sidb_cell_clk_lyt::cell_type::INPUT); + + auto lyt_transformed = convert_offset_to_cube_coordinates(lyt); + + CHECK(lyt_transformed.num_cells() == 2); + CHECK(lyt_transformed.area() == lyt.area()); + CHECK(lyt_transformed.get_cell_type({5, 3}) == sidb_cell_clk_lyt_cube::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 1}) == sidb_cell_clk_lyt_cube::cell_type::INPUT); + } + + SECTION("layout with three cells") + { + const auto x = 5, y = 3; + + sidb_cell_clk_lyt lyt{{x, y}}; + + lyt.assign_cell_type({0, 0}, sidb_cell_clk_lyt::cell_type::NORMAL); + lyt.assign_cell_type({5, 3}, sidb_cell_clk_lyt::cell_type::INPUT); + lyt.assign_cell_type({5, 1}, sidb_cell_clk_lyt::cell_type::OUTPUT); + lyt.assign_cell_name({0, 0}, "normal cell"); + lyt.assign_cell_name({5, 3}, "input cell"); + lyt.assign_cell_name({5, 1}, "output cell"); + + auto lyt_transformed = convert_offset_to_cube_coordinates(lyt); + + CHECK(lyt_transformed.num_cells() == 3); + CHECK(lyt_transformed.area() == lyt.area()); + CHECK(lyt_transformed.get_cell_type({0, 0}) == sidb_cell_clk_lyt_cube::cell_type::NORMAL); + CHECK(lyt_transformed.get_cell_type({5, 3}) == sidb_cell_clk_lyt_cube::cell_type::INPUT); + CHECK(lyt_transformed.get_cell_type({5, 1}) == sidb_cell_clk_lyt_cube::cell_type::OUTPUT); + CHECK(lyt_transformed.get_cell_name({0, 0}) == "normal cell"); + CHECK(lyt_transformed.get_cell_name({5, 3}) == "input cell"); + CHECK(lyt_transformed.get_cell_name({5, 1}) == "output cell"); + } +} + TEMPLATE_TEST_CASE("Convert offset::ucoord_t layout to SiQAD coordinate layout", "[layout-utils]", sidb_cell_clk_lyt) { SECTION("empty layout") From 5037d2e4504b40aa1c37c338e41cc327fb60f87c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 Nov 2023 08:36:32 +0100 Subject: [PATCH 089/191] :art: small change. --- .../physical_design/apply_gate_library.hpp | 7 ++- .../sidb_on_the_fly_gate_library.hpp | 49 +++++++++++-------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 70c8b4b1a..ce89356bd 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -55,7 +55,7 @@ class apply_gate_library_impl * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. */ template - [[nodiscard]] CellLyt design_gates_on_the_fly(const Params& params) + [[nodiscard]] CellLyt run_parameterized_gate_library(const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar @@ -235,8 +235,7 @@ template , "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - static_assert(has_offset_ucoord_v || has_cube_coord_v, - "CellLyt must be either based on cube or offset coordinates"); + static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); static_assert(mockturtle::has_is_constant_v, "GateLyt does not implement the is_constant function"); static_assert(mockturtle::has_foreach_node_v, "GateLyt does not implement the foreach_node function"); @@ -245,7 +244,7 @@ template p{lyt}; - return p.template design_gates_on_the_fly(params); + return p.template run_parameterized_gate_library(params); } } // namespace fiction diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index eb126bf29..8adc8bc41 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -479,7 +479,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton, const std::vector& spec, @@ -578,29 +578,36 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library& center_cell, const cell& absolute_cell, const Params& params) { - static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); - - const auto skeleton_in_cube_coordinates = - convert_offset_to_cube_coordinates(skeleton); - auto skeleton_with_defect_in_cube = sidb_surface{skeleton_in_cube_coordinates}; + static_assert(has_offset_ucoord_v || has_cube_coord_v, + "CellLyt must be either based on cube or offset coordinates"); - const auto center_cell_cube = offset_to_cube_coord(center_cell); - const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); + if constexpr (has_cube_coord_v) + { + auto skeleton_with_defect = sidb_surface{skeleton}; - params.defect_surface.foreach_sidb_defect( - [&skeleton_with_defect_in_cube, ¢er_cell_cube, &absolute_cell_cube, ¶ms](const auto& cd) - { - // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken - // into account. - const auto defect_in_cube = fiction::offset_to_cube_coord(cd.first); - if (sidb_nanometer_distance(sidb_cell_clk_lyt_cube{}, center_cell_cube, defect_in_cube) < - params.influence_radius_charged_defects) + params.defect_surface.foreach_sidb_defect( + [&skeleton_with_defect, ¢er_cell, &absolute_cell, ¶ms](const auto& cd) { - const auto relative_cell = defect_in_cube - absolute_cell_cube; - skeleton_with_defect_in_cube.assign_sidb_defect(relative_cell, cd.second); - } - }); - return skeleton_with_defect_in_cube; + // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken + // into account. + const auto defect_in_cube = fiction::offset_to_cube_coord(cd.first); + if (sidb_nanometer_distance(sidb_cell_clk_lyt_cube{}, center_cell, defect_in_cube) < + params.influence_radius_charged_defects) + { + const auto relative_cell = defect_in_cube - absolute_cell; + skeleton_with_defect.assign_sidb_defect(relative_cell, cd.second); + } + }); + return skeleton_with_defect; + } + else + { + const auto skeleton_in_cube_coordinates = + convert_offset_to_cube_coordinates(skeleton); + const auto center_cell_cube = offset_to_cube_coord(center_cell); + const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); + return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, params); + } } /** From 4a2b37f18db7cfa05aef3b1a3bb618428aae40a3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 Nov 2023 15:19:43 +0100 Subject: [PATCH 090/191] :art: add termination condition. --- .../physical_design/design_sidb_gates.hpp | 46 +++++-- .../physical_design/design_sidb_gates.cpp | 121 +++++++++++------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 3f0205415..98cbebb1b 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -44,6 +44,20 @@ namespace fiction template struct design_sidb_gates_params { + /** + * Selector for the different termination conditions for the SiDB gate design process. + */ + enum class termination_condition + { + /** + * The design process is terminated when a valid SiDB gate design is found. + */ + SOLUTION_FOUND, + /** + * The design process ends after all possible combinations of SiDBs within the canvas are enumerated. + */ + ALL_COMBINATIONS_ENUMERATED + }; /** * Selector for the available design approaches. */ @@ -82,6 +96,12 @@ struct design_sidb_gates_params * The percentage of all combinations that are tested before the design process is canceled. */ double procentual_maximum_attemps = 1.0; + /** + * The design process is terminated after a valid SiDB gate design is found. + * + * @note This parameter has no effect unless the gate design is exhaustive. + */ + termination_condition termination_cond = termination_condition::ALL_COMBINATIONS_ENUMERATED; }; namespace detail @@ -104,7 +124,7 @@ class design_sidb_gates_impl skeleton_layout{skeleton}, truth_table{spec}, parameter{ps}, - all_sidbs_in_canvas{all_sidbs_in_spanned_area(parameter.canvas.first, parameter.canvas.second)} + all_sidbs_in_canvas{all_coordinates_in_spanned_area(parameter.canvas.first, parameter.canvas.second)} {} /** * Design gates exhaustively and in parallel. @@ -144,26 +164,28 @@ class design_sidb_gates_impl { for (const auto& comb : combination) { - if (!solution_found && !are_sidbs_too_close(comb, sidbs_affected_by_defects) && + if (!are_sidbs_too_close(comb, sidbs_affected_by_defects) && global_iteration_counter < static_cast(parameter.procentual_maximum_attemps * static_cast(total_comb))) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); - - if (!solution_found) + if (const auto [status, sim_calls] = + is_operational(layout_with_added_cells, truth_table, params_is_operational); + status == operational_status::OPERATIONAL) { - if (const auto [status, sim_calls] = - is_operational(layout_with_added_cells, truth_table, params_is_operational); - status == operational_status::OPERATIONAL) { - { - const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; - designed_gate_layouts.push_back(layout_with_added_cells); - } - solution_found = true; + const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; + designed_gate_layouts.push_back(layout_with_added_cells); } + solution_found = true; + } + if (solution_found && (parameter.termination_cond == + design_sidb_gates_params>::termination_condition::SOLUTION_FOUND)) + { + return; } + continue; } global_iteration_counter++; } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 107cb1208..d92ee97f5 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -46,50 +46,83 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - - // using cube coordinates - const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_cube{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts_cube = - design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); - - REQUIRE(found_gate_layouts_cube.size() == 1); - CHECK(found_gate_layouts_cube[0].num_cells() == 14); - CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == - layout::technology::NORMAL); - - // using offset coordinates - const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_offset{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), - 1, sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts_offset = - design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); - - REQUIRE(found_gate_layouts_offset.size() == 1); - CHECK(found_gate_layouts_offset[0].num_cells() == 14); - CHECK(found_gate_layouts_offset[0].get_cell_type( - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + SECTION("One cell in canvas") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + + // using cube coordinates + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_cube = + design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); + + REQUIRE(found_gate_layouts_cube.size() == 1); + CHECK(found_gate_layouts_cube[0].num_cells() == 14); + CHECK(found_gate_layouts_cube[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), + 1, sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_offset = + design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); + + REQUIRE(found_gate_layouts_offset.size() == 1); + CHECK(found_gate_layouts_offset[0].num_cells() == 14); + CHECK(found_gate_layouts_offset[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + } + SECTION("Four cells in canvas, design all gates") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {13, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 4); + } + SECTION("Four cells in canvas, design process is terminated after first solution is found") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT, + 1.0, + design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + } } TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") From e99c505a5a4a7a589dae8911427f266541678240 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 Nov 2023 17:35:41 +0100 Subject: [PATCH 091/191] :art: small fix. --- .../algorithms/physical_design/design_sidb_gates.hpp | 4 ++-- .../technology/sidb_on_the_fly_gate_library.hpp | 10 ++++++---- test/utils/layout_utils.cpp | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 98cbebb1b..823175762 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -303,11 +303,11 @@ class design_sidb_gates_impl /** * Parameters for the *SiDB Gate Designer*. */ - const design_sidb_gates_params& parameter; + design_sidb_gates_params parameter; /** * All cells within the canvas. */ - const std::vector all_sidbs_in_canvas; + std::vector all_sidbs_in_canvas; /** * Calculates all possible combinations of distributing the given number of SiDBs within a canvas * based on the provided parameters. It generates combinations of SiDB indices (representing the cell position in diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 8adc8bc41..0e761f6a2 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -449,8 +449,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library, gate_y_size()> result{}; - const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); - uint64_t counter = 0; + const auto all_cell = + all_coordinates_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); + uint64_t counter = 0; for (auto& row : result) { @@ -529,8 +530,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library::max(), std::numeric_limits::max()}}; - const auto all_cell = all_sidbs_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); - uint64_t counter = 0; + const auto all_cell = + all_coordinates_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); + uint64_t counter = 0; for (size_t i = 0; i < gate_y_size(); ++i) { diff --git a/test/utils/layout_utils.cpp b/test/utils/layout_utils.cpp index 5067309ae..3a10497d3 100644 --- a/test/utils/layout_utils.cpp +++ b/test/utils/layout_utils.cpp @@ -72,7 +72,7 @@ TEST_CASE("Convert offset::ucoord_t layout to cube::coord_t layout", "[layout-ut { const auto x = 10, y = 10; - sidb_cell_clk_lyt lyt{{x, y}, "test"}; + const sidb_cell_clk_lyt lyt{{x, y}, "test"}; auto lyt_transformed = convert_offset_to_cube_coordinates(lyt); From 9c661a73956888c72c7c9ad8cf958aaf9e8bd407 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 3 Dec 2023 11:26:55 +0100 Subject: [PATCH 092/191] :construction: trying to fix windows CI issue. --- .../physical_design/design_sidb_gates.cpp | 666 +++++++++--------- 1 file changed, 333 insertions(+), 333 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index d92ee97f5..6e367d541 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -1,334 +1,334 @@ +//// +//// Created by Jan Drewniok on 12.09.23. +//// // -// Created by Jan Drewniok on 12.09.23. -// - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace fiction; - -TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") -{ - - using layout = sidb_cell_clk_lyt_siqad; - using layout_cube = cell_level_layout>>; - using layout_offset = cell_level_layout>>; - - layout 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({20, 0, 0}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({18, 1, 0}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({6, 3, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 3, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({4, 2, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({16, 2, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({10, 9, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({10, 10, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({10, 12, 1}, sidb_technology::cell_type::NORMAL); - - CHECK(lyt.num_cells() == 13); - - SECTION("One cell in canvas") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - - // using cube coordinates - const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_cube{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts_cube = - design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); - - REQUIRE(found_gate_layouts_cube.size() == 1); - CHECK(found_gate_layouts_cube[0].num_cells() == 14); - CHECK(found_gate_layouts_cube[0].get_cell_type( - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); - - // using offset coordinates - const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_offset{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), - 1, sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts_offset = - design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); - - REQUIRE(found_gate_layouts_offset.size() == 1); - CHECK(found_gate_layouts_offset[0].num_cells() == 14); - CHECK(found_gate_layouts_offset[0].get_cell_type( - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); - } - SECTION("Four cells in canvas, design all gates") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {13, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 4); - } - SECTION("Four cells in canvas, design process is terminated after first solution is found") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT, - 1.0, - design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - } -} - -TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") -{ - using layout = sidb_cell_clk_lyt_siqad; - - layout 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); - - lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - - design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{4, 4, 0}, {14, 5, 1}}, - 1, - sidb_simulation_engine::EXGS}; - - SECTION("Exhaustive Generation") - { - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - CHECK(!found_gate_layouts.empty()); - } - - SECTION("Random Generation") - { - params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - CHECK(!found_gate_layouts.empty()); - } -} - -TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") -{ - using layout = sidb_cell_clk_lyt_siqad; - - layout 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); - - // SiDB, originally part of the Bestagon fo2 gate, is excluded. - // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - - SECTION("generate original FO2") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); - - // generate gate by placing one SiDB - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 21); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); - } - - SECTION("replace the output perturbers by equivalent negatively charged defects") - { - const design_sidb_gates_params params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); - defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); - CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); - CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); - - defect_layout.assign_sidb_defect( - {36, 19, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, - params.phys_params.lambda_tf}); - - const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 19); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == - technology::cell_type::NORMAL); - } -} - -TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") -{ - using layout = sidb_cell_clk_lyt_siqad; - - layout lyt{}; - - lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - - SECTION("Random Generation") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - REQUIRE(!found_gate_layouts.empty()); - CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); - } - - SECTION("Random Generation with defects") - { - sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - - const design_sidb_gates_params params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - - defect_layout.assign_sidb_defect( - {15, 10, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect( - {20, 12, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); - - const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); - REQUIRE(!found_gate_layouts.empty()); - CHECK(found_gate_layouts.front().num_defects() == 3); - CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); - - found_gate_layouts.front().foreach_cell( - [](const auto& cell) - { - CHECK(cell != siqad::coord_t{15, 10, 0}); - CHECK(cell != siqad::coord_t{20, 12, 0}); - }); - } -} +//#include +// +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +//using namespace fiction; +// +//TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") +//{ +// +// using layout = sidb_cell_clk_lyt_siqad; +// using layout_cube = cell_level_layout>>; +// using layout_offset = cell_level_layout>>; +// +// layout 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({20, 0, 0}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({18, 1, 0}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({6, 3, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 3, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({4, 2, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({16, 2, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({10, 9, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({10, 10, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({10, 12, 1}, sidb_technology::cell_type::NORMAL); +// +// CHECK(lyt.num_cells() == 13); +// +// SECTION("One cell in canvas") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{10, 4, 0}, {10, 4, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 14); +// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); +// +// // using cube coordinates +// const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); +// const design_sidb_gates_params> params_cube{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts_cube = +// design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); +// +// REQUIRE(found_gate_layouts_cube.size() == 1); +// CHECK(found_gate_layouts_cube[0].num_cells() == 14); +// CHECK(found_gate_layouts_cube[0].get_cell_type( +// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); +// +// // using offset coordinates +// const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); +// const design_sidb_gates_params> params_offset{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), +// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), +// 1, sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts_offset = +// design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); +// +// REQUIRE(found_gate_layouts_offset.size() == 1); +// CHECK(found_gate_layouts_offset[0].num_cells() == 14); +// CHECK(found_gate_layouts_offset[0].get_cell_type( +// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); +// } +// SECTION("Four cells in canvas, design all gates") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{10, 4, 0}, {13, 4, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 4); +// } +// SECTION("Four cells in canvas, design process is terminated after first solution is found") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{10, 4, 0}, {10, 4, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT, +// 1.0, +// design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 14); +// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); +// } +//} +// +//TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") +//{ +// using layout = sidb_cell_clk_lyt_siqad; +// +// layout 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); +// +// lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); +// +// design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.28}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{4, 4, 0}, {14, 5, 1}}, +// 1, +// sidb_simulation_engine::EXGS}; +// +// SECTION("Exhaustive Generation") +// { +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// CHECK(!found_gate_layouts.empty()); +// } +// +// SECTION("Random Generation") +// { +// params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// CHECK(!found_gate_layouts.empty()); +// } +//} +// +//TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") +//{ +// using layout = sidb_cell_clk_lyt_siqad; +// +// layout 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); +// +// // SiDB, originally part of the Bestagon fo2 gate, is excluded. +// // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); +// +// SECTION("generate original FO2") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{17, 11, 0}, {17, 11, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); +// +// // generate gate by placing one SiDB +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 21); +// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); +// } +// +// SECTION("replace the output perturbers by equivalent negatively charged defects") +// { +// const design_sidb_gates_params params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, +// {{17, 11, 0}, {17, 11, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; +// defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); +// defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); +// CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); +// CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); +// +// defect_layout.assign_sidb_defect( +// {36, 19, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, +// params.phys_params.lambda_tf}); +// +// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 19); +// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == +// technology::cell_type::NORMAL); +// } +//} +// +//TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") +//{ +// using layout = sidb_cell_clk_lyt_siqad; +// +// layout lyt{}; +// +// lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); +// +// SECTION("Random Generation") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, +// {{14, 6, 0}, {24, 12, 0}}, +// 3, +// sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// REQUIRE(!found_gate_layouts.empty()); +// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); +// } +// +// SECTION("Random Generation with defects") +// { +// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; +// +// const design_sidb_gates_params params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params::design_sidb_gates_mode::RANDOM, +// {{14, 6, 0}, {24, 12, 0}}, +// 3, +// sidb_simulation_engine::QUICKEXACT}; +// +// defect_layout.assign_sidb_defect( +// {15, 10, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect( +// {20, 12, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); +// +// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); +// REQUIRE(!found_gate_layouts.empty()); +// CHECK(found_gate_layouts.front().num_defects() == 3); +// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); +// +// found_gate_layouts.front().foreach_cell( +// [](const auto& cell) +// { +// CHECK(cell != siqad::coord_t{15, 10, 0}); +// CHECK(cell != siqad::coord_t{20, 12, 0}); +// }); +// } +//} From faa55709e0245af886f57eca881272ff76d1c9d5 Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Sun, 3 Dec 2023 10:28:24 +0000 Subject: [PATCH 093/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../physical_design/design_sidb_gates.cpp | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 6e367d541..47edd4ae5 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -2,20 +2,20 @@ //// Created by Jan Drewniok on 12.09.23. //// // -//#include +// #include // -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include // -//using namespace fiction; +// using namespace fiction; // -//TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") +// TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") //{ // // using layout = sidb_cell_clk_lyt_siqad; @@ -125,7 +125,7 @@ // } //} // -//TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") +// TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") //{ // using layout = sidb_cell_clk_lyt_siqad; // @@ -169,7 +169,7 @@ // } //} // -//TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") +// TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") //{ // using layout = sidb_cell_clk_lyt_siqad; // @@ -237,16 +237,19 @@ // sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; // defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); // defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); -// CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); -// CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); +// CHECK(defect_layout.get_cell_type({36, 19, 0}) == +// technology::cell_type::EMPTY); CHECK(defect_layout.get_cell_type({2, 19, 0}) +// == technology::cell_type::EMPTY); // // defect_layout.assign_sidb_defect( // {36, 19, 0}, // sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, +// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, +// params.phys_params.epsilon_r, // params.phys_params.lambda_tf}); // -// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); +// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, +// params); // // REQUIRE(found_gate_layouts.size() == 1); // CHECK(found_gate_layouts[0].num_cells() == 19); @@ -255,7 +258,7 @@ // } //} // -//TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") +// TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") //{ // using layout = sidb_cell_clk_lyt_siqad; // From 93afb115a7c0fc7595b209b1437854d4e6784a82 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 3 Dec 2023 11:29:51 +0100 Subject: [PATCH 094/191] :construction: trying to fix windows CI issue. --- .../physical_design/design_sidb_gates.cpp | 641 +++++++++--------- 1 file changed, 322 insertions(+), 319 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 6e367d541..54c0319a4 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -1,334 +1,337 @@ -//// -//// Created by Jan Drewniok on 12.09.23. -//// // -//#include -// -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -// -//using namespace fiction; -// -//TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") -//{ -// -// using layout = sidb_cell_clk_lyt_siqad; -// using layout_cube = cell_level_layout>>; -// using layout_offset = cell_level_layout>>; -// -// layout 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({20, 0, 0}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({18, 1, 0}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({6, 3, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 3, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({4, 2, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({16, 2, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({10, 9, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({10, 10, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({10, 12, 1}, sidb_technology::cell_type::NORMAL); -// -// CHECK(lyt.num_cells() == 13); -// -// SECTION("One cell in canvas") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {10, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 14); -// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); -// -// // using cube coordinates -// const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); -// const design_sidb_gates_params> params_cube{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts_cube = -// design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); -// -// REQUIRE(found_gate_layouts_cube.size() == 1); -// CHECK(found_gate_layouts_cube[0].num_cells() == 14); -// CHECK(found_gate_layouts_cube[0].get_cell_type( -// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); -// -// // using offset coordinates -// const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); -// const design_sidb_gates_params> params_offset{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), -// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), -// 1, sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts_offset = -// design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); -// -// REQUIRE(found_gate_layouts_offset.size() == 1); -// CHECK(found_gate_layouts_offset[0].num_cells() == 14); -// CHECK(found_gate_layouts_offset[0].get_cell_type( -// siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); -// } -// SECTION("Four cells in canvas, design all gates") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {13, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 4); -// } -// SECTION("Four cells in canvas, design process is terminated after first solution is found") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {10, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT, -// 1.0, -// design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 14); -// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); -// } -//} -// -//TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") +// Created by Jan Drewniok on 12.09.23. +// + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") +{ + + using layout = sidb_cell_clk_lyt_siqad; + using layout_cube = cell_level_layout>>; + using layout_offset = cell_level_layout>>; + + layout 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({20, 0, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({18, 1, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({6, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 3, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({4, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({16, 2, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({10, 9, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({10, 10, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({10, 12, 1}, sidb_technology::cell_type::NORMAL); + + CHECK(lyt.num_cells() == 13); + + SECTION("One cell in canvas") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + + // using cube coordinates + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_cube = + design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); + + REQUIRE(found_gate_layouts_cube.size() == 1); + CHECK(found_gate_layouts_cube[0].num_cells() == 14); + CHECK(found_gate_layouts_cube[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), + 1, sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts_offset = + design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); + + REQUIRE(found_gate_layouts_offset.size() == 1); + CHECK(found_gate_layouts_offset[0].num_cells() == 14); + CHECK(found_gate_layouts_offset[0].get_cell_type( + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + } + SECTION("Four cells in canvas, design all gates") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {13, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 4); + } + SECTION("Four cells in canvas, design process is terminated after first solution is found") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT, + 1.0, + design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + } +} + +// TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") //{ -// using layout = sidb_cell_clk_lyt_siqad; +// using layout = sidb_cell_clk_lyt_siqad; // -// layout lyt{}; +// layout 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); +// lyt.assign_cell_type({0, 0, 1}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({2, 1, 1}, sidb_technology::cell_type::INPUT); // -// lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); // -// lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); // -// lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); // -// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); // -// lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); // -// design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.28}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{4, 4, 0}, {14, 5, 1}}, -// 1, -// sidb_simulation_engine::EXGS}; +// design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.28}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{4, 4, 0}, {14, 5, 1}}, +// 1, +// sidb_simulation_engine::EXGS}; // -// SECTION("Exhaustive Generation") -// { -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// CHECK(!found_gate_layouts.empty()); -// } +// SECTION("Exhaustive Generation") +// { +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// CHECK(!found_gate_layouts.empty()); +// } // -// SECTION("Random Generation") -// { -// params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// CHECK(!found_gate_layouts.empty()); -// } -//} +// SECTION("Random Generation") +// { +// params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// CHECK(!found_gate_layouts.empty()); +// } +// } // -//TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") +// TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") //{ -// using layout = sidb_cell_clk_lyt_siqad; -// -// layout 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); -// -// // SiDB, originally part of the Bestagon fo2 gate, is excluded. -// // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); -// -// SECTION("generate original FO2") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{17, 11, 0}, {17, 11, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); -// -// // generate gate by placing one SiDB -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 21); -// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); -// } -// -// SECTION("replace the output perturbers by equivalent negatively charged defects") -// { -// const design_sidb_gates_params params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, -// {{17, 11, 0}, {17, 11, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; -// defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); -// defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); -// CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); -// CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); -// -// defect_layout.assign_sidb_defect( -// {36, 19, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, -// params.phys_params.lambda_tf}); -// -// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 19); -// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == -// technology::cell_type::NORMAL); -// } -//} -// -//TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") +// using layout = sidb_cell_clk_lyt_siqad; +// +// layout 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); +// +// // SiDB, originally part of the Bestagon fo2 gate, is excluded. +// // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); +// +// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); +// +// SECTION("generate original FO2") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{17, 11, 0}, {17, 11, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); +// +// // generate gate by placing one SiDB +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 21); +// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); +// } +// +// SECTION("replace the output perturbers by equivalent negatively charged defects") +// { +// const design_sidb_gates_params params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, +// {{17, 11, 0}, {17, 11, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; +// defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); +// defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); +// CHECK(defect_layout.get_cell_type({36, 19, 0}) == +// technology::cell_type::EMPTY); CHECK(defect_layout.get_cell_type({2, 19, 0}) +// == technology::cell_type::EMPTY); +// +// defect_layout.assign_sidb_defect( +// {36, 19, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, +// params.phys_params.epsilon_r, +// params.phys_params.lambda_tf}); +// +// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, +// params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 19); +// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == +// technology::cell_type::NORMAL); +// } +// } +// +// TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") //{ -// using layout = sidb_cell_clk_lyt_siqad; -// -// layout lyt{}; -// -// lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); -// -// SECTION("Random Generation") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, -// {{14, 6, 0}, {24, 12, 0}}, -// 3, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// REQUIRE(!found_gate_layouts.empty()); -// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); -// } -// -// SECTION("Random Generation with defects") -// { -// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; -// -// const design_sidb_gates_params params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params::design_sidb_gates_mode::RANDOM, -// {{14, 6, 0}, {24, 12, 0}}, -// 3, -// sidb_simulation_engine::QUICKEXACT}; -// -// defect_layout.assign_sidb_defect( -// {15, 10, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect( -// {20, 12, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); -// -// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); -// REQUIRE(!found_gate_layouts.empty()); -// CHECK(found_gate_layouts.front().num_defects() == 3); -// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); -// -// found_gate_layouts.front().foreach_cell( -// [](const auto& cell) -// { -// CHECK(cell != siqad::coord_t{15, 10, 0}); -// CHECK(cell != siqad::coord_t{20, 12, 0}); -// }); -// } -//} +// using layout = sidb_cell_clk_lyt_siqad; +// +// layout lyt{}; +// +// lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); +// lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); +// +// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); +// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); +// +// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); +// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); +// +// SECTION("Random Generation") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, +// {{14, 6, 0}, {24, 12, 0}}, +// 3, +// sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); +// REQUIRE(!found_gate_layouts.empty()); +// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); +// } +// +// SECTION("Random Generation with defects") +// { +// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; +// +// const design_sidb_gates_params params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params::design_sidb_gates_mode::RANDOM, +// {{14, 6, 0}, {24, 12, 0}}, +// 3, +// sidb_simulation_engine::QUICKEXACT}; +// +// defect_layout.assign_sidb_defect( +// {15, 10, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect( +// {20, 12, 0}, +// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); +// defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); +// +// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); +// REQUIRE(!found_gate_layouts.empty()); +// CHECK(found_gate_layouts.front().num_defects() == 3); +// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); +// +// found_gate_layouts.front().foreach_cell( +// [](const auto& cell) +// { +// CHECK(cell != siqad::coord_t{15, 10, 0}); +// CHECK(cell != siqad::coord_t{20, 12, 0}); +// }); +// } +// } From 8a37c183ce1a308a1010fa68b613a3fa90ceba70 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 3 Dec 2023 11:49:40 +0100 Subject: [PATCH 095/191] :construction: trying to fix windows CI issue. --- .../physical_design/design_sidb_gates.cpp | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 54c0319a4..6532d2767 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -17,7 +17,6 @@ using namespace fiction; TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; using layout_cube = cell_level_layout>>; using layout_offset = cell_level_layout>>; @@ -93,36 +92,36 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_offset[0].get_cell_type( siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } - SECTION("Four cells in canvas, design all gates") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {13, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 4); - } - SECTION("Four cells in canvas, design process is terminated after first solution is found") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT, - 1.0, - design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - } +// SECTION("Four cells in canvas, design all gates") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{10, 4, 0}, {13, 4, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 4); +// } +// SECTION("Four cells in canvas, design process is terminated after first solution is found") +// { +// const design_sidb_gates_params> params{ +// sidb_simulation_parameters{2, -0.32}, +// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, +// {{10, 4, 0}, {10, 4, 0}}, +// 1, +// sidb_simulation_engine::QUICKEXACT, +// 1.0, +// design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; +// +// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); +// +// REQUIRE(found_gate_layouts.size() == 1); +// CHECK(found_gate_layouts[0].num_cells() == 14); +// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); +// } } // TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") From 68d50e9967904d4f37c4a9cf90cd31d096324a7e Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Sun, 3 Dec 2023 10:50:46 +0000 Subject: [PATCH 096/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../physical_design/design_sidb_gates.cpp | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 6532d2767..ed4d85096 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -92,36 +92,36 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_offset[0].get_cell_type( siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } -// SECTION("Four cells in canvas, design all gates") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {13, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 4); -// } -// SECTION("Four cells in canvas, design process is terminated after first solution is found") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {10, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT, -// 1.0, -// design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 14); -// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); -// } + // SECTION("Four cells in canvas, design all gates") + // { + // const design_sidb_gates_params> params{ + // sidb_simulation_parameters{2, -0.32}, + // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + // {{10, 4, 0}, {13, 4, 0}}, + // 1, + // sidb_simulation_engine::QUICKEXACT}; + // + // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + // + // REQUIRE(found_gate_layouts.size() == 4); + // } + // SECTION("Four cells in canvas, design process is terminated after first solution is found") + // { + // const design_sidb_gates_params> params{ + // sidb_simulation_parameters{2, -0.32}, + // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + // {{10, 4, 0}, {10, 4, 0}}, + // 1, + // sidb_simulation_engine::QUICKEXACT, + // 1.0, + // design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + // + // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + // + // REQUIRE(found_gate_layouts.size() == 1); + // CHECK(found_gate_layouts[0].num_cells() == 14); + // CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + // } } // TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") From a54c86e0dcbd9a674588df615eada70f19dffb20 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 3 Dec 2023 11:52:11 +0100 Subject: [PATCH 097/191] :construction: trying to fix windows CI issue. --- .../physical_design/design_sidb_gates.cpp | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 6532d2767..b3d326281 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -47,9 +47,9 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ SECTION("One cell in canvas") { - const design_sidb_gates_params> params{ + const design_sidb_gates_params params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -62,9 +62,9 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ // using cube coordinates const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_cube{ + const design_sidb_gates_params params_cube{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, std::make_pair(cube::coord_t{10, 8, 0}, cube::coord_t{10, 8, 0}), 1, sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_cube = @@ -77,9 +77,9 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ // using offset coordinates const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_offset{ + const design_sidb_gates_params params_offset{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, std::make_pair(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})), 1, sidb_simulation_engine::QUICKEXACT}; @@ -92,36 +92,36 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_offset[0].get_cell_type( siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } -// SECTION("Four cells in canvas, design all gates") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {13, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 4); -// } -// SECTION("Four cells in canvas, design process is terminated after first solution is found") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{10, 4, 0}, {10, 4, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT, -// 1.0, -// design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 14); -// CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); -// } + // SECTION("Four cells in canvas, design all gates") + // { + // const design_sidb_gates_params> params{ + // sidb_simulation_parameters{2, -0.32}, + // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + // {{10, 4, 0}, {13, 4, 0}}, + // 1, + // sidb_simulation_engine::QUICKEXACT}; + // + // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + // + // REQUIRE(found_gate_layouts.size() == 4); + // } + // SECTION("Four cells in canvas, design process is terminated after first solution is found") + // { + // const design_sidb_gates_params> params{ + // sidb_simulation_parameters{2, -0.32}, + // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + // {{10, 4, 0}, {10, 4, 0}}, + // 1, + // sidb_simulation_engine::QUICKEXACT, + // 1.0, + // design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + // + // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + // + // REQUIRE(found_gate_layouts.size() == 1); + // CHECK(found_gate_layouts[0].num_cells() == 14); + // CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + // } } // TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") From c95d8ebf8714bdd91e07f4075f620d44398844cf Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 5 Dec 2023 15:56:49 +0100 Subject: [PATCH 098/191] :art: implement the first batch. --- docs/technology/simulation.rst | 10 + .../physical_design/design_sidb_gates.hpp | 82 +-- ...hpp => is_sidb_gate_design_impossible.hpp} | 23 +- .../sidb_on_the_fly_gate_library.hpp | 28 +- .../physical_design/design_sidb_gates.cpp | 480 +++++++++--------- .../is_sidb_gate_design_impossible.cpp} | 5 +- 6 files changed, 331 insertions(+), 297 deletions(-) rename include/fiction/technology/{sidb_is_gate_design_impossible.hpp => is_sidb_gate_design_impossible.hpp} (84%) rename test/{algorithms/simulation/sidb/is_gate_design_impossible.cpp => technology/is_sidb_gate_design_impossible.cpp} (97%) diff --git a/docs/technology/simulation.rst b/docs/technology/simulation.rst index a83d44673..0b4dcdd48 100644 --- a/docs/technology/simulation.rst +++ b/docs/technology/simulation.rst @@ -32,6 +32,16 @@ distributions of the SiDBs. Charge distribution surfaces are returned by the SiD :members: +SiDB Gate design is deemed impossible +------------------------------------- + +**Header:** ``fiction/technology/is_sidb_gate_design_impossible.hpp`` + +.. doxygenstruct:: fiction::is_gate_design_impossible_params + :members: +.. doxygenfunction:: fiction::is_sidb_gate_design_impossible + + Physical Constants ------------------ diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 823175762..1f4c860ed 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -123,8 +123,8 @@ class design_sidb_gates_impl const design_sidb_gates_params>& ps) : skeleton_layout{skeleton}, truth_table{spec}, - parameter{ps}, - all_sidbs_in_canvas{all_coordinates_in_spanned_area(parameter.canvas.first, parameter.canvas.second)} + params{ps}, + all_sidbs_in_canvas{all_coordinates_in_spanned_area(params.canvas.first, params.canvas.second)} {} /** * Design gates exhaustively and in parallel. @@ -136,7 +136,7 @@ class design_sidb_gates_impl */ [[nodiscard]] std::vector run_exhaustive_design() noexcept { - const is_operational_params params_is_operational{parameter.phys_params, parameter.sim_engine}; + const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; auto all_combinations = determine_all_combinations_of_given_sidbs_in_canvas(); std::unordered_set sidbs_affected_by_defects = {}; @@ -151,7 +151,7 @@ class design_sidb_gates_impl std::atomic solution_found = false; std::atomic global_iteration_counter(0); - const auto total_comb = binomial_coefficient(all_sidbs_in_canvas.size(), parameter.number_of_sidbs); + const auto total_comb = binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs); // Shuffle the combinations before dividing them among threads std::shuffle(all_combinations.begin(), all_combinations.end(), @@ -164,9 +164,9 @@ class design_sidb_gates_impl { for (const auto& comb : combination) { - if (!are_sidbs_too_close(comb, sidbs_affected_by_defects) && + if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects) && global_iteration_counter < - static_cast(parameter.procentual_maximum_attemps * static_cast(total_comb))) + static_cast(params.procentual_maximum_attemps * static_cast(total_comb))) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -180,7 +180,7 @@ class design_sidb_gates_impl } solution_found = true; } - if (solution_found && (parameter.termination_cond == + if (solution_found && (params.termination_cond == design_sidb_gates_params>::termination_condition::SOLUTION_FOUND)) { return; @@ -191,18 +191,18 @@ class design_sidb_gates_impl } }; - const uint64_t num_threads = std::thread::hardware_concurrency(); - const std::size_t chunk_size = all_combinations.size() / num_threads; + const auto num_threads = std::thread::hardware_concurrency(); + const auto chunk_size = all_combinations.size() / num_threads; - std::vector threads; + std::vector threads{}; threads.reserve(num_threads); for (auto i = 0u; i < num_threads; ++i) { - const std::size_t start = i * chunk_size; - const std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; - std::vector> chunk_combinations(all_combinations.begin() + start, - all_combinations.begin() + end); + const auto start = i * chunk_size; + const auto end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; + std::vector> chunk_combinations(all_combinations.cbegin() + start, + all_combinations.cbegin() + end); threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); } @@ -225,10 +225,10 @@ class design_sidb_gates_impl { std::vector randomly_designed_gate_layouts = {}; - const is_operational_params params_is_operational{parameter.phys_params, parameter.sim_engine}; + const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; const generate_random_sidb_layout_params parameter_random_layout{ - parameter.canvas, parameter.number_of_sidbs, + params.canvas, params.number_of_sidbs, generate_random_sidb_layout_params::positive_charges::FORBIDDEN}; const std::size_t num_threads = std::thread::hardware_concurrency(); @@ -303,7 +303,7 @@ class design_sidb_gates_impl /** * Parameters for the *SiDB Gate Designer*. */ - design_sidb_gates_params parameter; + design_sidb_gates_params params; /** * All cells within the canvas. */ @@ -316,22 +316,23 @@ class design_sidb_gates_impl * * @return All possible combinations as a vector of vectors of indices. */ - [[nodiscard]] std::vector> determine_all_combinations_of_given_sidbs_in_canvas() noexcept + [[nodiscard]] std::vector> + determine_all_combinations_of_given_sidbs_in_canvas() const noexcept { std::vector> all_combinations{}; - all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), parameter.number_of_sidbs)); + all_combinations.reserve(binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs)); std::vector numbers(all_sidbs_in_canvas.size()); std::iota(numbers.begin(), numbers.end(), 0); combinations::for_each_combination( numbers.begin(), - numbers.begin() + static_cast::difference_type>(parameter.number_of_sidbs), + numbers.begin() + static_cast::difference_type>(params.number_of_sidbs), numbers.end(), [this, &all_combinations](const auto begin, const auto end) { std::vector combination{}; - combination.reserve(parameter.number_of_sidbs); + combination.reserve(params.number_of_sidbs); for (auto it = begin; it != end; ++it) { @@ -353,31 +354,30 @@ class design_sidb_gates_impl * pair of SiDBs within a distance of 0.5 nanometers, it returns `true` to indicate that SiDBs are too close; * otherwise, it returns `false`. * - * @param cell_indices A vector of cell indices to check for SiDB proximity. + * @param cells A vector of cells to check for proximity. * @tparam affected_cells All SiDBs that are affected by atomic defects. * @return `true` if any SiDBs are too close; otherwise, `false`. */ - [[nodiscard]] bool are_sidbs_too_close(const std::vector& cell_indices, - const std::unordered_set& affected_cells = {}) noexcept + [[nodiscard]] bool + are_sidbs_too_close(const std::vector& cells, + const std::unordered_set& affected_cells = {}) const noexcept { - for (std::size_t i = 0; i < cell_indices.size(); i++) + for (std::size_t i = 0; i < cells.size(); i++) { if constexpr (has_get_sidb_defect_v) { - if (skeleton_layout.get_sidb_defect(all_sidbs_in_canvas[cell_indices[i]]).type != - sidb_defect_type::NONE) + if (skeleton_layout.get_sidb_defect(cells[i]).type != sidb_defect_type::NONE) { return true; } } - if (affected_cells.count(all_sidbs_in_canvas[cell_indices[i]]) > 0) + if (affected_cells.count(cells[i]) > 0) { return true; } - for (std::size_t j = i + 1; j < cell_indices.size(); j++) + for (std::size_t j = i + 1; j < cells.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, all_sidbs_in_canvas[cell_indices[i]], - all_sidbs_in_canvas[cell_indices[j]]) < 0.5) + if (sidb_nanometer_distance(skeleton_layout, cells[i], cells[j]) < 0.5) { return true; } @@ -391,7 +391,7 @@ class design_sidb_gates_impl * @param cell_indices A vector of indices of cells to be added to the skeleton layout. * @return A copy of the original layout (`skeleton_layout`) with SiDB cells added at specified indices. */ - [[nodiscard]] Lyt skeleton_layout_with_canvas_sidbs(const std::vector& cell_indices) noexcept + [[nodiscard]] Lyt skeleton_layout_with_canvas_sidbs(const std::vector& cell_indices) const noexcept { Lyt lyt_copy{skeleton_layout.clone()}; @@ -407,6 +407,24 @@ class design_sidb_gates_impl return lyt_copy; } + /** + * Converts a vector of cell indices to a vector of corresponding cells in the layout. + * + * @param cell_indices Vector of cell indices to convert. + * @return A vector of cells corresponding to the given indices. + */ + [[nodiscard]] std::vector + cell_indices_to_cell_vector(const std::vector& cell_indices) const noexcept + { + std::vector cells{}; + cells.reserve(cell_indices.size()); + for (const auto index : cell_indices) + { + assert(index < all_sidbs_in_canvas.size() && "Cell index is out of range."); + cells.push_back(all_sidbs_in_canvas[index]); + } + return cells; + } }; } // namespace detail diff --git a/include/fiction/technology/sidb_is_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp similarity index 84% rename from include/fiction/technology/sidb_is_gate_design_impossible.hpp rename to include/fiction/technology/is_sidb_gate_design_impossible.hpp index 85de32bca..56d3da468 100644 --- a/include/fiction/technology/sidb_is_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -2,8 +2,8 @@ // Created by Jan Drewniok on 25.10.23. // -#ifndef FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP -#define FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#ifndef FICTION_IS_SIDB_GATE_DESIGN_IMPOSSIBLE_HPP +#define FICTION_IS_SIDB_GATE_DESIGN_IMPOSSIBLE_HPP #include "fiction/algorithms/iter/bdl_input_iterator.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" @@ -17,14 +17,17 @@ namespace fiction { +/** + * This struct contains parameters to determine if SiDB gate design is impossible. + */ struct is_gate_design_impossible_params { /** - * All Parameters for physical SiDB simulations. + * All parameters for physical SiDB simulations. */ sidb_simulation_parameters phys_params{}; /** - * The simulation engine to be used for the operational domain computation. + * The simulation engine to be used for simulation. */ sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; }; @@ -32,14 +35,11 @@ struct is_gate_design_impossible_params * This function assesses whether it is impossible to design an SiDB gate for a given truth table in the provided layout * due to atomic defects. * - * @note If the function returns `false`, it does not imply that it is possible to design an SiDB gate for given - * parameters. - * - * @tparam Lyt The type of the layout. + * @tparam Lyt Cell-level layout type. * @tparam TT The type of the truth table. * @param layout The layout for which gate design feasibility is being checked. * @param spec A vector of truth tables representing the gate's functionality. - * @param params Parameter for the simulation. + * @param params Parameter to determine if the gate design is impossible. * @return `true` if gate design is impossible, `false` otherwise. * */ @@ -77,8 +77,7 @@ bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, }); } - // this function checks if parts of the bdl pairs are already neutrally charged due to nearby charged atomic - // defects. + // checks if parts of the bdl pairs are already neutrally charged due to nearby charged atomic defects. for (const auto& bdl : bdl_pairs) { if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.phys_params.mu_minus) > @@ -100,4 +99,4 @@ bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, } // namespace fiction -#endif // FICTION_SIDB_IS_GATE_DESIGN_IMPOSSIBLE_HPP +#endif // FICTION_IS_SIDB_GATE_DESIGN_IMPOSSIBLE_HPP diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 0e761f6a2..4f0c2ba21 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -10,7 +10,7 @@ #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" -#include "fiction/technology/sidb_is_gate_design_impossible.hpp" +#include "fiction/technology/is_sidb_gate_design_impossible.hpp" #include "fiction/technology/sidb_surface.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" @@ -99,6 +99,9 @@ class gate_design_exception : public std::exception template struct sidb_on_the_fly_gate_library_params { + /** + * This layout stores all atomic defects. + */ sidb_surface defect_surface{}; /** * This struct holds parameters to design SiDB gates on-the-fly. @@ -453,9 +456,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library{gate_x_size() - 1, gate_y_size() - 1}); uint64_t counter = 0; - for (auto& row : result) + for (const auto& row : result) { - for (auto& cell : row) + for (const auto& cell : row) { const auto cell_type = lyt.get_cell_type(all_cell[counter]); cell = (cell_type == Lyt::technology::cell_type::NORMAL || @@ -479,7 +482,6 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library @@ -534,27 +536,33 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library{gate_x_size() - 1, gate_y_size() - 1}); uint64_t counter = 0; - for (size_t i = 0; i < gate_y_size(); ++i) + for (std::size_t i = 0; i < gate_y_size(); ++i) { - for (size_t j = 0; j < gate_x_size(); ++j) + for (std::size_t j = 0; j < gate_x_size(); ++j) { const auto cell = cell_list[i][j]; switch (cell) { case 'x': // normal cell + { lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::NORMAL); break; - + } case 'i': // input cell + { lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::INPUT); break; - + } case 'o': // output cell + { lyt.assign_cell_type(all_cell[counter], Lyt::technology::cell_type::OUTPUT); break; - - case ' ': break; + } + case ' ': + { + break; + } } counter += 1; } diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index b3d326281..0a4383a71 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -92,245 +92,245 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_offset[0].get_cell_type( siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } - // SECTION("Four cells in canvas, design all gates") - // { - // const design_sidb_gates_params> params{ - // sidb_simulation_parameters{2, -0.32}, - // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - // {{10, 4, 0}, {13, 4, 0}}, - // 1, - // sidb_simulation_engine::QUICKEXACT}; - // - // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - // - // REQUIRE(found_gate_layouts.size() == 4); - // } - // SECTION("Four cells in canvas, design process is terminated after first solution is found") - // { - // const design_sidb_gates_params> params{ - // sidb_simulation_parameters{2, -0.32}, - // design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - // {{10, 4, 0}, {10, 4, 0}}, - // 1, - // sidb_simulation_engine::QUICKEXACT, - // 1.0, - // design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; - // - // const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - // - // REQUIRE(found_gate_layouts.size() == 1); - // CHECK(found_gate_layouts[0].num_cells() == 14); - // CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - // } + SECTION("Four cells in canvas, design all gates") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {13, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 4); + } + SECTION("Four cells in canvas, design process is terminated after first solution is found") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT, + 1.0, + design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + } } -// TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") -//{ -// using layout = sidb_cell_clk_lyt_siqad; -// -// layout 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); -// -// lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); -// -// design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.28}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{4, 4, 0}, {14, 5, 1}}, -// 1, -// sidb_simulation_engine::EXGS}; -// -// SECTION("Exhaustive Generation") -// { -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// CHECK(!found_gate_layouts.empty()); -// } -// -// SECTION("Random Generation") -// { -// params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// CHECK(!found_gate_layouts.empty()); -// } -// } -// -// TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") -//{ -// using layout = sidb_cell_clk_lyt_siqad; -// -// layout 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); -// -// // SiDB, originally part of the Bestagon fo2 gate, is excluded. -// // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); -// -// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); -// -// SECTION("generate original FO2") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, -// {{17, 11, 0}, {17, 11, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); -// -// // generate gate by placing one SiDB -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 21); -// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); -// } -// -// SECTION("replace the output perturbers by equivalent negatively charged defects") -// { -// const design_sidb_gates_params params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, -// {{17, 11, 0}, {17, 11, 0}}, -// 1, -// sidb_simulation_engine::QUICKEXACT}; -// -// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; -// defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); -// defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); -// CHECK(defect_layout.get_cell_type({36, 19, 0}) == -// technology::cell_type::EMPTY); CHECK(defect_layout.get_cell_type({2, 19, 0}) -// == technology::cell_type::EMPTY); -// -// defect_layout.assign_sidb_defect( -// {36, 19, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, -// params.phys_params.epsilon_r, -// params.phys_params.lambda_tf}); -// -// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, -// params); -// -// REQUIRE(found_gate_layouts.size() == 1); -// CHECK(found_gate_layouts[0].num_cells() == 19); -// CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == -// technology::cell_type::NORMAL); -// } -// } -// -// TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") -//{ -// using layout = sidb_cell_clk_lyt_siqad; -// -// layout lyt{}; -// -// lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); -// lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); -// -// lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); -// lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); -// -// lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); -// lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); -// -// SECTION("Random Generation") -// { -// const design_sidb_gates_params> params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, -// {{14, 6, 0}, {24, 12, 0}}, -// 3, -// sidb_simulation_engine::QUICKEXACT}; -// -// const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); -// REQUIRE(!found_gate_layouts.empty()); -// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); -// } -// -// SECTION("Random Generation with defects") -// { -// sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; -// -// const design_sidb_gates_params params{ -// sidb_simulation_parameters{2, -0.32}, -// design_sidb_gates_params::design_sidb_gates_mode::RANDOM, -// {{14, 6, 0}, {24, 12, 0}}, -// 3, -// sidb_simulation_engine::QUICKEXACT}; -// -// defect_layout.assign_sidb_defect( -// {15, 10, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect( -// {20, 12, 0}, -// sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); -// defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); -// -// const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); -// REQUIRE(!found_gate_layouts.empty()); -// CHECK(found_gate_layouts.front().num_defects() == 3); -// CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); -// -// found_gate_layouts.front().foreach_cell( -// [](const auto& cell) -// { -// CHECK(cell != siqad::coord_t{15, 10, 0}); -// CHECK(cell != siqad::coord_t{20, 12, 0}); -// }); -// } -// } + TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") +{ + using layout = sidb_cell_clk_lyt_siqad; + + layout 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); + + lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); + + design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.28}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{4, 4, 0}, {14, 5, 1}}, + 1, + sidb_simulation_engine::EXGS}; + + SECTION("Exhaustive Generation") + { + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + CHECK(!found_gate_layouts.empty()); + } + + SECTION("Random Generation") + { + params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + CHECK(!found_gate_layouts.empty()); + } + } + + TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") +{ + using layout = sidb_cell_clk_lyt_siqad; + + layout 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); + + // SiDB, originally part of the Bestagon fo2 gate, is excluded. + // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); + + SECTION("generate original FO2") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); + + // generate gate by placing one SiDB + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 21); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + } + + SECTION("replace the output perturbers by equivalent negatively charged defects") + { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); + defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({36, 19, 0}) == + technology::cell_type::EMPTY); CHECK(defect_layout.get_cell_type({2, 19, 0}) + == technology::cell_type::EMPTY); + + defect_layout.assign_sidb_defect( + {36, 19, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, + params.phys_params.epsilon_r, + params.phys_params.lambda_tf}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, + params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 19); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == + technology::cell_type::NORMAL); + } + } + + TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") +{ + using layout = sidb_cell_clk_lyt_siqad; + + layout lyt{}; + + lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); + + SECTION("Random Generation") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + REQUIRE(!found_gate_layouts.empty()); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + } + + SECTION("Random Generation with defects") + { + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + + defect_layout.assign_sidb_defect( + {15, 10, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect( + {20, 12, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); + REQUIRE(!found_gate_layouts.empty()); + CHECK(found_gate_layouts.front().num_defects() == 3); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + + found_gate_layouts.front().foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::coord_t{15, 10, 0}); + CHECK(cell != siqad::coord_t{20, 12, 0}); + }); + } + } diff --git a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp b/test/technology/is_sidb_gate_design_impossible.cpp similarity index 97% rename from test/algorithms/simulation/sidb/is_gate_design_impossible.cpp rename to test/technology/is_sidb_gate_design_impossible.cpp index 5723ff091..e5f76e409 100644 --- a/test/algorithms/simulation/sidb/is_gate_design_impossible.cpp +++ b/test/technology/is_sidb_gate_design_impossible.cpp @@ -2,9 +2,8 @@ // Created by Jan Drewniok on 25.10.23. // -#include - -#include "fiction/technology/sidb_is_gate_design_impossible.hpp" +#include "catch2/catch_template_test_macros.hpp" +#include "fiction/technology/is_sidb_gate_design_impossible.hpp" #include #include From 906129bcef056358732cc190f693852faea8ee11 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 12 Dec 2023 14:49:47 +0100 Subject: [PATCH 099/191] :art: some changes here and there. --- ...cal_design_with_on_the_fly_gate_design.cpp | 377 +++++++++--------- .../physical_design/design_sidb_gates.hpp | 30 +- .../sidb_on_the_fly_gate_library.hpp | 17 +- .../physical_design/design_sidb_gates.cpp | 3 +- 4 files changed, 202 insertions(+), 225 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 3dfd36928..a89230f76 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -1,19 +1,20 @@ // -// Created by marcel on 16.11.21. +// Created by Jan Drewniok on 20.10.23. // +#include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #if (FICTION_Z3_SOLVER) #include "fiction_experiments.hpp" -#include #include // technology mapping #include // layout conversion to cell-level -#include // SMT-based physical design of FCN layouts -#include +#include +#include // SMT-based physical design of FCN layouts #include // critical path and throughput calculations -#include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include +#include // reader for simulated SiDB surfaces +#include // writer for SiQAD files (physical simulation) #include #include // technology-mapped network type #include // area requirement calculations @@ -22,6 +23,7 @@ #include // a dynamic SiDB gate library #include #include // SiDB surface with support for atomic defects +#include #include #include // pre-defined types suitable for the FCN domain #include @@ -34,13 +36,14 @@ #include // NPN databases for cut rewriting of XAGs and AIGs #include // call-backs to read Verilog files into networks #include // XOR-AND-inverter graphs -#include // to determine network levels +#include +#include // to determine network levels #include #include #include +#include #include -#include #include // This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SDB @@ -51,218 +54,208 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt; + fiction::design_sidb_gates_params design_gate_params{}; + design_gate_params.phys_params = fiction::sidb_simulation_parameters{2, -0.32}; + design_gate_params.canvas = {{24, 17}, {34, 28}}; + design_gate_params.number_of_sidbs = 3; + design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; + design_gate_params.termination_cond = + fiction::design_sidb_gates_params::termination_condition::AFTER_FIRST_SOLUTION; + + // save atomic defects which their respective phyiscal parameters as exerimentally determined by T. R. Huff, T. + // Dienel, M. Rashidi, R. Achal, L. Livadaru, J. Croshaw, and R. A. Wolkow, “Electrostatic landscape of a + // Hydrogen-terminated Silicon Surface Probed by a Moveable Quantum Dot." + const auto stray_db = fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}; + const auto si_vacancy = fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}; + static const std::string layouts_folder = fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); - const std::vector defect_concentrations = {1}; + auto surface_lattice_initial = fiction::read_sidb_surface_defects( + "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt"); - for (const auto& concentration : defect_concentrations) - { - std::cout << fmt::format("--------------- defect concentration: {} % --------------- ", concentration) - << std::endl; - auto surface_lattice_initial = fiction::read_sidb_surface_defects( - fmt::format("../../experiments/defect_aware_physical_design/{}_percent_with_charged_surface.txt", - concentration), - "py_test_surface"); - - fiction::sidb_surface surface_lattice{ - {std::numeric_limits::max(), std::numeric_limits::max()}}; - - surface_lattice_initial.foreach_sidb_defect( - [&surface_lattice](const auto& cd) - { - if (cd.second.type == fiction::sidb_defect_type::DB) - { - surface_lattice.assign_sidb_defect( - cd.first, fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}); - } - else if (cd.second.type == fiction::sidb_defect_type::SI_VACANCY) - { - surface_lattice.assign_sidb_defect( - cd.first, fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}); - } - else - { - surface_lattice.assign_sidb_defect(cd.first, cd.second); - } - }); - - const auto lattice_tiling = gate_lyt{{11, 30}}; - - experiments::experiment - bestagon_exp{"bestagon", - "benchmark", - "inputs", - "outputs", - "initial nodes", - "initial depth", - "optimized nodes", - "optimized depth", - "layout width (in tiles)", - "layout height (in tiles)", - "layout area (in tiles)", - "gates", - "wires", - "critical path", - "throughput", - "runtime (in sec)", - "equivalent", - "SiDB dots", - "layout area in nm²"}; - - // parameters for SMT-based physical design - fiction::exact_physical_design_params exact_params{}; - exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); - exact_params.crossings = false; - exact_params.border_io = false; - exact_params.desynchronize = true; - exact_params.upper_bound_x = 11; // 12 x 31 tiles - exact_params.upper_bound_y = 30; // 12 x 31 tiles - exact_params.timeout = 3'600'000; // 1h in ms - - constexpr const uint64_t bench_select = - fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & - ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & - ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & - ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; - - // constexpr const uint64_t bench_select = - // fiction_experiments::t; - - for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) + fiction::sidb_surface surface_lattice{ + {std::numeric_limits::max(), std::numeric_limits::max()}}; + + surface_lattice_initial.foreach_sidb_defect( + [&surface_lattice, &stray_db, &si_vacancy](const auto& cd) { - fmt::print("[attempts] processing {}\n", benchmark); - mockturtle::xag_network xag{}; + if (cd.second.type == fiction::sidb_defect_type::DB) + { + surface_lattice.assign_sidb_defect(cd.first, stray_db); + } + else if (cd.second.type == fiction::sidb_defect_type::SI_VACANCY) + { + surface_lattice.assign_sidb_defect(cd.first, si_vacancy); + } + else + { + surface_lattice.assign_sidb_defect(cd.first, cd.second); + } + }); + + const auto lattice_tiling = gate_lyt{{11, 30}}; + + experiments::experiment + sidb_circuits_with_defects{"sidb_circuits_with_defects", + "benchmark", + "inputs", + "outputs", + "initial nodes", + "initial depth", + "optimized nodes", + "optimized depth", + "layout width (in tiles)", + "layout height (in tiles)", + "layout area (in tiles)", + "gates", + "wires", + "critical path", + "throughput", + "runtime (in sec)", + "equivalent", + "SiDB dots", + "layout area in nm²"}; + + // parameters for SMT-based physical design + fiction::exact_physical_design_params exact_params{}; + exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); + exact_params.crossings = false; + exact_params.border_io = false; + exact_params.desynchronize = true; + exact_params.upper_bound_x = 11; // 12 x 31 tiles + exact_params.upper_bound_y = 30; // 12 x 31 tiles + exact_params.timeout = 3'600'000; // 1h in ms + + constexpr const uint64_t bench_select = + fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & + ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & + ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & + ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; + + for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) + { + fmt::print("[attempts] processing {}\n", benchmark); + mockturtle::xag_network xag{}; - const auto read_verilog_result = - lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); - assert(read_verilog_result == lorina::return_code::success); + const auto read_verilog_result = + lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); + assert(read_verilog_result == lorina::return_code::success); - // compute depth - const mockturtle::depth_view depth_xag{xag}; + // compute depth + const mockturtle::depth_view depth_xag{xag}; - const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); + const fiction::technology_mapping_params tech_map_params = fiction::all_2_input_functions(); - // parameters for cut rewriting - mockturtle::cut_rewriting_params cut_params{}; - cut_params.cut_enumeration_ps.cut_size = 4; + // parameters for cut rewriting + mockturtle::cut_rewriting_params cut_params{}; + cut_params.cut_enumeration_ps.cut_size = 4; - const mockturtle::xag_npn_resynthesis< - mockturtle::xag_network, // the input network type - mockturtle::xag_network, // the database network type - mockturtle::xag_npn_db_kind::xag_complete> // the kind of database to use - resynthesis_function{}; + const mockturtle::xag_npn_resynthesis // the kind of database to use + resynthesis_function{}; - // rewrite network cuts using the given re-synthesis function - const auto cut_xag = mockturtle::cut_rewriting(xag, resynthesis_function, cut_params); + // rewrite network cuts using the given re-synthesis function + const auto cut_xag = mockturtle::cut_rewriting(xag, resynthesis_function, cut_params); - // perform technology mapping - const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); - // compute depth - const mockturtle::depth_view depth_mapped_network{mapped_network}; + // perform technology mapping + const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); + // compute depth + const mockturtle::depth_view depth_mapped_network{mapped_network}; - std::optional gate_level_layout = std::nullopt; - cell_lyt cell_level_layout{{}, "fail"}; + std::optional gate_level_layout = std::nullopt; + cell_lyt cell_level_layout{{}, "fail"}; - auto black_list = fiction::sidb_surface_analysis( - lattice_tiling, surface_lattice, std::make_pair(0, 0)); + auto black_list = fiction::sidb_surface_analysis( + lattice_tiling, surface_lattice, std::make_pair(0, 0)); - uint64_t attempts = 0; + auto attempts = 0u; - mockturtle::stopwatch<>::duration time_counter{}; + mockturtle::stopwatch<>::duration time_counter{}; - bool gate_design_failed = true; + auto gate_design_failed = true; - { - const mockturtle::stopwatch stop{time_counter}; + { + const mockturtle::stopwatch stop{time_counter}; - while (!gate_level_layout.has_value() || gate_design_failed) + while (!gate_level_layout.has_value() || gate_design_failed) + { + exact_params.black_list = black_list; + fiction::exact_physical_design_stats exact_stats{}; + if (!gate_level_layout.has_value() && attempts > 0) + { + break; + } + std::cout << black_list.size() << '\n'; + gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); + if (gate_level_layout.has_value()) { - exact_params.black_list = black_list; - fiction::exact_physical_design_stats exact_stats{}; - if (!gate_level_layout.has_value() && attempts > 0) + try { - break; + auto parameter_gate_library = + fiction::sidb_on_the_fly_gate_library_params{surface_lattice, design_gate_params}; + + cell_level_layout = fiction::apply_parameterized_gate_library< + cell_lyt, fiction::sidb_on_the_fly_gate_library, gate_lyt, + fiction::sidb_on_the_fly_gate_library_params>(*gate_level_layout, + parameter_gate_library); + gate_design_failed = false; } - std::cout << black_list.size() << std::endl; - gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); - if (gate_level_layout.has_value()) + catch (const fiction::gate_design_exception& e) { - try - { - const fiction::design_sidb_gates_params design_gate_params{ - fiction::sidb_simulation_parameters{2, -0.32}, - fiction::design_sidb_gates_params< - fiction::cube::coord_t>::design_sidb_gates_mode::EXHAUSTIVE, - {{24, 17}, {34, 28}}, - 3, - fiction::sidb_simulation_engine::QUICKEXACT, - 1}; - - auto parameter_gate_library = fiction::sidb_on_the_fly_gate_library_params{ - surface_lattice, design_gate_params}; - - cell_level_layout = fiction::apply_parameterized_gate_library< - cell_lyt, fiction::sidb_on_the_fly_gate_library, gate_lyt, - fiction::sidb_on_the_fly_gate_library_params>(*gate_level_layout, - parameter_gate_library); - gate_design_failed = false; - } - catch (const fiction::gate_design_exception& e) - { - gate_design_failed = true; - black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); - } - - catch (const std::exception& e) - { - std::cerr << "Caught std::exception: " << e.what() << std::endl; - } + gate_design_failed = true; + black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); } - attempts++; - } - } - if (!gate_level_layout.has_value()) - { - continue; + catch (const std::exception& e) + { + std::cerr << "Caught std::exception: " << e.what() << '\n'; + } + } + attempts++; } + } - // check equivalence - const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); - const auto eq = mockturtle::equivalence_checking(*miter); - assert(eq.has_value()); - - // compute critical path and throughput - fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; - fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); - - // apply dynamic gate library - - // compute area - fiction::area_stats area_stats{}; - fiction::area_params area_ps{}; - fiction::area(cell_level_layout, area_ps, &area_stats); - fiction::sidb_surface defect_surface{cell_level_layout}; - - surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) - { defect_surface.assign_sidb_defect(defect.first, defect.second); }); - // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, fmt::format("{}/{}_{}_percent_after_big_change.sqd", - layouts_folder, benchmark, concentration)); - - // log results - bestagon_exp(benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), - mapped_network.num_gates(), depth_mapped_network.depth(), gate_level_layout->x() + 1, - gate_level_layout->y() + 1, (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), - gate_level_layout->num_gates(), gate_level_layout->num_wires(), - cp_tp_stats.critical_path_length, cp_tp_stats.throughput, mockturtle::to_seconds(time_counter), - *eq, cell_level_layout.num_cells(), area_stats.area); - bestagon_exp.save(); - bestagon_exp.table(); + if (!gate_level_layout.has_value()) + { + continue; } + + // check equivalence + const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); + const auto eq = mockturtle::equivalence_checking(*miter); + assert(eq.has_value()); + + // compute critical path and throughput + fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; + fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); + + // apply dynamic gate library + + // compute area + fiction::area_stats area_stats{}; + fiction::area_params area_ps{}; + fiction::area(cell_level_layout, area_ps, &area_stats); + fiction::sidb_surface defect_surface{cell_level_layout}; + + // add defects to the file + surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) + { defect_surface.assign_sidb_defect(defect.first, defect.second); }); + // write a SiQAD simulation file + fiction::write_sqd_layout(defect_surface, + fmt::format("{}/{}_percent_after_big_change.sqd", layouts_folder, benchmark)); + + // log results + sidb_circuits_with_defects( + benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), mapped_network.num_gates(), + depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1, + (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(), + gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput, + mockturtle::to_seconds(time_counter), *eq, cell_level_layout.num_cells(), area_stats.area); + sidb_circuits_with_defects.save(); + sidb_circuits_with_defects.table(); } return EXIT_SUCCESS; diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 1f4c860ed..25690f5a0 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -24,9 +24,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -52,7 +52,7 @@ struct design_sidb_gates_params /** * The design process is terminated when a valid SiDB gate design is found. */ - SOLUTION_FOUND, + AFTER_FIRST_SOLUTION, /** * The design process ends after all possible combinations of SiDBs within the canvas are enumerated. */ @@ -92,10 +92,6 @@ struct design_sidb_gates_params * The simulation engine to be used for the operational domain computation. */ sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; - /** - * The percentage of all combinations that are tested before the design process is canceled. - */ - double procentual_maximum_attemps = 1.0; /** * The design process is terminated after a valid SiDB gate design is found. * @@ -146,12 +142,9 @@ class design_sidb_gates_impl sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(std::make_pair(0, 0)); } - std::vector designed_gate_layouts = {}; - std::mutex mutex_to_protect_designer_gate_layouts; - std::atomic solution_found = false; - std::atomic global_iteration_counter(0); - - const auto total_comb = binomial_coefficient(all_sidbs_in_canvas.size(), params.number_of_sidbs); + std::vector designed_gate_layouts = {}; + std::mutex mutex_to_protect_designer_gate_layouts; + std::atomic solution_found = false; // Shuffle the combinations before dividing them among threads std::shuffle(all_combinations.begin(), all_combinations.end(), @@ -159,14 +152,11 @@ class design_sidb_gates_impl const auto add_combination_to_layout_and_check_operation = [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, - &sidbs_affected_by_defects, &solution_found, &global_iteration_counter, - &total_comb](const auto& combination) noexcept + &sidbs_affected_by_defects, &solution_found](const auto& combination) noexcept { for (const auto& comb : combination) { - if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects) && - global_iteration_counter < - static_cast(params.procentual_maximum_attemps * static_cast(total_comb))) + if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects)) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); @@ -180,14 +170,14 @@ class design_sidb_gates_impl } solution_found = true; } - if (solution_found && (params.termination_cond == - design_sidb_gates_params>::termination_condition::SOLUTION_FOUND)) + if (solution_found && + (params.termination_cond == + design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION)) { return; } continue; } - global_iteration_counter++; } }; diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 4f0c2ba21..3d010610f 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -12,12 +12,13 @@ #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/is_sidb_gate_design_impossible.hpp" #include "fiction/technology/sidb_surface.hpp" -#include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" +#include "fiction/utils/truth_table_utils.hpp" #include +#include #include #include #include @@ -106,13 +107,7 @@ struct sidb_on_the_fly_gate_library_params /** * This struct holds parameters to design SiDB gates on-the-fly. */ - design_sidb_gates_params> design_gate_params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{}, {}}, - 3, - sidb_simulation_engine::QUICKEXACT, - 1}; + design_sidb_gates_params> design_gate_params{}; /** * This variable defines the number of canvas SiDBs dedicated to complex gates, such as crossing, double wire, * and half-adder. @@ -449,16 +444,16 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library [[nodiscard]] static std::array, gate_y_size()> - cell_level_layout_to_list(const Lyt& lyt) + cell_level_layout_to_list(const Lyt& lyt) noexcept { std::array, gate_y_size()> result{}; const auto all_cell = all_coordinates_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); uint64_t counter = 0; - for (const auto& row : result) + for (auto& row : result) { - for (const auto& cell : row) + for (auto& cell : row) { const auto cell_type = lyt.get_cell_type(all_cell[counter]); cell = (cell_type == Lyt::technology::cell_type::NORMAL || diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 0a4383a71..f49a1fb72 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -113,8 +113,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT, - 1.0, - design_sidb_gates_params>::termination_condition::SOLUTION_FOUND}; + design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); From 1f7f348fd5f5cb9ac4a0fb568d7795d06855d87b Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Mon, 29 Jan 2024 17:21:15 +0000 Subject: [PATCH 100/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- .../physical_design/design_sidb_gates.cpp | 447 +++++++++--------- .../is_sidb_gate_design_impossible.cpp | 3 +- 2 files changed, 224 insertions(+), 226 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index f49a1fb72..11590de13 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -92,244 +92,241 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_offset[0].get_cell_type( siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); } - SECTION("Four cells in canvas, design all gates") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {13, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 4); - } - SECTION("Four cells in canvas, design process is terminated after first solution is found") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT, - design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); - } + SECTION("Four cells in canvas, design all gates") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {13, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 4); + } + SECTION("Four cells in canvas, design process is terminated after first solution is found") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{10, 4, 0}, {10, 4, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT, + design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + } } - TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") +TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; + using layout = sidb_cell_clk_lyt_siqad; - layout lyt{}; + layout 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); + lyt.assign_cell_type({0, 0, 1}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({2, 1, 1}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({20, 0, 1}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({18, 1, 1}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({4, 2, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({6, 3, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 3, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({16, 2, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({10, 6, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({10, 7, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{4, 4, 0}, {14, 5, 1}}, - 1, - sidb_simulation_engine::EXGS}; + design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.28}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{4, 4, 0}, {14, 5, 1}}, + 1, + sidb_simulation_engine::EXGS}; - SECTION("Exhaustive Generation") - { - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - CHECK(!found_gate_layouts.empty()); - } + SECTION("Exhaustive Generation") + { + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + CHECK(!found_gate_layouts.empty()); + } - SECTION("Random Generation") - { - params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - CHECK(!found_gate_layouts.empty()); - } - } + SECTION("Random Generation") + { + params.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + CHECK(!found_gate_layouts.empty()); + } +} - TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") +TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate original one", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; - - layout 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); - - // SiDB, originally part of the Bestagon fo2 gate, is excluded. - // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); - - lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); - - SECTION("generate original FO2") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); - - // generate gate by placing one SiDB - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 21); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); - } - - SECTION("replace the output perturbers by equivalent negatively charged defects") - { - const design_sidb_gates_params params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{17, 11, 0}, {17, 11, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - - sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); - defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); - CHECK(defect_layout.get_cell_type({36, 19, 0}) == - technology::cell_type::EMPTY); CHECK(defect_layout.get_cell_type({2, 19, 0}) - == technology::cell_type::EMPTY); - - defect_layout.assign_sidb_defect( - {36, 19, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, - params.phys_params.epsilon_r, - params.phys_params.lambda_tf}); - - const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, - params); - - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 19); - CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == - technology::cell_type::NORMAL); - } - } - - TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") + using layout = sidb_cell_clk_lyt_siqad; + + layout 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); + + // SiDB, originally part of the Bestagon fo2 gate, is excluded. + // lyt.assign_cell_type({17, 11, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({21, 11, 1}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({18, 13, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({19, 7, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({18, 6, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({12, 16, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 15, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({8, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({6, 18, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); + + lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({2, 19, 0}, sidb_technology::cell_type::NORMAL); + + SECTION("generate original FO2") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + CHECK(lyt.get_cell_type({17, 11, 0}) == layout::technology::EMPTY); + + // generate gate by placing one SiDB + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_fan_out_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 21); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == layout::technology::NORMAL); + } + + SECTION("replace the output perturbers by equivalent negatively charged defects") + { + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + {{17, 11, 0}, {17, 11, 0}}, + 1, + sidb_simulation_engine::QUICKEXACT}; + + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + defect_layout.assign_cell_type({36, 19, 0}, technology::cell_type::EMPTY); + defect_layout.assign_cell_type({2, 19, 0}, technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({36, 19, 0}) == technology::cell_type::EMPTY); + CHECK(defect_layout.get_cell_type({2, 19, 0}) == technology::cell_type::EMPTY); + + defect_layout.assign_sidb_defect( + {36, 19, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({2, 19, 0}, sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, + params.phys_params.lambda_tf}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_fan_out_tt()}, params); + + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 19); + CHECK(found_gate_layouts[0].get_cell_type({17, 11, 0}) == + technology::cell_type::NORMAL); + } +} + +TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") { - using layout = sidb_cell_clk_lyt_siqad; - - layout lyt{}; - - lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); - lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); - - lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); - lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); - - lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); - lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); - - SECTION("Random Generation") - { - const design_sidb_gates_params> params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); - REQUIRE(!found_gate_layouts.empty()); - CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); - } - - SECTION("Random Generation with defects") - { - sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; - - const design_sidb_gates_params params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, - {{14, 6, 0}, {24, 12, 0}}, - 3, - sidb_simulation_engine::QUICKEXACT}; - - defect_layout.assign_sidb_defect( - {15, 10, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect( - {20, 12, 0}, - sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); - defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); - - const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); - REQUIRE(!found_gate_layouts.empty()); - CHECK(found_gate_layouts.front().num_defects() == 3); - CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); - - found_gate_layouts.front().foreach_cell( - [](const auto& cell) - { - CHECK(cell != siqad::coord_t{15, 10, 0}); - CHECK(cell != siqad::coord_t{20, 12, 0}); - }); - } - } + using layout = sidb_cell_clk_lyt_siqad; + + layout lyt{}; + + lyt.assign_cell_type({38, 0, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({0, 0, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({36, 1, 0}, sidb_technology::cell_type::INPUT); + lyt.assign_cell_type({2, 1, 0}, sidb_technology::cell_type::INPUT); + + lyt.assign_cell_type({6, 2, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({32, 2, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({30, 3, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({8, 3, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({26, 4, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({12, 4, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({24, 5, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({14, 5, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({24, 15, 0}, sidb_technology::cell_type::NORMAL); + lyt.assign_cell_type({26, 16, 0}, sidb_technology::cell_type::NORMAL); + + lyt.assign_cell_type({30, 17, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({32, 18, 0}, sidb_technology::cell_type::OUTPUT); + lyt.assign_cell_type({36, 19, 0}, sidb_technology::cell_type::NORMAL); + + SECTION("Random Generation") + { + const design_sidb_gates_params> params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + + const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); + REQUIRE(!found_gate_layouts.empty()); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + } + + SECTION("Random Generation with defects") + { + sidb_defect_cell_clk_lyt_siqad defect_layout{lyt}; + + const design_sidb_gates_params params{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + {{14, 6, 0}, {24, 12, 0}}, + 3, + sidb_simulation_engine::QUICKEXACT}; + + defect_layout.assign_sidb_defect( + {15, 10, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect( + {20, 12, 0}, + sidb_defect{sidb_defect_type::DB, -1, params.phys_params.epsilon_r, params.phys_params.lambda_tf}); + defect_layout.assign_sidb_defect({23, 12, 0}, sidb_defect{sidb_defect_type::GUNK}); + + const auto found_gate_layouts = design_sidb_gates(defect_layout, std::vector{create_and_tt()}, params); + REQUIRE(!found_gate_layouts.empty()); + CHECK(found_gate_layouts.front().num_defects() == 3); + CHECK(found_gate_layouts.front().num_cells() == lyt.num_cells() + 3); + + found_gate_layouts.front().foreach_cell( + [](const auto& cell) + { + CHECK(cell != siqad::coord_t{15, 10, 0}); + CHECK(cell != siqad::coord_t{20, 12, 0}); + }); + } +} diff --git a/test/technology/is_sidb_gate_design_impossible.cpp b/test/technology/is_sidb_gate_design_impossible.cpp index e5f76e409..1a4eef08e 100644 --- a/test/technology/is_sidb_gate_design_impossible.cpp +++ b/test/technology/is_sidb_gate_design_impossible.cpp @@ -2,9 +2,10 @@ // Created by Jan Drewniok on 25.10.23. // -#include "catch2/catch_template_test_macros.hpp" #include "fiction/technology/is_sidb_gate_design_impossible.hpp" +#include "catch2/catch_template_test_macros.hpp" + #include #include #include From b19d7cd559155f67d5d98a232b3518ced5253516 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 30 Jan 2024 08:58:15 +0100 Subject: [PATCH 101/191] :art: more consistency. --- docs/technology/gate_libraries.rst | 4 +- ...cal_design_with_on_the_fly_gate_design.cpp | 39 +++-- .../physical_design/apply_gate_library.hpp | 74 +++++---- include/fiction/layouts/coordinates.hpp | 7 +- .../is_sidb_gate_design_impossible.hpp | 14 +- ...ary.hpp => parameterized_gate_library.hpp} | 146 +++++++++--------- .../technology/parameterized_gate_library.cpp | 19 +++ .../technology/sidb_bestagon_gate_library.cpp | 2 +- .../sidb_on_the_fly_gate_library.cpp | 19 --- 9 files changed, 175 insertions(+), 149 deletions(-) rename include/fiction/technology/{sidb_on_the_fly_gate_library.hpp => parameterized_gate_library.hpp} (97%) create mode 100644 test/technology/parameterized_gate_library.cpp delete mode 100644 test/technology/sidb_on_the_fly_gate_library.cpp diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index f8ee5838e..3d53d6126 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -62,9 +62,9 @@ SiDB Bestagon Library On-the-fly SiDB Library ----------------------- -**Header:** ``fiction/technology/sidb_on_the_fly_gate_library.hpp`` +**Header:** ``fiction/technology/parameterized_gate_library.hpp`` .. doxygenstruct:: fiction::sidb_on_the_fly_gate_library_params :members: -.. doxygenclass:: fiction::sidb_on_the_fly_gate_library +.. doxygenclass:: fiction::parameterized_gate_library :members: diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index a89230f76..1021dc030 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -9,24 +9,22 @@ #include // technology mapping #include // layout conversion to cell-level -#include -#include // SMT-based physical design of FCN layouts +#include // design gate +#include // SMT-based physical design of FCN layouts #include // critical path and throughput calculations -#include -#include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) -#include -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations -#include -#include // a dynamic SiDB gate library -#include -#include // SiDB surface with support for atomic defects -#include -#include +#include // choose design engine (ExGS, QuickSim, QuickExact) +#include // reader for simulated SiDB surfaces +#include // writer for SiQAD files (physical simulation) +#include // layout coordinates +#include // technology-mapped network type +#include // area requirement calculations +#include // cell implementations +#include // a dynamic SiDB gate library +#include // Atomic defects +#include // a static skeleton SiDB gate library defining the input/output wires +#include // SiDB surface with support for atomic defects +#include // Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library #include // pre-defined types suitable for the FCN domain -#include #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -36,8 +34,8 @@ #include // NPN databases for cut rewriting of XAGs and AIGs #include // call-backs to read Verilog files into networks #include // XOR-AND-inverter graphs -#include -#include // to determine network levels +#include // used to measure runtime +#include // to determine network levels #include #include @@ -46,7 +44,7 @@ #include #include -// This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SDB +// This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SiDB // circuits can be designed in the presence of atomic defects. int main() // NOLINT @@ -155,6 +153,7 @@ int main() // NOLINT const mockturtle::xag_npn_resynthesis // the kind of database to use + resynthesis_function{}; // rewrite network cuts using the given re-synthesis function @@ -198,7 +197,7 @@ int main() // NOLINT fiction::sidb_on_the_fly_gate_library_params{surface_lattice, design_gate_params}; cell_level_layout = fiction::apply_parameterized_gate_library< - cell_lyt, fiction::sidb_on_the_fly_gate_library, gate_lyt, + cell_lyt, fiction::parameterized_gate_library, gate_lyt, fiction::sidb_on_the_fly_gate_library_params>(*gate_level_layout, parameter_gate_library); gate_design_failed = false; diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index ce89356bd..829244916 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -7,11 +7,12 @@ #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/inml_topolinano_library.hpp" +#include "fiction/technology/parameterized_gate_library.hpp" #include "fiction/technology/qca_one_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" -#include "fiction/technology/sidb_on_the_fly_gate_library.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" +#include "fiction/utils/name_utils.hpp" #if (PROGRESS_BARS) #include @@ -45,22 +46,22 @@ class apply_gate_library_impl {} /** - * This function designs gates on-the-fly based on the provided atomic defects and gate types defined in `lyt`. - * It creates a cell-level layout by adapting a gate-level layout on-the-fly to implement the gate types using - * building blocks from the `GateLibrary`. Atomic defects are incorporated into the gate designs during this - * process. + * Run the cell layout generation process. + * + * This function performs the cell layout generation process based on the gate library and the gate-level layout + * information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the gate-level layout and + * assigns gates to cells based on their corresponding positions and types. Optionally, it performs post-layout + * optimization and sets the layout name if certain conditions are met. * - * @tparam Params Type of the parameter used for the on-the-fly gate library. - * @param params Parameter for the gate library. - * @return A cell-level layout implementing gate types with building blocks defined in `GateLibrary`. + * @return A `CellLyt` object representing the generated cell layout. */ - template - [[nodiscard]] CellLyt run_parameterized_gate_library(const Params& params) + [[nodiscard]] CellLyt run_static_gate_library() { #if (PROGRESS_BARS) // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif + gate_lyt.foreach_node( [&, this](const auto& n, [[maybe_unused]] auto i) { @@ -73,9 +74,7 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - const auto gate = GateLibrary::template set_up_gate(gate_lyt, t, params); - - assign_gate(c, gate, n); + assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); } #if (PROGRESS_BARS) // update progress @@ -88,7 +87,6 @@ class apply_gate_library_impl { GateLibrary::post_layout_optimization(cell_lyt); } - // if available, recover layout name if constexpr (has_get_layout_name_v && has_set_layout_name_v) { @@ -97,24 +95,25 @@ class apply_gate_library_impl return cell_lyt; } - /** * Run the cell layout generation process. * - * This function performs the cell layout generation process based on the gate library and the gate-level layout - * information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the gate-level layout and - * assigns gates to cells based on their corresponding positions and types. Optionally, it performs post-layout - * optimization and sets the layout name if certain conditions are met. + * This function performs the cell layout generation process based on the parameterized gate library and the + * gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the + * gate-level layout and assigns gates to cells based on their corresponding positions and types. Optionally, it + * performs post-layout optimization and sets the layout name if certain conditions are met. * + * @tparam Type of the Parameters used for the parameterized gate library. + * @param params Parameters used for the parameterized gate library. * @return A `CellLyt` object representing the generated cell layout. */ - [[nodiscard]] CellLyt run() + template + [[nodiscard]] CellLyt run_parameterized_gate_library(const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar mockturtle::progress_bar bar{static_cast(gate_lyt.size()), "[i] applying gate library: |{0}|"}; #endif - gate_lyt.foreach_node( [&, this](const auto& n, [[maybe_unused]] auto i) { @@ -127,7 +126,9 @@ class apply_gate_library_impl relative_to_absolute_cell_position(gate_lyt, t, cell{0, 0}); - assign_gate(c, GateLibrary::set_up_gate(gate_lyt, t), n); + const auto gate = GateLibrary::template set_up_gate(gate_lyt, t, params); + + assign_gate(c, gate, n); } #if (PROGRESS_BARS) // update progress @@ -140,19 +141,30 @@ class apply_gate_library_impl { GateLibrary::post_layout_optimization(cell_lyt); } + // if available, recover layout name - if constexpr (has_get_layout_name_v && has_set_layout_name_v) - { - cell_lyt.set_layout_name(gate_lyt.get_layout_name()); - } + cell_lyt.set_layout_name(get_name(gate_lyt)); return cell_lyt; } private: + /** + * Gate-level layout. + */ GateLyt gate_lyt; + /** + * Cell-level layout. + */ CellLyt cell_lyt; + /** + * This function assigns a given SiDB gate implemetation to the total cell layout. + * + * @param c Top-left cell of the tile where the gate is placed. + * @param g Gate implementation. + * @param n Corresponding node in the gate-level layout. + */ void assign_gate(const cell& c, const typename GateLibrary::fcn_gate& g, const mockturtle::node& n) { @@ -213,19 +225,19 @@ template detail::apply_gate_library_impl p{lyt}; - return p.run(); + return p.run_static_gate_library(); } /** - * Applies an on-the-fly gate library (i.e., gates are designed on-the-fly by respecting atomic defects) to a given + * Applies a parameterized gate library to a given * gate-level layout and, thereby, creates and returns a cell-level layout. * - * May pass through, and thereby throw, an `unsupported_gate_type_exception` or an - * `unsupported_gate_orientation_exception`. + * May pass through, and thereby throw, an `unsupported_gate_type_exception`, an + * `unsupported_gate_orientation_exception` and any further custom exceptions of the gate libraries. * * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. - * @tparam Params Type of the parameter used for the on-the-fly gate library. + * @tparam Params Type of the parameter used for parameterized gate library. * @param lyt The gate-level layout. * @param params Parameter for the gate library. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 73d15bf3b..3d04fda9a 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -816,12 +816,11 @@ constexpr cube::coord_t offset_to_cube_coord(const offset::ucoord_t& coord) noex { assert(coord.x <= std::numeric_limits::max() && coord.y <= std::numeric_limits::max() && coord.z <= std::numeric_limits::max() && "Coordinate is out-of-range and cannot be transformed"); - if (!coord.is_dead()) + if (coord.is_dead()) { - return {static_cast(coord.x), static_cast(coord.y), static_cast(coord.z)}; + return cube::coord_t{}; } - - return cube::coord_t{}; + return {static_cast(coord.x), static_cast(coord.y), static_cast(coord.z)}; } /** diff --git a/include/fiction/technology/is_sidb_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp index 56d3da468..9a3782e36 100644 --- a/include/fiction/technology/is_sidb_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -8,13 +8,19 @@ #include "fiction/algorithms/iter/bdl_input_iterator.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #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/technology/charge_distribution_surface.hpp" +#include "fiction/technology/physical_constants.hpp" #include "fiction/technology/sidb_defects.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/truth_table_utils.hpp" +#include +#include + namespace fiction { /** @@ -32,13 +38,15 @@ struct is_gate_design_impossible_params sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; }; /** - * This function assesses whether it is impossible to design an SiDB gate for a given truth table in the provided layout - * due to atomic defects. + * This function evaluates whether it is impossible to design a SiDB gate for a given truth table in the given layout + * due to atomic defects. It determines the possible charge states at the output BDL pairs. Atomic defects can cause a + * BDL pair to be neutrally charged only. Thus, the BDL pair would not work as intended. * * @tparam Lyt Cell-level layout type. * @tparam TT The type of the truth table. * @param layout The layout for which gate design feasibility is being checked. - * @param spec A vector of truth tables representing the gate's functionality. + * @param spec A vector of truth tables (each truth table is representing one output) representing the gate's + * functionality. * @param params Parameter to determine if the gate design is impossible. * @return `true` if gate design is impossible, `false` otherwise. * diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp similarity index 97% rename from include/fiction/technology/sidb_on_the_fly_gate_library.hpp rename to include/fiction/technology/parameterized_gate_library.hpp index 3d010610f..c3bde93d1 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -2,12 +2,14 @@ // Created by Jan Drewniok 20.09.23. // -#ifndef FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP -#define FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP +#ifndef FICTION_PARAMETERIZED_GATE_LIBRARY_HPP +#define FICTION_PARAMETERIZED_GATE_LIBRARY_HPP #include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" +#include "fiction/layouts/coordinates.hpp" +#include "fiction/technology/cell_ports.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/is_sidb_gate_design_impossible.hpp" @@ -98,7 +100,7 @@ class gate_design_exception : public std::exception * @tparam Lyt Cell-level layout type. */ template -struct sidb_on_the_fly_gate_library_params +struct parameterized_gate_library_params { /** * This layout stores all atomic defects. @@ -121,13 +123,14 @@ struct sidb_on_the_fly_gate_library_params }; /** - * An on-the-fly gate library for SiDB technology. It allows the design of SiDB gates tailored to given atomic defects, - * thus enabling the design of SiDB circuits in the presence of atomic defects. + * A parameterized gate library for SiDB technology. It allows the design of SiDB gates tailored to given atomic + * defects, thus enabling the design of SiDB circuits in the presence of atomic defects. The skeleton (i.e., the + * pre-defined input and output wires) are hexagonal in shape. */ -class sidb_on_the_fly_gate_library : public fcn_gate_library // width and height of a hexagon +class parameterized_gate_library : public fcn_gate_library // width and height of a hexagon { public: - explicit sidb_on_the_fly_gate_library() = delete; + explicit parameterized_gate_library() = delete; /** * Overrides the corresponding function in fcn_gate_library. Given a tile `t`, this function takes all necessary @@ -139,11 +142,11 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const Params& parameter = Params{}) + static fcn_gate set_up_gate(const GateLyt& lyt, const tile& t, const Params& parameters = Params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); @@ -169,10 +172,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, create_fan_out_tt(), parameter, p, t); + layout, create_fan_out_tt(), parameters, p, t); } } } @@ -192,17 +195,17 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_TWO_OUT), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(DOUBLE_WIRE), - create_double_wire_tt(), parameter)) + create_double_wire_tt(), parameters)) { return DOUBLE_WIRE; } - auto complex_gate_param = parameter; + auto complex_gate_param = parameters; complex_gate_param.design_gate_params.number_of_sidbs = - parameter.canvas_sidb_complex_gates; + parameters.canvas_sidb_complex_gates; return design_gate, tt, CellLyt, GateLyt>( layout, create_double_wire_tt(), complex_gate_param, p, t); @@ -210,16 +213,17 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_TWO_OUT), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); if (is_bestagon_gate_applicable(cell_list_to_cell_level_layout(CROSSING), - create_crossing_wire_tt(), parameter)) + create_crossing_wire_tt(), parameters)) { return CROSSING; } - auto complex_gate_param = parameter; - complex_gate_param.design_gate_params.number_of_sidbs = parameter.canvas_sidb_complex_gates; + auto complex_gate_param = parameters; + complex_gate_param.design_gate_params.number_of_sidbs = + parameters.canvas_sidb_complex_gates; return design_gate, tt, CellLyt, GateLyt>( layout, create_crossing_wire_tt(), complex_gate_param, p, t); @@ -231,10 +235,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(cell_list), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } return EMPTY_GATE; } @@ -245,10 +249,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (mockturtle::has_is_and_v) @@ -257,10 +261,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (mockturtle::has_is_or_v) @@ -269,10 +273,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_nand_v) @@ -281,10 +285,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_nor_v) @@ -293,10 +297,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (mockturtle::has_is_xor_v) @@ -305,10 +309,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_xnor_v) @@ -317,10 +321,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_ge_v) @@ -329,10 +333,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_le_v) @@ -341,10 +345,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_gt_v) @@ -353,10 +357,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } if constexpr (fiction::has_is_lt_v) @@ -365,10 +369,10 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), - center_cell, absolute_cell, parameter); + center_cell, absolute_cell, parameters); return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameter, p, t); + layout, std::vector{f}, parameters, p, t); } } } @@ -388,19 +392,19 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library [[nodiscard]] static bool is_bestagon_gate_applicable(const Lyt& bestagon_lyt, const std::vector& truth_table, - const Params& parameter) + const Params& parameters) { - auto defect_copy = parameter.defect_surface.clone(); + auto defect_copy = parameters.defect_surface.clone(); const auto sidbs_affected_by_defects = defect_copy.all_affected_sidbs(std::pair(0, 0)); bool is_bestagon_gate_applicable = true; @@ -429,8 +433,8 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(status == operational_status::OPERATIONAL); } @@ -447,7 +451,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library, gate_y_size()> result{}; - const auto all_cell = + const auto all_coordinates_in_the_spanned_area = all_coordinates_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); uint64_t counter = 0; @@ -455,7 +459,7 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton, const std::vector& spec, - const sidb_on_the_fly_gate_library_params& parameter, + [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton_with_defects, const std::vector& spec, + const parameterized_gate_library_params& parameters, const port_list& p, const tile& tile) { - const auto params = is_gate_design_impossible_params{parameter.design_gate_params.phys_params, - parameter.design_gate_params.sim_engine}; + const auto params = is_gate_design_impossible_params{parameters.design_gate_params.phys_params, + parameters.design_gate_params.sim_engine}; if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) { - if (is_gate_design_impossible(skeleton, spec, params)) + if (is_gate_design_impossible(skeleton_with_defects, spec, params)) { throw gate_design_exception(tile, create_id_tt(), p); } - const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameter.design_gate_params); + const auto found_gate_layouts = + design_sidb_gates(skeleton_with_defects, spec, parameters.design_gate_params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, create_id_tt(), p); @@ -501,11 +509,11 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(tile, spec.front(), p); } - const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameter.design_gate_params); + const auto found_gate_layouts = design_sidb_gates(skeleton_with_defects, spec, parameters.design_gate_params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, spec.front(), p); @@ -575,13 +583,13 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library [[nodiscard]] static sidb_surface add_defect_to_skeleton(const CellLyt& skeleton, const cell& center_cell, - const cell& absolute_cell, const Params& params) + const cell& absolute_cell, const Params& parameters) { static_assert(has_offset_ucoord_v || has_cube_coord_v, "CellLyt must be either based on cube or offset coordinates"); @@ -590,14 +598,14 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library(skeleton); const auto center_cell_cube = offset_to_cube_coord(center_cell); const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); - return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, params); + return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, parameters); } } @@ -1303,4 +1311,4 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Parameterized gate library traits", "[sidb-dynamic-gate-library]") +{ + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); +} diff --git a/test/technology/sidb_bestagon_gate_library.cpp b/test/technology/sidb_bestagon_gate_library.cpp index 3da87fc81..282f2d7be 100644 --- a/test/technology/sidb_bestagon_gate_library.cpp +++ b/test/technology/sidb_bestagon_gate_library.cpp @@ -10,7 +10,7 @@ using namespace fiction; -TEST_CASE("traits", "[sidb-bestagon-gate-library]") +TEST_CASE("Bestagon traits", "[sidb-bestagon-gate-library]") { CHECK(!has_post_layout_optimization_v); CHECK(!has_post_layout_optimization_v); diff --git a/test/technology/sidb_on_the_fly_gate_library.cpp b/test/technology/sidb_on_the_fly_gate_library.cpp deleted file mode 100644 index 2b3090014..000000000 --- a/test/technology/sidb_on_the_fly_gate_library.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// -// Created by Jan Drewniok on 24.10.23. -// - -#include - -#include -#include -#include - -using namespace fiction; - -TEST_CASE("Layout optimization traits", "[sidb-dynamic-gate-library]") -{ - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); -} From 2cf2c21c34aa451a65d29a3efea6a37df7f7b47e Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Tue, 30 Jan 2024 08:04:41 +0000 Subject: [PATCH 102/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- include/fiction/technology/parameterized_gate_library.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index c3bde93d1..cc7f209c8 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -619,7 +619,8 @@ class parameterized_gate_library : public fcn_gate_library(skeleton); const auto center_cell_cube = offset_to_cube_coord(center_cell); const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); - return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, parameters); + return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, + parameters); } } From 25f7b4988203909c89d8e633320e82f5b8efd200 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 30 Jan 2024 09:32:05 +0100 Subject: [PATCH 103/191] :art: update experiments. --- .../physical_design_with_on_the_fly_gate_design.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 1021dc030..89d327297 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -2,7 +2,6 @@ // Created by Jan Drewniok on 20.10.23. // -#include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #if (FICTION_Z3_SOLVER) #include "fiction_experiments.hpp" @@ -194,12 +193,12 @@ int main() // NOLINT try { auto parameter_gate_library = - fiction::sidb_on_the_fly_gate_library_params{surface_lattice, design_gate_params}; + fiction::parameterized_gate_library_params{surface_lattice, design_gate_params}; cell_level_layout = fiction::apply_parameterized_gate_library< cell_lyt, fiction::parameterized_gate_library, gate_lyt, - fiction::sidb_on_the_fly_gate_library_params>(*gate_level_layout, - parameter_gate_library); + fiction::parameterized_gate_library_params>(*gate_level_layout, + parameter_gate_library); gate_design_failed = false; } catch (const fiction::gate_design_exception& e) From ec974c6f3f6285854ee1fe0559ece413a16e168a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 30 Jan 2024 10:38:57 +0100 Subject: [PATCH 104/191] :white_check_mark: add unit test. --- test/technology/sidb_defects.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/technology/sidb_defects.cpp b/test/technology/sidb_defects.cpp index b83e1209a..b2a6eb844 100644 --- a/test/technology/sidb_defects.cpp +++ b/test/technology/sidb_defects.cpp @@ -49,6 +49,9 @@ TEST_CASE("Defect extent", "[sidb-defects]") static constexpr std::pair charged_spacing{SIDB_CHARGED_DEFECT_HORIZONTAL_SPACING, SIDB_CHARGED_DEFECT_VERTICAL_SPACING}; + static constexpr std::pair neutral_spacing_overwrite{1, 0}; + static constexpr std::pair charged_spacing_overwrite{1, 1}; + CHECK(defect_extent(sidb_defect{sidb_defect_type::NONE}) == no_spacing); CHECK(defect_extent(sidb_defect{sidb_defect_type::DB}) == charged_spacing); CHECK(defect_extent(sidb_defect{sidb_defect_type::SI_VACANCY}) == charged_spacing); @@ -63,6 +66,11 @@ TEST_CASE("Defect extent", "[sidb-defects]") CHECK(defect_extent(sidb_defect{sidb_defect_type::STEP_EDGE}) == neutral_spacing); CHECK(defect_extent(sidb_defect{sidb_defect_type::GUNK}) == neutral_spacing); CHECK(defect_extent(sidb_defect{sidb_defect_type::UNKNOWN}) == neutral_spacing); + + CHECK(defect_extent(sidb_defect{sidb_defect_type::UNKNOWN, 0}, charged_spacing_overwrite, + neutral_spacing_overwrite) == neutral_spacing_overwrite); + CHECK(defect_extent(sidb_defect{sidb_defect_type::UNKNOWN, -1}, charged_spacing_overwrite, + neutral_spacing_overwrite) == charged_spacing_overwrite); } TEST_CASE("Test for units", "[sidb-defects]") From 0a2b4abac316c82dd18855b497801f55ef8a2e24 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 8 Mar 2024 15:08:23 +0100 Subject: [PATCH 105/191] :twisted_rightwards_arrows: resolve merge conflict. --- .../algorithms/physical_design/design_sidb_gates.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 2d0fe4746..a73dbb826 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -11,6 +11,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/layouts/coordinates.hpp" +#include "fiction/technology/cell_technologies.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" @@ -18,6 +19,7 @@ #include "fiction/utils/truth_table_utils.hpp" #include +#include #include #include @@ -25,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -133,7 +135,7 @@ class design_sidb_gates_impl { const is_operational_params params_is_operational{params.phys_params, params.sim_engine}; - const auto all_combinations = determine_all_combinations_of_distributing_k_entities_on_n_positions( + auto all_combinations = determine_all_combinations_of_distributing_k_entities_on_n_positions( params.number_of_sidbs, static_cast(all_sidbs_in_canvas.size())); std::unordered_set sidbs_affected_by_defects = {}; From 8f96508f3e6c12364a33f33a826d0cbb15389200 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 22 Mar 2024 15:46:55 +0100 Subject: [PATCH 106/191] :art: small update of experiment script. --- .../physical_design_with_on_the_fly_gate_design.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 89d327297..1cdaba127 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -227,8 +227,7 @@ int main() // NOLINT assert(eq.has_value()); // compute critical path and throughput - fiction::critical_path_length_and_throughput_stats cp_tp_stats{}; - fiction::critical_path_length_and_throughput(*gate_level_layout, &cp_tp_stats); + const auto cp_tp_stats = fiction::critical_path_length_and_throughput(*gate_level_layout); // apply dynamic gate library From c33c5e09b8db8fbd68841b5ce81a28bbe58d8131 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 7 Apr 2024 14:43:33 +0200 Subject: [PATCH 107/191] :twisted_rightwards_arrows: merge ``main`` in. --- .../physical_design/design_sidb_gates.hpp | 5 +- .../simulation/sidb/is_operational.hpp | 2 +- .../technology/parameterized_gate_library.hpp | 38 +++---- .../technology/sidb_surface_analysis.hpp | 5 +- .../physical_design/design_sidb_gates.cpp | 107 +++++++++--------- .../is_sidb_gate_design_impossible.cpp | 2 +- 6 files changed, 80 insertions(+), 79 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index fb35a7c63..2a1230b1d 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -19,7 +19,6 @@ #include #include - #include #include #include @@ -315,7 +314,7 @@ class design_sidb_gates_impl are_sidbs_too_close(const std::vector& cells, const std::unordered_set& affected_cells = {}) const noexcept { - for (std::size_t i = 0; i < cell_indices.size(); i++) + for (std::size_t i = 0; i < cells.size(); i++) { if constexpr (has_get_sidb_defect_v) { @@ -330,7 +329,7 @@ class design_sidb_gates_impl } for (std::size_t j = i + 1; j < cells.size(); j++) { - if (sidb_nanometer_distance(skeleton_layout, cells[i], cells[j]) < 0.5) + if (sidb_nanometer_distance(cells[i], cells[j]) < 0.5) { return true; } diff --git a/include/fiction/algorithms/simulation/sidb/is_operational.hpp b/include/fiction/algorithms/simulation/sidb/is_operational.hpp index 09ce38fa6..879bdf08c 100644 --- a/include/fiction/algorithms/simulation/sidb/is_operational.hpp +++ b/include/fiction/algorithms/simulation/sidb/is_operational.hpp @@ -197,7 +197,7 @@ class is_operational_impl ++simulator_invocations; // if positively charged SiDBs can occur, the SiDB layout is considered as non-operational - if (can_positive_charges_occur(*bii, parameters.simulation_parameter)) + if (can_positive_charges_occur(*bii, parameters.phys_params)) { continue; } diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index cc7f209c8..f5f0951d1 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -13,7 +13,7 @@ #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/is_sidb_gate_design_impossible.hpp" -#include "fiction/technology/sidb_surface.hpp" +#include "fiction/technology/sidb_defect_surface.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" @@ -105,7 +105,7 @@ struct parameterized_gate_library_params /** * This layout stores all atomic defects. */ - sidb_surface defect_surface{}; + sidb_defect_surface defect_surface{}; /** * This struct holds parameters to design SiDB gates on-the-fly. */ @@ -174,7 +174,7 @@ class parameterized_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, create_fan_out_tt(), parameters, p, t); } } @@ -207,7 +207,7 @@ class parameterized_gate_library : public fcn_gate_library, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, create_double_wire_tt(), complex_gate_param, p, t); } @@ -225,7 +225,7 @@ class parameterized_gate_library : public fcn_gate_library, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, create_crossing_wire_tt(), complex_gate_param, p, t); } @@ -237,7 +237,7 @@ class parameterized_gate_library : public fcn_gate_library(cell_list), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } return EMPTY_GATE; @@ -251,7 +251,7 @@ class parameterized_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -263,7 +263,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -275,7 +275,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -287,7 +287,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -299,7 +299,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -311,7 +311,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -323,7 +323,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -335,7 +335,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -347,7 +347,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -359,7 +359,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -371,7 +371,7 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( + return design_gate, tt, CellLyt, GateLyt>( layout, std::vector{f}, parameters, p, t); } } @@ -587,7 +587,7 @@ class parameterized_gate_library : public fcn_gate_library - [[nodiscard]] static sidb_surface + [[nodiscard]] static sidb_defect_surface add_defect_to_skeleton(const CellLyt& skeleton, const cell& center_cell, const cell& absolute_cell, const Params& parameters) { @@ -596,7 +596,7 @@ class parameterized_gate_library : public fcn_gate_library) { - auto skeleton_with_defect = sidb_surface{skeleton}; + auto skeleton_with_defect = sidb_defect_surface{skeleton}; parameters.defect_surface.foreach_sidb_defect( [&skeleton_with_defect, ¢er_cell, &absolute_cell, ¶meters](const auto& cd) diff --git a/include/fiction/technology/sidb_surface_analysis.hpp b/include/fiction/technology/sidb_surface_analysis.hpp index e6cfe782d..5ecaee231 100644 --- a/include/fiction/technology/sidb_surface_analysis.hpp +++ b/include/fiction/technology/sidb_surface_analysis.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -49,7 +50,7 @@ using surface_black_list = * @tparam GateLyt Gate-level layout type that specifies the tiling of the SiDB surface. * @tparam CellLyt Cell-level layout type that is underlying to the SiDB surface. * @param gate_lyt Gate-level layout instance that specifies the aspect ratio. - * @param surface SiDB surface that instantiates the defects. + * @param sidb_defect_surface SiDB surface that instantiates the defects. * @param charged_defect_spacing_overwrite Override the default influence distance of charged atomic defects on SiDBs * with an optional pair of horizontal and vertical distances. * @param neutral_defect_spacing_overwrite Override the default influence distance of neutral atomic defects on SiDBs @@ -58,7 +59,7 @@ using surface_black_list = */ template [[nodiscard]] auto sidb_surface_analysis( - const GateLyt& gate_lyt, const sidb_surface& surface, + const GateLyt& gate_lyt, const sidb_defect_surface& surface, const std::optional>& charged_defect_spacing_overwrite = std::nullopt, const std::optional>& neutral_defect_spacing_overwrite = std::nullopt) noexcept { diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index de5a7289e..877960a69 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -55,68 +55,69 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; + SECTION("One cell in canvas") { - const design_sidb_gates_params params{ + const design_sidb_gates_params params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); - REQUIRE(found_gate_layouts.size() == 1); - CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == siqad_layout::technology::NORMAL); + REQUIRE(found_gate_layouts.size() == 1); + CHECK(found_gate_layouts[0].num_cells() == 14); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == siqad_layout::technology::NORMAL); - // using cube coordinates - const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params params_cube{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + // using cube coordinates + const auto lyt_in_cube_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_cube = design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); - REQUIRE(found_gate_layouts_cube.size() == 1); - CHECK(found_gate_layouts_cube[0].num_cells() == 14); - CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == - siqad_layout::technology::NORMAL); + REQUIRE(found_gate_layouts_cube.size() == 1); + CHECK(found_gate_layouts_cube[0].num_cells() == 14); + CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord( + siqad::coord_t{10, 4, 0})) == siqad_layout::technology::NORMAL); - // using offset coordinates - const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params params_offset{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_offset = design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); REQUIRE(found_gate_layouts_offset.size() == 1); CHECK(found_gate_layouts_offset[0].num_cells() == 14); - CHECK(found_gate_layouts_offset[0].get_cell_type( - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})) == layout::technology::NORMAL); + CHECK(found_gate_layouts_offset[0].get_cell_type(siqad::to_fiction_coord( + siqad::coord_t{10, 4, 0})) == offset_layout::technology::NORMAL); } SECTION("Four cells in canvas, design all gates") { - const design_sidb_gates_params> params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {13, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -127,19 +128,19 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ } SECTION("Four cells in canvas, design process is terminated after first solution is found") { - const design_sidb_gates_params> params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT, - design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION}; + design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION}; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); REQUIRE(found_gate_layouts.size() == 1); CHECK(found_gate_layouts[0].num_cells() == 14); - CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == layout::technology::NORMAL); + CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == siqad_layout::technology::NORMAL); } } @@ -164,9 +165,9 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ lyt.assign_cell_type({10, 9, 1}, sidb_technology::cell_type::NORMAL); - design_sidb_gates_params params{ + design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.28}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{4, 4, 0}, {14, 5, 1}}, 1, sidb_simulation_engine::EXGS}; @@ -179,7 +180,8 @@ TEST_CASE("Use SiQAD's AND gate skeleton to generate all possible AND gates", "[ SECTION("Random Generation") { - params.design_mode = design_sidb_gates_params::design_sidb_gates_mode::RANDOM; + params.design_mode = + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM; const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_and_tt()}, params); CHECK(!found_gate_layouts.empty()); } @@ -221,9 +223,9 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("generate original FO2") { - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{17, 11, 0}, {17, 11, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -241,10 +243,9 @@ TEST_CASE("Use FO2 Bestagon gate without SiDB at {17, 11, 0} and generate origin SECTION("replace the output perturbers by equivalent negatively charged defects") { - const design_sidb_gates_params> params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params< - sidb_defect_surface>::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{17, 11, 0}, {17, 11, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; @@ -300,9 +301,9 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") SECTION("Random Generation") { - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, {{14, 6, 0}, {24, 12, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; @@ -316,9 +317,9 @@ TEST_CASE("Design AND Bestagon shaped gate", "[design-sidb-gates]") { sidb_defect_surface defect_layout{lyt}; - const design_sidb_gates_params> params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, {{14, 6, 0}, {24, 12, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; @@ -377,9 +378,9 @@ TEST_CASE("Design AND Bestagon shaped gate on H-Si 111", "[design-sidb-gates]") SECTION("Random Generation") { - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::RANDOM, + design_sidb_gates_params>::design_sidb_gates_mode::RANDOM, {{10, 11, 0}, {14, 17, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; @@ -391,9 +392,9 @@ TEST_CASE("Design AND Bestagon shaped gate on H-Si 111", "[design-sidb-gates]") SECTION("Random Generation") { - const design_sidb_gates_params params{ + const design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 11, 0}, {14, 17, 0}}, 3, sidb_simulation_engine::QUICKEXACT}; diff --git a/test/technology/is_sidb_gate_design_impossible.cpp b/test/technology/is_sidb_gate_design_impossible.cpp index 1a4eef08e..58a80169c 100644 --- a/test/technology/is_sidb_gate_design_impossible.cpp +++ b/test/technology/is_sidb_gate_design_impossible.cpp @@ -6,8 +6,8 @@ #include "catch2/catch_template_test_macros.hpp" +#include #include -#include #include #include From 886b630d29ca9e53e6054d9687c5044cc1875c4d Mon Sep 17 00:00:00 2001 From: ClangFormat Date: Sat, 13 Apr 2024 12:48:22 +0000 Subject: [PATCH 108/191] :art: ClangFormat changes Signed-off-by: ClangFormat --- include/fiction/io/print_layout.hpp | 34 ++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/include/fiction/io/print_layout.hpp b/include/fiction/io/print_layout.hpp index 1b9feb1d4..256b2b004 100644 --- a/include/fiction/io/print_layout.hpp +++ b/include/fiction/io/print_layout.hpp @@ -405,26 +405,26 @@ void print_sidb_layout(std::ostream& os, const Lyt& lyt, const bool lat_color = std::sort(defects.begin(), defects.end()); - if (min_nw.x > defects.front().x) - { - min_nw.x = defects.front().x; - } - else if (min_nw.y > defects.front().y) - { - min_nw.y = defects.front().y; - } + if (min_nw.x > defects.front().x) + { + min_nw.x = defects.front().x; + } + else if (min_nw.y > defects.front().y) + { + min_nw.y = defects.front().y; + } - if (max_se.x < defects.back().x) - { - max_se.x = defects.back().x; - } - else if (max_se.y < defects.back().y) - { - max_se.y = defects.back().y; + if (max_se.x < defects.back().x) + { + max_se.x = defects.back().x; + } + else if (max_se.y < defects.back().y) + { + max_se.y = defects.back().y; + } + // if a defect is more south-east than se, this position is used as max } - // if a defect is more south-east than se, this position is used as max } - } if (crop_layout) { From 2cd33aadbf88c35763367a735668cc1ed815ad1f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 09:19:28 +0000 Subject: [PATCH 109/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/algorithms/apply_gate_library.rst | 2 +- .../physical_design_with_on_the_fly_gate_design.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index f856e611e..5121d7aaa 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -10,4 +10,4 @@ in the same :ref:`technology ` as the provided gate libra implementations for each gate present in the passed ``gate_level_layout``. .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) -.. doxygenfunction:: fiction::apply_parameterized_gate_library \ No newline at end of file +.. doxygenfunction:: fiction::apply_parameterized_gate_library diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 1cdaba127..7605e5063 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -60,7 +60,7 @@ int main() // NOLINT fiction::design_sidb_gates_params::termination_condition::AFTER_FIRST_SOLUTION; // save atomic defects which their respective phyiscal parameters as exerimentally determined by T. R. Huff, T. - // Dienel, M. Rashidi, R. Achal, L. Livadaru, J. Croshaw, and R. A. Wolkow, “Electrostatic landscape of a + // Dienel, M. Rashidi, R. Achal, L. Livadaru, J. Croshaw, and R. A. Wolkow, "Electrostatic landscape of a // Hydrogen-terminated Silicon Surface Probed by a Moveable Quantum Dot." const auto stray_db = fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}; const auto si_vacancy = fiction::sidb_defect{fiction::sidb_defect_type::SI_VACANCY, -1, 10.6, 5.9}; From dd3c9197cb237d899b4a7ad55e0dac703856ca5c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 24 Apr 2024 07:48:45 +0200 Subject: [PATCH 110/191] :art: update code after merge. --- ...cal_design_with_on_the_fly_gate_design.cpp | 8 ++-- .../technology/parameterized_gate_library.hpp | 43 +++++++------------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 7605e5063..adf47bc5c 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -19,9 +19,9 @@ #include // area requirement calculations #include // cell implementations #include // a dynamic SiDB gate library +#include // SiDB surface with support for atomic defects #include // Atomic defects #include // a static skeleton SiDB gate library defining the input/output wires -#include // SiDB surface with support for atomic defects #include // Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library #include // pre-defined types suitable for the FCN domain @@ -39,7 +39,9 @@ #include #include #include +#include #include +#include #include #include @@ -71,7 +73,7 @@ int main() // NOLINT auto surface_lattice_initial = fiction::read_sidb_surface_defects( "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt"); - fiction::sidb_surface surface_lattice{ + fiction::sidb_defect_surface surface_lattice{ {std::numeric_limits::max(), std::numeric_limits::max()}}; surface_lattice_initial.foreach_sidb_defect( @@ -235,7 +237,7 @@ int main() // NOLINT fiction::area_stats area_stats{}; fiction::area_params area_ps{}; fiction::area(cell_level_layout, area_ps, &area_stats); - fiction::sidb_surface defect_surface{cell_level_layout}; + fiction::sidb_defect_surface defect_surface{cell_level_layout}; // add defects to the file surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index f5f0951d1..d411bf38c 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -591,37 +591,24 @@ class parameterized_gate_library : public fcn_gate_library& center_cell, const cell& absolute_cell, const Params& parameters) { - static_assert(has_offset_ucoord_v || has_cube_coord_v, - "CellLyt must be either based on cube or offset coordinates"); + static_assert(has_cube_coord_v, "CellLyt must be based on offset coordinates"); - if constexpr (has_cube_coord_v) - { - auto skeleton_with_defect = sidb_defect_surface{skeleton}; + auto skeleton_with_defect = sidb_defect_surface{skeleton}; - parameters.defect_surface.foreach_sidb_defect( - [&skeleton_with_defect, ¢er_cell, &absolute_cell, ¶meters](const auto& cd) + parameters.defect_surface.foreach_sidb_defect( + [&skeleton_with_defect, ¢er_cell, &absolute_cell, ¶meters](const auto& cd) + { + // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken + // into account. + const auto defect_in_cube = offset_to_cube_coord(cd.first); + if (sidb_nanometer_distance(sidb_cell_clk_lyt_cube{}, center_cell, defect_in_cube) < + parameters.influence_radius_charged_defects) { - // all defects (charged) in a distance of influence_radius_charged_defects from the center are taken - // into account. - const auto defect_in_cube = offset_to_cube_coord(cd.first); - if (sidb_nanometer_distance(sidb_cell_clk_lyt_cube{}, center_cell, defect_in_cube) < - parameters.influence_radius_charged_defects) - { - const auto relative_cell = defect_in_cube - absolute_cell; - skeleton_with_defect.assign_sidb_defect(relative_cell, cd.second); - } - }); - return skeleton_with_defect; - } - else - { - const auto skeleton_in_cube_coordinates = - convert_offset_to_cube_coordinates(skeleton); - const auto center_cell_cube = offset_to_cube_coord(center_cell); - const auto absolute_cell_cube = offset_to_cube_coord(absolute_cell); - return add_defect_to_skeleton(skeleton_in_cube_coordinates, center_cell_cube, absolute_cell_cube, - parameters); - } + const auto relative_cell = defect_in_cube - absolute_cell; + skeleton_with_defect.assign_sidb_defect(relative_cell, cd.second); + } + }); + return skeleton_with_defect; } /** From 9a09cb908835fdf9024406db2db0e0da74a9453b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 24 Apr 2024 19:20:56 +0200 Subject: [PATCH 111/191] :art: update code after merge. --- .../fiction/algorithms/physical_design/design_sidb_gates.hpp | 5 ++--- include/fiction/algorithms/simulation/sidb/quickexact.hpp | 2 +- .../fiction/technology/is_sidb_gate_design_impossible.hpp | 5 ++--- test/algorithms/simulation/sidb/quickexact.cpp | 4 ++-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 0b043d217..e890c4f7d 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -6,12 +6,11 @@ #define FICTION_DESIGN_SIDB_GATES_HPP #include "fiction/algorithms/simulation/sidb/is_operational.hpp" -#include "fiction/algorithms/simulation/sidb/operational_domain.hpp" #include "fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" -#include "fiction/layouts/coordinates.hpp" #include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/sidb_nm_distance.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" #include "fiction/utils/math_utils.hpp" @@ -329,7 +328,7 @@ class design_sidb_gates_impl } for (std::size_t j = i + 1; j < cells.size(); j++) { - if (sidb_nanometer_distance(cells[i], cells[j]) < 0.5) + if (sidb_nm_distance(Lyt{}, cells[i], cells[j]) < 0.5) { return true; } diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index 72e7aa6f3..b159af844 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -498,7 +498,7 @@ class quickexact_impl { const auto& [cell, defect] = cd; - if (defect.type != sidb_defect_type::NONE && is_charged_defect(cd.second)) + if (defect.type != sidb_defect_type::NONE && is_charged_defect_type(cd.second)) { charge_lyt.add_sidb_defect_to_potential_landscape(cell, layout.get_sidb_defect(cell)); } diff --git a/include/fiction/technology/is_sidb_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp index 9a3782e36..64b199457 100644 --- a/include/fiction/technology/is_sidb_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -9,14 +9,13 @@ #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #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/technology/charge_distribution_surface.hpp" #include "fiction/technology/physical_constants.hpp" +#include "fiction/technology/sidb_charge_state.hpp" #include "fiction/technology/sidb_defects.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" -#include "fiction/utils/truth_table_utils.hpp" #include #include @@ -78,7 +77,7 @@ bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, layout.foreach_sidb_defect( [&charge_lyt](const auto& cd) { - if (is_charged_defect(cd.second)) + if (is_charged_defect_type(cd.second)) { charge_lyt.add_sidb_defect_to_potential_landscape(cd.first, cd.second); } diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 98a80248a..414dd9af4 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -1177,7 +1177,7 @@ TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shaped SiDB OR gate with input { SECTION("Epsilon_r = 8") { - params.physical_parameters.epsilon_r = 8; + params.simulation_parameters.epsilon_r = 8; std::set ground_state{}; std::set charge_index{}; for (auto i = 0; i < 10000; i++) @@ -1193,7 +1193,7 @@ TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shaped SiDB OR gate with input } SECTION("Epsilon_r = 2") { - params.physical_parameters.epsilon_r = 2; + params.simulation_parameters.epsilon_r = 2; std::set ground_state{}; std::set charge_index{}; for (auto i = 0; i < 10000; i++) From 7fecd25bc2bb25604c7734e81c399b3dbe87bac8 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 24 Apr 2024 19:31:11 +0200 Subject: [PATCH 112/191] :memo: small fix. --- docs/technology/gate_libraries.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index 3d53d6126..042bc3fb9 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -64,7 +64,7 @@ On-the-fly SiDB Library **Header:** ``fiction/technology/parameterized_gate_library.hpp`` -.. doxygenstruct:: fiction::sidb_on_the_fly_gate_library_params +.. doxygenstruct:: fiction::parameterized_gate_library_params :members: .. doxygenclass:: fiction::parameterized_gate_library :members: From 6437bd9e0a065299343f0e9a2363701a16f56351 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 24 Apr 2024 19:38:28 +0200 Subject: [PATCH 113/191] :memo: small fix. --- docs/algorithms/design_sidb_gates.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index 867b57d3a..d6eb229aa 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -22,4 +22,5 @@ Utility Functions **Header:** ``fiction/algorithms/physical_design/is_gate_design_impossible.hpp`` +.. doxygenstruct:: fiction::is_gate_design_impossible_params .. doxygenfunction:: fiction::is_gate_design_impossible From 1a2f65b77945764a765c4eed0ecf562d91ccebd6 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 25 Apr 2024 06:36:29 +0200 Subject: [PATCH 114/191] :memo: small fix. --- docs/algorithms/apply_gate_library.rst | 2 +- docs/algorithms/design_sidb_gates.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index bb55632b4..277d836ec 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -12,7 +12,7 @@ implementations for each gate present in the passed ``gate_level_layout``. **Header:** ``fiction/algorithms/physical_design/apply_gate_library.hpp`` .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) - .. doxygenfunction:: fiction::apply_parameterized_gate_library + .. doxygenfunction:: fiction::apply_parameterized_gate_library(const GateLyt& lyt, Params& params) .. tab:: Python .. autofunction:: mnt.pyfiction.apply_qca_one_library diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index d6eb229aa..9b5a832a5 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -23,4 +23,5 @@ Utility Functions **Header:** ``fiction/algorithms/physical_design/is_gate_design_impossible.hpp`` .. doxygenstruct:: fiction::is_gate_design_impossible_params + :members: .. doxygenfunction:: fiction::is_gate_design_impossible From 713b5280fd328051cede026e33d0248f78366fca Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 25 Apr 2024 06:41:35 +0200 Subject: [PATCH 115/191] :memo: small fix. --- docs/algorithms/design_sidb_gates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index 9b5a832a5..bc4e2039c 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -20,7 +20,7 @@ SiDB Gate Designer Utility Functions ################# -**Header:** ``fiction/algorithms/physical_design/is_gate_design_impossible.hpp`` +**Header:** ``fiction/algorithms/physical_design/is_sidb_gate_design_impossible.hpp`` .. doxygenstruct:: fiction::is_gate_design_impossible_params :members: From dc255463a66b8ead60fe3515664ad96bf26e96f3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 25 Apr 2024 06:47:14 +0200 Subject: [PATCH 116/191] :memo: small fix. --- docs/algorithms/design_sidb_gates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index bc4e2039c..3116d7bff 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -20,7 +20,7 @@ SiDB Gate Designer Utility Functions ################# -**Header:** ``fiction/algorithms/physical_design/is_sidb_gate_design_impossible.hpp`` +**Header:** ``fiction/technology/is_sidb_gate_design_impossible.hpp`` .. doxygenstruct:: fiction::is_gate_design_impossible_params :members: From ac71a114d2612e073e75c6ab5fd5afb5c83bb69e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 25 Apr 2024 10:18:21 +0200 Subject: [PATCH 117/191] :art: small update of experiments. --- ...ysical_design_with_on_the_fly_gate_design.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index adf47bc5c..faa3e4e20 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -54,10 +54,10 @@ int main() // NOLINT using cell_lyt = fiction::sidb_cell_clk_lyt; fiction::design_sidb_gates_params design_gate_params{}; - design_gate_params.phys_params = fiction::sidb_simulation_parameters{2, -0.32}; - design_gate_params.canvas = {{24, 17}, {34, 28}}; - design_gate_params.number_of_sidbs = 3; - design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; + design_gate_params.simulation_parameters = fiction::sidb_simulation_parameters{2, -0.32}; + design_gate_params.canvas = {{24, 17}, {34, 28}}; + design_gate_params.number_of_sidbs = 3; + design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; design_gate_params.termination_cond = fiction::design_sidb_gates_params::termination_condition::AFTER_FIRST_SOLUTION; @@ -118,8 +118,8 @@ int main() // NOLINT "layout area in nm²"}; // parameters for SMT-based physical design - fiction::exact_physical_design_params exact_params{}; - exact_params.scheme = fiction::ptr(fiction::row_clocking(fiction::num_clks::FOUR)); + fiction::exact_physical_design_params exact_params{}; + exact_params.scheme = "ROW4"; exact_params.crossings = false; exact_params.border_io = false; exact_params.desynchronize = true; @@ -182,14 +182,14 @@ int main() // NOLINT while (!gate_level_layout.has_value() || gate_design_failed) { - exact_params.black_list = black_list; fiction::exact_physical_design_stats exact_stats{}; if (!gate_level_layout.has_value() && attempts > 0) { break; } std::cout << black_list.size() << '\n'; - gate_level_layout = fiction::exact(mapped_network, exact_params, &exact_stats); + gate_level_layout = + fiction::exact_with_blacklist(mapped_network, black_list, exact_params, &exact_stats); if (gate_level_layout.has_value()) { try From ee0f25aaf606aae11496795014c1289262d3401f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 26 May 2024 10:51:58 +0200 Subject: [PATCH 118/191] :art: fix smaller issues. --- ...cal_design_with_on_the_fly_gate_design.cpp | 4 +- .../physical_design/apply_gate_library.hpp | 6 +- .../physical_design/design_sidb_gates.hpp | 2 +- .../technology/parameterized_gate_library.hpp | 79 ++++++------- .../technology_mapping.cpp | 108 ++++++++++++------ .../physical_design/design_sidb_gates.cpp | 22 ++-- 6 files changed, 132 insertions(+), 89 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index faa3e4e20..dbe94bc36 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -51,7 +51,7 @@ int main() // NOLINT { using gate_lyt = fiction::hex_even_row_gate_clk_lyt; - using cell_lyt = fiction::sidb_cell_clk_lyt; + using cell_lyt = fiction::sidb_cell_clk_lyt_cube; fiction::design_sidb_gates_params design_gate_params{}; design_gate_params.simulation_parameters = fiction::sidb_simulation_parameters{2, -0.32}; @@ -71,7 +71,7 @@ int main() // NOLINT fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); auto surface_lattice_initial = fiction::read_sidb_surface_defects( - "../../experiments/defect_aware_physical_design/1_percent_with_charged_surface.txt"); + "../../experiments/physical_design_with_on_the_fly_gate_design/1_percent_with_charged_surface.txt"); fiction::sidb_defect_surface surface_lattice{ {std::numeric_limits::max(), std::numeric_limits::max()}}; diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 2632a20b1..453776426 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -14,6 +14,8 @@ #include "fiction/utils/layout_utils.hpp" #include "fiction/utils/name_utils.hpp" +#include + #if (PROGRESS_BARS) #include #endif @@ -42,7 +44,7 @@ class apply_gate_library_impl { cell_lyt.resize(aspect_ratio{((gate_lyt.x() + 1) * GateLibrary::gate_x_size()) - 1, ((gate_lyt.y() + 1) * GateLibrary::gate_y_size()) - 1, gate_lyt.z()}); - cell_lyt.replace_clocking_scheme(gate_lyt.get_clocking_scheme()); + // cell_lyt.replace_clocking_scheme(gate_lyt.get_clocking_scheme()); cell_lyt.set_tile_size_x(GateLibrary::gate_x_size()); cell_lyt.set_tile_size_y(GateLibrary::gate_y_size()); } @@ -249,7 +251,7 @@ template , "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); + // static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); static_assert(mockturtle::has_is_constant_v, "GateLyt does not implement the is_constant function"); static_assert(mockturtle::has_foreach_node_v, "GateLyt does not implement the foreach_node function"); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 12da4ba1c..d9b03515a 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -113,7 +113,7 @@ class design_sidb_gates_impl * @param spec Expected Boolean function of the layout given as a multi-output truth table. * @param ps Parameters and settings for the gate designer. */ - design_sidb_gates_impl(const Lyt& skeleton, const std::vector& tt, + design_sidb_gates_impl(const Lyt& skeleton, const std::vector& spec, const design_sidb_gates_params>& ps) : skeleton_layout{skeleton}, truth_table{spec}, diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index d411bf38c..91196230a 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -5,7 +5,6 @@ #ifndef FICTION_PARAMETERIZED_GATE_LIBRARY_HPP #define FICTION_PARAMETERIZED_GATE_LIBRARY_HPP -#include "fiction/algorithms/path_finding/distance.hpp" #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" #include "fiction/layouts/coordinates.hpp" @@ -14,6 +13,7 @@ #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/is_sidb_gate_design_impossible.hpp" #include "fiction/technology/sidb_defect_surface.hpp" +#include "fiction/technology/sidb_nm_distance.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" @@ -21,8 +21,10 @@ #include #include +#include #include #include +#include #include #include @@ -149,7 +151,7 @@ class parameterized_gate_library : public fcn_gate_library& t, const Params& parameters = Params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); - static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); + // static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); @@ -174,8 +176,8 @@ class parameterized_gate_library : public fcn_gate_library(ONE_IN_TWO_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, create_fan_out_tt(), parameters, p, t); + return design_gate(layout, create_fan_out_tt(), + parameters, p, t); } } } @@ -207,7 +209,7 @@ class parameterized_gate_library : public fcn_gate_library, tt, CellLyt, GateLyt>( + return design_gate( layout, create_double_wire_tt(), complex_gate_param, p, t); } @@ -225,7 +227,7 @@ class parameterized_gate_library : public fcn_gate_library, tt, CellLyt, GateLyt>( + return design_gate( layout, create_crossing_wire_tt(), complex_gate_param, p, t); } @@ -237,8 +239,8 @@ class parameterized_gate_library : public fcn_gate_library(cell_list), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, + parameters, p, t); } return EMPTY_GATE; } @@ -251,8 +253,8 @@ class parameterized_gate_library : public fcn_gate_library(ONE_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (mockturtle::has_is_and_v) @@ -263,8 +265,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (mockturtle::has_is_or_v) @@ -275,8 +277,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_nand_v) @@ -287,8 +289,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_nor_v) @@ -299,8 +301,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (mockturtle::has_is_xor_v) @@ -311,8 +313,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_xnor_v) @@ -323,8 +325,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_ge_v) @@ -335,8 +337,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_le_v) @@ -347,8 +349,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_gt_v) @@ -359,8 +361,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } if constexpr (fiction::has_is_lt_v) @@ -371,8 +373,8 @@ class parameterized_gate_library : public fcn_gate_library(TWO_IN_ONE_OUT_MAP.at(p)), center_cell, absolute_cell, parameters); - return design_gate, tt, CellLyt, GateLyt>( - layout, std::vector{f}, parameters, p, t); + return design_gate(layout, std::vector{f}, parameters, + p, t); } } } @@ -411,7 +413,7 @@ class parameterized_gate_library : public fcn_gate_library(status == operational_status::OPERATIONAL); @@ -491,7 +493,7 @@ class parameterized_gate_library : public fcn_gate_library& parameters, const port_list& p, const tile& tile) { - const auto params = is_gate_design_impossible_params{parameters.design_gate_params.phys_params, + const auto params = is_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters, parameters.design_gate_params.sim_engine}; if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) { @@ -587,11 +589,11 @@ class parameterized_gate_library : public fcn_gate_library - [[nodiscard]] static sidb_defect_surface + [[nodiscard]] static sidb_defect_surface add_defect_to_skeleton(const CellLyt& skeleton, const cell& center_cell, const cell& absolute_cell, const Params& parameters) { - static_assert(has_cube_coord_v, "CellLyt must be based on offset coordinates"); + static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); auto skeleton_with_defect = sidb_defect_surface{skeleton}; @@ -600,11 +602,10 @@ class parameterized_gate_library : public fcn_gate_library -void map_and_check_all_3_inp(const Ntk& ntk) -void map_and_check_all_2_inp(const Ntk& ntk) +void map_and_check_all_standard_2_inp(const Ntk& ntk) { technology_mapping_stats stats{}; - const auto mapped_ntk = technology_mapping(ntk, all_2_input_functions(), &stats); + const auto mapped_ntk = technology_mapping(ntk, all_standard_2_input_functions(), &stats); REQUIRE(!stats.mapper_stats.mapping_error); @@ -125,18 +124,10 @@ void map_and_check_all_2_inp(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - - CHECK(gt_stats.num_and2 >= 0); - CHECK(gt_stats.num_or2 >= 0); - CHECK(gt_stats.num_nand2 >= 0); - CHECK(gt_stats.num_nor2 >= 0); - CHECK(gt_stats.num_xor2 >= 0); - CHECK(gt_stats.num_xnor2 >= 0); - CHECK(gt_stats.num_lt2 >= 0); - CHECK(gt_stats.num_gt2 >= 0); - CHECK(gt_stats.num_le2 >= 0); - CHECK(gt_stats.num_ge2 >= 0); + CHECK(gt_stats.num_lt2 == 0); + CHECK(gt_stats.num_gt2 == 0); + CHECK(gt_stats.num_le2 == 0); + CHECK(gt_stats.num_ge2 == 0); CHECK(gt_stats.num_and3 == 0); CHECK(gt_stats.num_xor_and == 0); @@ -183,12 +174,11 @@ void map_and_check_all_standard_3_inp(const Ntk& ntk) } template -void map_and_check_all_func(const Ntk& ntk) -void map_and_check_all_standard_func(const Ntk& ntk) +void map_and_check_all_3_inp(const Ntk& ntk) { technology_mapping_stats stats{}; - const auto mapped_ntk = technology_mapping(ntk, all_supported_standard_functions(), &stats); + const auto mapped_ntk = technology_mapping(ntk, all_standard_3_input_functions(), &stats); REQUIRE(!stats.mapper_stats.mapping_error); @@ -198,14 +188,39 @@ void map_and_check_all_standard_func(const Ntk& ntk) count_gate_types(mapped_ntk, >_stats); CHECK(gt_stats.num_inv >= 0); + CHECK(gt_stats.num_and3 >= 0); + CHECK(gt_stats.num_xor_and >= 0); + CHECK(gt_stats.num_or_and >= 0); + CHECK(gt_stats.num_onehot >= 0); + CHECK(gt_stats.num_maj3 >= 0); + CHECK(gt_stats.num_gamble >= 0); + CHECK(gt_stats.num_dot >= 0); + CHECK(gt_stats.num_mux >= 0); + CHECK(gt_stats.num_and_xor >= 0); - CHECK(gt_stats.num_and2 >= 0); - CHECK(gt_stats.num_or2 >= 0); - CHECK(gt_stats.num_nand2 >= 0); - CHECK(gt_stats.num_nor2 >= 0); - CHECK(gt_stats.num_xor2 >= 0); - CHECK(gt_stats.num_xnor2 >= 0); + CHECK(gt_stats.num_and2 == 0); + CHECK(gt_stats.num_or2 == 0); + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); +} + +template +void map_and_check_all_func(const Ntk& ntk) +{ + technology_mapping_stats stats{}; + + const auto mapped_ntk = technology_mapping(ntk, all_standard_3_input_functions(), &stats); + + REQUIRE(!stats.mapper_stats.mapping_error); + + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + CHECK(gt_stats.num_inv >= 0); CHECK(gt_stats.num_and3 >= 0); CHECK(gt_stats.num_xor_and >= 0); CHECK(gt_stats.num_or_and >= 0); @@ -215,22 +230,51 @@ void map_and_check_all_standard_func(const Ntk& ntk) CHECK(gt_stats.num_dot >= 0); CHECK(gt_stats.num_mux >= 0); CHECK(gt_stats.num_and_xor >= 0); + + CHECK(gt_stats.num_and2 == 0); + CHECK(gt_stats.num_or2 == 0); + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); + + CHECK(gt_stats.num_lt2 >= 0); + CHECK(gt_stats.num_gt2 >= 0); + CHECK(gt_stats.num_le2 >= 0); + CHECK(gt_stats.num_ge2 >= 0); } -TEMPLATE_TEST_CASE("Name conservation after technology mapping", "[technology-mapping]", mockturtle::aig_network, - mockturtle::xag_network, mockturtle::mig_network, mockturtle::xmg_network) +template +void map_and_check_all_standard_func(const Ntk& ntk) { - auto maj = blueprints::maj1_network>(); - maj.set_network_name("maj"); - technology_mapping_stats stats{}; - const auto mapped_maj = technology_mapping(maj, and_or_not_maj(), &stats); + const auto mapped_ntk = technology_mapping(ntk, all_standard_3_input_functions(), &stats); REQUIRE(!stats.mapper_stats.mapping_error); - // network name - CHECK(mapped_maj.get_network_name() == "maj"); + check_eq(ntk, mapped_ntk); + + count_gate_types_stats gt_stats{}; + count_gate_types(mapped_ntk, >_stats); + + CHECK(gt_stats.num_inv >= 0); + CHECK(gt_stats.num_and3 >= 0); + CHECK(gt_stats.num_xor_and >= 0); + CHECK(gt_stats.num_or_and >= 0); + CHECK(gt_stats.num_onehot >= 0); + CHECK(gt_stats.num_maj3 >= 0); + CHECK(gt_stats.num_gamble >= 0); + CHECK(gt_stats.num_dot >= 0); + CHECK(gt_stats.num_mux >= 0); + CHECK(gt_stats.num_and_xor >= 0); + + CHECK(gt_stats.num_and2 == 0); + CHECK(gt_stats.num_or2 == 0); + CHECK(gt_stats.num_nand2 == 0); + CHECK(gt_stats.num_nor2 == 0); + CHECK(gt_stats.num_xor2 == 0); + CHECK(gt_stats.num_xnor2 == 0); } TEMPLATE_TEST_CASE("Simple AOI network mapping", "[technology-mapping]", mockturtle::aig_network) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 6caf5022d..534cc2b98 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -61,10 +61,6 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ {{10, 4, 0}, {10, 4, 0}}, 1, sidb_simulation_engine::QUICKEXACT}; - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; SECTION("One cell in canvas") { @@ -99,15 +95,15 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord( siqad::coord_t{10, 4, 0})) == siqad_layout::technology::NORMAL); - // using offset coordinates - const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_offset{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + // using offset coordinates + const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_offset = design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); From d4dc6bb9120c349cc067df3bc1ca7d8227af35b5 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 26 May 2024 08:53:20 +0000 Subject: [PATCH 119/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 515 +++++++++++++++++- 1 file changed, 501 insertions(+), 14 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 90f8453db..0ef768e34 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -153,6 +153,13 @@ static const char *__doc_fiction_a_star_params_crossings = R"doc(Allow paths to cross over obstructed tiles if they are occupied by wire segments.)doc"; +static const char *__doc_fiction_all_2_input_functions = +R"doc(Auxiliary function to create technology mapping parameters for AND, +OR, NAND, NOR, XOR, XNOR, LE, GE, LT, GT, and NOT gates. + +Returns: + Technology mapping parameters.)doc"; + static const char *__doc_fiction_all_coordinates_in_spanned_area = R"doc(Generates a vector of all coordinates within an area spanned by two coordinates. @@ -198,6 +205,13 @@ static const char *__doc_fiction_all_standard_3_input_functions = R"doc(Auxiliary function to create technology mapping parameters for AND3, XOR_AND, OR_AND, ONEHOT, MAJ3, GAMBLE, DOT, MUX, and AND_XOR gates. +Returns: + Technology mapping parameters.)doc"; + +static const char *__doc_fiction_all_supported_functions = +R"doc(Auxiliary function to create technology mapping parameters for all +supported functions. + Returns: Technology mapping parameters.)doc"; @@ -250,6 +264,37 @@ Parameter ``lyt``: A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`.)doc"; +static const char *__doc_fiction_apply_parameterized_gate_library = +R"doc(Applies a parameterized gate library to a given gate-level layout and, +thereby, creates and returns a cell-level layout. + +May pass through, and thereby throw, an +`unsupported_gate_type_exception`, an +`unsupported_gate_orientation_exception` and any further custom +exceptions of the gate libraries. + +Template parameter ``CellLyt``: + Type of the returned cell-level layout. + +Template parameter ``GateLibrary``: + Type of the gate library to apply. + +Template parameter ``GateLyt``: + Type of the gate-level layout to apply the library to. + +Template parameter ``Params``: + Type of the parameter used for parameterized gate library. + +Parameter ``lyt``: + The gate-level layout. + +Parameter ``params``: + Parameter for the gate library. + +Returns: + A cell-level layout that implements `lyt`'s gate types with + building blocks defined in `GateLibrary`.)doc"; + static const char *__doc_fiction_area = R"doc(Computes the area of a given coordinate assuming its origin is (0, 0, 0). Calculates :math:`(|x| + 1) \cdot (|y| + 1)` by default. The @@ -2580,8 +2625,16 @@ static const char *__doc_fiction_count_gate_types_stats_num_fanout = R"doc()doc" static const char *__doc_fiction_count_gate_types_stats_num_gamble = R"doc()doc"; +static const char *__doc_fiction_count_gate_types_stats_num_ge2 = R"doc()doc"; + +static const char *__doc_fiction_count_gate_types_stats_num_gt2 = R"doc()doc"; + static const char *__doc_fiction_count_gate_types_stats_num_inv = R"doc()doc"; +static const char *__doc_fiction_count_gate_types_stats_num_le2 = R"doc()doc"; + +static const char *__doc_fiction_count_gate_types_stats_num_lt2 = R"doc()doc"; + static const char *__doc_fiction_count_gate_types_stats_num_maj3 = R"doc()doc"; static const char *__doc_fiction_count_gate_types_stats_num_mux = R"doc()doc"; @@ -3233,16 +3286,26 @@ static const char *__doc_fiction_debug_write_dot_layout = R"doc()doc"; static const char *__doc_fiction_debug_write_dot_network = R"doc()doc"; static const char *__doc_fiction_defect_extent = -R"doc(Returns the extent of a defect as a pair of SiDB distances in -horizontal and vertical direction. If `defect` has the `NONE` defect -type, `{0, 0}` is returned. +R"doc(Returns the extent of a defect as a pair of SiDB distances in the +horizontal and vertical directions. If the defect type is `NONE`, `{0, +0}` is returned. Parameter ``defect``: - Defect to evaluate. + Defect type to evaluate. + +Parameter ``charged_defect_spacing_overwrite``: + Override the default influence distance of charged atomic defects + on SiDBs with an optional pair of horizontal and vertical + distances. + +Parameter ``neutral_defect_spacing_overwrite``: + Override the default influence distance of neutral atomic defects + on SiDBs with an optional pair of horizontal and vertical + distances. Returns: - Number of horizontal and vertical SiDBs that are affected by the - given defect.)doc"; + A pair of uint16_t values representing the number of horizontal + and vertical SiDBs affected by the given defect type.)doc"; static const char *__doc_fiction_dependent_cell_mode = R"doc(An enumeration of modes for the dependent cell.)doc"; @@ -3321,6 +3384,25 @@ computation.)doc"; static const char *__doc_fiction_design_sidb_gates_params_simulation_parameters = R"doc(All Parameters for physical SiDB simulations.)doc"; +static const char *__doc_fiction_design_sidb_gates_params_termination_cond = +R"doc(The design process is terminated after a valid SiDB gate design is +found. + +@note This parameter has no effect unless the gate design is +exhaustive.)doc"; + +static const char *__doc_fiction_design_sidb_gates_params_termination_condition = +R"doc(Selector for the different termination conditions for the SiDB gate +design process.)doc"; + +static const char *__doc_fiction_design_sidb_gates_params_termination_condition_AFTER_FIRST_SOLUTION = +R"doc(The design process is terminated when a valid SiDB gate design is +found.)doc"; + +static const char *__doc_fiction_design_sidb_gates_params_termination_condition_ALL_COMBINATIONS_ENUMERATED = +R"doc(The design process ends after all possible combinations of SiDBs +within the canvas are enumerated.)doc"; + static const char *__doc_fiction_detail_a_star_impl = R"doc()doc"; static const char *__doc_fiction_detail_a_star_impl_a_star_impl = R"doc()doc"; @@ -3613,13 +3695,55 @@ static const char *__doc_fiction_detail_apply_gate_library_impl = R"doc()doc"; static const char *__doc_fiction_detail_apply_gate_library_impl_apply_gate_library_impl = R"doc()doc"; -static const char *__doc_fiction_detail_apply_gate_library_impl_assign_gate = R"doc()doc"; +static const char *__doc_fiction_detail_apply_gate_library_impl_assign_gate = +R"doc(This function assigns a given SiDB gate implemetation to the total +cell layout. + +Parameter ``c``: + Top-left cell of the tile where the gate is placed. + +Parameter ``g``: + Gate implementation. -static const char *__doc_fiction_detail_apply_gate_library_impl_cell_lyt = R"doc()doc"; +Parameter ``n``: + Corresponding node in the gate-level layout.)doc"; -static const char *__doc_fiction_detail_apply_gate_library_impl_gate_lyt = R"doc()doc"; +static const char *__doc_fiction_detail_apply_gate_library_impl_cell_lyt = R"doc(Cell-level layout.)doc"; -static const char *__doc_fiction_detail_apply_gate_library_impl_run = R"doc()doc"; +static const char *__doc_fiction_detail_apply_gate_library_impl_gate_lyt = R"doc(Gate-level layout.)doc"; + +static const char *__doc_fiction_detail_apply_gate_library_impl_run_parameterized_gate_library = +R"doc(Run the cell layout generation process. + +This function performs the cell layout generation process based on the +parameterized gate library and the gate-level layout information +provided by `GateLibrary` and `gate_lyt`. It iterates through the +nodes in the gate-level layout and assigns gates to cells based on +their corresponding positions and types. Optionally, it performs post- +layout optimization and sets the layout name if certain conditions are +met. + +Template parameter ``Type``: + of the Parameters used for the parameterized gate library. + +Parameter ``params``: + Parameters used for the parameterized gate library. + +Returns: + A `CellLyt` object representing the generated cell layout.)doc"; + +static const char *__doc_fiction_detail_apply_gate_library_impl_run_static_gate_library = +R"doc(Run the cell layout generation process. + +This function performs the cell layout generation process based on the +gate library and the gate-level layout information provided by +`GateLibrary` and `gate_lyt`. It iterates through the nodes in the +gate-level layout and assigns gates to cells based on their +corresponding positions and types. Optionally, it performs post-layout +optimization and sets the layout name if certain conditions are met. + +Returns: + A `CellLyt` object representing the generated cell layout.)doc"; static const char *__doc_fiction_detail_assess_physical_population_stability_impl = R"doc()doc"; @@ -4010,12 +4134,25 @@ the distance between SiDBs. If it finds any pair of SiDBs within a distance of 0.5 nanometers, it returns `true` to indicate that SiDBs are too close; otherwise, it returns `false`. -Parameter ``cell_indices``: - A vector of cell indices to check for SiDB proximity. +Parameter ``cells``: + A vector of cells to check for proximity. + +Template parameter ``affected_cells``: + All SiDBs that are affected by atomic defects. Returns: `true` if any SiDBs are too close; otherwise, `false`.)doc"; +static const char *__doc_fiction_detail_design_sidb_gates_impl_cell_indices_to_cell_vector = +R"doc(Converts a vector of cell indices to a vector of corresponding cells +in the layout. + +Parameter ``cell_indices``: + Vector of cell indices to convert. + +Returns: + A vector of cells corresponding to the given indices.)doc"; + static const char *__doc_fiction_detail_design_sidb_gates_impl_design_sidb_gates_impl = R"doc(This constructor initializes an instance of the *SiDB Gate Designer* implementation with the provided skeleton layout and configuration @@ -4024,7 +4161,7 @@ parameters. Parameter ``skeleton``: The skeleton layout used as a basis for gate design. -Parameter ``tt``: +Parameter ``spec``: Expected Boolean function of the layout given as a multi-output truth table. @@ -8259,6 +8396,41 @@ Parameter ``n``: Parameter ``fn``: Function object to apply to each outgoing edge of `n` in `ntk`.)doc"; +static const char *__doc_fiction_gate_design_exception = +R"doc(This exception is thrown when an error occurs during the design of an +SiDB gate. It provides information about the tile, truth table, and +port list associated with the error. + +Template parameter ``TT``: + The type representing the truth table. + +Template parameter ``GateLyt``: + The type representing the gate-level layout.)doc"; + +static const char *__doc_fiction_gate_design_exception_error_tile = R"doc(The tile associated with the error.)doc"; + +static const char *__doc_fiction_gate_design_exception_gate_design_exception = +R"doc(Constructor for the gate_design_exception class. + +Parameter ``ti``: + The tile associated with the error. + +Parameter ``spec``: + The truth table associated with the error. + +Parameter ``portlist``: + The port list associated with the error.)doc"; + +static const char *__doc_fiction_gate_design_exception_p = R"doc(The port list associated with the error.)doc"; + +static const char *__doc_fiction_gate_design_exception_truth_table = R"doc(The truth table associated with the error.)doc"; + +static const char *__doc_fiction_gate_design_exception_which_port_list = R"doc(Get the port list associated with the exception.)doc"; + +static const char *__doc_fiction_gate_design_exception_which_tile = R"doc(Get the tile associated with the exception.)doc"; + +static const char *__doc_fiction_gate_design_exception_which_truth_table = R"doc(Get the truth table associated with the exception.)doc"; + static const char *__doc_fiction_gate_layout_cartesian_drawer = R"doc(An extended gate-level layout DOT drawer for Cartesian layouts. @@ -9205,6 +9377,10 @@ Parameter ``t``: Returns: `true` iff `t` hosts a node that is a neither a constant nor a PI.)doc"; +static const char *__doc_fiction_gate_level_layout_is_ge = R"doc()doc"; + +static const char *__doc_fiction_gate_level_layout_is_gt = R"doc()doc"; + static const char *__doc_fiction_gate_level_layout_is_incoming_signal = R"doc(Checks whether signal `s` is incoming to tile `t`. That is, whether tile `t` hosts a node that has a fanin assigned to the tile that @@ -9232,6 +9408,10 @@ Parameter ``n``: Returns: `true` iff `n` is a NOT gate.)doc"; +static const char *__doc_fiction_gate_level_layout_is_le = R"doc()doc"; + +static const char *__doc_fiction_gate_level_layout_is_lt = R"doc()doc"; + static const char *__doc_fiction_gate_level_layout_is_maj = R"doc()doc"; static const char *__doc_fiction_gate_level_layout_is_nand = R"doc()doc"; @@ -9981,10 +10161,18 @@ static const char *__doc_fiction_has_is_gamble = R"doc()doc"; static const char *__doc_fiction_has_is_gate_tile = R"doc()doc"; +static const char *__doc_fiction_has_is_ge = R"doc()doc"; + +static const char *__doc_fiction_has_is_gt = R"doc()doc"; + static const char *__doc_fiction_has_is_incoming_clocked = R"doc()doc"; static const char *__doc_fiction_has_is_inv = R"doc()doc"; +static const char *__doc_fiction_has_is_le = R"doc()doc"; + +static const char *__doc_fiction_has_is_lt = R"doc()doc"; + static const char *__doc_fiction_has_is_mux = R"doc()doc"; static const char *__doc_fiction_has_is_nand = R"doc()doc"; @@ -11126,6 +11314,40 @@ Parameter ``ps``: `true` iff `ntk` is properly fanout-substituted with regard to `ps`.)doc"; +static const char *__doc_fiction_is_gate_design_impossible = +R"doc(This function evaluates whether it is impossible to design a SiDB gate +for a given truth table in the given layout due to atomic defects. It +determines the possible charge states at the output BDL pairs. Atomic +defects can cause a BDL pair to be neutrally charged only. Thus, the +BDL pair would not work as intended. + +Template parameter ``Lyt``: + Cell-level layout type. + +Template parameter ``TT``: + The type of the truth table. + +Parameter ``layout``: + The layout for which gate design feasibility is being checked. + +Parameter ``spec``: + A vector of truth tables (each truth table is representing one + output) representing the gate's functionality. + +Parameter ``params``: + Parameter to determine if the gate design is impossible. + +Returns: + `true` if gate design is impossible, `false` otherwise.)doc"; + +static const char *__doc_fiction_is_gate_design_impossible_params = +R"doc(This struct contains parameters to determine if SiDB gate design is +impossible.)doc"; + +static const char *__doc_fiction_is_gate_design_impossible_params_phys_params = R"doc(All parameters for physical SiDB simulations.)doc"; + +static const char *__doc_fiction_is_gate_design_impossible_params_sim_engine = R"doc(The simulation engine to be used for simulation.)doc"; + static const char *__doc_fiction_is_gate_level_layout = R"doc()doc"; static const char *__doc_fiction_is_ground_state = @@ -11676,6 +11898,15 @@ R"doc(\verbatim / \ / \ / \ / \ / \ / \ | (0,0) | (1,0) | (2,0) | | | | | \ static const char *__doc_fiction_offset_operator_lshift = R"doc()doc"; +static const char *__doc_fiction_offset_to_cube_coord = +R"doc(Converts offset coordinates to cube coordinates + +Parameter ``coord``: + Offset coordinate to convert to a cube coordinate. + +Returns: + Cube coordinate.)doc"; + static const char *__doc_fiction_offset_ucoord_t = R"doc(Unsigned offset coordinates. @@ -12392,6 +12623,201 @@ Parameter ``e``: Parameter ``other``: Edge whose color is to be used to paint `e`.)doc"; +static const char *__doc_fiction_parameterized_gate_library = +R"doc(A parameterized gate library for SiDB technology. It allows the design +of SiDB gates tailored to given atomic defects, thus enabling the +design of SiDB circuits in the presence of atomic defects. The +skeleton (i.e., the pre-defined input and output wires) are hexagonal +in shape.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_add_defect_to_skeleton = +R"doc(This function takes a defect surface and a skeleton skeleton and adds +defects from the surrounding area to the skeleton. The defects within +a specified distance from the center cell are taken into account. The +resulting skeleton with added defects is returned. + +Template parameter ``CellLyt``: + The type of the defect surface, which should not have SiQAD + coordinates. + +Template parameter ``Params``: + Type of Parameters. + +Parameter ``skeleton``: + The skeleton to which defects will be added. + +Parameter ``center_cell``: + The coordinates of the center cell. + +Parameter ``absolute_cell``: + The coordinates of the skeleton's absolute cell. + +Parameter ``parameters``: + Parameters for defect handling. + +Returns: + The updated skeleton with added defects from the surrounding area.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_cell_level_layout_to_list = +R"doc(Generates a cell-level layout as a 2D array of characters based on the +provided cell layout information. + +Template parameter ``CellLyt``: + Cell-level layout type. + +Parameter ``lyt``: + Cell-level layout + +Returns: + A 2D array of characters representing the cell-level layout.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_cell_list_to_cell_level_layout = +R"doc(The function generates a layout where each cell is assigned a specific +cell type according to the characters in the cell list/input grid. + +Template parameter ``Lyt``: + The type of the cell-level layout to be generated. + +Parameter ``cell_list``: + A 2D grid representing the cells and their types. + +Returns: + The cell-level layout with assigned cell types.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_design_gate = +R"doc(This function designs an SiDB gate for a given Boolean function at a +given tile and a given rotation. If atomic defects exist, they are +incorporated into the design process. + +An exception is thrown in case there is no possible gate design. + +Template parameter ``LytSkeleton``: + The cell-level layout of the skeleton. + +Template parameter ``TT``: + Truth table type. + +Template parameter ``CellLyt``: + The cell-level layout. + +Template parameter ``GateLyt``: + The gate-level layout. + +Parameter ``skeleton``: + Skeleton with atomic defects if available. + +Parameter ``spec``: + Expected Boolean function of the layout given as a multi-output + truth table. + +Parameter ``parameters``: + Parameters for the SiDB gate design process. + +Parameter ``p``: + The list of ports and their directions. + +Parameter ``tile``: + The specific tile on which the gate should be designed. + +Returns: + A fcn gate object.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_determine_port_routing = +R"doc(This function determines the port routing for a specific tile within a +layout represented by the object `lyt` of type `Lyt`. It examines the +tile's characteristics and connectivity to determine the appropriate +incoming and outgoing connector ports and populates them in a +`port_list` object. + +Parameter ``lyt``: + A reference to an object of type `Lyt` representing the layout. + +Parameter ``t``: + The tile for which port routing is being determined. + +Returns: + A `port_list` object containing the determined port directions for + incoming and outgoing signals.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_is_bestagon_gate_applicable = +R"doc(This function evaluates whether a Bestagon gate can be applied to the +given node by considering various conditions, including the presence +of defects and spacing requirements. + +Template parameter ``Lyt``: + The type of the cell-level layout. + +Template parameter ``TT``: + Truth table type. + +Template parameter ``Params``: + Type of the parameters used for the on-the-fly gate library. + +Parameter ``bestagon_lyt``: + The Bestagon gate which is to be applied. + +Parameter ``defect_lyt``: + The layout with defects that may affect gate applicability. + +Parameter ``parameters``: + Parameters for the gate design and simulation. + +Parameter ``truth_table``: + The truth table representing the gate's logic function. + +Returns: + `true` if the Bestagon gate is applicable to the layout, + considering the provided conditions; otherwise, returns `false`.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_parameterized_gate_library = R"doc()doc"; + +static const char *__doc_fiction_parameterized_gate_library_params = +R"doc(This struct encapsulates parameters for the on-the-fly SiDB gate +library. + +Template parameter ``Lyt``: + Cell-level layout type.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_params_canvas_sidb_complex_gates = +R"doc(This variable defines the number of canvas SiDBs dedicated to complex +gates, such as crossing, double wire, and half-adder.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_params_defect_surface = R"doc(This layout stores all atomic defects.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates on-the-fly.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_params_influence_radius_charged_defects = +R"doc(This variable specifies the radius around the middle of the hexagon +where atomic defects are incorporated into the gate design.)doc"; + +static const char *__doc_fiction_parameterized_gate_library_set_up_gate = +R"doc(Overrides the corresponding function in fcn_gate_library. Given a tile +`t`, this function takes all necessary information from the stored +grid into account to design the correct fcn_gate representation for +that tile. In case there is no possible SiDB design, the blacklist is +updated and an error fcn gate is returned. + +Template parameter ``GateLyt``: + Pointy-top hexagonal gate-level layout type. + +Template parameter ``CellLyt``: + The type of the cell-level layout. + +Template parameter ``Params``: + Type of the parameter used for the on-the-fly gate library. + +Parameter ``lyt``: + Layout that hosts tile `t`. + +Parameter ``t``: + Tile to be realized as a Bestagon gate. + +Parameter ``parameters``: + Parameter to design SiDB gates on-the-fly. + +Returns: + Bestagon gate representation of `t` including mirroring.)doc"; + static const char *__doc_fiction_path_collection = R"doc(An ordered collection of multiple paths in a layout. @@ -14036,6 +14462,37 @@ static const char *__doc_fiction_sidb_simulation_result_simulation_parameters = static const char *__doc_fiction_sidb_simulation_result_simulation_runtime = R"doc(Total simulation runtime.)doc"; +static const char *__doc_fiction_sidb_skeleton_bestagon_library = +R"doc(This library contains SiDB I/O wires designed for both 1- and 2-input +functions. Each wire comprises 2 BDL pairs. The library contains all +mirrored versions, a double wire and a crossing.)doc"; + +static const char *__doc_fiction_sidb_skeleton_bestagon_library_determine_port_routing = R"doc()doc"; + +static const char *__doc_fiction_sidb_skeleton_bestagon_library_get_functional_implementations = +R"doc(Returns a map of all gate functions supported by the library and their +respectively possible implementations. + +This is an optional interface function that is required by some +algorithms. + +Returns: + Map of all gate functions supported by the library and their + respective implementations as Bestagon skeletons.)doc"; + +static const char *__doc_fiction_sidb_skeleton_bestagon_library_get_gate_ports = +R"doc(Returns a map of all different gate implementations and their +respective port information. + +This is an optional interface function that is required by some +algorithms. + +Returns: + Map of all different gate implementations and their respective + port information.)doc"; + +static const char *__doc_fiction_sidb_skeleton_bestagon_library_sidb_skeleton_bestagon_library = R"doc()doc"; + static const char *__doc_fiction_sidb_surface_analysis = R"doc(Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library. Any gate type that cannot be realized on @@ -14058,9 +14515,19 @@ Template parameter ``CellLyt``: Parameter ``gate_lyt``: Gate-level layout instance that specifies the aspect ratio. -Parameter ``surface``: +Parameter ``sidb_defect_surface``: SiDB surface that instantiates the defects. +Parameter ``charged_defect_spacing_overwrite``: + Override the default influence distance of charged atomic defects + on SiDBs with an optional pair of horizontal and vertical + distances. + +Parameter ``neutral_defect_spacing_overwrite``: + Override the default influence distance of neutral atomic defects + on SiDBs with an optional pair of horizontal and vertical + distances. + Returns: A black list of gate functions associated with tiles.)doc"; @@ -14724,8 +15191,16 @@ static const char *__doc_fiction_technology_mapping_params_dot = R"doc(3-input D static const char *__doc_fiction_technology_mapping_params_gamble = R"doc(3-input GAMBLE gate.)doc"; +static const char *__doc_fiction_technology_mapping_params_ge2 = R"doc(2-input greater-or-equal gate.)doc"; + +static const char *__doc_fiction_technology_mapping_params_gt2 = R"doc(2-input greater-than gate.)doc"; + static const char *__doc_fiction_technology_mapping_params_inv = R"doc()doc"; +static const char *__doc_fiction_technology_mapping_params_le2 = R"doc(2-input less-or-equal gate.)doc"; + +static const char *__doc_fiction_technology_mapping_params_lt2 = R"doc(2-input less-than gate.)doc"; + static const char *__doc_fiction_technology_mapping_params_maj3 = R"doc(3-input MAJ gate.)doc"; static const char *__doc_fiction_technology_mapping_params_mapper_params = R"doc(mockturtle's mapper parameters.)doc"; @@ -14797,6 +15272,10 @@ Parameter ``a``: static const char *__doc_fiction_technology_network_create_dot = R"doc()doc"; +static const char *__doc_fiction_technology_network_create_ge = R"doc()doc"; + +static const char *__doc_fiction_technology_network_create_gt = R"doc()doc"; + static const char *__doc_fiction_technology_network_create_ite = R"doc()doc"; static const char *__doc_fiction_technology_network_create_le = R"doc()doc"; @@ -14860,6 +15339,10 @@ Parameter ``n``: static const char *__doc_fiction_technology_network_is_gamble = R"doc()doc"; +static const char *__doc_fiction_technology_network_is_ge = R"doc()doc"; + +static const char *__doc_fiction_technology_network_is_gt = R"doc()doc"; + static const char *__doc_fiction_technology_network_is_inv = R"doc(Returns whether the given node `n` is an inverter node. @@ -14871,6 +15354,10 @@ Parameter ``n``: static const char *__doc_fiction_technology_network_is_ite = R"doc()doc"; +static const char *__doc_fiction_technology_network_is_le = R"doc()doc"; + +static const char *__doc_fiction_technology_network_is_lt = R"doc()doc"; + static const char *__doc_fiction_technology_network_is_maj = R"doc()doc"; static const char *__doc_fiction_technology_network_is_nand = R"doc()doc"; From 31a6c3be581e892176cd391467eb0afd22401886 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 26 May 2024 11:31:10 +0200 Subject: [PATCH 120/191] :art: small fix. --- .../algorithms/network_transformation/fanout_substitution.hpp | 1 + .../algorithms/network_transformation/technology_mapping.hpp | 1 + .../pyfiction/include/pyfiction/layouts/cartesian_layout.hpp | 1 + .../pyfiction/include/pyfiction/technology/sidb_defects.hpp | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/fanout_substitution.hpp b/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/fanout_substitution.hpp index d9298bf1b..5f6eb5bf4 100644 --- a/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/fanout_substitution.hpp +++ b/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/fanout_substitution.hpp @@ -10,6 +10,7 @@ #include +#include #include namespace pyfiction diff --git a/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/technology_mapping.hpp b/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/technology_mapping.hpp index 7961e17e5..705c56a84 100644 --- a/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/technology_mapping.hpp +++ b/bindings/pyfiction/include/pyfiction/algorithms/network_transformation/technology_mapping.hpp @@ -10,6 +10,7 @@ #include +#include #include namespace pyfiction diff --git a/bindings/pyfiction/include/pyfiction/layouts/cartesian_layout.hpp b/bindings/pyfiction/include/pyfiction/layouts/cartesian_layout.hpp index e0b6f9040..ee2a1e25b 100644 --- a/bindings/pyfiction/include/pyfiction/layouts/cartesian_layout.hpp +++ b/bindings/pyfiction/include/pyfiction/layouts/cartesian_layout.hpp @@ -8,6 +8,7 @@ #include "pyfiction/documentation.hpp" #include "pyfiction/types.hpp" +#include #include #include diff --git a/bindings/pyfiction/include/pyfiction/technology/sidb_defects.hpp b/bindings/pyfiction/include/pyfiction/technology/sidb_defects.hpp index 0d6830570..4f4cd8439 100644 --- a/bindings/pyfiction/include/pyfiction/technology/sidb_defects.hpp +++ b/bindings/pyfiction/include/pyfiction/technology/sidb_defects.hpp @@ -67,7 +67,8 @@ inline void sidb_defects(pybind11::module& m) m.def("is_neutrally_charged_defect", &fiction::is_neutrally_charged_defect, "defect"_a, DOC(fiction_is_neutrally_charged_defect)); - m.def("defect_extent", &fiction::defect_extent, "defect"_a, DOC(fiction_defect_extent)); + m.def("defect_extent", &fiction::defect_extent, "defect"_a, "charged_defect_spacing_overwrite"_a, + "neutral_defect_spacing_overwrite"_a, DOC(fiction_defect_extent)); } } // namespace pyfiction From f239635e7231d1c529e213b87c6ad26a4735edf8 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 May 2024 10:32:39 +0200 Subject: [PATCH 121/191] :art: add defect support to bounding box. --- include/fiction/layouts/bounding_box.hpp | 212 ++++++++++++++++++----- test/layouts/bounding_box.cpp | 146 +++++++++++++++- 2 files changed, 315 insertions(+), 43 deletions(-) diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index 4ed64b9d9..746235b2a 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -58,84 +58,216 @@ class bounding_box_2d // empty layouts don't need further computation if (layout.is_empty()) { - return; + if constexpr (is_sidb_defect_surface_v) + { + if (layout.num_defects() == 0) + { + return; + } + } + else + { + return; + } } // the layout is based on SiQAD coordinates if constexpr (has_siqad_coord_v) { - int32_t min_x = std::numeric_limits::max(); - int32_t max_x = std::numeric_limits::min(); + int32_t min_x_cell = std::numeric_limits::max(); + int32_t max_x_cell = std::numeric_limits::min(); - int32_t min_y = std::numeric_limits::max(); - int32_t max_y = std::numeric_limits::min(); + int32_t min_y_cell = std::numeric_limits::max(); + int32_t max_y_cell = std::numeric_limits::min(); - uint8_t min_z = 1; - uint8_t max_z = 0; + uint8_t min_z_cell = 1; + uint8_t max_z_cell = 0; layout.foreach_cell( - [&min_x, &max_x, &min_y, &max_y, &min_z, &max_z](const auto& c) + [&min_x_cell, &max_x_cell, &min_y_cell, &max_y_cell, &min_z_cell, &max_z_cell](const auto& c) { - if (c.x < min_x) + if (c.x < min_x_cell) { - min_x = c.x; + min_x_cell = c.x; } - if (c.x > max_x) + if (c.x > max_x_cell) { - max_x = c.x; + max_x_cell = c.x; } - if (c.y == min_y && c.z < min_z) + if (c.y == min_y_cell && c.z < min_z_cell) { - min_z = c.z; + min_z_cell = c.z; } - if (c.y < min_y) + if (c.y < min_y_cell) { - min_y = c.y; - min_z = c.z; + min_y_cell = c.y; + min_z_cell = c.z; } - if (c.y == max_y && c.z > max_z) + if (c.y == max_y_cell && c.z > max_z_cell) { - max_z = c.z; + max_z_cell = c.z; } - if (c.y > max_y) + if (c.y > max_y_cell) { - max_y = c.y; - max_z = c.z; + max_y_cell = c.y; + max_z_cell = c.z; } }); - min = {min_x, min_y, min_z}; - max = {max_x, max_y, max_z}; + + const auto min_cell = coordinate{min_x_cell, min_y_cell, min_z_cell}; + const auto max_cell = coordinate{max_x_cell, max_y_cell, max_z_cell}; + + min = min_cell; + max = max_cell; + + if constexpr (is_sidb_defect_surface_v) + { + int32_t min_x_defect = std::numeric_limits::max(); + int32_t max_x_defect = std::numeric_limits::min(); + + int32_t min_y_defect = std::numeric_limits::max(); + int32_t max_y_defect = std::numeric_limits::min(); + + uint8_t min_z_defect = 1; + uint8_t max_z_defect = 0; + + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, + &max_z_defect](const auto& defect) + { + if (defect.first.x < min_x_defect) + { + min_x_defect = defect.first.x; + } + if (defect.first.x > max_x_defect) + { + max_x_defect = defect.first.x; + } + + if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) + { + min_z_defect = defect.first.z; + } + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + min_z_defect = defect.first.z; + } + + if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) + { + max_z_defect = defect.first.z; + } + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + max_z_defect = defect.first.z; + } + }); + const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; + + min = (min_cell < min_defect) ? min_cell : min_defect; + max = (max_cell > max_defect) ? max_cell : max_defect; + } } else { - // set min to max coordinate in the layout - min = {layout.x(), layout.y()}; + min = coordinate{std::numeric_limits::x)>::max(), + std::numeric_limits::x)>::max()}; - layout.foreach_coordinate( - [this](const auto& c) - { - if (!is_empty_coordinate(c)) + if constexpr (is_gate_level_layout_v) + { + layout.foreach_coordinate( + [this](const auto& c) { - if (c.x < min.x) + if (!is_empty_coordinate(c)) { - min.x = c.x; + if (c.x < min.x) + { + min.x = c.x; + } + if (c.y < min.y) + { + min.y = c.y; + } + if (c.x > max.x) + { + max.x = c.x; + } + if (c.y > max.y) + { + max.y = c.y; + } } - if (c.y < min.y) + }); + } + + if constexpr (is_cell_level_layout_v) + { + layout.foreach_cell( + [this](const auto& c) + { + if (!layout.is_empty_cell(c)) { - min.y = c.y; + if (c.x < min.x) + { + min.x = c.x; + } + if (c.y < min.y) + { + min.y = c.y; + } + if (c.x > max.x) + { + max.x = c.x; + } + if (c.y > max.y) + { + max.y = c.y; + } } - if (c.x > max.x) + }); + } + + if constexpr (is_sidb_defect_surface_v) + { + auto min_x_defect = std::numeric_limits::x)>::max(); + auto max_x_defect = std::numeric_limits::y)>::min(); + + auto min_y_defect = std::numeric_limits::x)>::max(); + auto max_y_defect = std::numeric_limits::y)>::min(); + + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) + { + if (defect.first.x < min_x_defect) { - max.x = c.x; + min_x_defect = defect.first.x; } - if (c.y > max.y) + if (defect.first.x > max_x_defect) { - max.y = c.y; + max_x_defect = defect.first.x; } - } - }); + + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + } + + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + } + }); + const auto min_defect = coordinate{min_x_defect, min_y_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect}; + + min = (min < min_defect) ? min : min_defect; + max = (max > max_defect) ? max : max_defect; + } } x_size = max.x - min.x; diff --git a/test/layouts/bounding_box.cpp b/test/layouts/bounding_box.cpp index f4610df23..6fcb8c0e5 100644 --- a/test/layouts/bounding_box.cpp +++ b/test/layouts/bounding_box.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include @@ -36,7 +36,7 @@ TEST_CASE("Initialize 2D gate-level bounding box", "[bounding-box]") const auto lyt_or_not = blueprints::or_not_gate_layout(); - bounding_box_2d bb_or_not{lyt_or_not}; + const bounding_box_2d bb_or_not{lyt_or_not}; CHECK(bb_or_not.get_min() == tile{0, 0}); CHECK(bb_or_not.get_max() == tile{2, 2}); @@ -93,7 +93,7 @@ TEST_CASE("Initialize 2D cell-level bounding box", "[bounding-box]") { const auto lyt_and = blueprints::single_layer_qca_and_gate(); - bounding_box_2d bb_and{lyt_and}; + const bounding_box_2d bb_and{lyt_and}; CHECK(bb_and.get_min() == cell{0, 0}); CHECK(bb_and.get_max() == cell{4, 4}); @@ -223,3 +223,143 @@ TEMPLATE_TEST_CASE("2D bounding box for siqad layout", "[bounding-box]", sidb_ce CHECK(se == siqad::coord_t{2, 4, 1}); } } + +TEMPLATE_TEST_CASE("2D bounding box for siqad layout with atomic defect", "[bounding-box]", + sidb_defect_cell_clk_lyt_siqad, sidb_defect_surface, + sidb_defect_100_cell_clk_lyt_siqad) +{ + SECTION("empyt layout") + { + const TestType lyt{}; + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == siqad::coord_t(0, 0, 0)); + CHECK(se == siqad::coord_t(0, 0, 0)); + } + + SECTION("one cell and one defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == siqad::coord_t{1, 0, 0}); + CHECK(se == siqad::coord_t{2, 0, 0}); + } + + SECTION("two cell and two defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); + lyt.assign_cell_type({-2, 0, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); + lyt.assign_sidb_defect({2, 0, 1}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == siqad::coord_t{-2, 0, 0}); + CHECK(se == siqad::coord_t{2, 0, 1}); + } +} + +TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-box]", sidb_defect_cell_clk_lyt, + sidb_defect_surface, sidb_defect_100_cell_clk_lyt) +{ + SECTION("empyt layout") + { + const TestType lyt{}; + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{0, 0, 0}); + CHECK(se == cell{0, 0, 0}); + } + + SECTION("one cell and one defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{1, 0, 0}); + CHECK(se == cell{2, 0, 0}); + } + + SECTION("two cell and two defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); + lyt.assign_cell_type({3, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({2, 0}, sidb_defect{}); + lyt.assign_sidb_defect({2, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{1, 0}); + CHECK(se == cell{3, 0}); + } +} + +TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bounding-box]", + sidb_defect_cell_clk_lyt_cube, sidb_defect_surface, + sidb_defect_100_cell_clk_lyt_cube) +{ + SECTION("empyt layout") + { + const TestType lyt{}; + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{0, 0}); + CHECK(se == cell{0, 0}); + } + + SECTION("one cell and one defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({2, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{1, 0}); + CHECK(se == cell{2, 0}); + } + + SECTION("two cell and two defect") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); + lyt.assign_cell_type({2, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({-3, 0}, sidb_defect{}); + lyt.assign_sidb_defect({2, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{-3, 0}); + CHECK(se == cell{2, 0}); + } +} From 1658dcbdc5a86d084c2e9c3a0302fdd8f69d97ab Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 May 2024 10:33:09 +0200 Subject: [PATCH 122/191] :art: small fixes. --- ...physical_design_with_on_the_fly_gate_design.cpp | 14 ++++++++++---- include/fiction/io/read_sidb_surface_defects.hpp | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index dbe94bc36..82b1c698c 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -13,7 +13,8 @@ #include // critical path and throughput calculations #include // choose design engine (ExGS, QuickSim, QuickExact) #include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include // writer for SiQAD files (physical simulation) +#include #include // layout coordinates #include // technology-mapped network type #include // area requirement calculations @@ -23,7 +24,8 @@ #include // Atomic defects #include // a static skeleton SiDB gate library defining the input/output wires #include // Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library -#include // pre-defined types suitable for the FCN domain +#include // pre-defined traits +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing @@ -73,8 +75,8 @@ int main() // NOLINT auto surface_lattice_initial = fiction::read_sidb_surface_defects( "../../experiments/physical_design_with_on_the_fly_gate_design/1_percent_with_charged_surface.txt"); - fiction::sidb_defect_surface surface_lattice{ - {std::numeric_limits::max(), std::numeric_limits::max()}}; + // create an empty surface with the maximal possible dimension. + fiction::sidb_defect_surface surface_lattice{}; surface_lattice_initial.foreach_sidb_defect( [&surface_lattice, &stray_db, &si_vacancy](const auto& cd) @@ -93,6 +95,10 @@ int main() // NOLINT } }); + const auto bb = fiction::bounding_box_2d{surface_lattice}; + + surface_lattice.resize(bb.get_max()); + const auto lattice_tiling = gate_lyt{{11, 30}}; experiments::experiment(row_matches.size() - 1); } - else if (row_matches.size() - 1 < max_cell_pos.x) + else if (static_cast(row_matches.size() - 1) < max_cell_pos.x) { // row y has fewer SiDBs than previous rows throw missing_sidb_position_exception(y); From 3ce98c0be166c696525e9f264dfc1c2a4299f1ef Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 08:34:13 +0000 Subject: [PATCH 123/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physical_design_with_on_the_fly_gate_design.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 82b1c698c..090063090 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -24,8 +24,8 @@ #include // Atomic defects #include // a static skeleton SiDB gate library defining the input/output wires #include // Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library -#include // pre-defined traits -#include // pre-defined types suitable for the FCN domain +#include // pre-defined traits +#include // pre-defined types suitable for the FCN domain #include // output formatting #include // Verilog/BLIF/AIGER/... file parsing From b5b3432234d40e9b750117dda8d3141ca03776db Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 May 2024 11:00:18 +0200 Subject: [PATCH 124/191] :bug: ``min`` and ``max`` are calculated correctly. --- include/fiction/io/print_layout.hpp | 33 -------- include/fiction/layouts/bounding_box.hpp | 18 ++-- .../technology/parameterized_gate_library.hpp | 9 +- test/io/print_layout.cpp | 84 +++++++++---------- 4 files changed, 61 insertions(+), 83 deletions(-) diff --git a/include/fiction/io/print_layout.hpp b/include/fiction/io/print_layout.hpp index 256b2b004..ad3b19d0d 100644 --- a/include/fiction/io/print_layout.hpp +++ b/include/fiction/io/print_layout.hpp @@ -393,39 +393,6 @@ void print_sidb_layout(std::ostream& os, const Lyt& lyt, const bool lat_color = auto min_nw = bb.get_min(); auto max_se = bb.get_max(); - std::vector defects{}; - - // if defects exist in the layout - if constexpr (has_get_sidb_defect_v) - { - if (lyt.num_defects() != 0) - { - defects.reserve(lyt.num_defects()); - lyt.foreach_sidb_defect([&defects](const auto& c) { defects.push_back(c.first); }); - - std::sort(defects.begin(), defects.end()); - - if (min_nw.x > defects.front().x) - { - min_nw.x = defects.front().x; - } - else if (min_nw.y > defects.front().y) - { - min_nw.y = defects.front().y; - } - - if (max_se.x < defects.back().x) - { - max_se.x = defects.back().x; - } - else if (max_se.y < defects.back().y) - { - max_se.y = defects.back().y; - } - // if a defect is more south-east than se, this position is used as max - } - } - if (crop_layout) { // apply padding of maximally one dimer row and two columns diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index 746235b2a..eb415ae70 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -5,13 +5,11 @@ #ifndef FICTION_BOUNDING_BOX_HPP #define FICTION_BOUNDING_BOX_HPP -#include "fiction/layouts/cell_level_layout.hpp" -#include "fiction/layouts/coordinates.hpp" -#include "fiction/technology/cell_ports.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" #include "fiction/utils/layout_utils.hpp" +#include #include #include @@ -169,8 +167,11 @@ class bounding_box_2d const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; - min = (min_cell < min_defect) ? min_cell : min_defect; - max = (max_cell > max_defect) ? max_cell : max_defect; + min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), + std::min(min_cell.z, min_defect.z)}; + max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), + std::max(max_cell.z, max_defect.z)}; + ; } } else @@ -265,8 +266,11 @@ class bounding_box_2d const auto min_defect = coordinate{min_x_defect, min_y_defect}; const auto max_defect = coordinate{max_x_defect, max_y_defect}; - min = (min < min_defect) ? min : min_defect; - max = (max > max_defect) ? max : max_defect; + min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), + std::min(min.z, min_defect.z)}; + max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), + std::max(max.z, max_defect.z)}; + ; } } diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index 91196230a..c4ad714b3 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -493,6 +493,10 @@ class parameterized_gate_library : public fcn_gate_library& parameters, const port_list& p, const tile& tile) { + 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_cube_coord_v, "Lyt is not based on cube coordinates"); + const auto params = is_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters, parameters.design_gate_params.sim_engine}; if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) @@ -593,7 +597,10 @@ class parameterized_gate_library : public fcn_gate_library& center_cell, const cell& absolute_cell, const Params& parameters) { - static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); + 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_cube_coord_v, "Lyt is not based on cube coordinates"); + ; auto skeleton_with_defect = sidb_defect_surface{skeleton}; diff --git a/test/io/print_layout.cpp b/test/io/print_layout.cpp index e18f4b415..819ad5087 100644 --- a/test/io/print_layout.cpp +++ b/test/io/print_layout.cpp @@ -469,68 +469,68 @@ TEST_CASE("Print Bestagon OR-gate with defect", "[print-charge-layout]") print_sidb_layout(print_stream, cl, false, true, true); constexpr const char* layout_print = - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊟ \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊟ · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · ◯ · ⊞ · · · · · · · · · · · · · · · · · · · · · · · ● · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · ◯ · ⊞ · · · · · · · · · · · · · · · · · · · · · · · ● · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · ● · · · · · · · · · · · · · · · · · · · · · ● · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · ● · · · · · · · · · · · · · · · · · · · · · ● · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · ● · · · · · · · · · · · · · ◯ · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · ⊡ · · · · \n" + " · · · · · · · · ● · · · · · · · · · · · · · ◯ · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · ⊡ · · · · · · \n" "\n" - " · · · · · · · · · · ● · · · · · · · · · ⨁ · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · ● · · · · · · · · · ⨁ · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · ⨁ · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · ⨁ · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · ● · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · ⨁ · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · ⨁ · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · ◯ · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · ◯ · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · ● · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · ● · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ● · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ● · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊞ · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · ⊞ · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" "\n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" - " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n"; + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n" + " · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · \n"; CHECK(layout_print == print_stream.str()); } From f4e3b32a5b055d46c2a7952e7107b4417e7ecf3b Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 27 May 2024 14:33:43 +0200 Subject: [PATCH 125/191] :art: small fix. --- .../algorithms/physical_design/design_sidb_gates.hpp | 1 + test/algorithms/physical_design/design_sidb_gates.cpp | 7 ------- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index d9b03515a..7b83ab3ca 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -10,6 +10,7 @@ #include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/technology/cell_technologies.hpp" +#include "fiction/technology/sidb_defects.hpp" #include "fiction/technology/sidb_nm_distance.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index 534cc2b98..ff8957865 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -64,13 +64,6 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ SECTION("One cell in canvas") { - const design_sidb_gates_params params{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params::design_sidb_gates_mode::EXHAUSTIVE, - {{10, 4, 0}, {10, 4, 0}}, - 1, - sidb_simulation_engine::QUICKEXACT}; - const auto found_gate_layouts = design_sidb_gates(lyt, std::vector{create_xnor_tt()}, params); REQUIRE(found_gate_layouts.size() == 1); From ea3b798a7eae3f04537a7635d4d7f5786787f7a8 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 28 May 2024 10:07:54 +0200 Subject: [PATCH 126/191] :art: simplify the experiment script. --- ...cal_design_with_on_the_fly_gate_design.cpp | 53 ++++++------------- 1 file changed, 15 insertions(+), 38 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 090063090..7e90dd9be 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -10,7 +10,6 @@ #include // layout conversion to cell-level #include // design gate #include // SMT-based physical design of FCN layouts -#include // critical path and throughput calculations #include // choose design engine (ExGS, QuickSim, QuickExact) #include // reader for simulated SiDB surfaces #include // writer for SiQAD files (physical simulation) @@ -42,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -95,38 +93,20 @@ int main() // NOLINT } }); + // ddetermine the bounding box around the defective surface. const auto bb = fiction::bounding_box_2d{surface_lattice}; - surface_lattice.resize(bb.get_max()); const auto lattice_tiling = gate_lyt{{11, 30}}; - experiments::experiment - sidb_circuits_with_defects{"sidb_circuits_with_defects", - "benchmark", - "inputs", - "outputs", - "initial nodes", - "initial depth", - "optimized nodes", - "optimized depth", - "layout width (in tiles)", - "layout height (in tiles)", - "layout area (in tiles)", - "gates", - "wires", - "critical path", - "throughput", - "runtime (in sec)", - "equivalent", - "SiDB dots", - "layout area in nm²"}; + experiments::experiment sidb_circuits_with_defects{ + "sidb_circuits_with_defects", "benchmark", "runtime (in sec)", "equivalent", "layout area in nm²", + "number of aspect ratios"}; // parameters for SMT-based physical design fiction::exact_physical_design_params exact_params{}; exact_params.scheme = "ROW4"; - exact_params.crossings = false; + exact_params.crossings = true; exact_params.border_io = false; exact_params.desynchronize = true; exact_params.upper_bound_x = 11; // 12 x 31 tiles @@ -137,7 +117,7 @@ int main() // NOLINT fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & ~fiction_experiments::b1_r2 & ~fiction_experiments::clpl & ~fiction_experiments::iscas85 & ~fiction_experiments::epfl & ~fiction_experiments::half_adder & ~fiction_experiments::full_adder & - ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj; + ~fiction_experiments::one_bit_add_aoig & ~fiction_experiments::one_bit_add_maj & ~fiction_experiments::cm82a_5; for (const auto& benchmark : fiction_experiments::all_benchmarks(bench_select)) { @@ -183,12 +163,14 @@ int main() // NOLINT auto gate_design_failed = true; + fiction::exact_physical_design_stats exact_stats{}; + { const mockturtle::stopwatch stop{time_counter}; while (!gate_level_layout.has_value() || gate_design_failed) { - fiction::exact_physical_design_stats exact_stats{}; + exact_stats = {}; if (!gate_level_layout.has_value() && attempts > 0) { break; @@ -234,15 +216,14 @@ int main() // NOLINT const auto eq = mockturtle::equivalence_checking(*miter); assert(eq.has_value()); - // compute critical path and throughput - const auto cp_tp_stats = fiction::critical_path_length_and_throughput(*gate_level_layout); - - // apply dynamic gate library + // determine bounding box + const auto bb_final = fiction::bounding_box_2d(cell_level_layout); // compute area fiction::area_stats area_stats{}; fiction::area_params area_ps{}; - fiction::area(cell_level_layout, area_ps, &area_stats); + fiction::area(bb_final, area_ps, &area_stats); + fiction::sidb_defect_surface defect_surface{cell_level_layout}; // add defects to the file @@ -253,12 +234,8 @@ int main() // NOLINT fmt::format("{}/{}_percent_after_big_change.sqd", layouts_folder, benchmark)); // log results - sidb_circuits_with_defects( - benchmark, xag.num_pis(), xag.num_pos(), xag.num_gates(), depth_xag.depth(), mapped_network.num_gates(), - depth_mapped_network.depth(), gate_level_layout->x() + 1, gate_level_layout->y() + 1, - (gate_level_layout->x() + 1) * (gate_level_layout->y() + 1), gate_level_layout->num_gates(), - gate_level_layout->num_wires(), cp_tp_stats.critical_path_length, cp_tp_stats.throughput, - mockturtle::to_seconds(time_counter), *eq, cell_level_layout.num_cells(), area_stats.area); + sidb_circuits_with_defects(benchmark, mockturtle::to_seconds(time_counter), *eq, area_stats.area, + exact_stats.num_aspect_ratios); sidb_circuits_with_defects.save(); sidb_circuits_with_defects.table(); } From ded3285dd4662f3d610753fe9e15387a10691eea Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 25 Jun 2024 12:59:15 +0200 Subject: [PATCH 127/191] :art: small fix. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 2 +- .../fiction/algorithms/physical_design/design_sidb_gates.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 453776426..39631ef33 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -251,7 +251,7 @@ template , "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); - // static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); + static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); static_assert(mockturtle::has_is_constant_v, "GateLyt does not implement the is_constant function"); static_assert(mockturtle::has_foreach_node_v, "GateLyt does not implement the foreach_node function"); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 7b83ab3ca..2d4bde565 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -378,6 +378,7 @@ class design_sidb_gates_impl return cells; } }; + } // namespace detail /** From a7d95adc5ec3568408cf2932665cea06c61755ba Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 25 Jun 2024 13:13:22 +0200 Subject: [PATCH 128/191] :art: small fix. --- .../fiction/algorithms/physical_design/exact.hpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/include/fiction/algorithms/physical_design/exact.hpp b/include/fiction/algorithms/physical_design/exact.hpp index 1ae5da824..72dd436d0 100644 --- a/include/fiction/algorithms/physical_design/exact.hpp +++ b/include/fiction/algorithms/physical_design/exact.hpp @@ -9,7 +9,6 @@ #include "fiction/algorithms/iter/aspect_ratio_iterator.hpp" #include "fiction/algorithms/network_transformation/fanout_substitution.hpp" -#include "fiction/io/print_layout.hpp" #include "fiction/layouts/clocking_scheme.hpp" #include "fiction/technology/cell_ports.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" @@ -41,8 +40,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -1976,9 +1977,13 @@ class exact_impl { solver->add(!(get_tn(t, n))); + // clang-format off + // same for the outgoing edges - foreach_outgoing_edge(network, n, [this, &t](const auto& e) + foreach_outgoing_edge(network, n, + [this, &t](const auto& e) { solver->add(!(get_te(t, e))); }); + // clang-format on } // cannot be placed with too little distance to south-east corner if (layout.x() - t.x + layout.y() - t.y < il) @@ -1987,10 +1992,15 @@ class exact_impl // following iterations check_point->assumptions.push_back(!(get_tn(t, n))); + // clang-format off + // same for the incoming edges foreach_incoming_edge( - network, n, [this, &t](const auto& e) + network, n, + [this, &t](const auto& e) { check_point->assumptions.push_back(!(get_te(t, e))); }); + + // clang-format on } }); } From 518005b31ac83607203e9836d4c738c7acb57435 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 26 Jun 2024 10:54:52 +0200 Subject: [PATCH 129/191] :art: minor changes. --- .../algorithms/physical_design/apply_gate_library.hpp | 1 - .../algorithms/physical_design/design_sidb_gates.hpp | 4 +++- .../fiction/technology/is_sidb_gate_design_impossible.hpp | 1 - include/fiction/technology/parameterized_gate_library.hpp | 6 ++---- include/fiction/technology/sidb_bestagon_library.hpp | 4 ++-- include/fiction/technology/sidb_defect_surface.hpp | 5 +---- 6 files changed, 8 insertions(+), 13 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 39631ef33..a620da2bc 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -44,7 +44,6 @@ class apply_gate_library_impl { cell_lyt.resize(aspect_ratio{((gate_lyt.x() + 1) * GateLibrary::gate_x_size()) - 1, ((gate_lyt.y() + 1) * GateLibrary::gate_y_size()) - 1, gate_lyt.z()}); - // cell_lyt.replace_clocking_scheme(gate_lyt.get_clocking_scheme()); cell_lyt.set_tile_size_x(GateLibrary::gate_x_size()); cell_lyt.set_tile_size_y(GateLibrary::gate_y_size()); } diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 2d4bde565..1197fe1f5 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -135,8 +135,9 @@ class design_sidb_gates_impl auto all_combinations = determine_all_combinations_of_distributing_k_entities_on_n_positions( params.number_of_sidbs, static_cast(all_sidbs_in_canvas.size())); - std::unordered_set sidbs_affected_by_defects = {}; + std::unordered_set> sidbs_affected_by_defects = {}; + // used to collect all SiDBs that are affected due to neutrally charged defects. if constexpr (has_get_sidb_defect_v) { sidbs_affected_by_defects = skeleton_layout.all_affected_sidbs(std::make_pair(0, 0)); @@ -156,6 +157,7 @@ class design_sidb_gates_impl { for (const auto& comb : combination) { + // if sidb are too close of the position are impossible due to closely placed neutrally charged defects. if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects)) { // canvas SiDBs are added to the skeleton diff --git a/include/fiction/technology/is_sidb_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp index 64b199457..dfae13726 100644 --- a/include/fiction/technology/is_sidb_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -15,7 +15,6 @@ #include "fiction/technology/sidb_charge_state.hpp" #include "fiction/technology/sidb_defects.hpp" #include "fiction/traits.hpp" -#include "fiction/types.hpp" #include #include diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index c4ad714b3..23cc742b9 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -151,7 +151,7 @@ class parameterized_gate_library : public fcn_gate_library& t, const Params& parameters = Params{}) { static_assert(is_gate_level_layout_v, "GateLyt must be a gate-level layout"); - // static_assert(has_offset_ucoord_v, "CellLyt must be based on offset coordinates"); + static_assert(has_cube_coord_v, "CellLyt must be based on cube coordinates"); const auto n = lyt.get_node(t); const auto f = lyt.node_function(n); @@ -539,7 +539,7 @@ class parameterized_gate_library : public fcn_gate_library [[nodiscard]] static Lyt cell_list_to_cell_level_layout(const fcn_gate& cell_list) noexcept { - Lyt lyt{{std::numeric_limits::max(), std::numeric_limits::max()}}; + Lyt lyt{}; const auto all_cell = all_coordinates_in_spanned_area({0, 0, 0}, cell{gate_x_size() - 1, gate_y_size() - 1}); @@ -600,7 +600,6 @@ class parameterized_gate_library : public fcn_gate_library, "Lyt is not a cell-level layout"); static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); static_assert(has_cube_coord_v, "Lyt is not based on cube coordinates"); - ; auto skeleton_with_defect = sidb_defect_surface{skeleton}; @@ -609,7 +608,6 @@ class parameterized_gate_library : public fcn_gate_library #include -#include +#include +#include namespace fiction { diff --git a/include/fiction/technology/sidb_defect_surface.hpp b/include/fiction/technology/sidb_defect_surface.hpp index 891d99fd7..9dbd80031 100644 --- a/include/fiction/technology/sidb_defect_surface.hpp +++ b/include/fiction/technology/sidb_defect_surface.hpp @@ -212,10 +212,7 @@ class sidb_defect_surface : public Lyt for (auto x = static_cast(c.x - horizontal_extent); x <= static_cast(c.x + horizontal_extent); ++x) { - if (const auto affected = typename Lyt::coordinate{x, y, c.z}; Lyt::is_within_bounds(affected)) - { - influenced_sidbs.insert(affected); - } + influenced_sidbs.insert({x, y, c.z}); } } } From 80a930977169d98386b1c5ba2aed188798d76b92 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Wed, 26 Jun 2024 12:35:34 +0200 Subject: [PATCH 130/191] :art: resize via bb. --- include/fiction/technology/parameterized_gate_library.hpp | 7 ++++++- include/fiction/technology/sidb_defect_surface.hpp | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index 23cc742b9..cb55dbabb 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -7,7 +7,7 @@ #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" -#include "fiction/layouts/coordinates.hpp" +#include "fiction/layouts/bounding_box.hpp" #include "fiction/technology/cell_ports.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/fcn_gate_library.hpp" @@ -576,6 +576,7 @@ class parameterized_gate_library : public fcn_gate_library : public Lyt for (auto x = static_cast(c.x - horizontal_extent); x <= static_cast(c.x + horizontal_extent); ++x) { - influenced_sidbs.insert({x, y, c.z}); + if (const auto affected = typename Lyt::coordinate{x, y, c.z}; Lyt::is_within_bounds(affected)) + { + influenced_sidbs.insert(affected); + } } } } From 0ac92b69d228d709c9a47e265b5c41a00c8ddef2 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 27 Jun 2024 07:04:45 +0200 Subject: [PATCH 131/191] :art: a few structural changes. --- docs/layouts/bounding_box.rst | 1 + ...cal_design_with_on_the_fly_gate_design.cpp | 179 ++++----------- .../algorithms/physical_design/exact.hpp | 6 +- ...ly_circuit_design_on_defective_surface.hpp | 210 ++++++++++++++++++ .../algorithms/simulation/sidb/quickexact.hpp | 2 + include/fiction/layouts/bounding_box.hpp | 180 ++++++++------- .../technology/parameterized_gate_library.hpp | 3 +- include/fiction/utils/layout_utils.hpp | 1 - 8 files changed, 370 insertions(+), 212 deletions(-) create mode 100644 include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp diff --git a/docs/layouts/bounding_box.rst b/docs/layouts/bounding_box.rst index 3c534ca8b..bd47791d1 100644 --- a/docs/layouts/bounding_box.rst +++ b/docs/layouts/bounding_box.rst @@ -5,6 +5,7 @@ Bounding Box .. tab:: C++ **Header:** ``fiction/layouts/bounding_box.hpp`` + .. doxygenenum:: fiction::bounding_box_2d_setting .. doxygenclass:: fiction::bounding_box_2d :members: diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 7e90dd9be..e5f80f081 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -6,44 +6,32 @@ #include "fiction_experiments.hpp" -#include // technology mapping -#include // layout conversion to cell-level -#include // design gate -#include // SMT-based physical design of FCN layouts -#include // choose design engine (ExGS, QuickSim, QuickExact) -#include // reader for simulated SiDB surfaces -#include // writer for SiQAD files (physical simulation) +#include +#include +#include +#include +#include +#include #include -#include // layout coordinates -#include // technology-mapped network type -#include // area requirement calculations -#include // cell implementations -#include // a dynamic SiDB gate library -#include // SiDB surface with support for atomic defects -#include // Atomic defects -#include // a static skeleton SiDB gate library defining the input/output wires -#include // Analyzes a given defective SiDB surface and matches it against gate tiles provided by a library -#include // pre-defined traits -#include // pre-defined types suitable for the FCN domain - -#include // output formatting -#include // Verilog/BLIF/AIGER/... file parsing -#include // logic optimization with cut rewriting -#include // equivalence checking -#include // miter structure -#include // NPN databases for cut rewriting of XAGs and AIGs -#include // call-backs to read Verilog files into networks -#include // XOR-AND-inverter graphs -#include // used to measure runtime -#include // to determine network levels +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include #include -#include #include -#include -#include #include -#include // This script conducts defect-aware placement and routing with defect-aware on-the-fly SiDB gate design. Thereby, SiDB // circuits can be designed in the presence of atomic defects. @@ -53,15 +41,15 @@ int main() // NOLINT using gate_lyt = fiction::hex_even_row_gate_clk_lyt; using cell_lyt = fiction::sidb_cell_clk_lyt_cube; - fiction::design_sidb_gates_params design_gate_params{}; + fiction::design_sidb_gates_params> design_gate_params{}; design_gate_params.simulation_parameters = fiction::sidb_simulation_parameters{2, -0.32}; design_gate_params.canvas = {{24, 17}, {34, 28}}; design_gate_params.number_of_sidbs = 3; design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; design_gate_params.termination_cond = - fiction::design_sidb_gates_params::termination_condition::AFTER_FIRST_SOLUTION; + fiction::design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION; - // save atomic defects which their respective phyiscal parameters as exerimentally determined by T. R. Huff, T. + // save atomic defects which their respective phyiscal parameters as experimentally determined by T. R. Huff, T. // Dienel, M. Rashidi, R. Achal, L. Livadaru, J. Croshaw, and R. A. Wolkow, "Electrostatic landscape of a // Hydrogen-terminated Silicon Surface Probed by a Moveable Quantum Dot." const auto stray_db = fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}; @@ -93,25 +81,13 @@ int main() // NOLINT } }); - // ddetermine the bounding box around the defective surface. - const auto bb = fiction::bounding_box_2d{surface_lattice}; - surface_lattice.resize(bb.get_max()); + const auto bb_defect_surface = fiction::bounding_box_2d{surface_lattice}; + surface_lattice.resize(bb_defect_surface.get_max()); const auto lattice_tiling = gate_lyt{{11, 30}}; - experiments::experiment sidb_circuits_with_defects{ - "sidb_circuits_with_defects", "benchmark", "runtime (in sec)", "equivalent", "layout area in nm²", - "number of aspect ratios"}; - - // parameters for SMT-based physical design - fiction::exact_physical_design_params exact_params{}; - exact_params.scheme = "ROW4"; - exact_params.crossings = true; - exact_params.border_io = false; - exact_params.desynchronize = true; - exact_params.upper_bound_x = 11; // 12 x 31 tiles - exact_params.upper_bound_y = 30; // 12 x 31 tiles - exact_params.timeout = 3'600'000; // 1h in ms + experiments::experiment sidb_circuits_with_defects{ + "sidb_circuits_with_defects", "benchmark", "runtime", "number of aspect ratios"}; constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & @@ -148,96 +124,39 @@ int main() // NOLINT // perform technology mapping const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); - // compute depth - const mockturtle::depth_view depth_mapped_network{mapped_network}; - - std::optional gate_level_layout = std::nullopt; - cell_lyt cell_level_layout{{}, "fail"}; - auto black_list = fiction::sidb_surface_analysis( - lattice_tiling, surface_lattice, std::make_pair(0, 0)); + fiction::on_the_fly_circuit_design_params params{}; + params.exact_design_parameter.scheme = "ROW4"; + params.exact_design_parameter.crossings = true; + params.exact_design_parameter.border_io = false; + params.exact_design_parameter.desynchronize = true; + params.exact_design_parameter.upper_bound_x = 11; // 12 x 31 tiles + params.exact_design_parameter.upper_bound_y = 30; // 12 x 31 tiles + params.exact_design_parameter.timeout = 3'600'000; // 1h in ms - auto attempts = 0u; + params.parameterized_gate_library_parameter.defect_surface = surface_lattice; + params.parameterized_gate_library_parameter.design_gate_params = design_gate_params; - mockturtle::stopwatch<>::duration time_counter{}; + fiction::on_the_fly_circuit_design_stats st{}; - auto gate_design_failed = true; + const auto result = + fiction::on_the_fly_circuit_design_on_defective_surface( + mapped_network, params, lattice_tiling, &st); - fiction::exact_physical_design_stats exact_stats{}; - - { - const mockturtle::stopwatch stop{time_counter}; - - while (!gate_level_layout.has_value() || gate_design_failed) - { - exact_stats = {}; - if (!gate_level_layout.has_value() && attempts > 0) - { - break; - } - std::cout << black_list.size() << '\n'; - gate_level_layout = - fiction::exact_with_blacklist(mapped_network, black_list, exact_params, &exact_stats); - if (gate_level_layout.has_value()) - { - try - { - auto parameter_gate_library = - fiction::parameterized_gate_library_params{surface_lattice, design_gate_params}; - - cell_level_layout = fiction::apply_parameterized_gate_library< - cell_lyt, fiction::parameterized_gate_library, gate_lyt, - fiction::parameterized_gate_library_params>(*gate_level_layout, - parameter_gate_library); - gate_design_failed = false; - } - catch (const fiction::gate_design_exception& e) - { - gate_design_failed = true; - black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); - } - - catch (const std::exception& e) - { - std::cerr << "Caught std::exception: " << e.what() << '\n'; - } - } - attempts++; - } - } - - if (!gate_level_layout.has_value()) - { - continue; - } - - // check equivalence - const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); - const auto eq = mockturtle::equivalence_checking(*miter); - assert(eq.has_value()); - - // determine bounding box - const auto bb_final = fiction::bounding_box_2d(cell_level_layout); + // determine bounding box and exclude atomic defects + const auto bb = fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::EXCLUDE_DEFECTS); // compute area fiction::area_stats area_stats{}; fiction::area_params area_ps{}; - fiction::area(bb_final, area_ps, &area_stats); - - fiction::sidb_defect_surface defect_surface{cell_level_layout}; + fiction::area(bb, area_ps, &area_stats); - // add defects to the file - surface_lattice.foreach_sidb_defect([&defect_surface](const auto& defect) - { defect_surface.assign_sidb_defect(defect.first, defect.second); }); - // write a SiQAD simulation file - fiction::write_sqd_layout(defect_surface, - fmt::format("{}/{}_percent_after_big_change.sqd", layouts_folder, benchmark)); - - // log results - sidb_circuits_with_defects(benchmark, mockturtle::to_seconds(time_counter), *eq, area_stats.area, - exact_stats.num_aspect_ratios); + sidb_circuits_with_defects(benchmark, mockturtle::to_seconds(st.time_total), st.exact_stats.num_aspect_ratios); sidb_circuits_with_defects.save(); sidb_circuits_with_defects.table(); + + // write a SiQAD simulation file + fiction::write_sqd_layout(result, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); } return EXIT_SUCCESS; diff --git a/include/fiction/algorithms/physical_design/exact.hpp b/include/fiction/algorithms/physical_design/exact.hpp index 72dd436d0..a1d273f5c 100644 --- a/include/fiction/algorithms/physical_design/exact.hpp +++ b/include/fiction/algorithms/physical_design/exact.hpp @@ -3257,7 +3257,7 @@ std::optional exact_with_blacklist(const Ntk& ntk, const surface_black_list throw unsupported_clocking_scheme_exception(); } // check for input degree - else if (has_high_degree_fanin_nodes(ntk, clocking_scheme->max_in_degree)) + if (has_high_degree_fanin_nodes(ntk, clocking_scheme->max_in_degree)) { throw high_degree_fanin_exception(); } @@ -3268,14 +3268,14 @@ std::optional exact_with_blacklist(const Ntk& ntk, const surface_black_list { std::cout << "[w] Lyt does not implement the foreach_adjacent_opposite_tiles function; straight inverters " "cannot be guaranteed" - << std::endl; + << '\n'; } } if constexpr (!fiction::has_synchronization_elements_v) { if (ps.synchronization_elements) { - std::cout << "[w] Lyt does not support synchronization elements; not using them" << std::endl; + std::cout << "[w] Lyt does not support synchronization elements; not using them" << '\n'; } } diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp new file mode 100644 index 000000000..054170cfd --- /dev/null +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -0,0 +1,210 @@ +// +// Created by Jan Drewniok on 26.06.24. +// + +#ifndef FICTION_ON_THE_FLY_CIRCUIT_DESIGN_ON_DEFECTIVE_SURFACE_HPP +#define FICTION_ON_THE_FLY_CIRCUIT_DESIGN_ON_DEFECTIVE_SURFACE_HPP + +#include "fiction/algorithms/physical_design/apply_gate_library.hpp" +#include "fiction/algorithms/physical_design/design_sidb_gates.hpp" +#include "fiction/algorithms/physical_design/exact.hpp" +#include "fiction/networks/technology_network.hpp" +#include "fiction/technology/parameterized_gate_library.hpp" +#include "fiction/technology/sidb_defect_surface.hpp" +#include "fiction/technology/sidb_skeleton_bestagon_library.hpp" +#include "fiction/technology/sidb_surface_analysis.hpp" +#include "fiction/traits.hpp" +#include "fiction/types.hpp" + +#include // equivalence checking +#include // miter structure +#include + +#include +#include +#include +#include + +namespace fiction +{ + +/** + * This struct stores the parameters to design SiDB circuit on a defective surface. + * + * @tparam CellLyt Cell-level layout type. + */ +template +struct on_the_fly_circuit_design_params +{ + parameterized_gate_library_params parameterized_gate_library_parameter = {}; + /** + * Parameters for the *exact* placement&routing algorithm. + */ + exact_physical_design_params exact_design_parameter = {}; +}; + +/** + * Statistics for the on-the-fly circuit design. + */ +struct on_the_fly_circuit_design_stats +{ + /** + * The total runtime of the operational domain computation. + */ + mockturtle::stopwatch<>::duration time_total{0}; + /** + * The `stats`of the *exact* algorithm. + */ + exact_physical_design_stats exact_stats{}; +}; + +namespace detail +{ + +template +class on_the_fly_circuit_design_impl +{ + public: + on_the_fly_circuit_design_impl(const Ntk& network, const on_the_fly_circuit_design_params& design_params, + const GateLyt& tiling, on_the_fly_circuit_design_stats& st) : + lattice_tiling{tiling}, + mapped_network{network}, + params{design_params}, + stats{st} + {} + + [[nodiscard]] sidb_defect_surface design_circuit_on_defective_surface() + { + std::optional gate_level_layout = std::nullopt; + CellLyt cell_level_layout{{}, "fail"}; + + auto black_list = sidb_surface_analysis( + lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); + + auto attempts = 0u; + + const mockturtle::stopwatch stop{stats.time_total}; + + bool gate_design_failed = true; + + { + while (!gate_level_layout.has_value() || gate_design_failed) + { + if (!gate_level_layout.has_value() && attempts > 0) + { + break; + } + + gate_level_layout = exact_with_blacklist(mapped_network, black_list, + params.exact_design_parameter, &stats.exact_stats); + if (gate_level_layout.has_value()) + { + try + { + + cell_level_layout = + apply_parameterized_gate_library>( + *gate_level_layout, params.parameterized_gate_library_parameter); + gate_design_failed = false; + } + catch (const gate_design_exception& e) + { + gate_design_failed = true; + black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); + } + + catch (const std::exception& e) + { + std::cerr << "Caught std::exception: " << e.what() << '\n'; + } + } + attempts++; + } + } + + if (!gate_level_layout.has_value()) + { + return sidb_defect_surface{}; + } + + // check equivalence + const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); + const auto eq = mockturtle::equivalence_checking(*miter); + if (!eq.has_value()) + { + return sidb_defect_surface{}; + } + + if (*eq) + { + sidb_defect_surface sidbs_and_defects{cell_level_layout}; + + // add defects to the circuit. + params.parameterized_gate_library_parameter.defect_surface.foreach_sidb_defect( + [&sidbs_and_defects](const auto& defect) + { sidbs_and_defects.assign_sidb_defect(defect.first, defect.second); }); + + return sidbs_and_defects; + } + + return sidb_defect_surface{}; + } + + private: + /** + * Gate-level layout. + */ + GateLyt lattice_tiling; + /** + * Mapped network. + */ + Ntk mapped_network{}; + /** + * Parameters for the on-the-fly circuit design. + */ + on_the_fly_circuit_design_params params{}; + /** + * Statistics for the on-the-fly circuit design. + */ + on_the_fly_circuit_design_stats& stats; +}; + +} // namespace detail + +/** + * This function applies the on-the-fly circuit design algorithm to a specified defective surface, automatically + * creating customized SiDB gates while integrating atomic defects as essential components of the design. + * + * @tparam Ntk The type of the input network. + * @tparam CellLyt The type of the cell layout. + * @tparam GateLyt The type of the gate layout. + * @param mapped_network The input network to be mapped onto the defective surface. + * @param design_params The parameters used for designing the circuit, encapsulated in an + * `on_the_fly_circuit_design_params` object. + * @param lattice_tiling The lattice tiling used for the circuit design. + * @param defect_surface The defective surface on which the circuit is to be designed. + * @param stats Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. + * + * @return A `sidb_defect_surface` representing the designed circuit on the defective surface. + */ +template +[[nodiscard]] sidb_defect_surface on_the_fly_circuit_design_on_defective_surface( + const Ntk& mapped_network, const on_the_fly_circuit_design_params& design_params, + const GateLyt& lattice_tiling, on_the_fly_circuit_design_stats* stats = nullptr) +{ + on_the_fly_circuit_design_stats st{}; + detail::on_the_fly_circuit_design_impl p{mapped_network, design_params, lattice_tiling, st}; + + const auto result = p.design_circuit_on_defective_surface(); + + if (stats) + { + *stats = st; + } + return result; +} + +} // namespace fiction + +#endif // FICTION_ON_THE_FLY_CIRCUIT_DESIGN_ON_DEFECTIVE_SURFACE_HPP diff --git a/include/fiction/algorithms/simulation/sidb/quickexact.hpp b/include/fiction/algorithms/simulation/sidb/quickexact.hpp index b159af844..31edc1401 100644 --- a/include/fiction/algorithms/simulation/sidb/quickexact.hpp +++ b/include/fiction/algorithms/simulation/sidb/quickexact.hpp @@ -26,6 +26,8 @@ namespace fiction /** * This struct stores the parameters for the *QuickExact* algorithm. + * + * @tparam CellType Cell type. */ template struct quickexact_params diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index eb415ae70..f5a02910e 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -19,6 +19,20 @@ namespace fiction { +/** + * Modes to use for creating the 2D-bounding box. + */ +enum class bounding_box_2d_selection +{ + /** + * The bounding box includes atomic defects. + */ + INCLUDE_DEFECTS, + /** + * The bounding box is determined based on the cells, excluding atomic defects. + */ + EXCLUDE_DEFECTS +}; /** * A 2D bounding box object that computes a minimum-sized box around all non-empty coordinates in a given layout. @@ -45,10 +59,20 @@ class bounding_box_2d static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); update_bounding_box(); } + /** + * Standard constructor that computes an initial bounding box. + * + * @param lyt Gate-level or cell-level layout whose bounding box is desired. + */ + explicit bounding_box_2d(const Lyt& lyt, const bounding_box_2d_selection& bb_selection) noexcept : layout{lyt} + { + static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); + update_bounding_box(bb_selection); + } /** * The bounding box is not automatically updated when the layout changes. This function recomputes the bounding box. */ - void update_bounding_box() + void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::INCLUDE_DEFECTS) { min = {0, 0, 0}; max = {0, 0, 0}; @@ -122,56 +146,58 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - int32_t min_x_defect = std::numeric_limits::max(); - int32_t max_x_defect = std::numeric_limits::min(); + if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) + { + int32_t min_x_defect = std::numeric_limits::max(); + int32_t max_x_defect = std::numeric_limits::min(); - int32_t min_y_defect = std::numeric_limits::max(); - int32_t max_y_defect = std::numeric_limits::min(); + int32_t min_y_defect = std::numeric_limits::max(); + int32_t max_y_defect = std::numeric_limits::min(); - uint8_t min_z_defect = 1; - uint8_t max_z_defect = 0; + uint8_t min_z_defect = 1; + uint8_t max_z_defect = 0; - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, - &max_z_defect](const auto& defect) - { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, + &max_z_defect](const auto& defect) { - max_x_defect = defect.first.x; - } + if (defect.first.x < min_x_defect) + { + min_x_defect = defect.first.x; + } + if (defect.first.x > max_x_defect) + { + max_x_defect = defect.first.x; + } - if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) - { - min_z_defect = defect.first.z; - } - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - min_z_defect = defect.first.z; - } + if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) + { + min_z_defect = defect.first.z; + } + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + min_z_defect = defect.first.z; + } - if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) - { - max_z_defect = defect.first.z; - } - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - max_z_defect = defect.first.z; - } - }); - const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; - - min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), - std::min(min_cell.z, min_defect.z)}; - max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), - std::max(max_cell.z, max_defect.z)}; - ; + if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) + { + max_z_defect = defect.first.z; + } + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + max_z_defect = defect.first.z; + } + }); + const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; + + min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), + std::min(min_cell.z, min_defect.z)}; + max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), + std::max(max_cell.z, max_defect.z)}; + } } } else @@ -235,42 +261,44 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - auto min_x_defect = std::numeric_limits::x)>::max(); - auto max_x_defect = std::numeric_limits::y)>::min(); + if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) + { + auto min_x_defect = std::numeric_limits::x)>::max(); + auto max_x_defect = std::numeric_limits::y)>::min(); - auto min_y_defect = std::numeric_limits::x)>::max(); - auto max_y_defect = std::numeric_limits::y)>::min(); + auto min_y_defect = std::numeric_limits::x)>::max(); + auto max_y_defect = std::numeric_limits::y)>::min(); - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) - { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) { - max_x_defect = defect.first.x; - } + if (defect.first.x < min_x_defect) + { + min_x_defect = defect.first.x; + } + if (defect.first.x > max_x_defect) + { + max_x_defect = defect.first.x; + } - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - } + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + } - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - } - }); - const auto min_defect = coordinate{min_x_defect, min_y_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect}; - - min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), - std::min(min.z, min_defect.z)}; - max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), - std::max(max.z, max_defect.z)}; - ; + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + } + }); + const auto min_defect = coordinate{min_x_defect, min_y_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect}; + + min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), + std::min(min.z, min_defect.z)}; + max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), + std::max(max.z, max_defect.z)}; + } } } diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index cb55dbabb..f742818f4 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -111,7 +110,7 @@ struct parameterized_gate_library_params /** * This struct holds parameters to design SiDB gates on-the-fly. */ - design_sidb_gates_params> design_gate_params{}; + design_sidb_gates_params> design_gate_params{}; /** * This variable defines the number of canvas SiDBs dedicated to complex gates, such as crossing, double wire, * and half-adder. diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index b3c510b00..35f10beb5 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -10,7 +10,6 @@ #include "fiction/technology/charge_distribution_surface.hpp" #include "fiction/technology/sidb_defect_surface.hpp" #include "fiction/technology/sidb_lattice.hpp" -#include "fiction/technology/sidb_lattice_orientations.hpp" #include "fiction/traits.hpp" #include "fiction/types.hpp" From 523c5e41b9cf20d6b3b12466fb60f5f483cf1388 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 27 Jun 2024 05:06:14 +0000 Subject: [PATCH 132/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 0ef768e34..91a26eac1 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -776,6 +776,12 @@ Template parameter ``Lyt``: static const char *__doc_fiction_bounding_box_2d_bounding_box_2d = R"doc(Standard constructor that computes an initial bounding box. +Parameter ``lyt``: + Gate-level or cell-level layout whose bounding box is desired.)doc"; + +static const char *__doc_fiction_bounding_box_2d_bounding_box_2d_2 = +R"doc(Standard constructor that computes an initial bounding box. + Parameter ``lyt``: Gate-level or cell-level layout whose bounding box is desired.)doc"; @@ -819,6 +825,14 @@ static const char *__doc_fiction_bounding_box_2d_max = R"doc()doc"; static const char *__doc_fiction_bounding_box_2d_min = R"doc()doc"; +static const char *__doc_fiction_bounding_box_2d_selection = R"doc(Modes to use for creating the 2D-bounding box.)doc"; + +static const char *__doc_fiction_bounding_box_2d_selection_EXCLUDE_DEFECTS = +R"doc(The bounding box is determined based on the cells, excluding atomic +defects.)doc"; + +static const char *__doc_fiction_bounding_box_2d_selection_INCLUDE_DEFECTS = R"doc(The bounding box includes atomic defects.)doc"; + static const char *__doc_fiction_bounding_box_2d_update_bounding_box = R"doc(The bounding box is not automatically updated when the layout changes. This function recomputes the bounding box.)doc"; @@ -5842,6 +5856,20 @@ static const char *__doc_fiction_detail_network_balancing_impl_ps = R"doc()doc"; static const char *__doc_fiction_detail_network_balancing_impl_run = R"doc()doc"; +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl = R"doc()doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_design_circuit_on_defective_surface = R"doc()doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_lattice_tiling = R"doc(Gate-level layout.)doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_mapped_network = R"doc(Mapped network.)doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_on_the_fly_circuit_design_impl = R"doc()doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_params = R"doc(Parameters for the on-the-fly circuit design.)doc"; + +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_stats = R"doc(Statistics for the on-the-fly circuit design.)doc"; + static const char *__doc_fiction_detail_operational_domain_impl = R"doc()doc"; static const char *__doc_fiction_detail_operational_domain_impl_contour_tracing = @@ -12085,6 +12113,59 @@ static const char *__doc_fiction_offset_ucoord_t_y = R"doc(31 bit for the y coor static const char *__doc_fiction_offset_ucoord_t_z = R"doc(1 bit for the z coordinate.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_on_defective_surface = +R"doc(This function applies the on-the-fly circuit design algorithm to a +specified defective surface, automatically creating customized SiDB +gates while integrating atomic defects as essential components of the +design. + +Template parameter ``Ntk``: + The type of the input network. + +Template parameter ``CellLyt``: + The type of the cell layout. + +Template parameter ``GateLyt``: + The type of the gate layout. + +Parameter ``mapped_network``: + The input network to be mapped onto the defective surface. + +Parameter ``design_params``: + The parameters used for designing the circuit, encapsulated in an + `on_the_fly_circuit_design_params` object. + +Parameter ``lattice_tiling``: + The lattice tiling used for the circuit design. + +Parameter ``defect_surface``: + The defective surface on which the circuit is to be designed. + +Parameter ``stats``: + Pointer to a structure for collecting statistics. If nullptr, + statistics are not collected. + +Returns: + A `sidb_defect_surface` representing the designed circuit + on the defective surface.)doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_params = +R"doc(This struct stores the parameters to design SiDB circuit on a +defective surface. + +Template parameter ``CellLyt``: + Cell-level layout type.)doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement&routing algorithm.)doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameter = R"doc()doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_stats = R"doc(Statistics for the on-the-fly circuit design.)doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_stats_duration = R"doc(The total runtime of the operational domain computation.)doc"; + +static const char *__doc_fiction_on_the_fly_circuit_design_stats_exact_stats = R"doc(The `stats`of the *exact* algorithm.)doc"; + static const char *__doc_fiction_open_clocking = R"doc(Returns an irregular clocking that maps every coordinate to the standard clock. It is intended to be overridden. @@ -13374,7 +13455,11 @@ Parameter ``params``: Returns: Simulation Results.)doc"; -static const char *__doc_fiction_quickexact_params = R"doc(This struct stores the parameters for the *QuickExact* algorithm.)doc"; +static const char *__doc_fiction_quickexact_params = +R"doc(This struct stores the parameters for the *QuickExact* algorithm. + +Template parameter ``CellType``: + Cell type.)doc"; static const char *__doc_fiction_quickexact_params_automatic_base_number_detection = R"doc(Modes to use for the *QuickExact* algorithm.)doc"; From e1618fc5bb9b66c43d0d44650658db6af9027519 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 27 Jun 2024 07:48:49 +0200 Subject: [PATCH 133/191] :art: delete header comments. --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 054170cfd..2931999c9 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -16,8 +16,8 @@ #include "fiction/traits.hpp" #include "fiction/types.hpp" -#include // equivalence checking -#include // miter structure +#include +#include #include #include @@ -76,7 +76,7 @@ class on_the_fly_circuit_design_impl [[nodiscard]] sidb_defect_surface design_circuit_on_defective_surface() { std::optional gate_level_layout = std::nullopt; - CellLyt cell_level_layout{{}, "fail"}; + CellLyt cell_level_layout{}; auto black_list = sidb_surface_analysis( lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); From 48dfa4ae7870cf902d0cb46027a9aeef369d3188 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 1 Jul 2024 09:15:33 +0200 Subject: [PATCH 134/191] :art: add missing header. --- include/fiction/layouts/coordinates.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index a1d417127..cbfde9a56 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include From 5d7fc87ab3a213cb099c94147697796cffb490fa Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 1 Jul 2024 15:09:44 +0200 Subject: [PATCH 135/191] :art: small fix. --- .../physical_design_with_on_the_fly_gate_design.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index e5f80f081..6e97bea30 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -64,6 +64,7 @@ int main() // NOLINT // create an empty surface with the maximal possible dimension. fiction::sidb_defect_surface surface_lattice{}; + // add physical parameters of the defects to the surface. surface_lattice_initial.foreach_sidb_defect( [&surface_lattice, &stray_db, &si_vacancy](const auto& cd) { From 73528b07c5237af39a2f0811ff373ce7f302e1c1 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 9 Jul 2024 08:57:59 +0200 Subject: [PATCH 136/191] :art: small fix. --- docs/layouts/bounding_box.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/layouts/bounding_box.rst b/docs/layouts/bounding_box.rst index bd47791d1..3cd53b035 100644 --- a/docs/layouts/bounding_box.rst +++ b/docs/layouts/bounding_box.rst @@ -5,7 +5,7 @@ Bounding Box .. tab:: C++ **Header:** ``fiction/layouts/bounding_box.hpp`` - .. doxygenenum:: fiction::bounding_box_2d_setting + .. doxygenenum:: fiction::bounding_box_2d_selection .. doxygenclass:: fiction::bounding_box_2d :members: From 0e7bc03d5defb4f4ea3c48670b3da7c32d4deedb Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 12 Jul 2024 18:04:24 +0200 Subject: [PATCH 137/191] :art: small renaming. --- .../physical_design_with_on_the_fly_gate_design.cpp | 3 ++- include/fiction/layouts/bounding_box.hpp | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 6e97bea30..fc1a030ea 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -145,7 +145,8 @@ int main() // NOLINT mapped_network, params, lattice_tiling, &st); // determine bounding box and exclude atomic defects - const auto bb = fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::EXCLUDE_DEFECTS); + const auto bb = + fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::DEFECTS_EXCLUDED); // compute area fiction::area_stats area_stats{}; diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index f5a02910e..d1a169dd7 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -27,11 +27,11 @@ enum class bounding_box_2d_selection /** * The bounding box includes atomic defects. */ - INCLUDE_DEFECTS, + DEFECTS_INCLUDED, /** * The bounding box is determined based on the cells, excluding atomic defects. */ - EXCLUDE_DEFECTS + DEFECTS_EXCLUDED }; /** @@ -72,7 +72,7 @@ class bounding_box_2d /** * The bounding box is not automatically updated when the layout changes. This function recomputes the bounding box. */ - void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::INCLUDE_DEFECTS) + void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::DEFECTS_INCLUDED) { min = {0, 0, 0}; max = {0, 0, 0}; @@ -146,7 +146,7 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) + if (selection == bounding_box_2d_selection::DEFECTS_INCLUDED) { int32_t min_x_defect = std::numeric_limits::max(); int32_t max_x_defect = std::numeric_limits::min(); @@ -261,7 +261,7 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) + if (selection == bounding_box_2d_selection::DEFECTS_INCLUDED) { auto min_x_defect = std::numeric_limits::x)>::max(); auto max_x_defect = std::numeric_limits::y)>::min(); From 4385648e38b0ba4a49b6a988a8ea7e2c309bac3e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 12 Jul 2024 18:05:10 +0200 Subject: [PATCH 138/191] :art: small change. --- .../physical_design_with_on_the_fly_gate_design.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index fc1a030ea..ee536a5e0 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -158,7 +158,7 @@ int main() // NOLINT sidb_circuits_with_defects.table(); // write a SiQAD simulation file - fiction::write_sqd_layout(result, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); + // fiction::write_sqd_layout(result, fmt::format("{}/{}.sqd", layouts_folder, benchmark)); } return EXIT_SUCCESS; From 7eea63664fdba25888faef88dd93585fd28980a9 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 12 Jul 2024 19:28:40 +0200 Subject: [PATCH 139/191] :art: small fixes. --- ...fly_circuit_design_on_defective_surface.hpp | 18 ++++++++++++------ .../technology/parameterized_gate_library.hpp | 10 +++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 2931999c9..70bc7f9da 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -36,6 +36,9 @@ namespace fiction template struct on_the_fly_circuit_design_params { + /** + * Parameters for the parameterized gate library. + */ parameterized_gate_library_params parameterized_gate_library_parameter = {}; /** * Parameters for the *exact* placement&routing algorithm. @@ -44,7 +47,7 @@ struct on_the_fly_circuit_design_params }; /** - * Statistics for the on-the-fly circuit design. + * Statistics for the on-the-fly defect-aware circuit design. */ struct on_the_fly_circuit_design_stats { @@ -53,7 +56,7 @@ struct on_the_fly_circuit_design_stats */ mockturtle::stopwatch<>::duration time_total{0}; /** - * The `stats`of the *exact* algorithm. + * The `stats` of the *exact* algorithm. */ exact_physical_design_stats exact_stats{}; }; @@ -81,7 +84,7 @@ class on_the_fly_circuit_design_impl auto black_list = sidb_surface_analysis( lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); - auto attempts = 0u; + auto placement_and_routing_attemps = 0u; const mockturtle::stopwatch stop{stats.time_total}; @@ -90,7 +93,7 @@ class on_the_fly_circuit_design_impl { while (!gate_level_layout.has_value() || gate_design_failed) { - if (!gate_level_layout.has_value() && attempts > 0) + if (!gate_level_layout.has_value() && placement_and_routing_attemps > 0) { break; } @@ -119,7 +122,7 @@ class on_the_fly_circuit_design_impl std::cerr << "Caught std::exception: " << e.what() << '\n'; } } - attempts++; + placement_and_routing_attemps++; } } @@ -174,7 +177,9 @@ class on_the_fly_circuit_design_impl /** * This function applies the on-the-fly circuit design algorithm to a specified defective surface, automatically - * creating customized SiDB gates while integrating atomic defects as essential components of the design. + * creating customized SiDB gates while integrating atomic defects as essential components of the design. It was + * proposed in \"On-the-fly Defect-Aware Design of Circuits based on Silicon Dangling Bond Logic\" by J. Drewniok, M. + * Walter, S. S. H. Ng, K. Walus, and R. Wille in IEEE NANO 2024. * * @tparam Ntk The type of the input network. * @tparam CellLyt The type of the cell layout. @@ -202,6 +207,7 @@ template { *stats = st; } + return result; } diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index f742818f4..25144bbb5 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -96,7 +96,7 @@ class gate_design_exception : public std::exception }; /** - * This struct encapsulates parameters for the on-the-fly SiDB gate library. + * This struct encapsulates parameters for the parameterized SiDB gate library. * * @tparam Lyt Cell-level layout type. */ @@ -108,7 +108,7 @@ struct parameterized_gate_library_params */ sidb_defect_surface defect_surface{}; /** - * This struct holds parameters to design SiDB gates on-the-fly. + * This struct holds parameters to design SiDB gates. */ design_sidb_gates_params> design_gate_params{}; /** @@ -140,10 +140,10 @@ class parameterized_gate_library : public fcn_gate_library @@ -393,7 +393,7 @@ class parameterized_gate_library : public fcn_gate_library Date: Fri, 12 Jul 2024 17:30:17 +0000 Subject: [PATCH 140/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index a126898e1..de6a94b39 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -827,11 +827,11 @@ static const char *__doc_fiction_bounding_box_2d_min = R"doc()doc"; static const char *__doc_fiction_bounding_box_2d_selection = R"doc(Modes to use for creating the 2D-bounding box.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection_EXCLUDE_DEFECTS = +static const char *__doc_fiction_bounding_box_2d_selection_DEFECTS_EXCLUDED = R"doc(The bounding box is determined based on the cells, excluding atomic defects.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection_INCLUDE_DEFECTS = R"doc(The bounding box includes atomic defects.)doc"; +static const char *__doc_fiction_bounding_box_2d_selection_DEFECTS_INCLUDED = R"doc(The bounding box includes atomic defects.)doc"; static const char *__doc_fiction_bounding_box_2d_update_bounding_box = R"doc(The bounding box is not automatically updated when the layout changes. @@ -12117,7 +12117,9 @@ static const char *__doc_fiction_on_the_fly_circuit_design_on_defective_surface R"doc(This function applies the on-the-fly circuit design algorithm to a specified defective surface, automatically creating customized SiDB gates while integrating atomic defects as essential components of the -design. +design. It was proposed in \"On-the-fly Defect-Aware Design of +Circuits based on Silicon Dangling Bond Logic\" by J. Drewniok, M. +Walter, S. S. H. Ng, K. Walus, and R. Wille in IEEE NANO 2024. Template parameter ``Ntk``: The type of the input network. @@ -12158,13 +12160,13 @@ Template parameter ``CellLyt``: static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement&routing algorithm.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameter = R"doc()doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameter = R"doc(Parameters for the parameterized gate library.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_stats = R"doc(Statistics for the on-the-fly circuit design.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_stats = R"doc(Statistics for the on-the-fly defect-aware circuit design.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_stats_duration = R"doc(The total runtime of the operational domain computation.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_stats_exact_stats = R"doc(The `stats`of the *exact* algorithm.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_stats_exact_stats = R"doc(The `stats` of the *exact* algorithm.)doc"; static const char *__doc_fiction_open_clocking = R"doc(Returns an irregular clocking that maps every coordinate to the @@ -12832,7 +12834,7 @@ Template parameter ``TT``: Truth table type. Template parameter ``Params``: - Type of the parameters used for the on-the-fly gate library. + Type of the parameters used for the parametrized gate library. Parameter ``bestagon_lyt``: The Bestagon gate which is to be applied. @@ -12853,7 +12855,7 @@ Parameter ``truth_table``: static const char *__doc_fiction_parameterized_gate_library_parameterized_gate_library = R"doc()doc"; static const char *__doc_fiction_parameterized_gate_library_params = -R"doc(This struct encapsulates parameters for the on-the-fly SiDB gate +R"doc(This struct encapsulates parameters for the parameterized SiDB gate library. Template parameter ``Lyt``: @@ -12865,7 +12867,7 @@ gates, such as crossing, double wire, and half-adder.)doc"; static const char *__doc_fiction_parameterized_gate_library_params_defect_surface = R"doc(This layout stores all atomic defects.)doc"; -static const char *__doc_fiction_parameterized_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates on-the-fly.)doc"; +static const char *__doc_fiction_parameterized_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates.)doc"; static const char *__doc_fiction_parameterized_gate_library_params_influence_radius_charged_defects = R"doc(This variable specifies the radius around the middle of the hexagon @@ -12885,7 +12887,7 @@ Template parameter ``CellLyt``: The type of the cell-level layout. Template parameter ``Params``: - Type of the parameter used for the on-the-fly gate library. + Type of the parameter used for the gate library. Parameter ``lyt``: Layout that hosts tile `t`. @@ -12894,7 +12896,7 @@ Parameter ``t``: Tile to be realized as a Bestagon gate. Parameter ``parameters``: - Parameter to design SiDB gates on-the-fly. + Parameter to design SiDB gates. Returns: Bestagon gate representation of `t` including mirroring.)doc"; From 2b94c9f6787597f578d3141bbb89d042dba2cc41 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 15 Jul 2024 11:06:29 +0200 Subject: [PATCH 141/191] :art: small fixes. --- ...cal_design_with_on_the_fly_gate_design.cpp | 20 +++--- ...ly_circuit_design_on_defective_surface.hpp | 61 ++++++++++--------- include/fiction/layouts/bounding_box.hpp | 12 ++-- test/layouts/bounding_box.cpp | 18 +++++- 4 files changed, 66 insertions(+), 45 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index ee536a5e0..d41ffab6e 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -11,13 +11,12 @@ #include #include #include -#include #include -#include #include #include #include #include +#include #include #include @@ -43,9 +42,11 @@ int main() // NOLINT fiction::design_sidb_gates_params> design_gate_params{}; design_gate_params.simulation_parameters = fiction::sidb_simulation_parameters{2, -0.32}; - design_gate_params.canvas = {{24, 17}, {34, 28}}; - design_gate_params.number_of_sidbs = 3; - design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; + // needs to be changed if a different skeleton is used. + design_gate_params.canvas = {{24, 17}, {34, 28}}; + + design_gate_params.number_of_sidbs = 3; + design_gate_params.sim_engine = fiction::sidb_simulation_engine::QUICKEXACT; design_gate_params.termination_cond = fiction::design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION; @@ -58,13 +59,14 @@ int main() // NOLINT static const std::string layouts_folder = fmt::format("{}/physical_design_with_on_the_fly_gate_design/layouts", EXPERIMENTS_PATH); + // read-in the initial defects. Physical parameters of the defects are not stored yet. auto surface_lattice_initial = fiction::read_sidb_surface_defects( "../../experiments/physical_design_with_on_the_fly_gate_design/1_percent_with_charged_surface.txt"); - // create an empty surface with the maximal possible dimension. + // create an empty surface. fiction::sidb_defect_surface surface_lattice{}; - // add physical parameters of the defects to the surface. + // add physical parameters of the defects to the defect-surface. surface_lattice_initial.foreach_sidb_defect( [&surface_lattice, &stray_db, &si_vacancy](const auto& cd) { @@ -82,6 +84,7 @@ int main() // NOLINT } }); + // determine bounding-box of the surface to set the aspect ratio of the surface lattice. const auto bb_defect_surface = fiction::bounding_box_2d{surface_lattice}; surface_lattice.resize(bb_defect_surface.get_max()); @@ -145,8 +148,7 @@ int main() // NOLINT mapped_network, params, lattice_tiling, &st); // determine bounding box and exclude atomic defects - const auto bb = - fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::DEFECTS_EXCLUDED); + const auto bb = fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::EXCLUDE_DEFECTS); // compute area fiction::area_stats area_stats{}; diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 70bc7f9da..30f939c23 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -81,51 +81,48 @@ class on_the_fly_circuit_design_impl std::optional gate_level_layout = std::nullopt; CellLyt cell_level_layout{}; + // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects + // is not considered as gates are designed on-the-fly. auto black_list = sidb_surface_analysis( lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); - auto placement_and_routing_attemps = 0u; - const mockturtle::stopwatch stop{stats.time_total}; - bool gate_design_failed = true; - + while (!gate_level_layout.has_value()) { - while (!gate_level_layout.has_value() || gate_design_failed) + // P&R with *exact* and the pre-determined blacklist + gate_level_layout = exact_with_blacklist(mapped_network, black_list, params.exact_design_parameter, + &stats.exact_stats); + if (gate_level_layout.has_value()) { - if (!gate_level_layout.has_value() && placement_and_routing_attemps > 0) + try + { + cell_level_layout = apply_parameterized_gate_library>( + *gate_level_layout, params.parameterized_gate_library_parameter); + } + + // on-the-fly gate design was unsuccessful at a certain tile. Hence, this tile-gate pair is added to the + // blacklist. + catch (const gate_design_exception& e) { - break; + black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); } - gate_level_layout = exact_with_blacklist(mapped_network, black_list, - params.exact_design_parameter, &stats.exact_stats); - if (gate_level_layout.has_value()) + catch (const std::exception& e) { - try - { - - cell_level_layout = - apply_parameterized_gate_library>( - *gate_level_layout, params.parameterized_gate_library_parameter); - gate_design_failed = false; - } - catch (const gate_design_exception& e) - { - gate_design_failed = true; - black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); - } - - catch (const std::exception& e) - { - std::cerr << "Caught std::exception: " << e.what() << '\n'; - } + std::cerr << "Caught std::exception: " << e.what() << '\n'; } - placement_and_routing_attemps++; + } + + // P&R was unsuccessful + else + { + break; } } + // empty defect-surface is returned when no P&R solution is found if (!gate_level_layout.has_value()) { return sidb_defect_surface{}; @@ -134,11 +131,14 @@ class on_the_fly_circuit_design_impl // check equivalence const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); const auto eq = mockturtle::equivalence_checking(*miter); + + // empty defect-surface is returned when equivalence check is empty if (!eq.has_value()) { return sidb_defect_surface{}; } + // in case of equality, defect-surface with the SiDBs of the circuit is returned if (*eq) { sidb_defect_surface sidbs_and_defects{cell_level_layout}; @@ -151,6 +151,7 @@ class on_the_fly_circuit_design_impl return sidbs_and_defects; } + // in case of no equality, empty defect-surface is returned return sidb_defect_surface{}; } diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index d1a169dd7..2a2f9c112 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -27,11 +27,11 @@ enum class bounding_box_2d_selection /** * The bounding box includes atomic defects. */ - DEFECTS_INCLUDED, + INCLUDE_DEFECTS, /** * The bounding box is determined based on the cells, excluding atomic defects. */ - DEFECTS_EXCLUDED + EXCLUDE_DEFECTS }; /** @@ -71,8 +71,10 @@ class bounding_box_2d } /** * The bounding box is not automatically updated when the layout changes. This function recomputes the bounding box. + * + * @param selection Modes to use for creating the bounding box. */ - void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::DEFECTS_INCLUDED) + void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::INCLUDE_DEFECTS) { min = {0, 0, 0}; max = {0, 0, 0}; @@ -146,7 +148,7 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::DEFECTS_INCLUDED) + if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) { int32_t min_x_defect = std::numeric_limits::max(); int32_t max_x_defect = std::numeric_limits::min(); @@ -261,7 +263,7 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::DEFECTS_INCLUDED) + if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) { auto min_x_defect = std::numeric_limits::x)>::max(); auto max_x_defect = std::numeric_limits::y)>::min(); diff --git a/test/layouts/bounding_box.cpp b/test/layouts/bounding_box.cpp index 6fcb8c0e5..209044d01 100644 --- a/test/layouts/bounding_box.cpp +++ b/test/layouts/bounding_box.cpp @@ -347,7 +347,7 @@ TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bound CHECK(se == cell{2, 0}); } - SECTION("two cell and two defect") + SECTION("two cell and two defect, include defects") { TestType lyt{}; lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); @@ -362,4 +362,20 @@ TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bound CHECK(nw == cell{-3, 0}); CHECK(se == cell{2, 0}); } + + SECTION("two cell and two defect, exclude defects") + { + TestType lyt{}; + lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); + lyt.assign_cell_type({2, 0}, TestType::technology::NORMAL); + lyt.assign_sidb_defect({-3, 0}, sidb_defect{}); + lyt.assign_sidb_defect({2, 0}, sidb_defect{}); + + const bounding_box_2d bb{lyt, bounding_box_2d_selection::EXCLUDE_DEFECTS}; + const auto nw = bb.get_min(); + const auto se = bb.get_max(); + + CHECK(nw == cell{1, 0}); + CHECK(se == cell{2, 0}); + } } From 71727a0643835274198773fee0b14f010823c1da Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Mon, 15 Jul 2024 09:10:28 +0000 Subject: [PATCH 142/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../include/pyfiction/pybind11_mkdoc_docstrings.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index de6a94b39..c9f7b732b 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -827,15 +827,18 @@ static const char *__doc_fiction_bounding_box_2d_min = R"doc()doc"; static const char *__doc_fiction_bounding_box_2d_selection = R"doc(Modes to use for creating the 2D-bounding box.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection_DEFECTS_EXCLUDED = +static const char *__doc_fiction_bounding_box_2d_selection_EXCLUDE_DEFECTS = R"doc(The bounding box is determined based on the cells, excluding atomic defects.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection_DEFECTS_INCLUDED = R"doc(The bounding box includes atomic defects.)doc"; +static const char *__doc_fiction_bounding_box_2d_selection_INCLUDE_DEFECTS = R"doc(The bounding box includes atomic defects.)doc"; static const char *__doc_fiction_bounding_box_2d_update_bounding_box = R"doc(The bounding box is not automatically updated when the layout changes. -This function recomputes the bounding box.)doc"; +This function recomputes the bounding box. + +Parameter ``selection``: + Modes to use for creating the bounding box.)doc"; static const char *__doc_fiction_bounding_box_2d_x_size = R"doc()doc"; From 333fd9ff8309f5aad18090f3b4f112c782fa2f65 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 15 Jul 2024 13:14:46 +0200 Subject: [PATCH 143/191] :art: small fixes. --- .../physical_design_with_on_the_fly_gate_design.cpp | 2 +- .../on_the_fly_circuit_design_on_defective_surface.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index d41ffab6e..3162959f9 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -66,7 +66,7 @@ int main() // NOLINT // create an empty surface. fiction::sidb_defect_surface surface_lattice{}; - // add physical parameters of the defects to the defect-surface. + // add physical parameters of the defects to the surface_lattice. surface_lattice_initial.foreach_sidb_defect( [&surface_lattice, &stray_db, &si_vacancy](const auto& cd) { diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 30f939c23..760cf1689 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -6,7 +6,6 @@ #define FICTION_ON_THE_FLY_CIRCUIT_DESIGN_ON_DEFECTIVE_SURFACE_HPP #include "fiction/algorithms/physical_design/apply_gate_library.hpp" -#include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/physical_design/exact.hpp" #include "fiction/networks/technology_network.hpp" #include "fiction/technology/parameterized_gate_library.hpp" From c5fcb1302ad845983e8e969e494dce6a1d8481b5 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 15 Jul 2024 13:26:31 +0200 Subject: [PATCH 144/191] :art: small fixes. --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 760cf1689..ddbd2a128 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -137,7 +137,7 @@ class on_the_fly_circuit_design_impl return sidb_defect_surface{}; } - // in case of equality, defect-surface with the SiDBs of the circuit is returned + // in case of equality, an sidb_defect_surface with the SiDBs of the circuit is returned if (*eq) { sidb_defect_surface sidbs_and_defects{cell_level_layout}; @@ -150,7 +150,7 @@ class on_the_fly_circuit_design_impl return sidbs_and_defects; } - // in case of no equality, empty defect-surface is returned + // in case of inequality, empty defect-surface is returned return sidb_defect_surface{}; } From 0bf8fe5fabaaa5690107f36e03adc3b00579f96e Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 24 Jul 2024 12:20:19 +0000 Subject: [PATCH 145/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index db02c6a39..8fb611517 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -12815,6 +12815,54 @@ Parameter ``e``: Parameter ``other``: Edge whose color is to be used to paint `e`.)doc"; +static const char *__doc_fiction_parameter_point = R"doc(The parameter point holds parameter values in the x and y dimension.)doc"; + +static const char *__doc_fiction_parameter_point_get = +R"doc(Support for structured bindings. + +Template parameter ``I``: + Index of the parameter value to be returned. + +Returns: + The parameter value at the specified index.)doc"; + +static const char *__doc_fiction_parameter_point_operator_eq = +R"doc(Equality operator. Checks if this parameter point is equal to another +point within a specified tolerance. The tolerance is defined by +`physical_constants::POP_STABILITY_ERR`. + +Parameter ``other``: + Other parameter point to compare with. + +Returns: + `true` iff the parameter points are equal.)doc"; + +static const char *__doc_fiction_parameter_point_operator_ne = +R"doc(Inequality operator. Checks if this parameter point is unequal to +another point within a specified tolerance. The tolerance is defined +by `physical_constants::POP_STABILITY_ERR`. + +Parameter ``other``: + Other parameter point to compare with. + +Returns: + `true` iff the parameter points are not equal.)doc"; + +static const char *__doc_fiction_parameter_point_parameter_point = R"doc(Standard default constructor.)doc"; + +static const char *__doc_fiction_parameter_point_parameter_point_2 = +R"doc(Standard constructor. + +Parameter ``x_val``: + X dimension parameter value. + +Parameter ``y_val``: + Y dimension parameter value.)doc"; + +static const char *__doc_fiction_parameter_point_x = R"doc(X dimension parameter value.)doc"; + +static const char *__doc_fiction_parameter_point_y = R"doc(Y dimension parameter value.)doc"; + static const char *__doc_fiction_parameterized_gate_library = R"doc(A parameterized gate library for SiDB technology. It allows the design of SiDB gates tailored to given atomic defects, thus enabling the @@ -13010,54 +13058,6 @@ Parameter ``parameters``: Returns: Bestagon gate representation of `t` including mirroring.)doc"; -static const char *__doc_fiction_parameter_point = R"doc(The parameter point holds parameter values in the x and y dimension.)doc"; - -static const char *__doc_fiction_parameter_point_get = -R"doc(Support for structured bindings. - -Template parameter ``I``: - Index of the parameter value to be returned. - -Returns: - The parameter value at the specified index.)doc"; - -static const char *__doc_fiction_parameter_point_operator_eq = -R"doc(Equality operator. Checks if this parameter point is equal to another -point within a specified tolerance. The tolerance is defined by -`physical_constants::POP_STABILITY_ERR`. - -Parameter ``other``: - Other parameter point to compare with. - -Returns: - `true` iff the parameter points are equal.)doc"; - -static const char *__doc_fiction_parameter_point_operator_ne = -R"doc(Inequality operator. Checks if this parameter point is unequal to -another point within a specified tolerance. The tolerance is defined -by `physical_constants::POP_STABILITY_ERR`. - -Parameter ``other``: - Other parameter point to compare with. - -Returns: - `true` iff the parameter points are not equal.)doc"; - -static const char *__doc_fiction_parameter_point_parameter_point = R"doc(Standard default constructor.)doc"; - -static const char *__doc_fiction_parameter_point_parameter_point_2 = -R"doc(Standard constructor. - -Parameter ``x_val``: - X dimension parameter value. - -Parameter ``y_val``: - Y dimension parameter value.)doc"; - -static const char *__doc_fiction_parameter_point_x = R"doc(X dimension parameter value.)doc"; - -static const char *__doc_fiction_parameter_point_y = R"doc(Y dimension parameter value.)doc"; - static const char *__doc_fiction_path_collection = R"doc(An ordered collection of multiple paths in a layout. From b9a7b9e4cfdfb398c452b6d92749fc455e268f16 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 28 Jul 2024 09:35:38 +0200 Subject: [PATCH 146/191] :art: integrate first batch of Marcel's comments. --- docs/algorithms/design_sidb_gates.rst | 10 - docs/layouts/bounding_box.rst | 1 - docs/technology/gate_libraries.rst | 4 +- docs/technology/simulation.rst | 2 +- .../physical_design/design_sidb_gates.hpp | 5 +- .../algorithms/physical_design/exact.hpp | 22 +- ...ly_circuit_design_on_defective_surface.hpp | 32 ++- include/fiction/layouts/bounding_box.hpp | 213 ++++++++---------- include/fiction/layouts/coordinates.hpp | 11 +- .../is_sidb_gate_design_impossible.hpp | 71 +++--- .../technology/parameterized_gate_library.hpp | 8 +- include/fiction/utils/layout_utils.hpp | 1 - .../technology_mapping.cpp | 53 ----- .../algorithms/simulation/sidb/quickexact.cpp | 4 +- test/layouts/bounding_box.cpp | 31 ++- .../is_sidb_gate_design_impossible.cpp | 25 +- .../technology/parameterized_gate_library.cpp | 2 +- 17 files changed, 210 insertions(+), 285 deletions(-) diff --git a/docs/algorithms/design_sidb_gates.rst b/docs/algorithms/design_sidb_gates.rst index 3116d7bff..b65c3577e 100644 --- a/docs/algorithms/design_sidb_gates.rst +++ b/docs/algorithms/design_sidb_gates.rst @@ -15,13 +15,3 @@ SiDB Gate Designer .. autoclass:: mnt.pyfiction.design_sidb_gates_params :members: .. autofunction:: mnt.pyfiction.design_sidb_gates - - -Utility Functions -################# - -**Header:** ``fiction/technology/is_sidb_gate_design_impossible.hpp`` - -.. doxygenstruct:: fiction::is_gate_design_impossible_params - :members: -.. doxygenfunction:: fiction::is_gate_design_impossible diff --git a/docs/layouts/bounding_box.rst b/docs/layouts/bounding_box.rst index 3cd53b035..3c534ca8b 100644 --- a/docs/layouts/bounding_box.rst +++ b/docs/layouts/bounding_box.rst @@ -5,7 +5,6 @@ Bounding Box .. tab:: C++ **Header:** ``fiction/layouts/bounding_box.hpp`` - .. doxygenenum:: fiction::bounding_box_2d_selection .. doxygenclass:: fiction::bounding_box_2d :members: diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index 042bc3fb9..c749ba32e 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -59,8 +59,8 @@ SiDB Bestagon Library .. doxygenclass:: fiction::sidb_bestagon_library :members: -On-the-fly SiDB Library ------------------------ +Parameterized SiDB Library +-------------------------- **Header:** ``fiction/technology/parameterized_gate_library.hpp`` diff --git a/docs/technology/simulation.rst b/docs/technology/simulation.rst index 133e474e2..31217b130 100644 --- a/docs/technology/simulation.rst +++ b/docs/technology/simulation.rst @@ -56,7 +56,7 @@ SiDB Gate design is deemed impossible **Header:** ``fiction/technology/is_sidb_gate_design_impossible.hpp`` -.. doxygenstruct:: fiction::is_gate_design_impossible_params +.. doxygenstruct:: fiction::is_sidb_gate_design_impossible_params :members: .. doxygenfunction:: fiction::is_sidb_gate_design_impossible diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 1197fe1f5..d11948e9a 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -200,7 +200,10 @@ class design_sidb_gates_impl for (auto& thread : threads) { - thread.join(); + if (thread.joinable()) + { + thread.join(); + } } return designed_gate_layouts; diff --git a/include/fiction/algorithms/physical_design/exact.hpp b/include/fiction/algorithms/physical_design/exact.hpp index a1d273f5c..37c5e541a 100644 --- a/include/fiction/algorithms/physical_design/exact.hpp +++ b/include/fiction/algorithms/physical_design/exact.hpp @@ -1977,13 +1977,9 @@ class exact_impl { solver->add(!(get_tn(t, n))); - // clang-format off - // same for the outgoing edges - foreach_outgoing_edge(network, n, - [this, &t](const auto& e) + foreach_outgoing_edge(network, n, [this, &t](const auto& e) { solver->add(!(get_te(t, e))); }); - // clang-format on } // cannot be placed with too little distance to south-east corner if (layout.x() - t.x + layout.y() - t.y < il) @@ -1992,15 +1988,10 @@ class exact_impl // following iterations check_point->assumptions.push_back(!(get_tn(t, n))); - // clang-format off - // same for the incoming edges foreach_incoming_edge( - network, n, - [this, &t](const auto& e) + network, n, [this, &t](const auto& e) { check_point->assumptions.push_back(!(get_te(t, e))); }); - - // clang-format on } }); } @@ -2972,7 +2963,7 @@ class exact_impl */ [[nodiscard]] std::optional run_asynchronously() { - std::cout << "You have called an unstable beta feature that might crash." << std::endl; + std::cout << "You have called an unstable beta feature that might crash.\n"; Lyt layout{{}, scheme}; @@ -3203,7 +3194,7 @@ std::optional exact(const Ntk& ntk, const exact_physical_design_params& ps { if (ps.synchronization_elements) { - std::cout << "[w] Lyt does not support synchronization elements; not using them" << std::endl; + std::cout << "[w] Lyt does not support synchronization elements; not using them\n"; } } @@ -3267,15 +3258,14 @@ std::optional exact_with_blacklist(const Ntk& ntk, const surface_black_list if (ps.straight_inverters) { std::cout << "[w] Lyt does not implement the foreach_adjacent_opposite_tiles function; straight inverters " - "cannot be guaranteed" - << '\n'; + "cannot be guaranteed\n"; } } if constexpr (!fiction::has_synchronization_elements_v) { if (ps.synchronization_elements) { - std::cout << "[w] Lyt does not support synchronization elements; not using them" << '\n'; + std::cout << "[w] Lyt does not support synchronization elements; not using them\n"; } } diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index ddbd2a128..b6c6650c9 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -28,7 +28,7 @@ namespace fiction { /** - * This struct stores the parameters to design SiDB circuit on a defective surface. + * This struct stores the parameters to design an SiDB circuit on a defective surface. * * @tparam CellLyt Cell-level layout type. */ @@ -38,7 +38,7 @@ struct on_the_fly_circuit_design_params /** * Parameters for the parameterized gate library. */ - parameterized_gate_library_params parameterized_gate_library_parameter = {}; + parameterized_gate_library_params parameterized_gate_library_parameters = {}; /** * Parameters for the *exact* placement&routing algorithm. */ @@ -77,16 +77,16 @@ class on_the_fly_circuit_design_impl [[nodiscard]] sidb_defect_surface design_circuit_on_defective_surface() { + const mockturtle::stopwatch stop{stats.time_total}; + std::optional gate_level_layout = std::nullopt; - CellLyt cell_level_layout{}; + CellLyt lyt{}; // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects // is not considered as gates are designed on-the-fly. auto black_list = sidb_surface_analysis( lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); - const mockturtle::stopwatch stop{stats.time_total}; - while (!gate_level_layout.has_value()) { // P&R with *exact* and the pre-determined blacklist @@ -96,8 +96,8 @@ class on_the_fly_circuit_design_impl { try { - cell_level_layout = apply_parameterized_gate_library>( + lyt = apply_parameterized_gate_library>( *gate_level_layout, params.parameterized_gate_library_parameter); } @@ -113,7 +113,6 @@ class on_the_fly_circuit_design_impl std::cerr << "Caught std::exception: " << e.what() << '\n'; } } - // P&R was unsuccessful else { @@ -140,7 +139,7 @@ class on_the_fly_circuit_design_impl // in case of equality, an sidb_defect_surface with the SiDBs of the circuit is returned if (*eq) { - sidb_defect_surface sidbs_and_defects{cell_level_layout}; + sidb_defect_surface sidbs_and_defects{lyt}; // add defects to the circuit. params.parameterized_gate_library_parameter.defect_surface.foreach_sidb_defect( @@ -162,11 +161,11 @@ class on_the_fly_circuit_design_impl /** * Mapped network. */ - Ntk mapped_network{}; + Ntk mapped_network; /** * Parameters for the on-the-fly circuit design. */ - on_the_fly_circuit_design_params params{}; + const on_the_fly_circuit_design_params params{}; /** * Statistics for the on-the-fly circuit design. */ @@ -181,15 +180,14 @@ class on_the_fly_circuit_design_impl * proposed in \"On-the-fly Defect-Aware Design of Circuits based on Silicon Dangling Bond Logic\" by J. Drewniok, M. * Walter, S. S. H. Ng, K. Walus, and R. Wille in IEEE NANO 2024. * - * @tparam Ntk The type of the input network. + * @tparam Ntk The type of the input network. * @tparam CellLyt The type of the cell layout. * @tparam GateLyt The type of the gate layout. - * @param mapped_network The input network to be mapped onto the defective surface. - * @param design_params The parameters used for designing the circuit, encapsulated in an + * @param mapped_network The input network to be mapped onto the defective surface. + * @param design_params The parameters used for designing the circuit, encapsulated in an * `on_the_fly_circuit_design_params` object. - * @param lattice_tiling The lattice tiling used for the circuit design. - * @param defect_surface The defective surface on which the circuit is to be designed. - * @param stats Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. + * @param lattice_tiling The lattice tiling used for the circuit design. + * @param stats Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. * * @return A `sidb_defect_surface` representing the designed circuit on the defective surface. */ diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index 2a2f9c112..e2dff78d6 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -19,21 +19,6 @@ namespace fiction { -/** - * Modes to use for creating the 2D-bounding box. - */ -enum class bounding_box_2d_selection -{ - /** - * The bounding box includes atomic defects. - */ - INCLUDE_DEFECTS, - /** - * The bounding box is determined based on the cells, excluding atomic defects. - */ - EXCLUDE_DEFECTS -}; - /** * A 2D bounding box object that computes a minimum-sized box around all non-empty coordinates in a given layout. * Layouts can be of arbitrary size and, thus, may be larger than their contained elements. Sometimes, it might be @@ -59,22 +44,10 @@ class bounding_box_2d static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); update_bounding_box(); } - /** - * Standard constructor that computes an initial bounding box. - * - * @param lyt Gate-level or cell-level layout whose bounding box is desired. - */ - explicit bounding_box_2d(const Lyt& lyt, const bounding_box_2d_selection& bb_selection) noexcept : layout{lyt} - { - static_assert(is_coordinate_layout_v, "Lyt is not a coordinate layout"); - update_bounding_box(bb_selection); - } /** * The bounding box is not automatically updated when the layout changes. This function recomputes the bounding box. - * - * @param selection Modes to use for creating the bounding box. */ - void update_bounding_box(const bounding_box_2d_selection& selection = bounding_box_2d_selection::INCLUDE_DEFECTS) + void update_bounding_box() { min = {0, 0, 0}; max = {0, 0, 0}; @@ -98,14 +71,14 @@ class bounding_box_2d // the layout is based on SiQAD coordinates if constexpr (has_siqad_coord_v) { - int32_t min_x_cell = std::numeric_limits::max(); - int32_t max_x_cell = std::numeric_limits::min(); + auto min_x_cell = std::numeric_limits::x)>::max(); + auto max_x_cell = std::numeric_limits::x)>::min(); - int32_t min_y_cell = std::numeric_limits::max(); - int32_t max_y_cell = std::numeric_limits::min(); + auto min_y_cell = std::numeric_limits::y)>::max(); + auto max_y_cell = std::numeric_limits::y)>::min(); - uint8_t min_z_cell = 1; - uint8_t max_z_cell = 0; + auto min_z_cell = 1; + auto max_z_cell = 0; layout.foreach_cell( [&min_x_cell, &max_x_cell, &min_y_cell, &max_y_cell, &min_z_cell, &max_z_cell](const auto& c) @@ -148,58 +121,56 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) - { - int32_t min_x_defect = std::numeric_limits::max(); - int32_t max_x_defect = std::numeric_limits::min(); + auto min_x_defect = std::numeric_limits::x)>::max(); + auto max_x_defect = std::numeric_limits::x)>::min(); - int32_t min_y_defect = std::numeric_limits::max(); - int32_t max_y_defect = std::numeric_limits::min(); + auto min_y_defect = std::numeric_limits::y)>::max(); + auto max_y_defect = std::numeric_limits::y)>::min(); - uint8_t min_z_defect = 1; - uint8_t max_z_defect = 0; + uint8_t min_z_defect = 1; + uint8_t max_z_defect = 0; - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, - &max_z_defect](const auto& defect) + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, + &max_z_defect](const auto& defect) + { + if (defect.first.x < min_x_defect) { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) - { - max_x_defect = defect.first.x; - } + min_x_defect = defect.first.x; + } + if (defect.first.x > max_x_defect) + { + max_x_defect = defect.first.x; + } - if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) - { - min_z_defect = defect.first.z; - } - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - min_z_defect = defect.first.z; - } + if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) + { + min_z_defect = defect.first.z; + } + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + min_z_defect = defect.first.z; + } - if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) - { - max_z_defect = defect.first.z; - } - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - max_z_defect = defect.first.z; - } - }); - const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; - - min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), - std::min(min_cell.z, min_defect.z)}; - max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), - std::max(max_cell.z, max_defect.z)}; - } + if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) + { + max_z_defect = defect.first.z; + } + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + max_z_defect = defect.first.z; + } + }); + + const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; + + min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), + std::min(min_cell.z, min_defect.z)}; + max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), + std::max(max_cell.z, max_defect.z)}; } } else @@ -263,44 +234,41 @@ class bounding_box_2d if constexpr (is_sidb_defect_surface_v) { - if (selection == bounding_box_2d_selection::INCLUDE_DEFECTS) - { - auto min_x_defect = std::numeric_limits::x)>::max(); - auto max_x_defect = std::numeric_limits::y)>::min(); + auto min_x_defect = std::numeric_limits::x)>::max(); + auto max_x_defect = std::numeric_limits::y)>::min(); - auto min_y_defect = std::numeric_limits::x)>::max(); - auto max_y_defect = std::numeric_limits::y)>::min(); + auto min_y_defect = std::numeric_limits::x)>::max(); + auto max_y_defect = std::numeric_limits::y)>::min(); - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) + layout.foreach_sidb_defect( + [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) + { + if (defect.first.x < min_x_defect) { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) - { - max_x_defect = defect.first.x; - } + min_x_defect = defect.first.x; + } + if (defect.first.x > max_x_defect) + { + max_x_defect = defect.first.x; + } - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - } + if (defect.first.y < min_y_defect) + { + min_y_defect = defect.first.y; + } - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - } - }); - const auto min_defect = coordinate{min_x_defect, min_y_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect}; - - min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), - std::min(min.z, min_defect.z)}; - max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), - std::max(max.z, max_defect.z)}; - } + if (defect.first.y > max_y_defect) + { + max_y_defect = defect.first.y; + } + }); + const auto min_defect = coordinate{min_x_defect, min_y_defect}; + const auto max_defect = coordinate{max_x_defect, max_y_defect}; + + min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), + std::min(min.z, min_defect.z)}; + max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), + std::max(max.z, max_defect.z)}; } } @@ -351,13 +319,32 @@ class bounding_box_2d } private: + /** + * The layout whose bounding box is being computed. + */ const Lyt& layout; + /** + * The minimum and maximum coordinates of the bounding box. + */ coordinate min{0, 0, 0}, max{0, 0, 0}; + /** + * The horizontal size of the bounding box in layout coordinates. + */ decltype(min.x) x_size{}; + + /** + * The vertical size of the bounding box in layout coordinates. + */ decltype(min.y) y_size{}; + /** + * Checks if a given coordinate is empty in the layout. + * + * @param c The coordinate to check. + * @return True if the coordinate is empty, false otherwise. + */ [[nodiscard]] bool is_empty_coordinate(const coordinate& c) const noexcept { static_assert(has_is_empty_tile_v || has_is_empty_cell_v, diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index cbfde9a56..62454623b 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -800,6 +800,7 @@ constexpr CoordinateType to_fiction_coord(const siqad::coord_t& coord) noexcept * @tparam CoordinateType Coordinate type to convert. * @param coord Coordinate to convert. * @return SiQAD coordinate representation of `coord`. + * */ template constexpr coord_t to_siqad_coord(const CoordinateType& coord) noexcept @@ -818,16 +819,24 @@ constexpr coord_t to_siqad_coord(const CoordinateType& coord) noexcept * * @param coord Offset coordinate to convert to a cube coordinate. * @return Cube coordinate. + * + * @note This function assumes that the input coordinates are within the valid range for cube coordinates. Specifically, + * the x, y, and z coordinates should be within the range of \f$(0, 0, 0)\f$ to \f$(2^{31} - 1, 2^{31} - 1, 1)\f$. If + * the input coordinates are outside this range, the behavior of the function is undefined. If the input coordinate is + * dead, a dead cube coordinate is returned. */ constexpr cube::coord_t offset_to_cube_coord(const offset::ucoord_t& coord) noexcept { assert(coord.x <= std::numeric_limits::max() && coord.y <= std::numeric_limits::max() && coord.z <= std::numeric_limits::max() && "Coordinate is out-of-range and cannot be transformed"); + if (coord.is_dead()) { return cube::coord_t{}; } - return {static_cast(coord.x), static_cast(coord.y), static_cast(coord.z)}; + + return {static_cast(coord.x), static_cast(coord.y), + static_cast(coord.z)}; } /** diff --git a/include/fiction/technology/is_sidb_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp index dfae13726..1fe7b4fe8 100644 --- a/include/fiction/technology/is_sidb_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -6,8 +6,7 @@ #define FICTION_IS_SIDB_GATE_DESIGN_IMPOSSIBLE_HPP #include "fiction/algorithms/iter/bdl_input_iterator.hpp" -#include "fiction/algorithms/simulation/sidb/is_operational.hpp" -#include "fiction/algorithms/simulation/sidb/sidb_simulation_engine.hpp" +#include "fiction/algorithms/simulation/sidb/detect_bdl_pairs.hpp" #include "fiction/algorithms/simulation/sidb/sidb_simulation_parameters.hpp" #include "fiction/technology/cell_technologies.hpp" #include "fiction/technology/charge_distribution_surface.hpp" @@ -24,75 +23,75 @@ namespace fiction /** * This struct contains parameters to determine if SiDB gate design is impossible. */ -struct is_gate_design_impossible_params +struct is_sidb_gate_design_impossible_params { /** * All parameters for physical SiDB simulations. */ - sidb_simulation_parameters phys_params{}; + sidb_simulation_parameters simulation_params{}; /** - * The simulation engine to be used for simulation. + * Parameters used to determine BDL pairs. */ - sidb_simulation_engine sim_engine{sidb_simulation_engine::QUICKEXACT}; + detect_bdl_pairs_params detect_bdl_params{}; }; /** - * This function evaluates whether it is impossible to design a SiDB gate for a given truth table in the given layout - * due to atomic defects. It determines the possible charge states at the output BDL pairs. Atomic defects can cause a - * BDL pair to be neutrally charged only. Thus, the BDL pair would not work as intended. + * This function evaluates whether it is impossible to design an SiDB gate for a given truth table and a given skeleton + * with atomic defects. It determines the possible charge states at the output BDL pairs. Atomic defects can cause a BDL + * pair to be neutrally charged only. Thus, the BDL pair would not work as intended. * - * @tparam Lyt Cell-level layout type. - * @tparam TT The type of the truth table. - * @param layout The layout for which gate design feasibility is being checked. - * @param spec A vector of truth tables (each truth table is representing one output) representing the gate's + * @tparam Lyt SiDB cell-level layout type. + * @tparam TT The truth table type. + * @param skeleton_with_defects An SiDB skeleton layout with atomic defects. + * @param spec A vector of truth tables (each truth table is representing one output) representing the gate's intended * functionality. - * @param params Parameter to determine if the gate design is impossible. + * @param params Parameters to determine if the gate design is impossible. * @return `true` if gate design is impossible, `false` otherwise. - * */ template -bool is_gate_design_impossible(const Lyt& layout, const std::vector& spec, - const is_gate_design_impossible_params& params = {}) +[[nodiscard]] bool is_sidb_gate_design_impossible(const Lyt& skeleton_with_defects, const std::vector& spec, + const is_sidb_gate_design_impossible_params& params = {}) 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(is_sidb_defect_surface_v, "Lyt is not an SiDB defect surface"); + static_assert(is_cell_level_layout_v, "Lyt is not an SiDB cell-level layout"); - assert(layout.num_pis() > 0 && "lyt needs input cells"); - assert(layout.num_pos() > 0 && "lyt needs output cells"); + assert(skeleton_with_defects.num_pis() > 0 && "lyt needs input cells"); + assert(skeleton_with_defects.num_pos() > 0 && "lyt needs output cells"); - const auto operation_params = is_operational_params{params.phys_params, params.sim_engine}; + const auto output_pairs = + detect_bdl_pairs(skeleton_with_defects, sidb_technology::cell_type::OUTPUT, params.detect_bdl_params); - const auto bdl_pairs = detect_bdl_pairs(layout, sidb_technology::cell_type::OUTPUT, operation_params.bdl_params); + assert(output_pairs.empty() == false && "lyt needs output BDL pairs"); - auto bdl_iter = bdl_input_iterator{layout, operation_params.bdl_params}; + auto bdl_iter = bdl_input_iterator{skeleton_with_defects, params.detect_bdl_params}; for (auto i = 0u; i < spec.front().num_bits(); ++i, ++bdl_iter) { - auto charge_lyt = charge_distribution_surface{layout, params.phys_params}; + auto charge_lyt = charge_distribution_surface{skeleton_with_defects, params.simulation_params}; charge_lyt.assign_all_charge_states(sidb_charge_state::NEUTRAL); charge_lyt.update_after_charge_change(); - if constexpr (has_get_sidb_defect_v) - { - layout.foreach_sidb_defect( - [&charge_lyt](const auto& cd) + skeleton_with_defects.foreach_sidb_defect( + [&charge_lyt](const auto& cd) + { + const auto& [defect_pos, defect] = cd; + if (is_charged_defect_type(defect)) { - if (is_charged_defect_type(cd.second)) - { - charge_lyt.add_sidb_defect_to_potential_landscape(cd.first, cd.second); - } - }); - } + charge_lyt.add_sidb_defect_to_potential_landscape(defect_pos, defect); + } + }); // checks if parts of the bdl pairs are already neutrally charged due to nearby charged atomic defects. - for (const auto& bdl : bdl_pairs) + for (const auto& bdl : output_pairs) { - if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.phys_params.mu_minus) > + if ((-(*charge_lyt.get_local_potential(bdl.lower)) + params.simulation_params.mu_minus) > -physical_constants::POP_STABILITY_ERR) { return true; // the lower part can never be negatively charged. Thus, BDL property is not fulfilled // anymore } - if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.phys_params.mu_minus) > + if ((-(*charge_lyt.get_local_potential(bdl.upper)) + params.simulation_params.mu_minus) > -physical_constants::POP_STABILITY_ERR) { return true; // the upper part can never be negatively charged. Thus, BDL property is not fulfilled diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index 25144bbb5..e8025e2b9 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -496,11 +496,11 @@ class parameterized_gate_library : public fcn_gate_library, "Lyt is not an SiDB layout"); static_assert(has_cube_coord_v, "Lyt is not based on cube coordinates"); - const auto params = is_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters, - parameters.design_gate_params.sim_engine}; + const auto params = is_sidb_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters, + parameters.design_gate_params.sim_engine}; if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) { - if (is_gate_design_impossible(skeleton_with_defects, spec, params)) + if (is_sidb_gate_design_impossible(skeleton_with_defects, spec, params)) { throw gate_design_exception(tile, create_id_tt(), p); } @@ -514,7 +514,7 @@ class parameterized_gate_library : public fcn_gate_library(tile, spec.front(), p); } diff --git a/include/fiction/utils/layout_utils.hpp b/include/fiction/utils/layout_utils.hpp index 35f10beb5..0eb0d7205 100644 --- a/include/fiction/utils/layout_utils.hpp +++ b/include/fiction/utils/layout_utils.hpp @@ -543,7 +543,6 @@ LytDest convert_to_fiction_coordinates(const LytSrc& lyt) noexcept } } } - /** * Generates a random coordinate within the region spanned by two given coordinates. The two given coordinates form the * top left corner and the bottom right corner of the spanned region. diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp index 345ca5ee1..f70838f78 100644 --- a/test/algorithms/network_transformation/technology_mapping.cpp +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -31,10 +31,6 @@ void map_and_check_aoi(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and2 >= 0); - CHECK(gt_stats.num_or2 >= 0); - CHECK(gt_stats.num_nand2 == 0); CHECK(gt_stats.num_nor2 == 0); CHECK(gt_stats.num_xor2 == 0); @@ -65,11 +61,6 @@ void map_and_check_aoim(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and2 >= 0); - CHECK(gt_stats.num_or2 >= 0); - CHECK(gt_stats.num_maj3 >= 0); - CHECK(gt_stats.num_nand2 == 0); CHECK(gt_stats.num_nor2 == 0); CHECK(gt_stats.num_xor2 == 0); @@ -154,17 +145,6 @@ void map_and_check_all_standard_3_inp(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and3 >= 0); - CHECK(gt_stats.num_xor_and >= 0); - CHECK(gt_stats.num_or_and >= 0); - CHECK(gt_stats.num_onehot >= 0); - CHECK(gt_stats.num_maj3 >= 0); - CHECK(gt_stats.num_gamble >= 0); - CHECK(gt_stats.num_dot >= 0); - CHECK(gt_stats.num_mux >= 0); - CHECK(gt_stats.num_and_xor >= 0); - CHECK(gt_stats.num_and2 == 0); CHECK(gt_stats.num_or2 == 0); CHECK(gt_stats.num_nand2 == 0); @@ -187,17 +167,6 @@ void map_and_check_all_3_inp(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and3 >= 0); - CHECK(gt_stats.num_xor_and >= 0); - CHECK(gt_stats.num_or_and >= 0); - CHECK(gt_stats.num_onehot >= 0); - CHECK(gt_stats.num_maj3 >= 0); - CHECK(gt_stats.num_gamble >= 0); - CHECK(gt_stats.num_dot >= 0); - CHECK(gt_stats.num_mux >= 0); - CHECK(gt_stats.num_and_xor >= 0); - CHECK(gt_stats.num_and2 == 0); CHECK(gt_stats.num_or2 == 0); CHECK(gt_stats.num_nand2 == 0); @@ -220,17 +189,6 @@ void map_and_check_all_func(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and3 >= 0); - CHECK(gt_stats.num_xor_and >= 0); - CHECK(gt_stats.num_or_and >= 0); - CHECK(gt_stats.num_onehot >= 0); - CHECK(gt_stats.num_maj3 >= 0); - CHECK(gt_stats.num_gamble >= 0); - CHECK(gt_stats.num_dot >= 0); - CHECK(gt_stats.num_mux >= 0); - CHECK(gt_stats.num_and_xor >= 0); - CHECK(gt_stats.num_and2 == 0); CHECK(gt_stats.num_or2 == 0); CHECK(gt_stats.num_nand2 == 0); @@ -258,17 +216,6 @@ void map_and_check_all_standard_func(const Ntk& ntk) count_gate_types_stats gt_stats{}; count_gate_types(mapped_ntk, >_stats); - CHECK(gt_stats.num_inv >= 0); - CHECK(gt_stats.num_and3 >= 0); - CHECK(gt_stats.num_xor_and >= 0); - CHECK(gt_stats.num_or_and >= 0); - CHECK(gt_stats.num_onehot >= 0); - CHECK(gt_stats.num_maj3 >= 0); - CHECK(gt_stats.num_gamble >= 0); - CHECK(gt_stats.num_dot >= 0); - CHECK(gt_stats.num_mux >= 0); - CHECK(gt_stats.num_and_xor >= 0); - CHECK(gt_stats.num_and2 == 0); CHECK(gt_stats.num_or2 == 0); CHECK(gt_stats.num_nand2 == 0); diff --git a/test/algorithms/simulation/sidb/quickexact.cpp b/test/algorithms/simulation/sidb/quickexact.cpp index 414dd9af4..8adabeb29 100644 --- a/test/algorithms/simulation/sidb/quickexact.cpp +++ b/test/algorithms/simulation/sidb/quickexact.cpp @@ -1175,7 +1175,7 @@ TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shaped SiDB OR gate with input SECTION("Check if QuickExact is deterministic") { - SECTION("Epsilon_r = 8") + SECTION("epsilon_r = 8") { params.simulation_parameters.epsilon_r = 8; std::set ground_state{}; @@ -1191,7 +1191,7 @@ TEMPLATE_TEST_CASE("QuickExact simulation of a Y-shaped SiDB OR gate with input CHECK(ground_state.size() == 1); CHECK(charge_index.size() == 1); } - SECTION("Epsilon_r = 2") + SECTION("epsilon_r = 2") { params.simulation_parameters.epsilon_r = 2; std::set ground_state{}; diff --git a/test/layouts/bounding_box.cpp b/test/layouts/bounding_box.cpp index 209044d01..e27f8a12a 100644 --- a/test/layouts/bounding_box.cpp +++ b/test/layouts/bounding_box.cpp @@ -225,8 +225,7 @@ TEMPLATE_TEST_CASE("2D bounding box for siqad layout", "[bounding-box]", sidb_ce } TEMPLATE_TEST_CASE("2D bounding box for siqad layout with atomic defect", "[bounding-box]", - sidb_defect_cell_clk_lyt_siqad, sidb_defect_surface, - sidb_defect_100_cell_clk_lyt_siqad) + sidb_defect_cell_clk_lyt_siqad, sidb_111_cell_clk_lyt_siqad, sidb_defect_100_cell_clk_lyt_siqad) { SECTION("empyt layout") { @@ -242,7 +241,7 @@ TEMPLATE_TEST_CASE("2D bounding box for siqad layout with atomic defect", "[boun SECTION("one cell and one defect") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); @@ -256,7 +255,7 @@ TEMPLATE_TEST_CASE("2D bounding box for siqad layout with atomic defect", "[boun SECTION("two cell and two defect") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); lyt.assign_cell_type({-2, 0, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); @@ -271,8 +270,7 @@ TEMPLATE_TEST_CASE("2D bounding box for siqad layout with atomic defect", "[boun } } -TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-box]", sidb_defect_cell_clk_lyt, - sidb_defect_surface, sidb_defect_100_cell_clk_lyt) +TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-box]", sidb_defect_cell_clk_lyt) { SECTION("empyt layout") { @@ -288,7 +286,7 @@ TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-b SECTION("one cell and one defect") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({2, 0, 0}, sidb_defect{}); @@ -302,7 +300,7 @@ TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-b SECTION("two cell and two defect") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); lyt.assign_cell_type({3, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({2, 0}, sidb_defect{}); @@ -317,9 +315,8 @@ TEMPLATE_TEST_CASE("2D bounding box for layout with atomic defect", "[bounding-b } } -TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bounding-box]", - sidb_defect_cell_clk_lyt_cube, sidb_defect_surface, - sidb_defect_100_cell_clk_lyt_cube) +TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bounding-box]", sidb_cell_clk_lyt_cube, + sidb_111_cell_clk_lyt_cube, sidb_100_cell_clk_lyt_cube) { SECTION("empyt layout") { @@ -335,7 +332,7 @@ TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bound SECTION("one cell and one defect") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({2, 0}, sidb_defect{}); @@ -349,7 +346,7 @@ TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bound SECTION("two cell and two defect, include defects") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); lyt.assign_cell_type({2, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({-3, 0}, sidb_defect{}); @@ -365,17 +362,17 @@ TEMPLATE_TEST_CASE("2D bounding box for cube layout with atomic defect", "[bound SECTION("two cell and two defect, exclude defects") { - TestType lyt{}; + sidb_defect_surface lyt{TestType{}}; lyt.assign_cell_type({1, 0}, TestType::technology::NORMAL); lyt.assign_cell_type({2, 0}, TestType::technology::NORMAL); lyt.assign_sidb_defect({-3, 0}, sidb_defect{}); lyt.assign_sidb_defect({2, 0}, sidb_defect{}); - const bounding_box_2d bb{lyt, bounding_box_2d_selection::EXCLUDE_DEFECTS}; + const bounding_box_2d bb{static_cast(lyt)}; const auto nw = bb.get_min(); const auto se = bb.get_max(); - CHECK(nw == cell{1, 0}); - CHECK(se == cell{2, 0}); + CHECK(nw == cell{1, 0, 0}); + CHECK(se == cell{2, 0, 0}); } } diff --git a/test/technology/is_sidb_gate_design_impossible.cpp b/test/technology/is_sidb_gate_design_impossible.cpp index 58a80169c..ce5e2579d 100644 --- a/test/technology/is_sidb_gate_design_impossible.cpp +++ b/test/technology/is_sidb_gate_design_impossible.cpp @@ -6,11 +6,14 @@ #include "catch2/catch_template_test_macros.hpp" -#include +#include #include #include +#include #include +#include + using namespace fiction; TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-gate-design-impossible]") @@ -38,16 +41,18 @@ TEST_CASE("SiQAD's AND gate with input BDL pairs of different size", "[is-gate-d SECTION("without defect") { - CHECK(!is_gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); + CHECK(!is_sidb_gate_design_impossible( + lyt, std::vector{create_and_tt()}, + is_sidb_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); } SECTION("with defect") { lyt.assign_sidb_defect({12, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); lyt.assign_sidb_defect({11, 6, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 10, 5}); - CHECK(is_gate_design_impossible(lyt, std::vector{create_and_tt()}, - is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); + CHECK(is_sidb_gate_design_impossible( + lyt, std::vector{create_and_tt()}, + is_sidb_gate_design_impossible_params{sidb_simulation_parameters{2, -0.28}})); } } @@ -99,15 +104,17 @@ TEST_CASE("Bestagon CROSSING gate", "[is-gate-design-impossible]") SECTION("without defect") { - CHECK(!is_gate_design_impossible(lyt, create_crossing_wire_tt(), - is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); + CHECK(!is_sidb_gate_design_impossible( + lyt, create_crossing_wire_tt(), + is_sidb_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); } SECTION("with defect") { lyt.assign_sidb_defect({34, 18, 0}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); lyt.assign_sidb_defect({34, 18, 1}, sidb_defect{sidb_defect_type::SI_VACANCY, -1, 5, 5}); - CHECK(is_gate_design_impossible(lyt, create_crossing_wire_tt(), - is_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); + CHECK(is_sidb_gate_design_impossible( + lyt, create_crossing_wire_tt(), + is_sidb_gate_design_impossible_params{sidb_simulation_parameters{2, -0.32}})); } } diff --git a/test/technology/parameterized_gate_library.cpp b/test/technology/parameterized_gate_library.cpp index 344bb0eb3..00ed384df 100644 --- a/test/technology/parameterized_gate_library.cpp +++ b/test/technology/parameterized_gate_library.cpp @@ -10,7 +10,7 @@ using namespace fiction; -TEST_CASE("Parameterized gate library traits", "[sidb-dynamic-gate-library]") +TEST_CASE("Parameterized gate library traits", "[parameterized-gate-library]") { CHECK(!has_post_layout_optimization_v); CHECK(!has_post_layout_optimization_v); From 7ae0dcf8f7ecdf065d9571efe5902f2d0e57b8f6 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 28 Jul 2024 07:37:00 +0000 Subject: [PATCH 147/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 118 +++++++++--------- 1 file changed, 56 insertions(+), 62 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 2c7730215..c4be2661a 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -776,12 +776,6 @@ Template parameter ``Lyt``: static const char *__doc_fiction_bounding_box_2d_bounding_box_2d = R"doc(Standard constructor that computes an initial bounding box. -Parameter ``lyt``: - Gate-level or cell-level layout whose bounding box is desired.)doc"; - -static const char *__doc_fiction_bounding_box_2d_bounding_box_2d_2 = -R"doc(Standard constructor that computes an initial bounding box. - Parameter ``lyt``: Gate-level or cell-level layout whose bounding box is desired.)doc"; @@ -817,32 +811,28 @@ R"doc(Returns the vertical size of the bounding box in layout coordinates. Returns: Bounding box size along the y-axis.)doc"; -static const char *__doc_fiction_bounding_box_2d_is_empty_coordinate = R"doc()doc"; - -static const char *__doc_fiction_bounding_box_2d_layout = R"doc()doc"; +static const char *__doc_fiction_bounding_box_2d_is_empty_coordinate = +R"doc(Checks if a given coordinate is empty in the layout. -static const char *__doc_fiction_bounding_box_2d_max = R"doc()doc"; +Parameter ``c``: + The coordinate to check. -static const char *__doc_fiction_bounding_box_2d_min = R"doc()doc"; +Returns: + True if the coordinate is empty, false otherwise.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection = R"doc(Modes to use for creating the 2D-bounding box.)doc"; +static const char *__doc_fiction_bounding_box_2d_layout = R"doc(The layout whose bounding box is being computed.)doc"; -static const char *__doc_fiction_bounding_box_2d_selection_EXCLUDE_DEFECTS = -R"doc(The bounding box is determined based on the cells, excluding atomic -defects.)doc"; +static const char *__doc_fiction_bounding_box_2d_max = R"doc()doc"; -static const char *__doc_fiction_bounding_box_2d_selection_INCLUDE_DEFECTS = R"doc(The bounding box includes atomic defects.)doc"; +static const char *__doc_fiction_bounding_box_2d_min = R"doc(The minimum and maximum coordinates of the bounding box.)doc"; static const char *__doc_fiction_bounding_box_2d_update_bounding_box = R"doc(The bounding box is not automatically updated when the layout changes. -This function recomputes the bounding box. - -Parameter ``selection``: - Modes to use for creating the bounding box.)doc"; +This function recomputes the bounding box.)doc"; -static const char *__doc_fiction_bounding_box_2d_x_size = R"doc()doc"; +static const char *__doc_fiction_bounding_box_2d_x_size = R"doc(The horizontal size of the bounding box in layout coordinates.)doc"; -static const char *__doc_fiction_bounding_box_2d_y_size = R"doc()doc"; +static const char *__doc_fiction_bounding_box_2d_y_size = R"doc(The vertical size of the bounding box in layout coordinates.)doc"; static const char *__doc_fiction_calculate_energy_and_state_type = R"doc(This function takes in an SiDB energy distribution. For each charge @@ -11501,40 +11491,6 @@ Parameter ``ps``: `true` iff `ntk` is properly fanout-substituted with regard to `ps`.)doc"; -static const char *__doc_fiction_is_gate_design_impossible = -R"doc(This function evaluates whether it is impossible to design a SiDB gate -for a given truth table in the given layout due to atomic defects. It -determines the possible charge states at the output BDL pairs. Atomic -defects can cause a BDL pair to be neutrally charged only. Thus, the -BDL pair would not work as intended. - -Template parameter ``Lyt``: - Cell-level layout type. - -Template parameter ``TT``: - The type of the truth table. - -Parameter ``layout``: - The layout for which gate design feasibility is being checked. - -Parameter ``spec``: - A vector of truth tables (each truth table is representing one - output) representing the gate's functionality. - -Parameter ``params``: - Parameter to determine if the gate design is impossible. - -Returns: - `true` if gate design is impossible, `false` otherwise.)doc"; - -static const char *__doc_fiction_is_gate_design_impossible_params = -R"doc(This struct contains parameters to determine if SiDB gate design is -impossible.)doc"; - -static const char *__doc_fiction_is_gate_design_impossible_params_phys_params = R"doc(All parameters for physical SiDB simulations.)doc"; - -static const char *__doc_fiction_is_gate_design_impossible_params_sim_engine = R"doc(The simulation engine to be used for simulation.)doc"; - static const char *__doc_fiction_is_gate_level_layout = R"doc()doc"; static const char *__doc_fiction_is_ground_state = @@ -11663,6 +11619,40 @@ static const char *__doc_fiction_is_shifted_cartesian_layout = R"doc()doc"; static const char *__doc_fiction_is_sidb_defect_surface = R"doc()doc"; +static const char *__doc_fiction_is_sidb_gate_design_impossible = +R"doc(This function evaluates whether it is impossible to design an SiDB +gate for a given truth table and a given skeleton with atomic defects. +It determines the possible charge states at the output BDL pairs. +Atomic defects can cause a BDL pair to be neutrally charged only. +Thus, the BDL pair would not work as intended. + +Template parameter ``Lyt``: + SiDB cell-level layout type. + +Template parameter ``TT``: + The truth table type. + +Parameter ``skeleton_with_defects``: + An SiDB skeleton layout with atomic defects. + +Parameter ``spec``: + A vector of truth tables (each truth table is representing one + output) representing the gate's intended functionality. + +Parameter ``params``: + Parameters to determine if the gate design is impossible. + +Returns: + `true` if gate design is impossible, `false` otherwise.)doc"; + +static const char *__doc_fiction_is_sidb_gate_design_impossible_params = +R"doc(This struct contains parameters to determine if SiDB gate design is +impossible.)doc"; + +static const char *__doc_fiction_is_sidb_gate_design_impossible_params_detect_bdl_params = R"doc(Parameters used to determine BDL pairs.)doc"; + +static const char *__doc_fiction_is_sidb_gate_design_impossible_params_simulation_params = R"doc(All parameters for physical SiDB simulations.)doc"; + static const char *__doc_fiction_is_sidb_lattice = R"doc()doc"; static const char *__doc_fiction_is_sidb_lattice_100 = R"doc()doc"; @@ -12092,7 +12082,14 @@ Parameter ``coord``: Offset coordinate to convert to a cube coordinate. Returns: - Cube coordinate.)doc"; + Cube coordinate. + +@note This function assumes that the input coordinates are within the +valid range for cube coordinates. Specifically, the x, y, and z +coordinates should be within the range of :math:`(0, 0, 0)` to +:math:`(2^{31} - 1, 2^{31} - 1, 1)`. If the input coordinates are +outside this range, the behavior of the function is undefined. If the +input coordinate is dead, a dead cube coordinate is returned.)doc"; static const char *__doc_fiction_offset_ucoord_t = R"doc(Unsigned offset coordinates. @@ -12299,9 +12296,6 @@ Parameter ``design_params``: Parameter ``lattice_tiling``: The lattice tiling used for the circuit design. -Parameter ``defect_surface``: - The defective surface on which the circuit is to be designed. - Parameter ``stats``: Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. @@ -12311,7 +12305,7 @@ Parameter ``stats``: on the defective surface.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_params = -R"doc(This struct stores the parameters to design SiDB circuit on a +R"doc(This struct stores the parameters to design an SiDB circuit on a defective surface. Template parameter ``CellLyt``: @@ -12319,7 +12313,7 @@ Template parameter ``CellLyt``: static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement&routing algorithm.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameter = R"doc(Parameters for the parameterized gate library.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameters = R"doc(Parameters for the parameterized gate library.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_stats = R"doc(Statistics for the on-the-fly defect-aware circuit design.)doc"; From 074f7e338ee349e29a63ebbb633e5d79487c3b6c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sun, 28 Jul 2024 11:25:30 +0200 Subject: [PATCH 148/191] :art: small fix. --- ...cal_design_with_on_the_fly_gate_design.cpp | 20 +++-- .../physical_design/apply_gate_library.hpp | 12 +-- .../physical_design/design_sidb_gates.hpp | 16 ++-- ...ly_circuit_design_on_defective_surface.hpp | 82 ++++++++----------- include/fiction/layouts/bounding_box.hpp | 2 +- .../technology/parameterized_gate_library.hpp | 4 +- 6 files changed, 66 insertions(+), 70 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 3162959f9..5ba874420 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -90,8 +90,8 @@ int main() // NOLINT const auto lattice_tiling = gate_lyt{{11, 30}}; - experiments::experiment sidb_circuits_with_defects{ - "sidb_circuits_with_defects", "benchmark", "runtime", "number of aspect ratios"}; + experiments::experiment sidb_circuits_with_defects{ + "sidb_circuits_with_defects", "benchmark", "runtime", "number of aspect ratios", "equivalent"}; constexpr const uint64_t bench_select = fiction_experiments::all & ~fiction_experiments::parity & ~fiction_experiments::two_bit_add_maj & @@ -138,24 +138,30 @@ int main() // NOLINT params.exact_design_parameter.upper_bound_y = 30; // 12 x 31 tiles params.exact_design_parameter.timeout = 3'600'000; // 1h in ms - params.parameterized_gate_library_parameter.defect_surface = surface_lattice; - params.parameterized_gate_library_parameter.design_gate_params = design_gate_params; + params.parameterized_gate_library_parameters.defect_surface = surface_lattice; + params.parameterized_gate_library_parameters.design_gate_params = design_gate_params; - fiction::on_the_fly_circuit_design_stats st{}; + fiction::on_the_fly_circuit_design_stats st{}; const auto result = fiction::on_the_fly_circuit_design_on_defective_surface( mapped_network, params, lattice_tiling, &st); + // check equivalence + const auto miter = mockturtle::miter(mapped_network, st.gate_layout.value()); + const auto eq = mockturtle::equivalence_checking(*miter); + assert(eq.has_value()); + // determine bounding box and exclude atomic defects - const auto bb = fiction::bounding_box_2d(result, fiction::bounding_box_2d_selection::EXCLUDE_DEFECTS); + const auto bb = fiction::bounding_box_2d(static_cast(result)); // compute area fiction::area_stats area_stats{}; fiction::area_params area_ps{}; fiction::area(bb, area_ps, &area_stats); - sidb_circuits_with_defects(benchmark, mockturtle::to_seconds(st.time_total), st.exact_stats.num_aspect_ratios); + sidb_circuits_with_defects(benchmark, mockturtle::to_seconds(st.time_total), st.exact_stats.num_aspect_ratios, + *eq); sidb_circuits_with_defects.save(); sidb_circuits_with_defects.table(); diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index a620da2bc..22dd2f641 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -53,8 +53,8 @@ class apply_gate_library_impl * * This function performs the cell layout generation process based on the gate library and the gate-level layout * information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the gate-level layout and - * assigns gates to cells based on their corresponding positions and types. Optionally, it performs post-layout - * optimization and sets the layout name if certain conditions are met. + * maps gates to cell implementations based on their corresponding positions and types. Optionally, it performs + * post-layout optimization and sets the layout name if certain conditions are met. * * @return A `CellLyt` object representing the generated cell layout. */ @@ -103,8 +103,8 @@ class apply_gate_library_impl * * This function performs the cell layout generation process based on the parameterized gate library and the * gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the - * gate-level layout and assigns gates to cells based on their corresponding positions and types. Optionally, it - * performs post-layout optimization and sets the layout name if certain conditions are met. + * gate-level layout and maps gates to cell implementations based on their corresponding positions and types. + * Optionally, it performs post-layout optimization and sets the layout name if certain conditions are met. * * @tparam Type of the Parameters used for the parameterized gate library. * @param params Parameters used for the parameterized gate library. @@ -162,7 +162,7 @@ class apply_gate_library_impl CellLyt cell_lyt; /** - * This function assigns a given SiDB gate implemetation to the total cell layout. + * This function assigns a given FCN gate implementation to the total cell layout. * * @param c Top-left cell of the tile where the gate is placed. * @param g Gate implementation. @@ -246,7 +246,7 @@ template * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -[[nodiscard]] CellLyt apply_parameterized_gate_library(const GateLyt& lyt, Params& params) +[[nodiscard]] CellLyt apply_parameterized_gate_library(const GateLyt& lyt, const Params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index d11948e9a..e38559de6 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -49,7 +49,7 @@ struct design_sidb_gates_params enum class termination_condition { /** - * The design process is terminated when a valid SiDB gate design is found. + * The design process is terminated as soon as the first valid SiDB gate design is found. */ AFTER_FIRST_SOLUTION, /** @@ -144,15 +144,15 @@ class design_sidb_gates_impl } std::vector designed_gate_layouts = {}; - std::mutex mutex_to_protect_designer_gate_layouts; + std::mutex mutex_to_protect_designed_gate_layouts; std::atomic solution_found = false; // Shuffle the combinations before dividing them among threads std::shuffle(all_combinations.begin(), all_combinations.end(), - std::default_random_engine(std::random_device()())); + std::default_random_engine(std::random_device{}())); const auto add_combination_to_layout_and_check_operation = - [this, &mutex_to_protect_designer_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, + [this, &mutex_to_protect_designed_gate_layouts, ¶ms_is_operational, &designed_gate_layouts, &sidbs_affected_by_defects, &solution_found](const auto& combination) noexcept { for (const auto& comb : combination) @@ -161,13 +161,13 @@ class design_sidb_gates_impl if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects)) { // canvas SiDBs are added to the skeleton - auto layout_with_added_cells = skeleton_layout_with_canvas_sidbs(comb); + auto layout_with_added_cells = add_canvas_sidbs_to_skeleton_layout(comb); if (const auto [status, sim_calls] = is_operational(layout_with_added_cells, truth_table, params_is_operational); status == operational_status::OPERATIONAL) { { - const std::lock_guard lock_vector{mutex_to_protect_designer_gate_layouts}; + const std::lock_guard lock_vector{mutex_to_protect_designed_gate_layouts}; designed_gate_layouts.push_back(layout_with_added_cells); } solution_found = true; @@ -183,7 +183,7 @@ class design_sidb_gates_impl } }; - const auto num_threads = std::thread::hardware_concurrency(); + static const auto num_threads = std::thread::hardware_concurrency(); const auto chunk_size = all_combinations.size() / num_threads; std::vector threads{}; @@ -348,7 +348,7 @@ class design_sidb_gates_impl * @param cell_indices A vector of indices of cells to be added to the skeleton layout. * @return A copy of the original layout (`skeleton_layout`) with SiDB cells added at specified indices. */ - [[nodiscard]] Lyt skeleton_layout_with_canvas_sidbs(const std::vector& cell_indices) const noexcept + [[nodiscard]] Lyt add_canvas_sidbs_to_skeleton_layout(const std::vector& cell_indices) const noexcept { Lyt lyt_copy{skeleton_layout.clone()}; diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index b6c6650c9..5a99aec1b 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -48,6 +48,7 @@ struct on_the_fly_circuit_design_params /** * Statistics for the on-the-fly defect-aware circuit design. */ +template struct on_the_fly_circuit_design_stats { /** @@ -58,6 +59,10 @@ struct on_the_fly_circuit_design_stats * The `stats` of the *exact* algorithm. */ exact_physical_design_stats exact_stats{}; + /** + * The gate-level layout after P&R. + */ + std::optional gate_layout{}; }; namespace detail @@ -67,10 +72,10 @@ template class on_the_fly_circuit_design_impl { public: - on_the_fly_circuit_design_impl(const Ntk& network, const on_the_fly_circuit_design_params& design_params, - const GateLyt& tiling, on_the_fly_circuit_design_stats& st) : + on_the_fly_circuit_design_impl(const Ntk& ntk, const on_the_fly_circuit_design_params& design_params, + const GateLyt& tiling, on_the_fly_circuit_design_stats& st) : lattice_tiling{tiling}, - mapped_network{network}, + network{ntk}, params{design_params}, stats{st} {} @@ -85,20 +90,21 @@ class on_the_fly_circuit_design_impl // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects // is not considered as gates are designed on-the-fly. auto black_list = sidb_surface_analysis( - lattice_tiling, params.parameterized_gate_library_parameter.defect_surface, std::make_pair(0, 0)); + lattice_tiling, params.parameterized_gate_library_parameters.defect_surface, std::make_pair(0, 0)); while (!gate_level_layout.has_value()) { // P&R with *exact* and the pre-determined blacklist - gate_level_layout = exact_with_blacklist(mapped_network, black_list, params.exact_design_parameter, - &stats.exact_stats); + gate_level_layout = + exact_with_blacklist(network, black_list, params.exact_design_parameter, &stats.exact_stats); + if (gate_level_layout.has_value()) { try { lyt = apply_parameterized_gate_library>( - *gate_level_layout, params.parameterized_gate_library_parameter); + *gate_level_layout, params.parameterized_gate_library_parameters); } // on-the-fly gate design was unsuccessful at a certain tile. Hence, this tile-gate pair is added to the @@ -120,37 +126,16 @@ class on_the_fly_circuit_design_impl } } - // empty defect-surface is returned when no P&R solution is found - if (!gate_level_layout.has_value()) - { - return sidb_defect_surface{}; - } + stats.gate_layout = gate_level_layout; - // check equivalence - const auto miter = mockturtle::miter(mapped_network, *gate_level_layout); - const auto eq = mockturtle::equivalence_checking(*miter); + sidb_defect_surface sidbs_and_defects{lyt}; - // empty defect-surface is returned when equivalence check is empty - if (!eq.has_value()) - { - return sidb_defect_surface{}; - } + // add defects to the circuit. + params.parameterized_gate_library_parameters.defect_surface.foreach_sidb_defect( + [&sidbs_and_defects](const auto& defect) + { sidbs_and_defects.assign_sidb_defect(defect.first, defect.second); }); - // in case of equality, an sidb_defect_surface with the SiDBs of the circuit is returned - if (*eq) - { - sidb_defect_surface sidbs_and_defects{lyt}; - - // add defects to the circuit. - params.parameterized_gate_library_parameter.defect_surface.foreach_sidb_defect( - [&sidbs_and_defects](const auto& defect) - { sidbs_and_defects.assign_sidb_defect(defect.first, defect.second); }); - - return sidbs_and_defects; - } - - // in case of inequality, empty defect-surface is returned - return sidb_defect_surface{}; + return sidbs_and_defects; } private: @@ -159,9 +144,9 @@ class on_the_fly_circuit_design_impl */ GateLyt lattice_tiling; /** - * Mapped network. + * Network. */ - Ntk mapped_network; + Ntk network; /** * Parameters for the on-the-fly circuit design. */ @@ -169,7 +154,7 @@ class on_the_fly_circuit_design_impl /** * Statistics for the on-the-fly circuit design. */ - on_the_fly_circuit_design_stats& stats; + on_the_fly_circuit_design_stats& stats; }; } // namespace detail @@ -183,21 +168,26 @@ class on_the_fly_circuit_design_impl * @tparam Ntk The type of the input network. * @tparam CellLyt The type of the cell layout. * @tparam GateLyt The type of the gate layout. - * @param mapped_network The input network to be mapped onto the defective surface. - * @param design_params The parameters used for designing the circuit, encapsulated in an - * `on_the_fly_circuit_design_params` object. + * @param network The input network to be mapped onto the defective surface. * @param lattice_tiling The lattice tiling used for the circuit design. + * @param params The parameters used for designing the circuit, encapsulated in an + * `on_the_fly_circuit_design_params` object. * @param stats Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. * * @return A `sidb_defect_surface` representing the designed circuit on the defective surface. */ template -[[nodiscard]] sidb_defect_surface on_the_fly_circuit_design_on_defective_surface( - const Ntk& mapped_network, const on_the_fly_circuit_design_params& design_params, - const GateLyt& lattice_tiling, on_the_fly_circuit_design_stats* stats = nullptr) +[[nodiscard]] sidb_defect_surface +on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& lattice_tiling, + const on_the_fly_circuit_design_params& params = {}, + on_the_fly_circuit_design_stats* stats = nullptr) { - on_the_fly_circuit_design_stats st{}; - detail::on_the_fly_circuit_design_impl p{mapped_network, design_params, lattice_tiling, st}; + static_assert(is_gate_level_layout_v, "Lyt is not a gate-level layout"); + static_assert(is_tile_based_layout_v, "Lyt is not a tile-based layout"); + static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); + + on_the_fly_circuit_design_stats st{}; + detail::on_the_fly_circuit_design_impl p{ntk, params, lattice_tiling, st}; const auto result = p.design_circuit_on_defective_surface(); diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index e2dff78d6..13da05b70 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -176,7 +176,7 @@ class bounding_box_2d else { min = coordinate{std::numeric_limits::x)>::max(), - std::numeric_limits::x)>::max()}; + std::numeric_limits::y)>::max()}; if constexpr (is_gate_level_layout_v) { diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index e8025e2b9..3bd2095c8 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -496,8 +496,8 @@ class parameterized_gate_library : public fcn_gate_library, "Lyt is not an SiDB layout"); static_assert(has_cube_coord_v, "Lyt is not based on cube coordinates"); - const auto params = is_sidb_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters, - parameters.design_gate_params.sim_engine}; + const auto params = is_sidb_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters}; + if (spec == create_crossing_wire_tt() || spec == create_double_wire_tt()) { if (is_sidb_gate_design_impossible(skeleton_with_defects, spec, params)) From 744305e7093c5241b372815d60760a2aa463f3f2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 28 Jul 2024 09:26:00 +0000 Subject: [PATCH 149/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fiction/algorithms/physical_design/design_sidb_gates.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index e38559de6..2fb420395 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -184,7 +184,7 @@ class design_sidb_gates_impl }; static const auto num_threads = std::thread::hardware_concurrency(); - const auto chunk_size = all_combinations.size() / num_threads; + const auto chunk_size = all_combinations.size() / num_threads; std::vector threads{}; threads.reserve(num_threads); From 3c08eecec17155d0c2b6471482fac14739e4341f Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 28 Jul 2024 09:26:55 +0000 Subject: [PATCH 150/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 57 ++++++++++--------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index c4be2661a..23c303a87 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -3415,8 +3415,8 @@ R"doc(Selector for the different termination conditions for the SiDB gate design process.)doc"; static const char *__doc_fiction_design_sidb_gates_params_termination_condition_AFTER_FIRST_SOLUTION = -R"doc(The design process is terminated when a valid SiDB gate design is -found.)doc"; +R"doc(The design process is terminated as soon as the first valid SiDB gate +design is found.)doc"; static const char *__doc_fiction_design_sidb_gates_params_termination_condition_ALL_COMBINATIONS_ENUMERATED = R"doc(The design process ends after all possible combinations of SiDBs @@ -3715,7 +3715,7 @@ static const char *__doc_fiction_detail_apply_gate_library_impl = R"doc()doc"; static const char *__doc_fiction_detail_apply_gate_library_impl_apply_gate_library_impl = R"doc()doc"; static const char *__doc_fiction_detail_apply_gate_library_impl_assign_gate = -R"doc(This function assigns a given SiDB gate implemetation to the total +R"doc(This function assigns a given FCN gate implementation to the total cell layout. Parameter ``c``: @@ -3737,10 +3737,10 @@ R"doc(Run the cell layout generation process. This function performs the cell layout generation process based on the parameterized gate library and the gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the -nodes in the gate-level layout and assigns gates to cells based on -their corresponding positions and types. Optionally, it performs post- -layout optimization and sets the layout name if certain conditions are -met. +nodes in the gate-level layout and maps gates to cell implementations +based on their corresponding positions and types. Optionally, it +performs post-layout optimization and sets the layout name if certain +conditions are met. Template parameter ``Type``: of the Parameters used for the parameterized gate library. @@ -3757,9 +3757,10 @@ R"doc(Run the cell layout generation process. This function performs the cell layout generation process based on the gate library and the gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the -gate-level layout and assigns gates to cells based on their -corresponding positions and types. Optionally, it performs post-layout -optimization and sets the layout name if certain conditions are met. +gate-level layout and maps gates to cell implementations based on +their corresponding positions and types. Optionally, it performs post- +layout optimization and sets the layout name if certain conditions are +met. Returns: A `CellLyt` object representing the generated cell layout.)doc"; @@ -4142,6 +4143,17 @@ Parameter ``to_delete``: static const char *__doc_fiction_detail_design_sidb_gates_impl = R"doc()doc"; +static const char *__doc_fiction_detail_design_sidb_gates_impl_add_canvas_sidbs_to_skeleton_layout = +R"doc(This function adds SiDBs (given by indices) to the skeleton layout +that is returned afterwards. + +Parameter ``cell_indices``: + A vector of indices of cells to be added to the skeleton layout. + +Returns: + A copy of the original layout (`skeleton_layout`) with SiDB cells + added at specified indices.)doc"; + static const char *__doc_fiction_detail_design_sidb_gates_impl_all_sidbs_in_canvas = R"doc(All cells within the canvas.)doc"; static const char *__doc_fiction_detail_design_sidb_gates_impl_are_sidbs_too_close = @@ -4214,17 +4226,6 @@ R"doc(The skeleton layout serves as a starting layout to which SiDBs are added to create unique SiDB layouts and, if possible, working gates. It defines input and output wires.)doc"; -static const char *__doc_fiction_detail_design_sidb_gates_impl_skeleton_layout_with_canvas_sidbs = -R"doc(This function adds SiDBs (given by indices) to the skeleton layout -that is returned afterwards. - -Parameter ``cell_indices``: - A vector of indices of cells to be added to the skeleton layout. - -Returns: - A copy of the original layout (`skeleton_layout`) with SiDB cells - added at specified indices.)doc"; - static const char *__doc_fiction_detail_design_sidb_gates_impl_truth_table = R"doc(Truth table of the given gate.)doc"; static const char *__doc_fiction_detail_determine_clocking_impl = R"doc()doc"; @@ -5867,7 +5868,7 @@ static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_design_ci static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_lattice_tiling = R"doc(Gate-level layout.)doc"; -static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_mapped_network = R"doc(Mapped network.)doc"; +static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_network = R"doc(Network.)doc"; static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_on_the_fly_circuit_design_impl = R"doc()doc"; @@ -12286,16 +12287,16 @@ Template parameter ``CellLyt``: Template parameter ``GateLyt``: The type of the gate layout. -Parameter ``mapped_network``: +Parameter ``network``: The input network to be mapped onto the defective surface. -Parameter ``design_params``: - The parameters used for designing the circuit, encapsulated in an - `on_the_fly_circuit_design_params` object. - Parameter ``lattice_tiling``: The lattice tiling used for the circuit design. +Parameter ``params``: + The parameters used for designing the circuit, encapsulated in an + `on_the_fly_circuit_design_params` object. + Parameter ``stats``: Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. @@ -12321,6 +12322,8 @@ static const char *__doc_fiction_on_the_fly_circuit_design_stats_duration = R"do static const char *__doc_fiction_on_the_fly_circuit_design_stats_exact_stats = R"doc(The `stats` of the *exact* algorithm.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_stats_gate_layout = R"doc(The gate-level layout after P&R.)doc"; + static const char *__doc_fiction_open_clocking = R"doc(Returns an irregular clocking that maps every coordinate to the standard clock. It is intended to be overridden. From 8bfb2342a0b8956dcaf69fe3e6d1002177ea9afc Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 3 Aug 2024 16:16:08 +0200 Subject: [PATCH 151/191] :art: implement Marcel's suggestions. --- .../physical_design_with_on_the_fly_gate_design.cpp | 2 +- .../on_the_fly_circuit_design_on_defective_surface.hpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 5ba874420..6e076a440 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -145,7 +145,7 @@ int main() // NOLINT const auto result = fiction::on_the_fly_circuit_design_on_defective_surface( - mapped_network, params, lattice_tiling, &st); + mapped_network, lattice_tiling, params, &st); // check equivalence const auto miter = mockturtle::miter(mapped_network, st.gate_layout.value()); diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 5a99aec1b..f0ad4e81c 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -85,6 +85,7 @@ class on_the_fly_circuit_design_impl const mockturtle::stopwatch stop{stats.time_total}; std::optional gate_level_layout = std::nullopt; + CellLyt lyt{}; // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects @@ -126,7 +127,7 @@ class on_the_fly_circuit_design_impl } } - stats.gate_layout = gate_level_layout; + stats.gate_layout = std::optional{gate_level_layout}; sidb_defect_surface sidbs_and_defects{lyt}; @@ -183,7 +184,7 @@ on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& la on_the_fly_circuit_design_stats* stats = nullptr) { static_assert(is_gate_level_layout_v, "Lyt is not a gate-level layout"); - static_assert(is_tile_based_layout_v, "Lyt is not a tile-based layout"); + static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); on_the_fly_circuit_design_stats st{}; From 9c20c1ea9063eba6fcc421c7e93fceb5b5f405e1 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 3 Aug 2024 16:16:17 +0200 Subject: [PATCH 152/191] :memo: add docu. --- docs/algorithms/algorithms.rst | 1 + ...ly_circuit_design_on_defective_surface.rst | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst diff --git a/docs/algorithms/algorithms.rst b/docs/algorithms/algorithms.rst index 05f936d19..c1d3486b6 100644 --- a/docs/algorithms/algorithms.rst +++ b/docs/algorithms/algorithms.rst @@ -57,6 +57,7 @@ Physical Design determine_clocking.rst apply_gate_library.rst design_sidb_gates.rst + on_the_fly_circuit_design_on_defective_surface.rst Verification diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst new file mode 100644 index 000000000..a120c6227 --- /dev/null +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -0,0 +1,37 @@ +.. _on_the_fly_design: + +SiDB Circuit Design Algorithm in the presence of Atomic Defects +--------------------------------------------------------------- + +**Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` + +This algorithm is designed to create SiDB circuits on a clocked surface, accommodating the presence of atomic defects. + +1. **Blacklist Generation**: + + Initially, a blacklist of gate-tile pairs is generated. This blacklist is based on the locations of neutrally charged atomic defects and their overlap with the I/O pins of the SiDB skeletons. + +2. **Gate-Level Layout Design**: + + Using the generated blacklist, a gate-level layout is designed with the `exact` algorithm. This process involves: + + - **Valid Layout Found**: + + If a valid gate-level layout is found, the corresponding gates are designed. + + - **Invalid Layout**: + + If a valid layout is not found, the blacklist is updated, and the placement and routing process is repeated. + +This iterative approach ensures that the designed SiDB circuits can effectively handle defects present on the surface. + + +.. tabs:: + .. tab:: C++ + **Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` + + .. doxygenstruct:: fiction::on_the_fly_circuit_design_params + :members: + .. doxygenstruct:: fiction::on_the_fly_circuit_design_stats + :members: + .. doxygenfunction:: fiction::on_the_fly_circuit_design_on_defective_surface From 8c26f9328f05d41c2710e1636319f86f5758b49c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 3 Aug 2024 14:16:40 +0000 Subject: [PATCH 153/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index f0ad4e81c..e647b1c9b 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -86,7 +86,7 @@ class on_the_fly_circuit_design_impl std::optional gate_level_layout = std::nullopt; - CellLyt lyt{}; + CellLyt lyt{}; // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects // is not considered as gates are designed on-the-fly. From 4989db1a0a91c7b18dc91c88a28e1db36e2ac60e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 3 Aug 2024 16:18:06 +0200 Subject: [PATCH 154/191] :memo: small fix. --- .../on_the_fly_circuit_design_on_defective_surface.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst index a120c6227..a97101948 100644 --- a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -13,7 +13,7 @@ This algorithm is designed to create SiDB circuits on a clocked surface, accommo 2. **Gate-Level Layout Design**: - Using the generated blacklist, a gate-level layout is designed with the `exact` algorithm. This process involves: + Using the generated blacklist, a gate-level layout is designed with the ``exact`` algorithm. This process involves: - **Valid Layout Found**: From c9624040e78cb005509fe82fa86d2468bc1fc7cb Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 3 Aug 2024 16:58:03 +0200 Subject: [PATCH 155/191] :memo: small fix. --- .../on_the_fly_circuit_design_on_defective_surface.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst index a97101948..629773d8f 100644 --- a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -32,6 +32,8 @@ This iterative approach ensures that the designed SiDB circuits can effectively .. doxygenstruct:: fiction::on_the_fly_circuit_design_params :members: - .. doxygenstruct:: fiction::on_the_fly_circuit_design_stats - :members: - .. doxygenfunction:: fiction::on_the_fly_circuit_design_on_defective_surface + .. doxygenstruct:: fiction::on_the_fly_circuit_design_stats + :members: + .. doxygenfunction:: fiction::on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& lattice_tiling, + const on_the_fly_circuit_design_params& params = {}, + on_the_fly_circuit_design_stats* stats = nullptr) From e580dd400a4b2900b692927cf18f48d11ea8c75c Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 6 Aug 2024 14:45:51 +0200 Subject: [PATCH 156/191] :memo: update docu. --- ...e_fly_circuit_design_on_defective_surface.hpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index e647b1c9b..6ef157160 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -161,10 +161,18 @@ class on_the_fly_circuit_design_impl } // namespace detail /** - * This function applies the on-the-fly circuit design algorithm to a specified defective surface, automatically - * creating customized SiDB gates while integrating atomic defects as essential components of the design. It was - * proposed in \"On-the-fly Defect-Aware Design of Circuits based on Silicon Dangling Bond Logic\" by J. Drewniok, M. - * Walter, S. S. H. Ng, K. Walus, and R. Wille in IEEE NANO 2024. + * This function implements an on-the-fly circuit design algorithm for a defective SiDB surface. + * + * The process begins with placement and routing using a blacklist and the `exact` method. The blacklist + * includes skeleton-tile pairs that are excluded due to collisions between skeleton and neutral defects on specific + * tiles. After identifying a valid placement and routing, a defect-aware SiDB gate design algorithm is applied. This + * algorithm designs gates for each tile while accounting for atomic defects. If the gate design is unsuccessful, the + * blacklist is updated with the problematic skeleton-gate pair, and the placement and routing process is restarted. If + * the gate design succeeds, the algorithm finalizes the design and returns the SiDB circuit. This approach ensures + * that the circuit remains functional even in the presence of defects. + * + * This methodology is detailed in the paper "On-the-fly Defect-Aware Design of Circuits based on Silicon Dangling Bond + * Logic" by J. Drewniok, M. Walter, S. S. H. Ng, K. Walus, and R. Wille, IEEE NANO 2024. * * @tparam Ntk The type of the input network. * @tparam CellLyt The type of the cell layout. From 9b9a09a1176a46c4c1a9e0d349947c7724742b61 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 6 Aug 2024 12:47:06 +0000 Subject: [PATCH 157/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 23c303a87..961988d66 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -12271,12 +12271,25 @@ static const char *__doc_fiction_offset_ucoord_t_y = R"doc(31 bit for the y coor static const char *__doc_fiction_offset_ucoord_t_z = R"doc(1 bit for the z coordinate.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_on_defective_surface = -R"doc(This function applies the on-the-fly circuit design algorithm to a -specified defective surface, automatically creating customized SiDB -gates while integrating atomic defects as essential components of the -design. It was proposed in \"On-the-fly Defect-Aware Design of -Circuits based on Silicon Dangling Bond Logic\" by J. Drewniok, M. -Walter, S. S. H. Ng, K. Walus, and R. Wille in IEEE NANO 2024. +R"doc(This function implements an on-the-fly circuit design algorithm for a +defective SiDB surface. + +The process begins with placement and routing using a blacklist and +the `exact` method. The blacklist includes skeleton-tile pairs that +are excluded due to collisions between skeleton and neutral defects on +specific tiles. After identifying a valid placement and routing, a +defect-aware SiDB gate design algorithm is applied. This algorithm +designs gates for each tile while accounting for atomic defects. If +the gate design is unsuccessful, the blacklist is updated with the +problematic skeleton-gate pair, and the placement and routing process +is restarted. If the gate design succeeds, the algorithm finalizes the +design and returns the SiDB circuit. This approach ensures that the +circuit remains functional even in the presence of defects. + +This methodology is detailed in the paper "On-the-fly Defect-Aware +Design of Circuits based on Silicon Dangling Bond Logic" by J. +Drewniok, M. Walter, S. S. H. Ng, K. Walus, and R. Wille, IEEE NANO +2024. Template parameter ``Ntk``: The type of the input network. From 6bd6d3f00962c237560e8570eb3b04086387bbc4 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 6 Aug 2024 14:56:34 +0200 Subject: [PATCH 158/191] :art: remove superfluous header files. --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 6ef157160..5471817ef 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -7,7 +7,6 @@ #include "fiction/algorithms/physical_design/apply_gate_library.hpp" #include "fiction/algorithms/physical_design/exact.hpp" -#include "fiction/networks/technology_network.hpp" #include "fiction/technology/parameterized_gate_library.hpp" #include "fiction/technology/sidb_defect_surface.hpp" #include "fiction/technology/sidb_skeleton_bestagon_library.hpp" @@ -15,8 +14,6 @@ #include "fiction/traits.hpp" #include "fiction/types.hpp" -#include -#include #include #include From 8c7fe8dee4b428112a432fd79494a87c59731424 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Tue, 6 Aug 2024 17:13:45 +0200 Subject: [PATCH 159/191] :art: add missing headers. --- .../physical_design_with_on_the_fly_gate_design.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 6e076a440..f56df3646 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -22,8 +22,11 @@ #include #include #include +#include +#include #include #include +#include #include #include #include From ffae62dab294bcdad2946630ccd6e9b6084dd704 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Thu, 8 Aug 2024 10:05:31 +0200 Subject: [PATCH 160/191] :art: fix headers. --- .../simulation/sidb/random_sidb_layout_generator.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp index daefb324f..44372bd6d 100644 --- a/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp +++ b/include/fiction/algorithms/simulation/sidb/random_sidb_layout_generator.hpp @@ -11,8 +11,7 @@ #include "fiction/utils/layout_utils.hpp" #include -#include -#include +#include #include #include From 0e3802de33cbb3a0c6f77eaab54cb2042a23899b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:06:00 +0000 Subject: [PATCH 161/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/fiction/layouts/coordinates.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index d2c00a098..7ce7e4ee3 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -10,8 +10,8 @@ #include #include -#include #include +#include #include #include #include From 95a1fb10dfd724c595403c7dc5e754b69d926557 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sun, 11 Aug 2024 15:12:32 +0000 Subject: [PATCH 162/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 5c116ed1e..a8f221141 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -6273,6 +6273,17 @@ static const char *__doc_fiction_detail_network_balancing_impl_ps = R"doc()doc"; static const char *__doc_fiction_detail_network_balancing_impl_run = R"doc()doc"; +static const char *__doc_fiction_detail_new_gate_location = +R"doc(When checking for possible paths on a layout between two tiles SRC and +DEST, one of them could also be the new tile for the next gate to be +placed and it therefore has to be checked if said tile is still empty)doc"; + +static const char *__doc_fiction_detail_new_gate_location_DEST = R"doc(Check if the destination tile is empty.)doc"; + +static const char *__doc_fiction_detail_new_gate_location_NONE = R"doc(Do not check any tiles.)doc"; + +static const char *__doc_fiction_detail_new_gate_location_SRC = R"doc(Check if the source tile is empty.)doc"; + static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl = R"doc()doc"; static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_design_circuit_on_defective_surface = R"doc()doc"; @@ -6287,17 +6298,6 @@ static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_params = static const char *__doc_fiction_detail_on_the_fly_circuit_design_impl_stats = R"doc(Statistics for the on-the-fly circuit design.)doc"; -static const char *__doc_fiction_detail_new_gate_location = -R"doc(When checking for possible paths on a layout between two tiles SRC and -DEST, one of them could also be the new tile for the next gate to be -placed and it therefore has to be checked if said tile is still empty)doc"; - -static const char *__doc_fiction_detail_new_gate_location_DEST = R"doc(Check if the destination tile is empty.)doc"; - -static const char *__doc_fiction_detail_new_gate_location_NONE = R"doc(Do not check any tiles.)doc"; - -static const char *__doc_fiction_detail_new_gate_location_SRC = R"doc(Check if the source tile is empty.)doc"; - static const char *__doc_fiction_detail_operational_domain_impl = R"doc()doc"; static const char *__doc_fiction_detail_operational_domain_impl_contour_tracing = From 9ff7da01208877a8c96e0fbee10d3c0f34bc139e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Mon, 12 Aug 2024 06:31:52 +0200 Subject: [PATCH 163/191] :memo: small fix. --- .../on_the_fly_circuit_design_on_defective_surface.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst index 629773d8f..4f2ce67c0 100644 --- a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -1,6 +1,6 @@ .. _on_the_fly_design: -SiDB Circuit Design Algorithm in the presence of Atomic Defects +SiDB Circuit Design Algorithm in the Presence of Atomic Defects --------------------------------------------------------------- **Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` @@ -17,7 +17,7 @@ This algorithm is designed to create SiDB circuits on a clocked surface, accommo - **Valid Layout Found**: - If a valid gate-level layout is found, the corresponding gates are designed. + If a valid gate-level layout is found, the corresponding gates are implemented with SiDBs. - **Invalid Layout**: From 2e514886385b451e359caf5ba625f3ab1d5ed5c9 Mon Sep 17 00:00:00 2001 From: Marcel Walter Date: Wed, 14 Aug 2024 18:44:32 +0200 Subject: [PATCH 164/191] :art: Consistency changes and docstring fixes --- ...ly_circuit_design_on_defective_surface.rst | 18 +++---- docs/technology/gate_libraries.rst | 5 ++ docs/technology/simulation.rst | 2 +- ...cal_design_with_on_the_fly_gate_design.cpp | 4 +- .../physical_design/apply_gate_library.hpp | 6 +-- .../physical_design/design_sidb_gates.hpp | 37 +++++++++----- ...ly_circuit_design_on_defective_surface.hpp | 34 ++++++------- include/fiction/layouts/coordinates.hpp | 9 ++-- .../is_sidb_gate_design_impossible.hpp | 1 + .../technology/parameterized_gate_library.hpp | 50 +++++++++---------- include/fiction/utils/layout_utils.hpp | 10 ++-- .../technology_mapping.cpp | 5 -- .../physical_design/design_sidb_gates.cpp | 10 ++-- 13 files changed, 99 insertions(+), 92 deletions(-) diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst index 4f2ce67c0..fb2f23b2c 100644 --- a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -26,14 +26,10 @@ This algorithm is designed to create SiDB circuits on a clocked surface, accommo This iterative approach ensures that the designed SiDB circuits can effectively handle defects present on the surface. -.. tabs:: - .. tab:: C++ - **Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` - - .. doxygenstruct:: fiction::on_the_fly_circuit_design_params - :members: - .. doxygenstruct:: fiction::on_the_fly_circuit_design_stats - :members: - .. doxygenfunction:: fiction::on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& lattice_tiling, - const on_the_fly_circuit_design_params& params = {}, - on_the_fly_circuit_design_stats* stats = nullptr) +**Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` + +.. doxygenstruct:: fiction::on_the_fly_circuit_design_params + :members: +.. doxygenstruct:: fiction::on_the_fly_circuit_design_stats + :members: +.. doxygenfunction:: fiction::on_the_fly_circuit_design_on_defective_surface diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index c749ba32e..fd1b986fa 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -20,7 +20,9 @@ Abstract Gate Library :members: .. doxygenclass:: fiction::unsupported_gate_type_exception + :members: .. doxygenclass:: fiction::unsupported_gate_orientation_exception + :members: **Header:** ``fiction/technology/cell_ports.hpp`` @@ -68,3 +70,6 @@ Parameterized SiDB Library :members: .. doxygenclass:: fiction::parameterized_gate_library :members: + +.. doxygenclass:: fiction::gate_design_exception + :members: diff --git a/docs/technology/simulation.rst b/docs/technology/simulation.rst index da635ea6a..1699d9cb4 100644 --- a/docs/technology/simulation.rst +++ b/docs/technology/simulation.rst @@ -56,7 +56,7 @@ distributions of the SiDBs. Charge distribution surfaces are returned by the SiD :members: -SiDB Gate design is deemed impossible +Is SiDB gate design deemed impossible ------------------------------------- **Header:** ``fiction/technology/is_sidb_gate_design_impossible.hpp`` diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index f56df3646..8944c2cc6 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -53,7 +53,7 @@ int main() // NOLINT design_gate_params.termination_cond = fiction::design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION; - // save atomic defects which their respective phyiscal parameters as experimentally determined by T. R. Huff, T. + // save atomic defects which their respective physical parameters as experimentally determined by T. R. Huff, T. // Dienel, M. Rashidi, R. Achal, L. Livadaru, J. Croshaw, and R. A. Wolkow, "Electrostatic landscape of a // Hydrogen-terminated Silicon Surface Probed by a Moveable Quantum Dot." const auto stray_db = fiction::sidb_defect{fiction::sidb_defect_type::DB, -1, 4.1, 1.8}; @@ -107,7 +107,7 @@ int main() // NOLINT fmt::print("[attempts] processing {}\n", benchmark); mockturtle::xag_network xag{}; - const auto read_verilog_result = + [[maybe_unused]] const auto read_verilog_result = lorina::read_verilog(fiction_experiments::benchmark_path(benchmark), mockturtle::verilog_reader(xag)); assert(read_verilog_result == lorina::return_code::success); diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 22dd2f641..bce193830 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -171,9 +171,9 @@ class apply_gate_library_impl void assign_gate(const cell& c, const typename GateLibrary::fcn_gate& g, const mockturtle::node& n) { - auto start_x = c.x; - auto start_y = c.y; - auto layer = c.z; + const auto start_x = c.x; + const auto start_y = c.y; + const auto layer = c.z; for (auto y = 0ul; y < g.size(); ++y) { diff --git a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp index 2fb420395..11a12cc35 100644 --- a/include/fiction/algorithms/physical_design/design_sidb_gates.hpp +++ b/include/fiction/algorithms/physical_design/design_sidb_gates.hpp @@ -157,11 +157,12 @@ class design_sidb_gates_impl { for (const auto& comb : combination) { - // if sidb are too close of the position are impossible due to closely placed neutrally charged defects. + // if SiDBs are too close of the position are impossible due to closely placed neutrally charged defects if (!are_sidbs_too_close(cell_indices_to_cell_vector(comb), sidbs_affected_by_defects)) { // canvas SiDBs are added to the skeleton auto layout_with_added_cells = add_canvas_sidbs_to_skeleton_layout(comb); + if (const auto [status, sim_calls] = is_operational(layout_with_added_cells, truth_table, params_is_operational); status == operational_status::OPERATIONAL) @@ -170,31 +171,36 @@ class design_sidb_gates_impl const std::lock_guard lock_vector{mutex_to_protect_designed_gate_layouts}; designed_gate_layouts.push_back(layout_with_added_cells); } + solution_found = true; } + if (solution_found && (params.termination_cond == design_sidb_gates_params>::termination_condition::AFTER_FIRST_SOLUTION)) { return; } + continue; } } }; - static const auto num_threads = std::thread::hardware_concurrency(); - const auto chunk_size = all_combinations.size() / num_threads; + const auto chunk_size = all_combinations.size() / num_threads; std::vector threads{}; threads.reserve(num_threads); for (auto i = 0u; i < num_threads; ++i) { - const auto start = i * chunk_size; - const auto end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; - std::vector> chunk_combinations(all_combinations.cbegin() + start, - all_combinations.cbegin() + end); + const std::size_t start = i * chunk_size; + const std::size_t end = (i == num_threads - 1) ? all_combinations.size() : (i + 1) * chunk_size; + + std::vector> chunk_combinations( + all_combinations.cbegin() + static_cast(start), + all_combinations.cbegin() + static_cast(end)); + threads.emplace_back(add_combination_to_layout_and_check_operation, chunk_combinations); } @@ -226,9 +232,9 @@ class design_sidb_gates_impl params.canvas, params.number_of_sidbs, generate_random_sidb_layout_params>::positive_charges::FORBIDDEN}; - const std::size_t num_threads = std::thread::hardware_concurrency(); std::vector threads{}; threads.reserve(num_threads); + std::mutex mutex_to_protect_designed_gate_layouts{}; // used to control access to shared resources std::atomic gate_layout_is_found(false); @@ -279,7 +285,10 @@ class design_sidb_gates_impl for (auto& thread : threads) { - thread.join(); + if (thread.joinable()) + { + thread.join(); + } } return randomly_designed_gate_layouts; @@ -303,13 +312,17 @@ class design_sidb_gates_impl * All cells within the canvas. */ std::vector all_sidbs_in_canvas; + /** + * Number of threads to be used for parallel execution. + */ + const std::size_t num_threads{std::thread::hardware_concurrency()}; /** * Checks if any SiDBs within the specified cell indices are located too closely together, with a distance of less * than 0.5 nanometers. * - * This function iterates through the provided cell indices and compares the distance between SiDBs. If it finds any - * pair of SiDBs within a distance of 0.5 nanometers, it returns `true` to indicate that SiDBs are too close; - * otherwise, it returns `false`. + * This function iterates over the provided cell indices and compares the distance between SiDBs. If it finds any + * pair of SiDBs within a distance of less than 0.5 nanometers, it returns `true` indicating that SiDBs are too + * close; otherwise, it returns `false`. * * @param cells A vector of cells to check for proximity. * @tparam affected_cells All SiDBs that are affected by atomic defects. diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 5471817ef..4e49f4923 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -37,7 +37,7 @@ struct on_the_fly_circuit_design_params */ parameterized_gate_library_params parameterized_gate_library_parameters = {}; /** - * Parameters for the *exact* placement&routing algorithm. + * Parameters for the *exact* placement and routing algorithm. */ exact_physical_design_params exact_design_parameter = {}; }; @@ -106,7 +106,7 @@ class on_the_fly_circuit_design_impl } // on-the-fly gate design was unsuccessful at a certain tile. Hence, this tile-gate pair is added to the - // blacklist. + // blacklist and the process is rerun. catch (const gate_design_exception& e) { black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); @@ -114,7 +114,7 @@ class on_the_fly_circuit_design_impl catch (const std::exception& e) { - std::cerr << "Caught std::exception: " << e.what() << '\n'; + std::cerr << e.what() << '\n'; } } // P&R was unsuccessful @@ -160,26 +160,25 @@ class on_the_fly_circuit_design_impl /** * This function implements an on-the-fly circuit design algorithm for a defective SiDB surface. * - * The process begins with placement and routing using a blacklist and the `exact` method. The blacklist - * includes skeleton-tile pairs that are excluded due to collisions between skeleton and neutral defects on specific - * tiles. After identifying a valid placement and routing, a defect-aware SiDB gate design algorithm is applied. This - * algorithm designs gates for each tile while accounting for atomic defects. If the gate design is unsuccessful, the - * blacklist is updated with the problematic skeleton-gate pair, and the placement and routing process is restarted. If - * the gate design succeeds, the algorithm finalizes the design and returns the SiDB circuit. This approach ensures - * that the circuit remains functional even in the presence of defects. + * The process begins with placement and routing using a blacklist and the `exact` method. The blacklist includes + * skeleton-tile pairs that are excluded due to collisions between skeleton and neutral defects on specific tiles. After + * identifying a valid placement and routing, a defect-aware SiDB gate design algorithm is applied. This algorithm + * designs gates for each tile while accounting for atomic defects. If the gate design is unsuccessful, the blacklist is + * updated with the problematic skeleton-gate pair, and the placement and routing process is restarted. If the gate + * design succeeds, the algorithm finalizes the design and returns the SiDB circuit. This approach ensures that the + * circuit remains functional even in the presence of defects. * * This methodology is detailed in the paper "On-the-fly Defect-Aware Design of Circuits based on Silicon Dangling Bond * Logic" by J. Drewniok, M. Walter, S. S. H. Ng, K. Walus, and R. Wille, IEEE NANO 2024. * - * @tparam Ntk The type of the input network. - * @tparam CellLyt The type of the cell layout. - * @tparam GateLyt The type of the gate layout. - * @param network The input network to be mapped onto the defective surface. - * @param lattice_tiling The lattice tiling used for the circuit design. + * @tparam Ntk The type of the input network. + * @tparam CellLyt Cell-level layout type. + * @tparam GateLyt Gate-level layout type. + * @param network The input network to be mapped onto the defective surface. + * @param lattice_tiling The lattice tiling used for the circuit design. * @param params The parameters used for designing the circuit, encapsulated in an * `on_the_fly_circuit_design_params` object. * @param stats Pointer to a structure for collecting statistics. If nullptr, statistics are not collected. - * * @return A `sidb_defect_surface` representing the designed circuit on the defective surface. */ template @@ -192,7 +191,8 @@ on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& la static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); - on_the_fly_circuit_design_stats st{}; + on_the_fly_circuit_design_stats st{}; + detail::on_the_fly_circuit_design_impl p{ntk, params, lattice_tiling, st}; const auto result = p.design_circuit_on_defective_surface(); diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 7ce7e4ee3..3cf0deec6 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -816,15 +816,15 @@ constexpr coord_t to_siqad_coord(const CoordinateType& coord) noexcept } // namespace siqad /** - * Converts offset coordinates to cube coordinates - * - * @param coord Offset coordinate to convert to a cube coordinate. - * @return Cube coordinate. + * Converts offset coordinates to cube coordinates. * * @note This function assumes that the input coordinates are within the valid range for cube coordinates. Specifically, * the x, y, and z coordinates should be within the range of \f$(0, 0, 0)\f$ to \f$(2^{31} - 1, 2^{31} - 1, 1)\f$. If * the input coordinates are outside this range, the behavior of the function is undefined. If the input coordinate is * dead, a dead cube coordinate is returned. + * + * @param coord Offset coordinate to convert to a cube coordinate. + * @return Cube coordinate equivalent to `coord`. */ constexpr cube::coord_t offset_to_cube_coord(const offset::ucoord_t& coord) noexcept { @@ -839,7 +839,6 @@ constexpr cube::coord_t offset_to_cube_coord(const offset::ucoord_t& coord) noex return {static_cast(coord.x), static_cast(coord.y), static_cast(coord.z)}; } - /** * Computes the area of a given coordinate assuming its origin is (0, 0, 0). Calculates \f$(|x| + 1) \cdot (|y| + 1)\f$ * by default. The exception is SiQAD coordinates, for which it computes \f$(|x| + 1) \cdot (2 \cdot |y| + |z| + 1)\f$. diff --git a/include/fiction/technology/is_sidb_gate_design_impossible.hpp b/include/fiction/technology/is_sidb_gate_design_impossible.hpp index 1fe7b4fe8..89d6ae12e 100644 --- a/include/fiction/technology/is_sidb_gate_design_impossible.hpp +++ b/include/fiction/technology/is_sidb_gate_design_impossible.hpp @@ -99,6 +99,7 @@ template } } } + return false; } diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/parameterized_gate_library.hpp index 3bd2095c8..e6e8eade5 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/parameterized_gate_library.hpp @@ -19,6 +19,8 @@ #include "fiction/utils/layout_utils.hpp" #include "fiction/utils/truth_table_utils.hpp" +#include + #include #include #include @@ -55,7 +57,6 @@ class gate_design_exception : public std::exception truth_table{spec}, p{portlist} {} - /** * Get the tile associated with the exception. */ @@ -63,7 +64,6 @@ class gate_design_exception : public std::exception { return error_tile; } - /** * Get the truth table associated with the exception. */ @@ -71,7 +71,6 @@ class gate_design_exception : public std::exception { return truth_table; } - /** * Get the port list associated with the exception. */ @@ -117,8 +116,8 @@ struct parameterized_gate_library_params */ uint64_t canvas_sidb_complex_gates = 3; /** - * This variable specifies the radius around the middle of the hexagon where atomic defects are incorporated into - * the gate design. + * This variable specifies the radius in nanometers around the center of the hexagon where atomic defects are + * incorporated into the gate design. */ double influence_radius_charged_defects = 15; // (unit: nm) }; @@ -156,7 +155,7 @@ class parameterized_gate_library : public fcn_gate_library( lyt, t, cell{gate_x_size() / 2, gate_y_size() / 2}); // center cell of the current tile @@ -395,9 +394,8 @@ class parameterized_gate_library : public fcn_gate_library(status == operational_status::OPERATIONAL); } - /** * Generates a cell-level layout as a 2D array of characters based on the provided cell layout information. * - * @tparam CellLyt Cell-level layout type. + * @tparam Lyt Cell-level layout type. * @param lyt Cell-level layout * @return A 2D array of characters representing the cell-level layout. */ @@ -468,6 +465,7 @@ class parameterized_gate_library : public fcn_gate_library - [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton_with_defects, const std::vector& spec, + [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton, const std::vector& spec, const parameterized_gate_library_params& parameters, const port_list& p, const tile& tile) { @@ -500,33 +498,33 @@ class parameterized_gate_library : public fcn_gate_library(tile, create_id_tt(), p); } - const auto found_gate_layouts = - design_sidb_gates(skeleton_with_defects, spec, parameters.design_gate_params); + + const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameters.design_gate_params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, create_id_tt(), p); } - const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); - return lyt; + + return cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); } - if (is_sidb_gate_design_impossible(skeleton_with_defects, spec, params)) + if (is_sidb_gate_design_impossible(skeleton, spec, params)) { throw gate_design_exception(tile, spec.front(), p); } - const auto found_gate_layouts = design_sidb_gates(skeleton_with_defects, spec, parameters.design_gate_params); + + const auto found_gate_layouts = design_sidb_gates(skeleton, spec, parameters.design_gate_params); if (found_gate_layouts.empty()) { throw gate_design_exception(tile, spec.front(), p); } - const auto lyt = cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); - return lyt; - } + return cell_list_to_gate(cell_level_layout_to_list(found_gate_layouts.front())); + } /** * The function generates a layout where each cell is assigned a specific * cell type according to the characters in the cell list/input grid. @@ -578,7 +576,6 @@ class parameterized_gate_library : public fcn_gate_library, port_list>, fcn_gate>; /** - * Lookup table for one input Boolean functions. + * Lookup table for 1-input/1-output Boolean functions. */ static inline const port_gate_map ONE_IN_ONE_OUT_MAP = { // primary inputs @@ -1259,7 +1256,6 @@ class parameterized_gate_library : public fcn_gate_library const auto c2_cube = siqad::to_fiction_coord(coord_se); const auto total_cell_count = static_cast(std::abs(c1_cube.x - c2_cube.x) + 1) * static_cast(std::abs(c1_cube.y - c2_cube.y) + 1); + std::vector all_cells{}; all_cells.reserve(total_cell_count); @@ -644,19 +647,19 @@ template return all_cells; } - // for cube and offset coordinates - else + else // for cube and offset coordinates { const auto total_cell_count = static_cast(std::abs(static_cast(coord_nw.x) - static_cast(coord_se.x)) + 1) * static_cast(std::abs(static_cast(coord_nw.y) - static_cast(coord_se.y)) + 1); + std::vector all_cells{}; all_cells.reserve(total_cell_count); auto current_cell = coord_nw; // collect all cells in the area (spanned by the nw `north-west` and se `south-east` cell) going from top to - // down from left to right. + // bottom from left to right. while (current_cell <= coord_se) { all_cells.push_back(current_cell); @@ -675,6 +678,7 @@ template return all_cells; } } +#pragma GCC diagnostic pop } // namespace fiction diff --git a/test/algorithms/network_transformation/technology_mapping.cpp b/test/algorithms/network_transformation/technology_mapping.cpp index f70838f78..9754722cc 100644 --- a/test/algorithms/network_transformation/technology_mapping.cpp +++ b/test/algorithms/network_transformation/technology_mapping.cpp @@ -195,11 +195,6 @@ void map_and_check_all_func(const Ntk& ntk) CHECK(gt_stats.num_nor2 == 0); CHECK(gt_stats.num_xor2 == 0); CHECK(gt_stats.num_xnor2 == 0); - - CHECK(gt_stats.num_lt2 >= 0); - CHECK(gt_stats.num_gt2 >= 0); - CHECK(gt_stats.num_le2 >= 0); - CHECK(gt_stats.num_ge2 >= 0); } template diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index f59096251..bd10c1aba 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -7,9 +7,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -55,7 +52,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(lyt.num_cells() == 13); - const design_sidb_gates_params> params{ + design_sidb_gates_params> params{ sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, @@ -90,6 +87,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ // using offset coordinates const auto lyt_in_offset_coord = convert_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, @@ -108,7 +106,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ } SECTION("Four cells in canvas, design all gates") { - const design_sidb_gates_params> params{ + params = design_sidb_gates_params>{ sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {13, 4, 0}}, @@ -121,7 +119,7 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ } SECTION("Four cells in canvas, design process is terminated after first solution is found") { - const design_sidb_gates_params> params{ + params = design_sidb_gates_params>{ sidb_simulation_parameters{2, -0.32}, design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, {{10, 4, 0}, {10, 4, 0}}, From 1727fcadc58cfd41c181c2b1a16a2bad81422808 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 14 Aug 2024 17:30:54 +0000 Subject: [PATCH 165/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index a8f221141..6727634ef 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -4160,10 +4160,10 @@ static const char *__doc_fiction_detail_design_sidb_gates_impl_are_sidbs_too_clo R"doc(Checks if any SiDBs within the specified cell indices are located too closely together, with a distance of less than 0.5 nanometers. -This function iterates through the provided cell indices and compares -the distance between SiDBs. If it finds any pair of SiDBs within a -distance of 0.5 nanometers, it returns `true` to indicate that SiDBs -are too close; otherwise, it returns `false`. +This function iterates over the provided cell indices and compares the +distance between SiDBs. If it finds any pair of SiDBs within a +distance of less than 0.5 nanometers, it returns `true` indicating +that SiDBs are too close; otherwise, it returns `false`. Parameter ``cells``: A vector of cells to check for proximity. @@ -4199,6 +4199,8 @@ Parameter ``spec``: Parameter ``ps``: Parameters and settings for the gate designer.)doc"; +static const char *__doc_fiction_detail_design_sidb_gates_impl_num_threads = R"doc(Number of threads to be used for parallel execution.)doc"; + static const char *__doc_fiction_detail_design_sidb_gates_impl_params = R"doc(Parameters for the *SiDB Gate Designer*.)doc"; static const char *__doc_fiction_detail_design_sidb_gates_impl_run_exhaustive_design = @@ -12880,20 +12882,20 @@ R"doc(\verbatim / \ / \ / \ / \ / \ / \ | (0,0) | (1,0) | (2,0) | | | | | \ static const char *__doc_fiction_offset_operator_lshift = R"doc()doc"; static const char *__doc_fiction_offset_to_cube_coord = -R"doc(Converts offset coordinates to cube coordinates - -Parameter ``coord``: - Offset coordinate to convert to a cube coordinate. - -Returns: - Cube coordinate. +R"doc(Converts offset coordinates to cube coordinates. @note This function assumes that the input coordinates are within the valid range for cube coordinates. Specifically, the x, y, and z coordinates should be within the range of :math:`(0, 0, 0)` to :math:`(2^{31} - 1, 2^{31} - 1, 1)`. If the input coordinates are outside this range, the behavior of the function is undefined. If the -input coordinate is dead, a dead cube coordinate is returned.)doc"; +input coordinate is dead, a dead cube coordinate is returned. + +Parameter ``coord``: + Offset coordinate to convert to a cube coordinate. + +Returns: + Cube coordinate equivalent to `coord`.)doc"; static const char *__doc_fiction_offset_ucoord_t = R"doc(Unsigned offset coordinates. @@ -13098,10 +13100,10 @@ Template parameter ``Ntk``: The type of the input network. Template parameter ``CellLyt``: - The type of the cell layout. + Cell-level layout type. Template parameter ``GateLyt``: - The type of the gate layout. + Gate-level layout type. Parameter ``network``: The input network to be mapped onto the defective surface. @@ -13128,7 +13130,7 @@ defective surface. Template parameter ``CellLyt``: Cell-level layout type.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement&routing algorithm.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement and routing algorithm.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameters = R"doc(Parameters for the parameterized gate library.)doc"; @@ -13729,7 +13731,7 @@ static const char *__doc_fiction_parameterized_gate_library_cell_level_layout_to R"doc(Generates a cell-level layout as a 2D array of characters based on the provided cell layout information. -Template parameter ``CellLyt``: +Template parameter ``Lyt``: Cell-level layout type. Parameter ``lyt``: @@ -13787,7 +13789,7 @@ Parameter ``tile``: The specific tile on which the gate should be designed. Returns: - A fcn gate object.)doc"; + An `fcn_gate` object.)doc"; static const char *__doc_fiction_parameterized_gate_library_determine_port_routing = R"doc(This function determines the port routing for a specific tile within a @@ -13796,6 +13798,9 @@ tile's characteristics and connectivity to determine the appropriate incoming and outgoing connector ports and populates them in a `port_list` object. +Template parameter ``Lyt``: + Cell-level layout type. + Parameter ``lyt``: A reference to an object of type `Lyt` representing the layout. @@ -13823,15 +13828,12 @@ Template parameter ``Params``: Parameter ``bestagon_lyt``: The Bestagon gate which is to be applied. -Parameter ``defect_lyt``: - The layout with defects that may affect gate applicability. +Parameter ``truth_table``: + The truth table representing the gate's logic function. Parameter ``parameters``: Parameters for the gate design and simulation. -Parameter ``truth_table``: - The truth table representing the gate's logic function. - Returns: `true` if the Bestagon gate is applicable to the layout, considering the provided conditions; otherwise, returns `false`.)doc"; @@ -13854,8 +13856,9 @@ static const char *__doc_fiction_parameterized_gate_library_params_defect_surfac static const char *__doc_fiction_parameterized_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates.)doc"; static const char *__doc_fiction_parameterized_gate_library_params_influence_radius_charged_defects = -R"doc(This variable specifies the radius around the middle of the hexagon -where atomic defects are incorporated into the gate design.)doc"; +R"doc(This variable specifies the radius in nanometers around the center of +the hexagon where atomic defects are incorporated into the gate +design.)doc"; static const char *__doc_fiction_parameterized_gate_library_set_up_gate = R"doc(Overrides the corresponding function in fcn_gate_library. Given a tile From c0b0cf7a1ae79c760828068b7a96051775dcc5c0 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 07:30:37 +0200 Subject: [PATCH 166/191] :art: small renaming. --- docs/algorithms/apply_gate_library.rst | 2 +- docs/technology/gate_libraries.rst | 6 ++--- ...cal_design_with_on_the_fly_gate_design.cpp | 4 ++-- .../physical_design/apply_gate_library.hpp | 12 +++++----- ...ly_circuit_design_on_defective_surface.hpp | 23 ++++++++----------- ...y.hpp => sidb_on_the_fly_gate_library.hpp} | 14 +++++------ .../technology/parameterized_gate_library.cpp | 19 --------------- .../sidb_on_the_fly_gate_library.cpp | 19 +++++++++++++++ 8 files changed, 48 insertions(+), 51 deletions(-) rename include/fiction/technology/{parameterized_gate_library.hpp => sidb_on_the_fly_gate_library.hpp} (99%) delete mode 100644 test/technology/parameterized_gate_library.cpp create mode 100644 test/technology/sidb_on_the_fly_gate_library.cpp diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 277d836ec..4f5c9b45b 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -12,7 +12,7 @@ implementations for each gate present in the passed ``gate_level_layout``. **Header:** ``fiction/algorithms/physical_design/apply_gate_library.hpp`` .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) - .. doxygenfunction:: fiction::apply_parameterized_gate_library(const GateLyt& lyt, Params& params) + .. doxygenfunction:: fiction::apply_sidb_on_the_fly_gate_library(const GateLyt& lyt, Params& params) .. tab:: Python .. autofunction:: mnt.pyfiction.apply_qca_one_library diff --git a/docs/technology/gate_libraries.rst b/docs/technology/gate_libraries.rst index fd1b986fa..24ae24568 100644 --- a/docs/technology/gate_libraries.rst +++ b/docs/technology/gate_libraries.rst @@ -64,11 +64,11 @@ SiDB Bestagon Library Parameterized SiDB Library -------------------------- -**Header:** ``fiction/technology/parameterized_gate_library.hpp`` +**Header:** ``fiction/technology/sidb_on_the_fly_gate_library.hpp`` -.. doxygenstruct:: fiction::parameterized_gate_library_params +.. doxygenstruct:: fiction::sidb_on_the_fly_gate_library_params :members: -.. doxygenclass:: fiction::parameterized_gate_library +.. doxygenclass:: fiction::sidb_on_the_fly_gate_library :members: .. doxygenclass:: fiction::gate_design_exception diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 8944c2cc6..1b1906704 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -141,8 +141,8 @@ int main() // NOLINT params.exact_design_parameter.upper_bound_y = 30; // 12 x 31 tiles params.exact_design_parameter.timeout = 3'600'000; // 1h in ms - params.parameterized_gate_library_parameters.defect_surface = surface_lattice; - params.parameterized_gate_library_parameters.design_gate_params = design_gate_params; + params.sidb_on_the_fly_gate_library_parameters.defect_surface = surface_lattice; + params.sidb_on_the_fly_gate_library_parameters.design_gate_params = design_gate_params; fiction::on_the_fly_circuit_design_stats st{}; diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index bce193830..40017b5f4 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -7,9 +7,9 @@ #include "fiction/technology/fcn_gate_library.hpp" #include "fiction/technology/inml_topolinano_library.hpp" -#include "fiction/technology/parameterized_gate_library.hpp" #include "fiction/technology/qca_one_library.hpp" #include "fiction/technology/sidb_bestagon_library.hpp" +#include "fiction/technology/sidb_on_the_fly_gate_library.hpp" #include "fiction/traits.hpp" #include "fiction/utils/layout_utils.hpp" #include "fiction/utils/name_utils.hpp" @@ -111,7 +111,7 @@ class apply_gate_library_impl * @return A `CellLyt` object representing the generated cell layout. */ template - [[nodiscard]] CellLyt run_parameterized_gate_library(const Params& params) + [[nodiscard]] CellLyt run_sidb_on_the_fly_gate_library(const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar @@ -231,7 +231,7 @@ template return p.run_static_gate_library(); } /** - * Applies a parameterized gate library to a given + * Applies an SiDB on-the-fly gate library to a given * gate-level layout and, thereby, creates and returns a cell-level layout. * * May pass through, and thereby throw, an `unsupported_gate_type_exception`, an @@ -240,13 +240,13 @@ template * @tparam CellLyt Type of the returned cell-level layout. * @tparam GateLibrary Type of the gate library to apply. * @tparam GateLyt Type of the gate-level layout to apply the library to. - * @tparam Params Type of the parameter used for parameterized gate library. + * @tparam Params Type of the parameter used for SiDB on-the-fly gate library. * @param lyt The gate-level layout. * @param params Parameter for the gate library. * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -[[nodiscard]] CellLyt apply_parameterized_gate_library(const GateLyt& lyt, const Params& params) +[[nodiscard]] CellLyt apply_sidb_on_the_fly_gate_library(const GateLyt& lyt, const Params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); @@ -259,7 +259,7 @@ template p{lyt}; - return p.template run_parameterized_gate_library(params); + return p.template run_sidb_on_the_fly_gate_library(params); } } // namespace fiction diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 4e49f4923..32bed323f 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -7,8 +7,8 @@ #include "fiction/algorithms/physical_design/apply_gate_library.hpp" #include "fiction/algorithms/physical_design/exact.hpp" -#include "fiction/technology/parameterized_gate_library.hpp" #include "fiction/technology/sidb_defect_surface.hpp" +#include "fiction/technology/sidb_on_the_fly_gate_library.hpp" #include "fiction/technology/sidb_skeleton_bestagon_library.hpp" #include "fiction/technology/sidb_surface_analysis.hpp" #include "fiction/traits.hpp" @@ -33,9 +33,9 @@ template struct on_the_fly_circuit_design_params { /** - * Parameters for the parameterized gate library. + * Parameters for the SiDB on-the-fly gate library. */ - parameterized_gate_library_params parameterized_gate_library_parameters = {}; + sidb_on_the_fly_gate_library_params sidb_on_the_fly_gate_library_parameters = {}; /** * Parameters for the *exact* placement and routing algorithm. */ @@ -88,7 +88,7 @@ class on_the_fly_circuit_design_impl // generating the blacklist based on neutral defects. The long-range electrostatic influence of charged defects // is not considered as gates are designed on-the-fly. auto black_list = sidb_surface_analysis( - lattice_tiling, params.parameterized_gate_library_parameters.defect_surface, std::make_pair(0, 0)); + lattice_tiling, params.sidb_on_the_fly_gate_library_parameters.defect_surface, std::make_pair(0, 0)); while (!gate_level_layout.has_value()) { @@ -100,9 +100,9 @@ class on_the_fly_circuit_design_impl { try { - lyt = apply_parameterized_gate_library>( - *gate_level_layout, params.parameterized_gate_library_parameters); + lyt = apply_sidb_on_the_fly_gate_library>( + *gate_level_layout, params.sidb_on_the_fly_gate_library_parameters); } // on-the-fly gate design was unsuccessful at a certain tile. Hence, this tile-gate pair is added to the @@ -111,11 +111,6 @@ class on_the_fly_circuit_design_impl { black_list[e.which_tile()][e.which_truth_table()].push_back(e.which_port_list()); } - - catch (const std::exception& e) - { - std::cerr << e.what() << '\n'; - } } // P&R was unsuccessful else @@ -129,7 +124,7 @@ class on_the_fly_circuit_design_impl sidb_defect_surface sidbs_and_defects{lyt}; // add defects to the circuit. - params.parameterized_gate_library_parameters.defect_surface.foreach_sidb_defect( + params.sidb_on_the_fly_gate_library_parameters.defect_surface.foreach_sidb_defect( [&sidbs_and_defects](const auto& defect) { sidbs_and_defects.assign_sidb_defect(defect.first, defect.second); }); @@ -188,7 +183,9 @@ on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& la on_the_fly_circuit_design_stats* stats = nullptr) { static_assert(is_gate_level_layout_v, "Lyt is not a gate-level layout"); + static_assert(is_hexagonal_layout_v, "Lyt is not a gate-level layout"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); + static_assert(has_sidb_technology_v, "Ntk is not a network type"); static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); on_the_fly_circuit_design_stats st{}; diff --git a/include/fiction/technology/parameterized_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp similarity index 99% rename from include/fiction/technology/parameterized_gate_library.hpp rename to include/fiction/technology/sidb_on_the_fly_gate_library.hpp index e6e8eade5..5f884d4c9 100644 --- a/include/fiction/technology/parameterized_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -2,8 +2,8 @@ // Created by Jan Drewniok 20.09.23. // -#ifndef FICTION_PARAMETERIZED_GATE_LIBRARY_HPP -#define FICTION_PARAMETERIZED_GATE_LIBRARY_HPP +#ifndef FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP +#define FICTION_SIDB_ON_THE_FLY_GATE_LIBRARY_HPP #include "fiction/algorithms/physical_design/design_sidb_gates.hpp" #include "fiction/algorithms/simulation/sidb/is_operational.hpp" @@ -100,7 +100,7 @@ class gate_design_exception : public std::exception * @tparam Lyt Cell-level layout type. */ template -struct parameterized_gate_library_params +struct sidb_on_the_fly_gate_library_params { /** * This layout stores all atomic defects. @@ -127,10 +127,10 @@ struct parameterized_gate_library_params * defects, thus enabling the design of SiDB circuits in the presence of atomic defects. The skeleton (i.e., the * pre-defined input and output wires) are hexagonal in shape. */ -class parameterized_gate_library : public fcn_gate_library // width and height of a hexagon +class sidb_on_the_fly_gate_library : public fcn_gate_library // width and height of a hexagon { public: - explicit parameterized_gate_library() = delete; + explicit sidb_on_the_fly_gate_library() = delete; /** * Overrides the corresponding function in fcn_gate_library. Given a tile `t`, this function takes all necessary @@ -487,7 +487,7 @@ class parameterized_gate_library : public fcn_gate_library [[nodiscard]] static fcn_gate design_gate(const LytSkeleton& skeleton, const std::vector& spec, - const parameterized_gate_library_params& parameters, + const sidb_on_the_fly_gate_library_params& parameters, const port_list& p, const tile& tile) { static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); @@ -1305,4 +1305,4 @@ class parameterized_gate_library : public fcn_gate_library - -#include -#include -#include - -using namespace fiction; - -TEST_CASE("Parameterized gate library traits", "[parameterized-gate-library]") -{ - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); - CHECK(!has_post_layout_optimization_v); -} diff --git a/test/technology/sidb_on_the_fly_gate_library.cpp b/test/technology/sidb_on_the_fly_gate_library.cpp new file mode 100644 index 000000000..fc1250f29 --- /dev/null +++ b/test/technology/sidb_on_the_fly_gate_library.cpp @@ -0,0 +1,19 @@ +// +// Created by Jan Drewniok on 24.10.23. +// + +#include + +#include +#include +#include + +using namespace fiction; + +TEST_CASE("Parameterized gate library traits", "[parameterized-gate-library]") +{ + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); + CHECK(!has_post_layout_optimization_v); +} From b304143e5f935da2e61d191beae7d32f1ca37a33 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 07:42:22 +0200 Subject: [PATCH 167/191] :art: small fix. --- .../algorithms/physical_design/apply_gate_library.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index 40017b5f4..e0ef63926 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -101,13 +101,13 @@ class apply_gate_library_impl /** * Run the cell layout generation process. * - * This function performs the cell layout generation process based on the parameterized gate library and the + * This function performs the cell layout generation process based on the SiDB on-the-fly gate library and the * gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the * gate-level layout and maps gates to cell implementations based on their corresponding positions and types. * Optionally, it performs post-layout optimization and sets the layout name if certain conditions are met. * - * @tparam Type of the Parameters used for the parameterized gate library. - * @param params Parameters used for the parameterized gate library. + * @tparam Type of the Parameters used for the SiDB on-the-fly gate library. + * @param params Parameters used for the SiDB on-the-fly gate library. * @return A `CellLyt` object representing the generated cell layout. */ template From 21b2a2b3ee24696ab75f0f5dd3a061708f40af82 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 16 Aug 2024 06:33:36 +0000 Subject: [PATCH 168/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/pybind11_mkdoc_docstrings.hpp | 410 +++++++++--------- 1 file changed, 205 insertions(+), 205 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 6727634ef..e42becd4b 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -264,9 +264,9 @@ Parameter ``lyt``: A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`.)doc"; -static const char *__doc_fiction_apply_parameterized_gate_library = -R"doc(Applies a parameterized gate library to a given gate-level layout and, -thereby, creates and returns a cell-level layout. +static const char *__doc_fiction_apply_sidb_on_the_fly_gate_library = +R"doc(Applies an SiDB on-the-fly gate library to a given gate-level layout +and, thereby, creates and returns a cell-level layout. May pass through, and thereby throw, an `unsupported_gate_type_exception`, an @@ -283,7 +283,7 @@ Template parameter ``GateLyt``: Type of the gate-level layout to apply the library to. Template parameter ``Params``: - Type of the parameter used for parameterized gate library. + Type of the parameter used for SiDB on-the-fly gate library. Parameter ``lyt``: The gate-level layout. @@ -3731,11 +3731,11 @@ static const char *__doc_fiction_detail_apply_gate_library_impl_cell_lyt = R"doc static const char *__doc_fiction_detail_apply_gate_library_impl_gate_lyt = R"doc(Gate-level layout.)doc"; -static const char *__doc_fiction_detail_apply_gate_library_impl_run_parameterized_gate_library = +static const char *__doc_fiction_detail_apply_gate_library_impl_run_sidb_on_the_fly_gate_library = R"doc(Run the cell layout generation process. This function performs the cell layout generation process based on the -parameterized gate library and the gate-level layout information +SiDB on-the-fly gate library and the gate-level layout information provided by `GateLibrary` and `gate_lyt`. It iterates through the nodes in the gate-level layout and maps gates to cell implementations based on their corresponding positions and types. Optionally, it @@ -3743,10 +3743,10 @@ performs post-layout optimization and sets the layout name if certain conditions are met. Template parameter ``Type``: - of the Parameters used for the parameterized gate library. + of the Parameters used for the SiDB on-the-fly gate library. Parameter ``params``: - Parameters used for the parameterized gate library. + Parameters used for the SiDB on-the-fly gate library. Returns: A `CellLyt` object representing the generated cell layout.)doc"; @@ -13132,7 +13132,7 @@ Template parameter ``CellLyt``: static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement and routing algorithm.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_params_parameterized_gate_library_parameters = R"doc(Parameters for the parameterized gate library.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_params_sidb_on_the_fly_gate_library_parameters = R"doc(Parameters for the SiDB on-the-fly gate library.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_stats = R"doc(Statistics for the on-the-fly defect-aware circuit design.)doc"; @@ -13692,202 +13692,6 @@ static const char *__doc_fiction_parameter_point_x = R"doc(X dimension parameter static const char *__doc_fiction_parameter_point_y = R"doc(Y dimension parameter value.)doc"; -static const char *__doc_fiction_parameterized_gate_library = -R"doc(A parameterized gate library for SiDB technology. It allows the design -of SiDB gates tailored to given atomic defects, thus enabling the -design of SiDB circuits in the presence of atomic defects. The -skeleton (i.e., the pre-defined input and output wires) are hexagonal -in shape.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_add_defect_to_skeleton = -R"doc(This function takes a defect surface and a skeleton skeleton and adds -defects from the surrounding area to the skeleton. The defects within -a specified distance from the center cell are taken into account. The -resulting skeleton with added defects is returned. - -Template parameter ``CellLyt``: - The type of the defect surface, which should not have SiQAD - coordinates. - -Template parameter ``Params``: - Type of Parameters. - -Parameter ``skeleton``: - The skeleton to which defects will be added. - -Parameter ``center_cell``: - The coordinates of the center cell. - -Parameter ``absolute_cell``: - The coordinates of the skeleton's absolute cell. - -Parameter ``parameters``: - Parameters for defect handling. - -Returns: - The updated skeleton with added defects from the surrounding area.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_cell_level_layout_to_list = -R"doc(Generates a cell-level layout as a 2D array of characters based on the -provided cell layout information. - -Template parameter ``Lyt``: - Cell-level layout type. - -Parameter ``lyt``: - Cell-level layout - -Returns: - A 2D array of characters representing the cell-level layout.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_cell_list_to_cell_level_layout = -R"doc(The function generates a layout where each cell is assigned a specific -cell type according to the characters in the cell list/input grid. - -Template parameter ``Lyt``: - The type of the cell-level layout to be generated. - -Parameter ``cell_list``: - A 2D grid representing the cells and their types. - -Returns: - The cell-level layout with assigned cell types.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_design_gate = -R"doc(This function designs an SiDB gate for a given Boolean function at a -given tile and a given rotation. If atomic defects exist, they are -incorporated into the design process. - -An exception is thrown in case there is no possible gate design. - -Template parameter ``LytSkeleton``: - The cell-level layout of the skeleton. - -Template parameter ``TT``: - Truth table type. - -Template parameter ``CellLyt``: - The cell-level layout. - -Template parameter ``GateLyt``: - The gate-level layout. - -Parameter ``skeleton``: - Skeleton with atomic defects if available. - -Parameter ``spec``: - Expected Boolean function of the layout given as a multi-output - truth table. - -Parameter ``parameters``: - Parameters for the SiDB gate design process. - -Parameter ``p``: - The list of ports and their directions. - -Parameter ``tile``: - The specific tile on which the gate should be designed. - -Returns: - An `fcn_gate` object.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_determine_port_routing = -R"doc(This function determines the port routing for a specific tile within a -layout represented by the object `lyt` of type `Lyt`. It examines the -tile's characteristics and connectivity to determine the appropriate -incoming and outgoing connector ports and populates them in a -`port_list` object. - -Template parameter ``Lyt``: - Cell-level layout type. - -Parameter ``lyt``: - A reference to an object of type `Lyt` representing the layout. - -Parameter ``t``: - The tile for which port routing is being determined. - -Returns: - A `port_list` object containing the determined port directions for - incoming and outgoing signals.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_is_bestagon_gate_applicable = -R"doc(This function evaluates whether a Bestagon gate can be applied to the -given node by considering various conditions, including the presence -of defects and spacing requirements. - -Template parameter ``Lyt``: - The type of the cell-level layout. - -Template parameter ``TT``: - Truth table type. - -Template parameter ``Params``: - Type of the parameters used for the parametrized gate library. - -Parameter ``bestagon_lyt``: - The Bestagon gate which is to be applied. - -Parameter ``truth_table``: - The truth table representing the gate's logic function. - -Parameter ``parameters``: - Parameters for the gate design and simulation. - -Returns: - `true` if the Bestagon gate is applicable to the layout, - considering the provided conditions; otherwise, returns `false`.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_parameterized_gate_library = R"doc()doc"; - -static const char *__doc_fiction_parameterized_gate_library_params = -R"doc(This struct encapsulates parameters for the parameterized SiDB gate -library. - -Template parameter ``Lyt``: - Cell-level layout type.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_params_canvas_sidb_complex_gates = -R"doc(This variable defines the number of canvas SiDBs dedicated to complex -gates, such as crossing, double wire, and half-adder.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_params_defect_surface = R"doc(This layout stores all atomic defects.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_params_influence_radius_charged_defects = -R"doc(This variable specifies the radius in nanometers around the center of -the hexagon where atomic defects are incorporated into the gate -design.)doc"; - -static const char *__doc_fiction_parameterized_gate_library_set_up_gate = -R"doc(Overrides the corresponding function in fcn_gate_library. Given a tile -`t`, this function takes all necessary information from the stored -grid into account to design the correct fcn_gate representation for -that tile. In case there is no possible SiDB design, the blacklist is -updated and an error fcn gate is returned. - -Template parameter ``GateLyt``: - Pointy-top hexagonal gate-level layout type. - -Template parameter ``CellLyt``: - The type of the cell-level layout. - -Template parameter ``Params``: - Type of the parameter used for the gate library. - -Parameter ``lyt``: - Layout that hosts tile `t`. - -Parameter ``t``: - Tile to be realized as a Bestagon gate. - -Parameter ``parameters``: - Parameter to design SiDB gates. - -Returns: - Bestagon gate representation of `t` including mirroring.)doc"; - static const char *__doc_fiction_path_collection = R"doc(An ordered collection of multiple paths in a layout. @@ -15451,6 +15255,202 @@ Parameter ``c``: A pair representing the `(x,y)` position of `c` in nanometers from the layout origin.)doc"; +static const char *__doc_fiction_sidb_on_the_fly_gate_library = +R"doc(A parameterized gate library for SiDB technology. It allows the design +of SiDB gates tailored to given atomic defects, thus enabling the +design of SiDB circuits in the presence of atomic defects. The +skeleton (i.e., the pre-defined input and output wires) are hexagonal +in shape.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_add_defect_to_skeleton = +R"doc(This function takes a defect surface and a skeleton skeleton and adds +defects from the surrounding area to the skeleton. The defects within +a specified distance from the center cell are taken into account. The +resulting skeleton with added defects is returned. + +Template parameter ``CellLyt``: + The type of the defect surface, which should not have SiQAD + coordinates. + +Template parameter ``Params``: + Type of Parameters. + +Parameter ``skeleton``: + The skeleton to which defects will be added. + +Parameter ``center_cell``: + The coordinates of the center cell. + +Parameter ``absolute_cell``: + The coordinates of the skeleton's absolute cell. + +Parameter ``parameters``: + Parameters for defect handling. + +Returns: + The updated skeleton with added defects from the surrounding area.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_cell_level_layout_to_list = +R"doc(Generates a cell-level layout as a 2D array of characters based on the +provided cell layout information. + +Template parameter ``Lyt``: + Cell-level layout type. + +Parameter ``lyt``: + Cell-level layout + +Returns: + A 2D array of characters representing the cell-level layout.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_cell_list_to_cell_level_layout = +R"doc(The function generates a layout where each cell is assigned a specific +cell type according to the characters in the cell list/input grid. + +Template parameter ``Lyt``: + The type of the cell-level layout to be generated. + +Parameter ``cell_list``: + A 2D grid representing the cells and their types. + +Returns: + The cell-level layout with assigned cell types.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_design_gate = +R"doc(This function designs an SiDB gate for a given Boolean function at a +given tile and a given rotation. If atomic defects exist, they are +incorporated into the design process. + +An exception is thrown in case there is no possible gate design. + +Template parameter ``LytSkeleton``: + The cell-level layout of the skeleton. + +Template parameter ``TT``: + Truth table type. + +Template parameter ``CellLyt``: + The cell-level layout. + +Template parameter ``GateLyt``: + The gate-level layout. + +Parameter ``skeleton``: + Skeleton with atomic defects if available. + +Parameter ``spec``: + Expected Boolean function of the layout given as a multi-output + truth table. + +Parameter ``parameters``: + Parameters for the SiDB gate design process. + +Parameter ``p``: + The list of ports and their directions. + +Parameter ``tile``: + The specific tile on which the gate should be designed. + +Returns: + An `fcn_gate` object.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_determine_port_routing = +R"doc(This function determines the port routing for a specific tile within a +layout represented by the object `lyt` of type `Lyt`. It examines the +tile's characteristics and connectivity to determine the appropriate +incoming and outgoing connector ports and populates them in a +`port_list` object. + +Template parameter ``Lyt``: + Cell-level layout type. + +Parameter ``lyt``: + A reference to an object of type `Lyt` representing the layout. + +Parameter ``t``: + The tile for which port routing is being determined. + +Returns: + A `port_list` object containing the determined port directions for + incoming and outgoing signals.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_is_bestagon_gate_applicable = +R"doc(This function evaluates whether a Bestagon gate can be applied to the +given node by considering various conditions, including the presence +of defects and spacing requirements. + +Template parameter ``Lyt``: + The type of the cell-level layout. + +Template parameter ``TT``: + Truth table type. + +Template parameter ``Params``: + Type of the parameters used for the parametrized gate library. + +Parameter ``bestagon_lyt``: + The Bestagon gate which is to be applied. + +Parameter ``truth_table``: + The truth table representing the gate's logic function. + +Parameter ``parameters``: + Parameters for the gate design and simulation. + +Returns: + `true` if the Bestagon gate is applicable to the layout, + considering the provided conditions; otherwise, returns `false`.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_params = +R"doc(This struct encapsulates parameters for the parameterized SiDB gate +library. + +Template parameter ``Lyt``: + Cell-level layout type.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_params_canvas_sidb_complex_gates = +R"doc(This variable defines the number of canvas SiDBs dedicated to complex +gates, such as crossing, double wire, and half-adder.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_params_defect_surface = R"doc(This layout stores all atomic defects.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_params_design_gate_params = R"doc(This struct holds parameters to design SiDB gates.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_params_influence_radius_charged_defects = +R"doc(This variable specifies the radius in nanometers around the center of +the hexagon where atomic defects are incorporated into the gate +design.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_set_up_gate = +R"doc(Overrides the corresponding function in fcn_gate_library. Given a tile +`t`, this function takes all necessary information from the stored +grid into account to design the correct fcn_gate representation for +that tile. In case there is no possible SiDB design, the blacklist is +updated and an error fcn gate is returned. + +Template parameter ``GateLyt``: + Pointy-top hexagonal gate-level layout type. + +Template parameter ``CellLyt``: + The type of the cell-level layout. + +Template parameter ``Params``: + Type of the parameter used for the gate library. + +Parameter ``lyt``: + Layout that hosts tile `t`. + +Parameter ``t``: + Tile to be realized as a Bestagon gate. + +Parameter ``parameters``: + Parameter to design SiDB gates. + +Returns: + Bestagon gate representation of `t` including mirroring.)doc"; + +static const char *__doc_fiction_sidb_on_the_fly_gate_library_sidb_on_the_fly_gate_library = R"doc()doc"; + static const char *__doc_fiction_sidb_simulation_engine = R"doc(Selector for the available SiDB simulation engines.)doc"; static const char *__doc_fiction_sidb_simulation_engine_EXGS = From e1fee6f12afc78162ee835b143fa210e43c4d782 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 07:08:21 +0000 Subject: [PATCH 169/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../physical_design/design_sidb_gates.cpp | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/algorithms/physical_design/design_sidb_gates.cpp b/test/algorithms/physical_design/design_sidb_gates.cpp index ca954fb9f..537433438 100644 --- a/test/algorithms/physical_design/design_sidb_gates.cpp +++ b/test/algorithms/physical_design/design_sidb_gates.cpp @@ -67,15 +67,15 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts[0].num_cells() == 14); CHECK(found_gate_layouts[0].get_cell_type({10, 4, 0}) == siqad_layout::technology::NORMAL); - // using cube coordinates - const auto lyt_in_cube_coord = convert_layout_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_cube{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + // using cube coordinates + const auto lyt_in_cube_coord = convert_layout_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_cube{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_cube = design_sidb_gates(lyt_in_cube_coord, std::vector{create_xnor_tt()}, params_cube); @@ -85,15 +85,15 @@ TEST_CASE("Use SiQAD XNOR skeleton and generate SiQAD XNOR gate, exhaustive", "[ CHECK(found_gate_layouts_cube[0].get_cell_type(siqad::to_fiction_coord( siqad::coord_t{10, 4, 0})) == siqad_layout::technology::NORMAL); - // using offset coordinates - const auto lyt_in_offset_coord = convert_layout_to_fiction_coordinates(lyt); - const design_sidb_gates_params> params_offset{ - sidb_simulation_parameters{2, -0.32}, - design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, - {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), - siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, - 1, - sidb_simulation_engine::QUICKEXACT}; + // using offset coordinates + const auto lyt_in_offset_coord = convert_layout_to_fiction_coordinates(lyt); + const design_sidb_gates_params> params_offset{ + sidb_simulation_parameters{2, -0.32}, + design_sidb_gates_params>::design_sidb_gates_mode::EXHAUSTIVE, + {siqad::to_fiction_coord(siqad::coord_t{10, 4, 0}), + siqad::to_fiction_coord(siqad::coord_t{10, 4, 0})}, + 1, + sidb_simulation_engine::QUICKEXACT}; const auto found_gate_layouts_offset = design_sidb_gates(lyt_in_offset_coord, std::vector{create_xnor_tt()}, params_offset); From f88bc18a4cece753eee04e42f2252c8050fef6fe Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 09:12:10 +0200 Subject: [PATCH 170/191] :art: small fix. --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 32bed323f..a95036522 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -182,10 +182,10 @@ on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& la const on_the_fly_circuit_design_params& params = {}, on_the_fly_circuit_design_stats* stats = nullptr) { - static_assert(is_gate_level_layout_v, "Lyt is not a gate-level layout"); - static_assert(is_hexagonal_layout_v, "Lyt is not a gate-level layout"); + static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); + static_assert(is_hexagonal_layout_v, "GateLyt is not a hexagonal"); static_assert(is_cell_level_layout_v, "Lyt is not a cell-level layout"); - static_assert(has_sidb_technology_v, "Ntk is not a network type"); + static_assert(has_sidb_technology_v, "Lyt is not an SiDB layout"); static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); on_the_fly_circuit_design_stats st{}; From a4170d4ad86d114ecf588a9bd69f35c180a6eeed Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 10:56:28 +0200 Subject: [PATCH 171/191] :art: symplify code. --- include/fiction/layouts/bounding_box.hpp | 209 ++++++----------------- include/fiction/layouts/coordinates.hpp | 12 ++ test/layouts/coordinates.cpp | 16 +- 3 files changed, 75 insertions(+), 162 deletions(-) diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index 13da05b70..c45e555e6 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -68,139 +68,74 @@ class bounding_box_2d } } - // the layout is based on SiQAD coordinates - if constexpr (has_siqad_coord_v) + // Helper function to update bounding box + auto update_min_max = [](auto& min_coord, auto& max_coord, const auto& coord) { - auto min_x_cell = std::numeric_limits::x)>::max(); - auto max_x_cell = std::numeric_limits::x)>::min(); - - auto min_y_cell = std::numeric_limits::y)>::max(); - auto max_y_cell = std::numeric_limits::y)>::min(); - - auto min_z_cell = 1; - auto max_z_cell = 0; + if constexpr (has_siqad_coord_v) + { + auto coord_siqad = siqad::to_fiction_coord(coord); + auto min_coord_cube = siqad::to_fiction_coord(min_coord); + auto max_coord_cube = siqad::to_fiction_coord(max_coord); - layout.foreach_cell( - [&min_x_cell, &max_x_cell, &min_y_cell, &max_y_cell, &min_z_cell, &max_z_cell](const auto& c) - { - if (c.x < min_x_cell) - { - min_x_cell = c.x; - } - if (c.x > max_x_cell) - { - max_x_cell = c.x; - } + min_coord_cube.x = std::min(min_coord_cube.x, coord_siqad.x); + max_coord_cube.x = std::max(max_coord_cube.x, coord_siqad.x); + min_coord_cube.y = std::min(min_coord_cube.y, coord_siqad.y); + max_coord_cube.y = std::max(max_coord_cube.y, coord_siqad.y); - if (c.y == min_y_cell && c.z < min_z_cell) - { - min_z_cell = c.z; - } - if (c.y < min_y_cell) - { - min_y_cell = c.y; - min_z_cell = c.z; - } + min_coord = fiction::siqad::to_siqad_coord(min_coord_cube); + max_coord = fiction::siqad::to_siqad_coord(max_coord_cube); + } + else + { + min_coord.x = std::min(min_coord.x, coord.x); + max_coord.x = std::max(max_coord.x, coord.x); + min_coord.y = std::min(min_coord.y, coord.y); + max_coord.y = std::max(max_coord.y, coord.y); + } + }; - if (c.y == max_y_cell && c.z > max_z_cell) - { - max_z_cell = c.z; - } - if (c.y > max_y_cell) - { - max_y_cell = c.y; - max_z_cell = c.z; - } - }); + if constexpr (has_siqad_coord_v) + { + auto min_cell = coordinate{std::numeric_limits::x)>::max(), + std::numeric_limits::y)>::max(), 1}; // Initial z = 1 + auto max_cell = coordinate{std::numeric_limits::x)>::min(), + std::numeric_limits::y)>::min(), 0}; // Initial z = 0 - const auto min_cell = coordinate{min_x_cell, min_y_cell, min_z_cell}; - const auto max_cell = coordinate{max_x_cell, max_y_cell, max_z_cell}; + layout.foreach_cell([&](const auto& c) { update_min_max(min_cell, max_cell, c); }); min = min_cell; max = max_cell; if constexpr (is_sidb_defect_surface_v) { - auto min_x_defect = std::numeric_limits::x)>::max(); - auto max_x_defect = std::numeric_limits::x)>::min(); + // Defect handling for SiDB defect surfaces + auto min_defect = min_cell; + auto max_defect = max_cell; - auto min_y_defect = std::numeric_limits::y)>::max(); - auto max_y_defect = std::numeric_limits::y)>::min(); + layout.foreach_sidb_defect([&](const auto& defect) + { update_min_max(min_defect, max_defect, defect.first); }); - uint8_t min_z_defect = 1; - uint8_t max_z_defect = 0; - - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect, &min_z_defect, - &max_z_defect](const auto& defect) - { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) - { - max_x_defect = defect.first.x; - } - - if (defect.first.y == min_y_defect && defect.first.z < min_z_defect) - { - min_z_defect = defect.first.z; - } - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - min_z_defect = defect.first.z; - } - - if (defect.first.y == max_y_defect && defect.first.z > max_z_defect) - { - max_z_defect = defect.first.z; - } - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - max_z_defect = defect.first.z; - } - }); - - const auto min_defect = coordinate{min_x_defect, min_y_defect, min_z_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect, max_z_defect}; - - min = cell{std::min(min_cell.x, min_defect.x), std::min(min_cell.y, min_defect.y), - std::min(min_cell.z, min_defect.z)}; - max = cell{std::max(max_cell.x, max_defect.x), std::max(max_cell.y, max_defect.y), - std::max(max_cell.z, max_defect.z)}; + // Adjust min and max based on defects + min = {std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), std::min(min.z, min_defect.z)}; + max = {std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), std::max(max.z, max_defect.z)}; } } else { - min = coordinate{std::numeric_limits::x)>::max(), - std::numeric_limits::y)>::max()}; + // Default coordinate system handling + min = {std::numeric_limits::x)>::max(), + std::numeric_limits::y)>::max()}; + max = {std::numeric_limits::x)>::min(), + std::numeric_limits::y)>::min()}; if constexpr (is_gate_level_layout_v) { layout.foreach_coordinate( - [this](const auto& c) + [&](const auto& c) { if (!is_empty_coordinate(c)) { - if (c.x < min.x) - { - min.x = c.x; - } - if (c.y < min.y) - { - min.y = c.y; - } - if (c.x > max.x) - { - max.x = c.x; - } - if (c.y > max.y) - { - max.y = c.y; - } + update_min_max(min, max, c); } }); } @@ -208,70 +143,22 @@ class bounding_box_2d if constexpr (is_cell_level_layout_v) { layout.foreach_cell( - [this](const auto& c) + [&](const auto& c) { if (!layout.is_empty_cell(c)) { - if (c.x < min.x) - { - min.x = c.x; - } - if (c.y < min.y) - { - min.y = c.y; - } - if (c.x > max.x) - { - max.x = c.x; - } - if (c.y > max.y) - { - max.y = c.y; - } + update_min_max(min, max, c); } }); } if constexpr (is_sidb_defect_surface_v) { - auto min_x_defect = std::numeric_limits::x)>::max(); - auto max_x_defect = std::numeric_limits::y)>::min(); - - auto min_y_defect = std::numeric_limits::x)>::max(); - auto max_y_defect = std::numeric_limits::y)>::min(); - - layout.foreach_sidb_defect( - [&min_x_defect, &max_x_defect, &min_y_defect, &max_y_defect](const auto& defect) - { - if (defect.first.x < min_x_defect) - { - min_x_defect = defect.first.x; - } - if (defect.first.x > max_x_defect) - { - max_x_defect = defect.first.x; - } - - if (defect.first.y < min_y_defect) - { - min_y_defect = defect.first.y; - } - - if (defect.first.y > max_y_defect) - { - max_y_defect = defect.first.y; - } - }); - const auto min_defect = coordinate{min_x_defect, min_y_defect}; - const auto max_defect = coordinate{max_x_defect, max_y_defect}; - - min = cell{std::min(min.x, min_defect.x), std::min(min.y, min_defect.y), - std::min(min.z, min_defect.z)}; - max = cell{std::max(max.x, max_defect.x), std::max(max.y, max_defect.y), - std::max(max.z, max_defect.z)}; + layout.foreach_sidb_defect([&](const auto& defect) { update_min_max(min, max, defect.first); }); } } + // Final bounding box dimensions x_size = max.x - min.x; y_size = max.y - min.y; } diff --git a/include/fiction/layouts/coordinates.hpp b/include/fiction/layouts/coordinates.hpp index 3cf0deec6..e397732d1 100644 --- a/include/fiction/layouts/coordinates.hpp +++ b/include/fiction/layouts/coordinates.hpp @@ -790,6 +790,18 @@ constexpr CoordinateType to_fiction_coord(const siqad::coord_t& coord) noexcept { if (!coord.is_dead()) { + if (2 * static_cast(coord.y) + static_cast(coord.z) > + static_cast(std::numeric_limits::max())) + { + return {coord.x, std::numeric_limits::max()}; + } + + if (2 * static_cast(coord.y) + static_cast(coord.z) < + static_cast(std::numeric_limits::min())) + { + return {coord.x, std::numeric_limits::min()}; + } + return {coord.x, coord.y * 2 + coord.z}; } diff --git a/test/layouts/coordinates.cpp b/test/layouts/coordinates.cpp index 61c997125..64490b6a2 100644 --- a/test/layouts/coordinates.cpp +++ b/test/layouts/coordinates.cpp @@ -15,6 +15,7 @@ #include #include #include +#include using namespace fiction; @@ -151,6 +152,19 @@ TEST_CASE("SiQAD coordinate conversion", "[coordinates]") CHECK(t8_siqad.y == -2); CHECK(t8_siqad.z == 0); CHECK(t8_fiction == siqad::to_fiction_coord(t8_siqad)); + + // Test for overflow scenario + auto t9 = coordinate{1, (std::numeric_limits::max()-1) / 2, 1}; + auto fiction_9 = siqad::to_fiction_coord(t9); + CHECK(fiction_9.x == t9.x); + CHECK(fiction_9.y == std::numeric_limits::max()); + + // Test for underflow scenario + auto t10 = coordinate{1, (std::numeric_limits::min()+1) / 2}; + auto fiction_10 = siqad::to_fiction_coord(t10); + CHECK(fiction_10.x == t10.x); + CHECK(fiction_10.y == std::numeric_limits::min()+2); + } TEST_CASE("Offset to cube coordinate conversion", "[coordinates]") @@ -193,7 +207,7 @@ TEMPLATE_TEST_CASE("Coordinate iteration", "[coordinates]", offset::ucoord_t, cu { lyt.foreach_coordinate(fill_coord_vector, {1, 0, 0}, {1, 1, 1}); - CHECK(coord_vector.size() == 6); + REQUIRE(coord_vector.size() == 6); CHECK(coord_vector[0] == TestType{1, 0, 0}); From 99ac4deca736323816a82eb1d71042f479741b70 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 10:55:55 +0000 Subject: [PATCH 172/191] =?UTF-8?q?=F0=9F=8E=A8=20Incorporated=20pre-commi?= =?UTF-8?q?t=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/fiction/layouts/bounding_box.hpp | 2 +- test/layouts/coordinates.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index c45e555e6..7675bb1b2 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -73,7 +73,7 @@ class bounding_box_2d { if constexpr (has_siqad_coord_v) { - auto coord_siqad = siqad::to_fiction_coord(coord); + auto coord_siqad = siqad::to_fiction_coord(coord); auto min_coord_cube = siqad::to_fiction_coord(min_coord); auto max_coord_cube = siqad::to_fiction_coord(max_coord); diff --git a/test/layouts/coordinates.cpp b/test/layouts/coordinates.cpp index 64490b6a2..c4beaa7bf 100644 --- a/test/layouts/coordinates.cpp +++ b/test/layouts/coordinates.cpp @@ -12,10 +12,10 @@ #include +#include #include #include #include -#include using namespace fiction; @@ -154,17 +154,16 @@ TEST_CASE("SiQAD coordinate conversion", "[coordinates]") CHECK(t8_fiction == siqad::to_fiction_coord(t8_siqad)); // Test for overflow scenario - auto t9 = coordinate{1, (std::numeric_limits::max()-1) / 2, 1}; + auto t9 = coordinate{1, (std::numeric_limits::max() - 1) / 2, 1}; auto fiction_9 = siqad::to_fiction_coord(t9); CHECK(fiction_9.x == t9.x); CHECK(fiction_9.y == std::numeric_limits::max()); // Test for underflow scenario - auto t10 = coordinate{1, (std::numeric_limits::min()+1) / 2}; + auto t10 = coordinate{1, (std::numeric_limits::min() + 1) / 2}; auto fiction_10 = siqad::to_fiction_coord(t10); CHECK(fiction_10.x == t10.x); - CHECK(fiction_10.y == std::numeric_limits::min()+2); - + CHECK(fiction_10.y == std::numeric_limits::min() + 2); } TEST_CASE("Offset to cube coordinate conversion", "[coordinates]") From b64d3e6c4925ff884c6d3f9a2832bbddaaf7b33e Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 13:18:44 +0200 Subject: [PATCH 173/191] :art: integrate Marcel's comment. --- .../fiction/algorithms/physical_design/apply_gate_library.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index e0ef63926..c8a6ef12b 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -231,7 +231,7 @@ template return p.run_static_gate_library(); } /** - * Applies an SiDB on-the-fly gate library to a given + * Applies a parameterized gate library to a given * gate-level layout and, thereby, creates and returns a cell-level layout. * * May pass through, and thereby throw, an `unsupported_gate_type_exception`, an @@ -246,7 +246,7 @@ template * @return A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`. */ template -[[nodiscard]] CellLyt apply_sidb_on_the_fly_gate_library(const GateLyt& lyt, const Params& params) +[[nodiscard]] CellLyt apply_parameterized_gate_library(const GateLyt& lyt, const Params& params) { static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); From 09434f5600aeede315ed8224da60159b1ade0cfa Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Fri, 16 Aug 2024 12:11:08 +0000 Subject: [PATCH 174/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../include/pyfiction/pybind11_mkdoc_docstrings.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 2acf14efc..3773065ba 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -264,9 +264,9 @@ Parameter ``lyt``: A cell-level layout that implements `lyt`'s gate types with building blocks defined in `GateLibrary`.)doc"; -static const char *__doc_fiction_apply_sidb_on_the_fly_gate_library = -R"doc(Applies an SiDB on-the-fly gate library to a given gate-level layout -and, thereby, creates and returns a cell-level layout. +static const char *__doc_fiction_apply_parameterized_gate_library = +R"doc(Applies a parameterized gate library to a given gate-level layout and, +thereby, creates and returns a cell-level layout. May pass through, and thereby throw, an `unsupported_gate_type_exception`, an From 82a69b8537fd26c1eadeeb712777e667738183c0 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Fri, 16 Aug 2024 15:01:12 +0200 Subject: [PATCH 175/191] :art: fix missing renaming. --- .../on_the_fly_circuit_design_on_defective_surface.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index a95036522..6592e43b7 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -100,8 +100,8 @@ class on_the_fly_circuit_design_impl { try { - lyt = apply_sidb_on_the_fly_gate_library>( + lyt = apply_parameterized_gate_library>( *gate_level_layout, params.sidb_on_the_fly_gate_library_parameters); } From d7fa79e26fad959de6d498937b75825b8c653f18 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:32:09 +0200 Subject: [PATCH 176/191] :art: integrate marcel's feedback. --- docs/algorithms/apply_gate_library.rst | 2 +- .../physical_design/apply_gate_library.hpp | 4 ++-- ...n_the_fly_circuit_design_on_defective_surface.hpp | 8 ++++---- include/fiction/layouts/bounding_box.hpp | 2 +- .../technology/sidb_on_the_fly_gate_library.hpp | 12 ++++++------ 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 4f5c9b45b..277d836ec 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -12,7 +12,7 @@ implementations for each gate present in the passed ``gate_level_layout``. **Header:** ``fiction/algorithms/physical_design/apply_gate_library.hpp`` .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) - .. doxygenfunction:: fiction::apply_sidb_on_the_fly_gate_library(const GateLyt& lyt, Params& params) + .. doxygenfunction:: fiction::apply_parameterized_gate_library(const GateLyt& lyt, Params& params) .. tab:: Python .. autofunction:: mnt.pyfiction.apply_qca_one_library diff --git a/include/fiction/algorithms/physical_design/apply_gate_library.hpp b/include/fiction/algorithms/physical_design/apply_gate_library.hpp index c8a6ef12b..7a0c411d4 100644 --- a/include/fiction/algorithms/physical_design/apply_gate_library.hpp +++ b/include/fiction/algorithms/physical_design/apply_gate_library.hpp @@ -111,7 +111,7 @@ class apply_gate_library_impl * @return A `CellLyt` object representing the generated cell layout. */ template - [[nodiscard]] CellLyt run_sidb_on_the_fly_gate_library(const Params& params) + [[nodiscard]] CellLyt run_parameterized_gate_library(const Params& params) { #if (PROGRESS_BARS) // initialize a progress bar @@ -259,7 +259,7 @@ template p{lyt}; - return p.template run_sidb_on_the_fly_gate_library(params); + return p.template run_parameterized_gate_library(params); } } // namespace fiction diff --git a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp index 6592e43b7..93adb8715 100644 --- a/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp +++ b/include/fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp @@ -39,7 +39,7 @@ struct on_the_fly_circuit_design_params /** * Parameters for the *exact* placement and routing algorithm. */ - exact_physical_design_params exact_design_parameter = {}; + exact_physical_design_params exact_design_parameters = {}; }; /** @@ -94,7 +94,7 @@ class on_the_fly_circuit_design_impl { // P&R with *exact* and the pre-determined blacklist gate_level_layout = - exact_with_blacklist(network, black_list, params.exact_design_parameter, &stats.exact_stats); + exact_with_blacklist(network, black_list, params.exact_design_parameters, &stats.exact_stats); if (gate_level_layout.has_value()) { @@ -184,8 +184,8 @@ on_the_fly_circuit_design_on_defective_surface(const Ntk& ntk, const GateLyt& la { static_assert(is_gate_level_layout_v, "GateLyt is not a gate-level layout"); static_assert(is_hexagonal_layout_v, "GateLyt is not a hexagonal"); - 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(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(has_sidb_technology_v, "CellLyt is not an SiDB layout"); static_assert(mockturtle::is_network_type_v, "Ntk is not a network type"); on_the_fly_circuit_design_stats st{}; diff --git a/include/fiction/layouts/bounding_box.hpp b/include/fiction/layouts/bounding_box.hpp index 7675bb1b2..5f5005f45 100644 --- a/include/fiction/layouts/bounding_box.hpp +++ b/include/fiction/layouts/bounding_box.hpp @@ -69,7 +69,7 @@ class bounding_box_2d } // Helper function to update bounding box - auto update_min_max = [](auto& min_coord, auto& max_coord, const auto& coord) + const auto update_min_max = [](auto& min_coord, auto& max_coord, const auto& coord) noexcept { if constexpr (has_siqad_coord_v) { diff --git a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp index 5f884d4c9..a0240eead 100644 --- a/include/fiction/technology/sidb_on_the_fly_gate_library.hpp +++ b/include/fiction/technology/sidb_on_the_fly_gate_library.hpp @@ -490,9 +490,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library& parameters, const port_list& p, const tile& tile) { - 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_cube_coord_v, "Lyt is not based on cube coordinates"); + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(has_sidb_technology_v, "CellLyt is not an SiDB layout"); + static_assert(has_cube_coord_v, "CellLyt is not based on cube coordinates"); const auto params = is_sidb_gate_design_impossible_params{parameters.design_gate_params.simulation_parameters}; @@ -594,9 +594,9 @@ class sidb_on_the_fly_gate_library : public fcn_gate_library& center_cell, const cell& absolute_cell, const Params& parameters) { - 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_cube_coord_v, "Lyt is not based on cube coordinates"); + static_assert(is_cell_level_layout_v, "CellLyt is not a cell-level layout"); + static_assert(has_sidb_technology_v, "CellLyt is not an SiDB layout"); + static_assert(has_cube_coord_v, "CellLyt is not based on cube coordinates"); auto skeleton_with_defect = sidb_defect_surface{skeleton}; From 0b1ab57e0227c798f82048933b48014f1302f1e3 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:32:24 +0200 Subject: [PATCH 177/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 416479fd1..cc061c091 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -39,8 +39,8 @@ jobs: build_and_test: strategy: matrix: - os: [ ubuntu-22.04 ] - compiler: [ g++-11 ] + os: [ macos-latest ] + compiler: [ gcc-14 ] name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} runs-on: ${{matrix.os}} From 2a4315fc93ae3a343b662b6b03f764cddef798dd Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Sat, 17 Aug 2024 09:33:14 +0000 Subject: [PATCH 178/191] :memo: Update pyfiction docstrings Signed-off-by: GitHub Actions --- .../pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp index 3773065ba..4189a3ee5 100644 --- a/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp +++ b/bindings/pyfiction/include/pyfiction/pybind11_mkdoc_docstrings.hpp @@ -3731,7 +3731,7 @@ static const char *__doc_fiction_detail_apply_gate_library_impl_cell_lyt = R"doc static const char *__doc_fiction_detail_apply_gate_library_impl_gate_lyt = R"doc(Gate-level layout.)doc"; -static const char *__doc_fiction_detail_apply_gate_library_impl_run_sidb_on_the_fly_gate_library = +static const char *__doc_fiction_detail_apply_gate_library_impl_run_parameterized_gate_library = R"doc(Run the cell layout generation process. This function performs the cell layout generation process based on the @@ -13169,7 +13169,7 @@ defective surface. Template parameter ``CellLyt``: Cell-level layout type.)doc"; -static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameter = R"doc(Parameters for the *exact* placement and routing algorithm.)doc"; +static const char *__doc_fiction_on_the_fly_circuit_design_params_exact_design_parameters = R"doc(Parameters for the *exact* placement and routing algorithm.)doc"; static const char *__doc_fiction_on_the_fly_circuit_design_params_sidb_on_the_fly_gate_library_parameters = R"doc(Parameters for the SiDB on-the-fly gate library.)doc"; From e9d89806c8bc102c11de3f91996ad45d562af929 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:37:52 +0200 Subject: [PATCH 179/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index cc061c091..b8077f08e 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -42,8 +42,8 @@ jobs: os: [ macos-latest ] compiler: [ gcc-14 ] - name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} - runs-on: ${{matrix.os}} + # name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} + # runs-on: ${{matrix.os}} steps: - name: Install the Compiler From fc0074cd93772e735f80d49b5dccf7b2122a915a Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:42:51 +0200 Subject: [PATCH 180/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b8077f08e..f658347d1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -42,14 +42,11 @@ jobs: os: [ macos-latest ] compiler: [ gcc-14 ] - # name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} - # runs-on: ${{matrix.os}} + name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} + runs-on: ${{matrix.os}} steps: - - name: Install the Compiler - run: sudo apt-get update && sudo apt-get install -yq ${{matrix.compiler}} - - - name: Clone Repository + - name: Check out Repository uses: actions/checkout@v4 with: submodules: recursive From 9252e4d865832e9580b9bf36f4abcf778a2f5bfb Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:48:13 +0200 Subject: [PATCH 181/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index f658347d1..acf70f969 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -68,10 +68,10 @@ jobs: - name: Setup mold uses: rui314/setup-mold@v1 - - name: Install pip packages - uses: BSFishy/pip-action@v1 - with: - requirements: ${{github.workspace}}/libs/mugen/requirements.txt + # - name: Install pip packages + # uses: BSFishy/pip-action@v1 + # with: + # requirements: ${{github.workspace}}/libs/mugen/requirements.txt - name: Setup Z3 Solver id: z3 From d27bdb202aff048d0694fc8fa0ffb8a4641885c0 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:49:43 +0200 Subject: [PATCH 182/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index acf70f969..b9f06bded 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -78,8 +78,8 @@ jobs: uses: cda-tum/setup-z3@v1 with: version: ${{env.Z3_VERSION}} - platform: linux - architecture: x64 + platform: macOS + architecture: ${{matrix.architecture}} env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 57b6e9f7130034674e8c56ea20f554a26f23f025 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:53:03 +0200 Subject: [PATCH 183/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index b9f06bded..9a05e3ad9 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -79,7 +79,7 @@ jobs: with: version: ${{env.Z3_VERSION}} platform: macOS - architecture: ${{matrix.architecture}} + architecture: arm64 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} From 4eefa56a642dba357b790668571b437c4b6f636f Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 11:59:45 +0200 Subject: [PATCH 184/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 9a05e3ad9..d05ff129b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -40,7 +40,7 @@ jobs: strategy: matrix: os: [ macos-latest ] - compiler: [ gcc-14 ] + compiler: [ clang++ ] name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} runs-on: ${{matrix.os}} From 9da21e6a8a62395b735f7a58302d0e5c899a6275 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 12:14:38 +0200 Subject: [PATCH 185/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d05ff129b..6026f0bbe 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -51,6 +51,19 @@ jobs: with: submodules: recursive + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10.x' + + - name: Setup TBB + run: brew install tbb + + - name: Setup XCode version + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: "^14.2" + - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -59,14 +72,6 @@ jobs: save: true max-size: 10G - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10.x' - cache: 'pip' - - - name: Setup mold - uses: rui314/setup-mold@v1 # - name: Install pip packages # uses: BSFishy/pip-action@v1 From 0191ac18ab6cc8a86fe40fa9627611d7873fa901 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 12:33:00 +0200 Subject: [PATCH 186/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6026f0bbe..56ce104a7 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -56,6 +56,14 @@ jobs: with: python-version: '3.10.x' + - name: Setup mold + uses: rui314/setup-mold@v1 + + - name: Install pip packages + uses: BSFishy/pip-action@v1 + with: + requirements: ${{github.workspace}}/libs/mugen/requirements.txt + - name: Setup TBB run: brew install tbb From e220cfcc6d047ed685f632bcc64c6ffa5f01b4a9 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 12:37:13 +0200 Subject: [PATCH 187/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 56ce104a7..71c28820a 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -59,10 +59,10 @@ jobs: - name: Setup mold uses: rui314/setup-mold@v1 - - name: Install pip packages - uses: BSFishy/pip-action@v1 - with: - requirements: ${{github.workspace}}/libs/mugen/requirements.txt + # - name: Install pip packages + # uses: BSFishy/pip-action@v1 + # with: + # requirements: ${{github.workspace}}/libs/mugen/requirements.txt - name: Setup TBB run: brew install tbb @@ -111,7 +111,6 @@ jobs: -DFICTION_TEST=ON -DFICTION_BENCHMARK=OFF -DFICTION_Z3=ON - -DFICTION_ENABLE_MUGEN=ON -DFICTION_PROGRESS_BARS=OFF -DFICTION_WARNINGS_AS_ERRORS=OFF -DFICTION_ENABLE_COVERAGE=ON From 8c437c01f742f13539887e00e076c7d577f243bf Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 12:52:29 +0200 Subject: [PATCH 188/191] :green_heart: try to fix codecov issue. --- .github/workflows/coverage.yml | 10 +++++++++- ...physical_design_with_on_the_fly_gate_design.cpp | 14 +++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 71c28820a..4b512809d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -125,9 +125,17 @@ jobs: run: ctest -C $BUILD_TYPE --verbose --output-on-failure --repeat until-pass:3 --parallel 4 + - name: Install lcov + run: | + if ! command -v brew &> /dev/null; then + echo "Homebrew not found. Installing..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + fi + brew install lcov + - name: Setup and run lcov run: | - sudo apt-get install lcov + ls -la ${{github.workspace}}/build/ lcov -t "result" -o lcov.info -c -d ${{github.workspace}}/build/ lcov -e lcov.info "${{github.workspace}}/include*" -o lcov_filtered.info lcov -l lcov_filtered.info diff --git a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp index 1b1906704..0aa4ac8a6 100644 --- a/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp +++ b/experiments/physical_design_with_on_the_fly_gate_design/physical_design_with_on_the_fly_gate_design.cpp @@ -133,13 +133,13 @@ int main() // NOLINT const auto mapped_network = fiction::technology_mapping(cut_xag, tech_map_params); fiction::on_the_fly_circuit_design_params params{}; - params.exact_design_parameter.scheme = "ROW4"; - params.exact_design_parameter.crossings = true; - params.exact_design_parameter.border_io = false; - params.exact_design_parameter.desynchronize = true; - params.exact_design_parameter.upper_bound_x = 11; // 12 x 31 tiles - params.exact_design_parameter.upper_bound_y = 30; // 12 x 31 tiles - params.exact_design_parameter.timeout = 3'600'000; // 1h in ms + params.exact_design_parameters.scheme = "ROW4"; + params.exact_design_parameters.crossings = true; + params.exact_design_parameters.border_io = false; + params.exact_design_parameters.desynchronize = true; + params.exact_design_parameters.upper_bound_x = 11; // 12 x 31 tiles + params.exact_design_parameters.upper_bound_y = 30; // 12 x 31 tiles + params.exact_design_parameters.timeout = 3'600'000; // 1h in ms params.sidb_on_the_fly_gate_library_parameters.defect_surface = surface_lattice; params.sidb_on_the_fly_gate_library_parameters.design_gate_params = design_gate_params; From c0160f8c72d62998e4c5e682ab0abab384ba35cf Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 13:04:12 +0200 Subject: [PATCH 189/191] :rewind: revert changes. --- .github/workflows/coverage.yml | 61 ++++++++++++---------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 4b512809d..416479fd1 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -39,39 +39,21 @@ jobs: build_and_test: strategy: matrix: - os: [ macos-latest ] - compiler: [ clang++ ] + os: [ ubuntu-22.04 ] + compiler: [ g++-11 ] name: Coverage on ${{matrix.os}} with ${{matrix.compiler}} runs-on: ${{matrix.os}} steps: - - name: Check out Repository + - name: Install the Compiler + run: sudo apt-get update && sudo apt-get install -yq ${{matrix.compiler}} + + - name: Clone Repository uses: actions/checkout@v4 with: submodules: recursive - - name: Setup Python - uses: actions/setup-python@v5 - with: - python-version: '3.10.x' - - - name: Setup mold - uses: rui314/setup-mold@v1 - - # - name: Install pip packages - # uses: BSFishy/pip-action@v1 - # with: - # requirements: ${{github.workspace}}/libs/mugen/requirements.txt - - - name: Setup TBB - run: brew install tbb - - - name: Setup XCode version - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: "^14.2" - - name: Setup ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -80,19 +62,27 @@ jobs: save: true max-size: 10G + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.10.x' + cache: 'pip' - # - name: Install pip packages - # uses: BSFishy/pip-action@v1 - # with: - # requirements: ${{github.workspace}}/libs/mugen/requirements.txt + - name: Setup mold + uses: rui314/setup-mold@v1 + + - name: Install pip packages + uses: BSFishy/pip-action@v1 + with: + requirements: ${{github.workspace}}/libs/mugen/requirements.txt - name: Setup Z3 Solver id: z3 uses: cda-tum/setup-z3@v1 with: version: ${{env.Z3_VERSION}} - platform: macOS - architecture: arm64 + platform: linux + architecture: x64 env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} @@ -111,6 +101,7 @@ jobs: -DFICTION_TEST=ON -DFICTION_BENCHMARK=OFF -DFICTION_Z3=ON + -DFICTION_ENABLE_MUGEN=ON -DFICTION_PROGRESS_BARS=OFF -DFICTION_WARNINGS_AS_ERRORS=OFF -DFICTION_ENABLE_COVERAGE=ON @@ -125,17 +116,9 @@ jobs: run: ctest -C $BUILD_TYPE --verbose --output-on-failure --repeat until-pass:3 --parallel 4 - - name: Install lcov - run: | - if ! command -v brew &> /dev/null; then - echo "Homebrew not found. Installing..." - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - fi - brew install lcov - - name: Setup and run lcov run: | - ls -la ${{github.workspace}}/build/ + sudo apt-get install lcov lcov -t "result" -o lcov.info -c -d ${{github.workspace}}/build/ lcov -e lcov.info "${{github.workspace}}/include*" -o lcov_filtered.info lcov -l lcov_filtered.info From 234f06058b66f35d3d4fef3c6af423fa0acc074d Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 13:40:46 +0200 Subject: [PATCH 190/191] :memo: small fix. --- docs/algorithms/apply_gate_library.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/algorithms/apply_gate_library.rst b/docs/algorithms/apply_gate_library.rst index 277d836ec..746476398 100644 --- a/docs/algorithms/apply_gate_library.rst +++ b/docs/algorithms/apply_gate_library.rst @@ -12,7 +12,7 @@ implementations for each gate present in the passed ``gate_level_layout``. **Header:** ``fiction/algorithms/physical_design/apply_gate_library.hpp`` .. doxygenfunction:: fiction::apply_gate_library(const GateLyt& lyt) - .. doxygenfunction:: fiction::apply_parameterized_gate_library(const GateLyt& lyt, Params& params) + .. doxygenfunction:: fiction::apply_parameterized_gate_library(const GateLyt& lyt, const Params& params) .. tab:: Python .. autofunction:: mnt.pyfiction.apply_qca_one_library From a8fff297deec0484755de9d38bbe898b76392926 Mon Sep 17 00:00:00 2001 From: Drewniok Date: Sat, 17 Aug 2024 17:47:57 +0200 Subject: [PATCH 191/191] :memo: small fix. --- .../on_the_fly_circuit_design_on_defective_surface.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst index fb2f23b2c..ddeeed916 100644 --- a/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst +++ b/docs/algorithms/on_the_fly_circuit_design_on_defective_surface.rst @@ -3,8 +3,6 @@ SiDB Circuit Design Algorithm in the Presence of Atomic Defects --------------------------------------------------------------- -**Header:** ``fiction/algorithms/physical_design/on_the_fly_circuit_design_on_defective_surface.hpp`` - This algorithm is designed to create SiDB circuits on a clocked surface, accommodating the presence of atomic defects. 1. **Blacklist Generation**: