diff --git a/docs/changelog.rst b/docs/changelog.rst index b62fba632..f96fe4e76 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog `_. +Unreleased +---------- + +Added +##### +- Experiments: + - Added information about how many layouts remain after each of QuickCell's pruning steps. + v0.6.6 - 2024-11-26 ------------------- diff --git a/experiments/quickcell/quickcell_3_input.cpp b/experiments/quickcell/quickcell_3_input.cpp index 8e1c345b0..118173de7 100644 --- a/experiments/quickcell/quickcell_3_input.cpp +++ b/experiments/quickcell/quickcell_3_input.cpp @@ -17,9 +17,11 @@ #include #include +#include #include #include #include +#include #include using namespace fiction; @@ -29,17 +31,31 @@ using namespace fiction; int main() // NOLINT { - experiments::experiment simulation_exp{"benchmark", "gate", "#Gates (QuickCell)", - "runtime (QuickCell) [s]"}; - - const auto truth_tables = std::vector>{ - std::vector{create_and3_tt()}, std::vector{create_xor_and_tt()}, std::vector{create_or_and_tt()}, - std::vector{create_onehot_tt()}, std::vector{create_maj_tt()}, std::vector{create_gamble_tt()}, - std::vector{create_dot_tt()}, std::vector{create_ite_tt()}, std::vector{create_and_xor_tt()}, - std::vector{create_xor3_tt()}}; - - static const std::vector gate_names = {"and3", "xor_and", "or_and", "onehot", "maj", - "gamble", "dot", "ite", "and_xor", "xor3"}; + experiments::experiment + simulation_exp{"benchmark", + "gate", // std::string + "#Total Layouts", // uint64_t + "#Gates (QuickCell)", // uint64_t + "runtime (QuickCell) [s]", // double + "#Lp1", // uint64_t + "#Lp1/N [%]", // double + "#Lp2", // uint64_t + "#Lp2/N [%]", // double + "#Lp3", // uint64_t + "#Lp3/N [%]"}; // double + + const auto truth_tables_and_names = + std::array, std::string>, 10>{{{std::vector{create_and3_tt()}, "and3"}, + {std::vector{create_xor_and_tt()}, "xor_and"}, + {std::vector{create_or_and_tt()}, "or_and"}, + {std::vector{create_onehot_tt()}, "onehot"}, + {std::vector{create_maj_tt()}, "maj"}, + {std::vector{create_gamble_tt()}, "gamble"}, + {std::vector{create_dot_tt()}, "dot"}, + {std::vector{create_ite_tt()}, "ite"}, + {std::vector{create_and_xor_tt()}, "and_xor"}, + {std::vector{create_xor3_tt()}, "xor3"}}}; static const std::string folder = fmt::format("{}/gate_skeletons/skeleton_3_input_1_output/", EXPERIMENTS_PATH); @@ -59,38 +75,39 @@ int main() // NOLINT {{22, 6, 0}, {32, 12, 0}}, 4}; - double sum_quickcell_runtime = 0; - - for (auto i = 0u; i < truth_tables.size(); i++) + for (const auto& [truth_tables, gate_names] : truth_tables_and_names) { - const auto& table = truth_tables[i]; - std::vector quickcell_design{}; design_sidb_gates_stats stats_quickcell{}; - if (gate_names[i] == "and3" || gate_names[i] == "gamble") + if (gate_names == "and3" || gate_names == "gamble") { - quickcell_design = design_sidb_gates(skeleton_one, table, params, &stats_quickcell); + quickcell_design = design_sidb_gates(skeleton_one, truth_tables, params, &stats_quickcell); } else { - quickcell_design = design_sidb_gates(skeleton_two, table, params, &stats_quickcell); + quickcell_design = design_sidb_gates(skeleton_two, truth_tables, params, &stats_quickcell); } const auto runtime_quickcell = mockturtle::to_seconds(stats_quickcell.time_total); - sum_quickcell_runtime += runtime_quickcell; - const auto final_number_of_gates = quickcell_design.size(); - simulation_exp(gate_names[i], final_number_of_gates, runtime_quickcell); + simulation_exp(gate_names, stats_quickcell.number_of_layouts, final_number_of_gates, runtime_quickcell, + stats_quickcell.number_of_layouts_after_first_pruning, + 100.0 * static_cast(stats_quickcell.number_of_layouts_after_first_pruning) / + static_cast(stats_quickcell.number_of_layouts), + stats_quickcell.number_of_layouts_after_second_pruning, + 100.0 * static_cast(stats_quickcell.number_of_layouts_after_second_pruning) / + static_cast(stats_quickcell.number_of_layouts), + stats_quickcell.number_of_layouts_after_third_pruning, + 100.0 * static_cast(stats_quickcell.number_of_layouts_after_third_pruning) / + static_cast(stats_quickcell.number_of_layouts)); simulation_exp.save(); simulation_exp.table(); } - simulation_exp("", 0, sum_quickcell_runtime); - simulation_exp.save(); simulation_exp.table(); diff --git a/experiments/quickcell/quickcell_vs_automatic_exhaustive_2_input.cpp b/experiments/quickcell/quickcell_vs_automatic_exhaustive_2_input.cpp index 298997f46..c238e7c79 100644 --- a/experiments/quickcell/quickcell_vs_automatic_exhaustive_2_input.cpp +++ b/experiments/quickcell/quickcell_vs_automatic_exhaustive_2_input.cpp @@ -16,10 +16,11 @@ #include #include +#include #include #include -#include #include +#include #include // This script uses the *Automatic Exhaustive Gate Designer* and *QuickCell* to design gate implementations for 2-input @@ -30,33 +31,59 @@ using namespace fiction; int main() // NOLINT { - experiments::experiment simulation_exp{ - "benchmark", - "gate", - "runtime (Automatic Exhaustive) [s]", - "#Gates (Automatic Exhaustive)", - "#Gates (QuickCell)", - "runtime (QuickCell) [s]", - "runtime (Automatic Exhaustive) / runtime (QuickCell) [s]"}; - - const auto truth_tables = std::vector>{ - std::vector{create_and_tt()}, std::vector{create_nand_tt()}, std::vector{create_or_tt()}, - std::vector{create_nor_tt()}, std::vector{create_xor_tt()}, std::vector{create_xnor_tt()}, - std::vector{create_lt_tt()}, std::vector{create_gt_tt()}, std::vector{create_le_tt()}, - std::vector{create_ge_tt()}, create_crossing_wire_tt(), create_half_adder_tt(), - create_double_wire_tt()}; - - static const std::vector gate_names = {"and", "nand", "or", "nor", "xor", "xnor", "lt", - "gt", "le", "ge", "cx", "ha", "hourglass"}; + experiments::experiment + simulation_exp{"benchmark", + "gate", // std::string + "#Total Layouts", // uint64_t + "runtime (Automatic Exhaustive) [s]", // double + "#Gates (Automatic Exhaustive, sota)", // uint64_t + "#Gates (QuickCell)", // uint64_t + "runtime (QuickCell, proposed) [s]", // double + "t_sota / t_proposed", // double + "#Lp1", // uint64_t + "#Lp1/N [%]", // double + "#Lp2", // uint64_t + "#Lp2/N [%]", // double + "#Lp3", // uint64_t + "#Lp3/N [%]"}; // double + + const auto truth_tables_and_names = std::array, std::string>, 15>{ + {{std::vector{create_id_tt()}, "inv"}, + {std::vector{create_not_tt()}, "wire"}, + {std::vector{create_and_tt()}, "and"}, + {std::vector{create_nand_tt()}, "nand"}, + {std::vector{create_or_tt()}, "or"}, + {std::vector{create_nor_tt()}, "nor"}, + {std::vector{create_xor_tt()}, "xor"}, + {std::vector{create_xnor_tt()}, "xnor"}, + {std::vector{create_lt_tt()}, "lt"}, + {std::vector{create_gt_tt()}, "gt"}, + {std::vector{create_le_tt()}, "le"}, + {std::vector{create_ge_tt()}, "ge"}, + {std::vector{create_crossing_wire_tt()}, "cx"}, + {std::vector{create_half_adder_tt()}, "ha"}, + {std::vector{create_double_wire_tt()}, "hourglass"}}}; static const std::string folder = fmt::format("{}/gate_skeletons/skeleton_bestagons_with_tags", EXPERIMENTS_PATH); + const auto skeleton_one_input_one_output_straight = read_sqd_layout( + fmt::format("{}/{}", folder, "skeleton_hex_inputsdbp_1i1o_straight.sqd")); + const auto skeleton_one_input_two_output = read_sqd_layout(fmt::format("{}/{}", folder, "skeleton_hex_inputsdbp_2i1o.sqd")); const auto skeleton_two_input_two_output = read_sqd_layout(fmt::format("{}/{}", folder, "skeleton_hex_inputsdbp_2i2o.sqd")); + design_sidb_gates_params> params_1_in_1_out_straight{ + is_operational_params{sidb_simulation_parameters{2, -0.32}, sidb_simulation_engine::QUICKEXACT, + bdl_input_iterator_params{}, operational_condition::REJECT_KINKS}, + design_sidb_gates_params< + fiction::cell>::design_sidb_gates_mode::AUTOMATIC_EXHAUSTIVE_GATE_DESIGNER, + {{9, 6, 0}, {21, 14, 0}}, + 3}; + design_sidb_gates_params> params_2_in_1_out{ is_operational_params{sidb_simulation_parameters{2, -0.32}, sidb_simulation_engine::QUICKEXACT, bdl_input_iterator_params{}, operational_condition::REJECT_KINKS}, @@ -76,10 +103,8 @@ int main() // NOLINT double sum_exhaustive_runtime = 0; double sum_quickcell_runtime = 0; - for (auto i = 0u; i < truth_tables.size(); i++) + for (const auto& [truth_table, gate_name] : truth_tables_and_names) { - const auto& table = truth_tables[i]; - design_sidb_gates_stats stats_automatic_exhaustive_design{}; std::vector automatic_exhaustive_design{}; @@ -91,37 +116,53 @@ int main() // NOLINT fiction::cell>::design_sidb_gates_mode::AUTOMATIC_EXHAUSTIVE_GATE_DESIGNER; params_2_in_2_out.operational_params.op_condition = operational_condition::REJECT_KINKS; - if (gate_names[i] == "cx" || gate_names[i] == "ha" || gate_names[i] == "hourglass") + params_1_in_1_out_straight.design_mode = design_sidb_gates_params< + fiction::cell>::design_sidb_gates_mode::AUTOMATIC_EXHAUSTIVE_GATE_DESIGNER; + params_1_in_1_out_straight.operational_params.op_condition = operational_condition::REJECT_KINKS; + + if (gate_name == "cx" || gate_name == "ha" || gate_name == "hourglass") + { + automatic_exhaustive_design = design_sidb_gates(skeleton_two_input_two_output, truth_table, + params_2_in_2_out, &stats_automatic_exhaustive_design); + } + else if (gate_name == "wire" || gate_name == "inv") { - automatic_exhaustive_design = design_sidb_gates(skeleton_two_input_two_output, table, params_2_in_2_out, - &stats_automatic_exhaustive_design); + automatic_exhaustive_design = + design_sidb_gates(skeleton_one_input_one_output_straight, truth_table, params_1_in_1_out_straight, + &stats_automatic_exhaustive_design); } else { - automatic_exhaustive_design = design_sidb_gates(skeleton_one_input_two_output, table, params_2_in_1_out, - &stats_automatic_exhaustive_design); + automatic_exhaustive_design = design_sidb_gates(skeleton_one_input_two_output, truth_table, + params_2_in_1_out, &stats_automatic_exhaustive_design); } - std::cout << mockturtle::to_seconds(stats_automatic_exhaustive_design.time_total) << '\n'; - std::vector quickcell_design{}; design_sidb_gates_stats stats_quickcell{}; params_2_in_1_out.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::QUICKCELL; - ; + params_2_in_2_out.design_mode = design_sidb_gates_params>::design_sidb_gates_mode::QUICKCELL; - if (gate_names[i] == "cx" || gate_names[i] == "ha" || gate_names[i] == "hourglass") + params_1_in_1_out_straight.design_mode = + design_sidb_gates_params>::design_sidb_gates_mode::QUICKCELL; + + if (gate_name == "cx" || gate_name == "ha" || gate_name == "hourglass") { quickcell_design = - design_sidb_gates(skeleton_two_input_two_output, table, params_2_in_2_out, &stats_quickcell); + design_sidb_gates(skeleton_two_input_two_output, truth_table, params_2_in_2_out, &stats_quickcell); + } + else if (gate_name == "wire" || gate_name == "inv") + { + quickcell_design = design_sidb_gates(skeleton_one_input_one_output_straight, truth_table, + params_1_in_1_out_straight, &stats_quickcell); } else { quickcell_design = - design_sidb_gates(skeleton_one_input_two_output, table, params_2_in_1_out, &stats_quickcell); + design_sidb_gates(skeleton_one_input_two_output, truth_table, params_2_in_1_out, &stats_quickcell); } const auto runtime_automatic_exhaustive_design = @@ -133,10 +174,19 @@ int main() // NOLINT const auto time_reduction = runtime_automatic_exhaustive_design / runtime_quickcell; - const auto final_number_of_gates = quickcell_design.size(); + const auto total_number_of_layout = stats_quickcell.number_of_layouts; - simulation_exp(gate_names[i], runtime_automatic_exhaustive_design, automatic_exhaustive_design.size(), - final_number_of_gates, runtime_quickcell, time_reduction); + simulation_exp(gate_name, total_number_of_layout, runtime_automatic_exhaustive_design, + automatic_exhaustive_design.size(), quickcell_design.size(), runtime_quickcell, time_reduction, + stats_quickcell.number_of_layouts_after_first_pruning, + static_cast(stats_quickcell.number_of_layouts_after_first_pruning) / + static_cast(total_number_of_layout) * 100, + stats_quickcell.number_of_layouts_after_second_pruning, + static_cast(stats_quickcell.number_of_layouts_after_second_pruning) / + static_cast(total_number_of_layout) * 100, + stats_quickcell.number_of_layouts_after_third_pruning, + static_cast(stats_quickcell.number_of_layouts_after_third_pruning) / + static_cast(total_number_of_layout) * 100); simulation_exp.save(); simulation_exp.table(); @@ -144,7 +194,8 @@ int main() // NOLINT const auto total_time_reduction = sum_exhaustive_runtime / sum_quickcell_runtime; - simulation_exp("", sum_exhaustive_runtime, 0, 0, sum_quickcell_runtime, total_time_reduction); + simulation_exp("", 0, sum_exhaustive_runtime, 0, 0, sum_quickcell_runtime, total_time_reduction, 0, 0.0, 0, 0.0, 0, + 0.0); simulation_exp.save(); simulation_exp.table();