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();