From 3f60bb030007675c2171b8d950d9ad858858d19c Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Sun, 3 Mar 2024 22:43:21 -0500 Subject: [PATCH 01/38] Add wrapper for Rust --- CMakeLists.txt | 1 + src/wrapper/CMakeLists.txt | 13 ++++++ src/wrapper/rust/oracle.cpp | 69 +++++++++++++++++++++++++++++++ src/wrapper/rust/oracle.h | 4 ++ src/wrapper/rust/test_wrapper.cpp | 42 +++++++++++++++++++ src/wrapper/rust/wrapper.cpp | 11 +++++ src/wrapper/rust/wrapper.h | 4 ++ 7 files changed, 144 insertions(+) create mode 100644 src/wrapper/CMakeLists.txt create mode 100644 src/wrapper/rust/oracle.cpp create mode 100644 src/wrapper/rust/oracle.h create mode 100644 src/wrapper/rust/test_wrapper.cpp create mode 100644 src/wrapper/rust/wrapper.cpp create mode 100644 src/wrapper/rust/wrapper.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 79481be0..8c405228 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,4 +156,5 @@ else() endif() add_subdirectory(src/test) +add_subdirectory(src/wrapper) add_subdirectory(src/benchmark) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt new file mode 100644 index 00000000..ea5ec45c --- /dev/null +++ b/src/wrapper/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(${CMAKE_INCLUDE_PATH}) +include_directories("..") + +link_directories("../..") + +file(GLOB_RECURSE WRAPPER "test_wrapper.cpp") +file(GLOB_RECURSE ORACLE "oracle.cpp") + +add_library(oracle SHARED ${ORACLE}) + +add_executable(wrapper ${WRAPPER}) +target_link_libraries(wrapper oracle) +target_link_libraries(wrapper quartz_runtime) diff --git a/src/wrapper/rust/oracle.cpp b/src/wrapper/rust/oracle.cpp new file mode 100644 index 00000000..e1ebaec7 --- /dev/null +++ b/src/wrapper/rust/oracle.cpp @@ -0,0 +1,69 @@ +#include "oracle.h" + +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" + +using namespace quartz; + +std::string optimize_(std::string circ_string, int n_qubits, + std::string cost_func, std::string ecc_path, + std::string gate_set, float timeout) { + ParamInfo param_info(0); + auto gate_set_vec = std::vector(); + if (gate_set == "Nam") { + gate_set_vec = {GateType::input_qubit, GateType::input_param, GateType::cx, + GateType::h, GateType::rz, GateType::x, + GateType::add}; + } else if (gate_set == "CliffordT") { + gate_set_vec = { + GateType::input_qubit, GateType::input_param, GateType::cx, GateType::h, + GateType::rz, GateType::x, GateType::t}; + } else { + std::cout << "Invalid gate set." << std::endl; + assert(false); + } + auto ctx = Context(gate_set_vec, n_qubits, ¶m_info); + + auto graph = Graph::from_qasm_str(&ctx, circ_string); + + EquivalenceSet eqs; + // Load equivalent dags from file + if (!eqs.load_json(&ctx, ecc_path, false)) { + std::cout << "Failed to load equivalence file." << std::endl; + assert(false); + } + + // Get xfer from the equivalent set + auto ecc = eqs.get_all_equivalence_sets(); + std::vector xfers; + for (auto eqcs : ecc) { + for (auto circ_0 : eqcs) { + for (auto circ_1 : eqcs) { + if (circ_0 != circ_1) { + auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_0, circ_1, true); + if (xfer != nullptr) { + xfers.push_back(xfer); + } + } + } + } + } + // std::cout << "number of xfers: " << xfers.size() << std::endl; + std::function cost_function; + if (cost_func == "Gate") { + cost_function = [](Graph *graph) { return graph->total_cost(); }; + } else if (cost_func == "Depth") { + cost_function = [](Graph *graph) { return graph->circuit_depth(); }; + } else if (cost_func == "Mixed") { + cost_function = [](Graph *graph) { + return graph->circuit_depth() + 0.1 * graph->total_cost(); + }; + } else { + std::cout << "Invalid cost function." << std::endl; + assert(false); + } + float init_cost = cost_function(graph.get()); + auto newgraph = graph->optimize(xfers, init_cost * 1.05, "barenco_tof_3", "", + false, cost_function, timeout); + return newgraph->to_qasm(false, false); +} \ No newline at end of file diff --git a/src/wrapper/rust/oracle.h b/src/wrapper/rust/oracle.h new file mode 100644 index 00000000..eada5b5c --- /dev/null +++ b/src/wrapper/rust/oracle.h @@ -0,0 +1,4 @@ +#include +std::string optimize_(std::string circ_string, int n_qubits, + std::string cost_func, std::string ecc_path, + std::string gate_set, float timeout); \ No newline at end of file diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp new file mode 100644 index 00000000..7fd6104f --- /dev/null +++ b/src/wrapper/rust/test_wrapper.cpp @@ -0,0 +1,42 @@ +#include "oracle.h" + +#include +#include +#include +int main() { + std::string my_circ = std::string(R"(OPENQASM 2.0; + include "qelib1.inc"; + qreg q[24]; + cx q[5], q[8]; + rz(-0.7853981633974483) q[11]; + rz(-0.7853981633974483) q[12]; + rz(-0.7853981633974483) q[18]; + rz(-0.7853981633974483) q[19]; + cx q[5], q[6]; + rz(0.7853981633974483) q[8]; + cx q[12], q[11]; + cx q[19], q[18]; + rz(-0.7853981633974483) q[6]; + h q[8]; + cx q[12], q[14]; + cx q[19], q[21]; + cx q[5], q[6]; + cx q[8], q[10]; + cx q[9], q[12]; + h q[14]; + cx q[15], q[19]; + h q[21]; + h q[21];)"); + // std::string my_circ = std::string(R"(OPENQASM 2.0; + // include "qelib1.inc"; + // qreg q[24]; + // tdg q[8]; + // t q[8];)"); + std::cout << optimize_(my_circ, 24, "Gate", + // "/home/pengyul/quicr/soam/resources/oracles/" + // "Nam_3_3_complete_ECC_set.json", + "/home/pengyul/quicr/soam/resources/quartz/build/" + "Nam_4_3_complete_ECC_set.json", + "Nam", 5); + return 0; +} \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.cpp b/src/wrapper/rust/wrapper.cpp new file mode 100644 index 00000000..85d275af --- /dev/null +++ b/src/wrapper/rust/wrapper.cpp @@ -0,0 +1,11 @@ +#include "wrapper.h" + +#include "oracle.h" + +#include +rust::String optimize(rust::String circ_string, int n_qubits, + rust::String cost_func, rust::String ecc_path, + rust::String gateset, float timeout) { + return optimize_(std::string(circ_string), std::string(cost_func), + std::string(ecc_path), std::string(gateset), timeout); +} \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.h b/src/wrapper/rust/wrapper.h new file mode 100644 index 00000000..bab83c2d --- /dev/null +++ b/src/wrapper/rust/wrapper.h @@ -0,0 +1,4 @@ +#include "rust/cxx.h" +rust::String optimize(rust::String circ_string, int n_qubits, + rust::String cost_func, rust::String ecc_path, + rust::String gateset, float timeout); \ No newline at end of file From 0c9ec4dea06d5db765887806ac4a44009d6b8d6b Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Sun, 3 Mar 2024 22:54:53 -0500 Subject: [PATCH 02/38] small bug fix --- src/wrapper/rust/wrapper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/rust/wrapper.cpp b/src/wrapper/rust/wrapper.cpp index 85d275af..25c1e6a5 100644 --- a/src/wrapper/rust/wrapper.cpp +++ b/src/wrapper/rust/wrapper.cpp @@ -6,6 +6,6 @@ rust::String optimize(rust::String circ_string, int n_qubits, rust::String cost_func, rust::String ecc_path, rust::String gateset, float timeout) { - return optimize_(std::string(circ_string), std::string(cost_func), + return optimize_(std::string(circ_string), n_qubits, std::string(cost_func), std::string(ecc_path), std::string(gateset), timeout); } \ No newline at end of file From ae0e333597b47483d92c277f7d446c992f071303 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Sun, 3 Mar 2024 23:28:18 -0500 Subject: [PATCH 03/38] Fix a bug --- src/wrapper/rust/oracle.cpp | 4 ++-- src/wrapper/rust/test_wrapper.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wrapper/rust/oracle.cpp b/src/wrapper/rust/oracle.cpp index e1ebaec7..4f7b9d48 100644 --- a/src/wrapper/rust/oracle.cpp +++ b/src/wrapper/rust/oracle.cpp @@ -24,8 +24,6 @@ std::string optimize_(std::string circ_string, int n_qubits, } auto ctx = Context(gate_set_vec, n_qubits, ¶m_info); - auto graph = Graph::from_qasm_str(&ctx, circ_string); - EquivalenceSet eqs; // Load equivalent dags from file if (!eqs.load_json(&ctx, ecc_path, false)) { @@ -48,6 +46,8 @@ std::string optimize_(std::string circ_string, int n_qubits, } } } + auto graph = Graph::from_qasm_str(&ctx, circ_string); + // std::cout << "number of xfers: " << xfers.size() << std::endl; std::function cost_function; if (cost_func == "Gate") { diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp index 7fd6104f..57cee36c 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rust/test_wrapper.cpp @@ -8,8 +8,8 @@ int main() { include "qelib1.inc"; qreg q[24]; cx q[5], q[8]; - rz(-0.7853981633974483) q[11]; - rz(-0.7853981633974483) q[12]; + rz(-0.123) q[11]; + rz(-0.234) q[12]; rz(-0.7853981633974483) q[18]; rz(-0.7853981633974483) q[19]; cx q[5], q[6]; From af8239a094da50c8d30fd26ef1451f918bd901b7 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 11 Mar 2024 11:06:20 -0400 Subject: [PATCH 04/38] update wrapper --- src/wrapper/rust/oracle.cpp | 61 +++++++--------------------- src/wrapper/rust/oracle.h | 67 +++++++++++++++++++++++++++++-- src/wrapper/rust/test_wrapper.cpp | 25 +++++------- src/wrapper/rust/wrapper.cpp | 23 +++++++---- src/wrapper/rust/wrapper.h | 13 ++++-- 5 files changed, 113 insertions(+), 76 deletions(-) diff --git a/src/wrapper/rust/oracle.cpp b/src/wrapper/rust/oracle.cpp index 4f7b9d48..6da67f69 100644 --- a/src/wrapper/rust/oracle.cpp +++ b/src/wrapper/rust/oracle.cpp @@ -1,54 +1,20 @@ #include "oracle.h" -#include "quartz/tasograph/substitution.h" -#include "quartz/tasograph/tasograph.h" - using namespace quartz; +std::unique_ptr get_context_(const std::string gate_set, + int n_qubits, + const std::string ecc_path) { + auto super_context = + std::make_unique(gate_set, n_qubits, ecc_path); + return super_context; +} -std::string optimize_(std::string circ_string, int n_qubits, - std::string cost_func, std::string ecc_path, - std::string gate_set, float timeout) { - ParamInfo param_info(0); - auto gate_set_vec = std::vector(); - if (gate_set == "Nam") { - gate_set_vec = {GateType::input_qubit, GateType::input_param, GateType::cx, - GateType::h, GateType::rz, GateType::x, - GateType::add}; - } else if (gate_set == "CliffordT") { - gate_set_vec = { - GateType::input_qubit, GateType::input_param, GateType::cx, GateType::h, - GateType::rz, GateType::x, GateType::t}; - } else { - std::cout << "Invalid gate set." << std::endl; - assert(false); - } - auto ctx = Context(gate_set_vec, n_qubits, ¶m_info); - - EquivalenceSet eqs; - // Load equivalent dags from file - if (!eqs.load_json(&ctx, ecc_path, false)) { - std::cout << "Failed to load equivalence file." << std::endl; - assert(false); - } +std::string optimize_(std::string circ_string, std::string cost_func, + float timeout, std::unique_ptr super_context - // Get xfer from the equivalent set - auto ecc = eqs.get_all_equivalence_sets(); - std::vector xfers; - for (auto eqcs : ecc) { - for (auto circ_0 : eqcs) { - for (auto circ_1 : eqcs) { - if (circ_0 != circ_1) { - auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_0, circ_1, true); - if (xfer != nullptr) { - xfers.push_back(xfer); - } - } - } - } - } - auto graph = Graph::from_qasm_str(&ctx, circ_string); +) { + auto graph = Graph::from_qasm_str(&super_context->ctx, circ_string); - // std::cout << "number of xfers: " << xfers.size() << std::endl; std::function cost_function; if (cost_func == "Gate") { cost_function = [](Graph *graph) { return graph->total_cost(); }; @@ -63,7 +29,8 @@ std::string optimize_(std::string circ_string, int n_qubits, assert(false); } float init_cost = cost_function(graph.get()); - auto newgraph = graph->optimize(xfers, init_cost * 1.05, "barenco_tof_3", "", - false, cost_function, timeout); + auto newgraph = + graph->optimize(super_context->xfers, init_cost * 1.05, "barenco_tof_3", + "", false, cost_function, timeout); return newgraph->to_qasm(false, false); } \ No newline at end of file diff --git a/src/wrapper/rust/oracle.h b/src/wrapper/rust/oracle.h index eada5b5c..c3455dd8 100644 --- a/src/wrapper/rust/oracle.h +++ b/src/wrapper/rust/oracle.h @@ -1,4 +1,65 @@ +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" + +#include #include -std::string optimize_(std::string circ_string, int n_qubits, - std::string cost_func, std::string ecc_path, - std::string gate_set, float timeout); \ No newline at end of file +#include +using namespace quartz; + +class SuperContext { + public: + Context ctx; + ParamInfo param_info; + std::vector xfers; + static Context createContext(const std::string &gate_set, int n_qubits, + ParamInfo ¶m_info, + const std::string &ecc_path) { + std::vector gates; + if (gate_set == "Nam") { + gates = {GateType::input_qubit, GateType::input_param, GateType::cx, + GateType::h, GateType::rz, GateType::x, + GateType::add}; + } else if (gate_set == "CliffordT") { + std::cerr << "Not implemented yet." << std::endl; + assert(false); + } else { + std::cerr << "Invalid gate set." << std::endl; + assert(false); + } + + return Context(gates, n_qubits, ¶m_info); + } + SuperContext(const std::string &gate_set, int n_qubits, + const std::string &ecc_path) + : param_info(0), + ctx(createContext(gate_set, n_qubits, param_info, ecc_path)) { + xfers = std::vector(); + EquivalenceSet eqs; + if (!eqs.load_json(&ctx, ecc_path, false)) { + std::cout << "Failed to load equivalence file." << std::endl; + assert(false); + } + + auto ecc = eqs.get_all_equivalence_sets(); + for (auto &eqcs : ecc) { + for (auto &circ_0 : eqcs) { + for (auto &circ_1 : eqcs) { + if (circ_0 != circ_1) { + auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_0, circ_1, true); + if (xfer != nullptr) { + xfers.push_back(xfer); + } + } + } + } + } + }; + ~SuperContext() = default; +}; + +std::unique_ptr get_context_(const std::string gate_set, + int n_qubits, + const std::string ecc_path); +std::string optimize_(std::string circ_string, std::string cost_func, + float timeout, + std::unique_ptr super_context); \ No newline at end of file diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp index 57cee36c..7d13b860 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rust/test_wrapper.cpp @@ -1,8 +1,8 @@ #include "oracle.h" +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" +using namespace quartz; -#include -#include -#include int main() { std::string my_circ = std::string(R"(OPENQASM 2.0; include "qelib1.inc"; @@ -24,19 +24,14 @@ int main() { cx q[8], q[10]; cx q[9], q[12]; h q[14]; - cx q[15], q[19]; + cx q[15], q[19]; h q[21]; h q[21];)"); - // std::string my_circ = std::string(R"(OPENQASM 2.0; - // include "qelib1.inc"; - // qreg q[24]; - // tdg q[8]; - // t q[8];)"); - std::cout << optimize_(my_circ, 24, "Gate", - // "/home/pengyul/quicr/soam/resources/oracles/" - // "Nam_3_3_complete_ECC_set.json", - "/home/pengyul/quicr/soam/resources/quartz/build/" - "Nam_4_3_complete_ECC_set.json", - "Nam", 5); + auto supercontext = + get_context_("Nam", 24, + "/home/pengyul/quicr/soam/resources/quartz/build/" + "Nam_4_3_complete_ECC_set.json"); + std::cout << optimize_(my_circ, "Gate", 1000, std::move(supercontext)) + << std::endl; return 0; } \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.cpp b/src/wrapper/rust/wrapper.cpp index 25c1e6a5..593a539c 100644 --- a/src/wrapper/rust/wrapper.cpp +++ b/src/wrapper/rust/wrapper.cpp @@ -1,11 +1,18 @@ #include "wrapper.h" -#include "oracle.h" - #include -rust::String optimize(rust::String circ_string, int n_qubits, - rust::String cost_func, rust::String ecc_path, - rust::String gateset, float timeout) { - return optimize_(std::string(circ_string), n_qubits, std::string(cost_func), - std::string(ecc_path), std::string(gateset), timeout); -} \ No newline at end of file +// rust::String optimize(rust::String circ_string, rust::String cost_func, +// float timeout, +// std::unique_ptr super_context) { +// return optimize_(std::string(circ_string), std::string(cost_func), timeout, +// super_context); +// } + +// std::unique_ptr get_context(rust::String gate_set, int +// n_qubits, +// rust::String ecc_path) { +// return get_context_(std::string(gate_set), n_qubits, +// std::string(ecc_path)); +// } + +void test() { printf("Hello from C++!\n"); } \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.h b/src/wrapper/rust/wrapper.h index bab83c2d..32425129 100644 --- a/src/wrapper/rust/wrapper.h +++ b/src/wrapper/rust/wrapper.h @@ -1,4 +1,11 @@ +#include "oracle.h" #include "rust/cxx.h" -rust::String optimize(rust::String circ_string, int n_qubits, - rust::String cost_func, rust::String ecc_path, - rust::String gateset, float timeout); \ No newline at end of file +// rust::String optimize(rust::String circ_string, rust::String cost_func, +// float timeout, +// std::unique_ptr super_context); + +// std::unique_ptr get_context(rust::String gate_set, int +// n_qubits, +// rust::String ecc_path); + +void test(); \ No newline at end of file From 4832f0191dfbe2abd710fe5498c9731ae622e6cf Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 11 Mar 2024 16:46:47 -0400 Subject: [PATCH 05/38] update wrapper with shared_ptr --- src/wrapper/rust/oracle.cpp | 6 +++--- src/wrapper/rust/oracle.h | 6 +++--- src/wrapper/rust/test_wrapper.cpp | 11 +++++------ src/wrapper/rust/wrapper.cpp | 24 ++++++++++-------------- src/wrapper/rust/wrapper.h | 13 +++++-------- 5 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/wrapper/rust/oracle.cpp b/src/wrapper/rust/oracle.cpp index 6da67f69..6ca46a1e 100644 --- a/src/wrapper/rust/oracle.cpp +++ b/src/wrapper/rust/oracle.cpp @@ -1,16 +1,16 @@ #include "oracle.h" using namespace quartz; -std::unique_ptr get_context_(const std::string gate_set, +std::shared_ptr get_context_(const std::string gate_set, int n_qubits, const std::string ecc_path) { auto super_context = - std::make_unique(gate_set, n_qubits, ecc_path); + std::make_shared(gate_set, n_qubits, ecc_path); return super_context; } std::string optimize_(std::string circ_string, std::string cost_func, - float timeout, std::unique_ptr super_context + float timeout, std::shared_ptr super_context ) { auto graph = Graph::from_qasm_str(&super_context->ctx, circ_string); diff --git a/src/wrapper/rust/oracle.h b/src/wrapper/rust/oracle.h index c3455dd8..b6ba008d 100644 --- a/src/wrapper/rust/oracle.h +++ b/src/wrapper/rust/oracle.h @@ -8,8 +8,8 @@ using namespace quartz; class SuperContext { public: - Context ctx; ParamInfo param_info; + Context ctx; std::vector xfers; static Context createContext(const std::string &gate_set, int n_qubits, ParamInfo ¶m_info, @@ -57,9 +57,9 @@ class SuperContext { ~SuperContext() = default; }; -std::unique_ptr get_context_(const std::string gate_set, +std::shared_ptr get_context_(const std::string gate_set, int n_qubits, const std::string ecc_path); std::string optimize_(std::string circ_string, std::string cost_func, float timeout, - std::unique_ptr super_context); \ No newline at end of file + std::shared_ptr super_context); \ No newline at end of file diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp index 7d13b860..2573c6cc 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rust/test_wrapper.cpp @@ -27,11 +27,10 @@ int main() { cx q[15], q[19]; h q[21]; h q[21];)"); - auto supercontext = - get_context_("Nam", 24, - "/home/pengyul/quicr/soam/resources/quartz/build/" - "Nam_4_3_complete_ECC_set.json"); - std::cout << optimize_(my_circ, "Gate", 1000, std::move(supercontext)) - << std::endl; + auto supercontext = get_context_("Nam", 24, + "/home/pengyul/quicr/soam/resources/" + "Nam_4_3_complete_ECC_set.json"); + std::cout << optimize_(my_circ, "Gate", 1, supercontext) << std::endl; + std::cout << optimize_(my_circ, "Gate", 1, supercontext) << std::endl; return 0; } \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.cpp b/src/wrapper/rust/wrapper.cpp index 593a539c..459614af 100644 --- a/src/wrapper/rust/wrapper.cpp +++ b/src/wrapper/rust/wrapper.cpp @@ -1,18 +1,14 @@ #include "wrapper.h" #include -// rust::String optimize(rust::String circ_string, rust::String cost_func, -// float timeout, -// std::unique_ptr super_context) { -// return optimize_(std::string(circ_string), std::string(cost_func), timeout, -// super_context); -// } +rust::String optimize(rust::String circ_string, rust::String cost_func, + float timeout, + std::shared_ptr super_context) { + return optimize_(std::string(circ_string), std::string(cost_func), timeout, + super_context); +} -// std::unique_ptr get_context(rust::String gate_set, int -// n_qubits, -// rust::String ecc_path) { -// return get_context_(std::string(gate_set), n_qubits, -// std::string(ecc_path)); -// } - -void test() { printf("Hello from C++!\n"); } \ No newline at end of file +std::shared_ptr get_context(rust::String gate_set, int n_qubits, + rust::String ecc_path) { + return get_context_(std::string(gate_set), n_qubits, std::string(ecc_path)); +} \ No newline at end of file diff --git a/src/wrapper/rust/wrapper.h b/src/wrapper/rust/wrapper.h index 32425129..0ad95ba1 100644 --- a/src/wrapper/rust/wrapper.h +++ b/src/wrapper/rust/wrapper.h @@ -1,11 +1,8 @@ #include "oracle.h" #include "rust/cxx.h" -// rust::String optimize(rust::String circ_string, rust::String cost_func, -// float timeout, -// std::unique_ptr super_context); +rust::String optimize(rust::String circ_string, rust::String cost_func, + float timeout, + std::shared_ptr super_context); -// std::unique_ptr get_context(rust::String gate_set, int -// n_qubits, -// rust::String ecc_path); - -void test(); \ No newline at end of file +std::shared_ptr get_context(rust::String gate_set, int n_qubits, + rust::String ecc_path); \ No newline at end of file From 89024419a3180a0a087c7d96043be3a83256c147 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 11 Mar 2024 17:42:00 -0400 Subject: [PATCH 06/38] Remove unused arguments --- src/wrapper/rust/oracle.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wrapper/rust/oracle.h b/src/wrapper/rust/oracle.h index b6ba008d..912515ec 100644 --- a/src/wrapper/rust/oracle.h +++ b/src/wrapper/rust/oracle.h @@ -12,8 +12,7 @@ class SuperContext { Context ctx; std::vector xfers; static Context createContext(const std::string &gate_set, int n_qubits, - ParamInfo ¶m_info, - const std::string &ecc_path) { + ParamInfo ¶m_info) { std::vector gates; if (gate_set == "Nam") { gates = {GateType::input_qubit, GateType::input_param, GateType::cx, @@ -32,7 +31,7 @@ class SuperContext { SuperContext(const std::string &gate_set, int n_qubits, const std::string &ecc_path) : param_info(0), - ctx(createContext(gate_set, n_qubits, param_info, ecc_path)) { + ctx(createContext(gate_set, n_qubits, param_info)) { xfers = std::vector(); EquivalenceSet eqs; if (!eqs.load_json(&ctx, ecc_path, false)) { From 9e35f5405a6449ad7e69801a032d3296c468b925 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 11 Mar 2024 21:31:45 -0400 Subject: [PATCH 07/38] print less info --- src/quartz/tasograph/tasograph.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/quartz/tasograph/tasograph.cpp b/src/quartz/tasograph/tasograph.cpp index 07a0b9ec..ee53ed52 100644 --- a/src/quartz/tasograph/tasograph.cpp +++ b/src/quartz/tasograph/tasograph.cpp @@ -2046,8 +2046,9 @@ Graph::optimize(const std::vector &xfers, double cost_upper_bound, .count() / 1000.0 > timeout) { - std::cout << "Timeout. Program terminated. Best cost is " << best_cost - << std::endl; + // std::cout << "Timeout. Program terminated. Best cost is " << + // best_cost + // << std::endl; return best_graph; } if (new_graph == nullptr) From 71e5bb4de1b667128742a950fb80889c102bd76b Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 12 Mar 2024 15:37:47 -0400 Subject: [PATCH 08/38] Add rpc binding method --- src/wrapper/CMakeLists.txt | 6 +++++- src/wrapper/rust/test_wrapper.cpp | 24 ++++++++++++++++++++---- src/wrapper/rust/wrapper_rpc.cpp | 21 +++++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 src/wrapper/rust/wrapper_rpc.cpp diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index ea5ec45c..df6006ea 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories("..") link_directories("../..") -file(GLOB_RECURSE WRAPPER "test_wrapper.cpp") +file(GLOB_RECURSE WRAPPER "wrapper_rpc.cpp") file(GLOB_RECURSE ORACLE "oracle.cpp") add_library(oracle SHARED ${ORACLE}) @@ -11,3 +11,7 @@ add_library(oracle SHARED ${ORACLE}) add_executable(wrapper ${WRAPPER}) target_link_libraries(wrapper oracle) target_link_libraries(wrapper quartz_runtime) + +add_library(librpc STATIC IMPORTED) +set_property(TARGET librpc PROPERTY IMPORTED_LOCATION /home/pengyul/lib/usr/local/lib/librpc.a) +target_link_libraries(wrapper librpc) \ No newline at end of file diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp index 2573c6cc..8badd8d1 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rust/test_wrapper.cpp @@ -1,9 +1,10 @@ #include "oracle.h" #include "quartz/tasograph/substitution.h" #include "quartz/tasograph/tasograph.h" -using namespace quartz; -int main() { +#include +using namespace quartz; +void task() { std::string my_circ = std::string(R"(OPENQASM 2.0; include "qelib1.inc"; qreg q[24]; @@ -30,7 +31,22 @@ int main() { auto supercontext = get_context_("Nam", 24, "/home/pengyul/quicr/soam/resources/" "Nam_4_3_complete_ECC_set.json"); - std::cout << optimize_(my_circ, "Gate", 1, supercontext) << std::endl; - std::cout << optimize_(my_circ, "Gate", 1, supercontext) << std::endl; + for (int i = 0; i < 5; ++i) { + optimize_(my_circ, "Gate", 1, supercontext); + std::cout << "Optimization " << i << " done." << std::endl; + } +} + +int main() { + std::vector threads; + + // for (int i = 0; i < 64; ++i) { + // threads.emplace_back(task); + // } + + // for (auto& thread : threads) { + // thread.join(); + // } + task(); return 0; } \ No newline at end of file diff --git a/src/wrapper/rust/wrapper_rpc.cpp b/src/wrapper/rust/wrapper_rpc.cpp new file mode 100644 index 00000000..2768c6c5 --- /dev/null +++ b/src/wrapper/rust/wrapper_rpc.cpp @@ -0,0 +1,21 @@ +#include "oracle.h" +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" +#include "rpc/server.h" + +#include +using namespace quartz; + +int main(int argc, char **argv) { + int port = atoi(argv[1]); + auto supercontext = get_context_("Nam", 24, + "/home/pengyul/quicr/soam/resources/" + "Nam_4_3_complete_ECC_set.json"); + rpc::server srv(port); + srv.bind("optimize", [supercontext](std::string my_circ) { + return optimize_(my_circ, "Gate", 10, supercontext); + }); + srv.run(); + + return 0; +} \ No newline at end of file From 61ac6623d9a8e5dd1ce30b80e51b89805592c21f Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 12 Mar 2024 18:53:11 -0400 Subject: [PATCH 09/38] tiny update --- src/wrapper/rust/wrapper_rpc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/wrapper/rust/wrapper_rpc.cpp b/src/wrapper/rust/wrapper_rpc.cpp index 2768c6c5..9261b5ed 100644 --- a/src/wrapper/rust/wrapper_rpc.cpp +++ b/src/wrapper/rust/wrapper_rpc.cpp @@ -8,10 +8,11 @@ using namespace quartz; int main(int argc, char **argv) { int port = atoi(argv[1]); + + rpc::server srv(port); auto supercontext = get_context_("Nam", 24, "/home/pengyul/quicr/soam/resources/" "Nam_4_3_complete_ECC_set.json"); - rpc::server srv(port); srv.bind("optimize", [supercontext](std::string my_circ) { return optimize_(my_circ, "Gate", 10, supercontext); }); From 75c14ddab2169bfff4d5f9e627a79573e1329e0e Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 12 Mar 2024 20:31:17 -0400 Subject: [PATCH 10/38] more configurable --- src/wrapper/rust/wrapper_rpc.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/wrapper/rust/wrapper_rpc.cpp b/src/wrapper/rust/wrapper_rpc.cpp index 9261b5ed..6fd7fe34 100644 --- a/src/wrapper/rust/wrapper_rpc.cpp +++ b/src/wrapper/rust/wrapper_rpc.cpp @@ -7,14 +7,18 @@ using namespace quartz; int main(int argc, char **argv) { + if (argc != 7) { + std::cerr << "Usage: " << argv[0] + << " \n"; + return 1; + } int port = atoi(argv[1]); - + float timeout = atof(argv[5]); + int nqubits = atoi(argv[6]); rpc::server srv(port); - auto supercontext = get_context_("Nam", 24, - "/home/pengyul/quicr/soam/resources/" - "Nam_4_3_complete_ECC_set.json"); - srv.bind("optimize", [supercontext](std::string my_circ) { - return optimize_(my_circ, "Gate", 10, supercontext); + auto supercontext = get_context_(argv[2], nqubits, argv[3]); + srv.bind("optimize", [supercontext, timeout, argv](std::string my_circ) { + return optimize_(my_circ, argv[4], timeout, supercontext); }); srv.run(); From b07aa07e56baf24f2c2db0271cac44e7648c5cfa Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 13 Mar 2024 11:02:10 -0400 Subject: [PATCH 11/38] Add an example for debugging --- src/test/gen_ecc_set.cpp | 35 +++++++++++------------ src/wrapper/CMakeLists.txt | 9 +++++- src/wrapper/rust/test_wrapper.cpp | 46 ++----------------------------- src/wrapper/rust/wrapper_rpc.cpp | 1 + 4 files changed, 30 insertions(+), 61 deletions(-) diff --git a/src/test/gen_ecc_set.cpp b/src/test/gen_ecc_set.cpp index 6ae78694..dd09fa1b 100644 --- a/src/test/gen_ecc_set.cpp +++ b/src/test/gen_ecc_set.cpp @@ -12,8 +12,9 @@ int main() { // gen_ecc_set({GateType::u1, GateType::u2, GateType::u3, GateType::cx, // GateType::add}, // "IBM_3_3_", true, 3, 4, 3); - gen_ecc_set({GateType::h, GateType::cz}, "eccset/H_CZ_2_2_", true, false, 2, - 0, 2); + // gen_ecc_set({GateType::h, GateType::cz}, "eccset/H_CZ_2_2_", true, false, + // 2, + // 0, 2); // for (int n = 5; n <= 8; n++) { // std::string file_prefix = "Rigetti_"; // file_prefix += std::to_string(n); @@ -24,20 +25,20 @@ int main() { // gen_ecc_set({GateType::u1, GateType::u2, GateType::u3, GateType::cx, // GateType::add}, // "IBM_4_3_", true, 3, 4, 4); - // for (int n = 2; n <= 4; n++) { - // for (int q = 3; q <= 3; q++) { - // std::string file_prefix = "Nam_"; - // file_prefix += std::to_string(n); - // file_prefix += "_"; - // file_prefix += std::to_string(q); - // file_prefix += "_"; - // gen_ecc_set( - // {GateType::rz, GateType::h, GateType::cx, GateType::x, - // GateType::add}, file_prefix, true, true, q, 2, n); - // } - // } - gen_ecc_set({GateType::t, GateType::tdg, GateType::h, GateType::x, - GateType::cx, GateType::add}, - "eccset/Clifford_T_5_3_", true, false, 3, 0, 5); + for (int n = 5; n <= 5; n++) { + for (int q = 3; q <= 3; q++) { + std::string file_prefix = "Nam_"; + file_prefix += std::to_string(n); + file_prefix += "_"; + file_prefix += std::to_string(q); + file_prefix += "_"; + gen_ecc_set( + {GateType::rz, GateType::h, GateType::cx, GateType::x, GateType::add}, + file_prefix, true, true, q, 2, n); + } + } + // gen_ecc_set({GateType::t, GateType::tdg, GateType::h, GateType::x, + // GateType::cx, GateType::add}, + // "eccset/Clifford_T_5_3_", true, false, 3, 0, 5); return 0; } diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index df6006ea..0111608f 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -4,14 +4,21 @@ include_directories("..") link_directories("../..") file(GLOB_RECURSE WRAPPER "wrapper_rpc.cpp") +file(GLOB_RECURSE TEST_WRAPPER "test_wrapper.cpp") file(GLOB_RECURSE ORACLE "oracle.cpp") add_library(oracle SHARED ${ORACLE}) add_executable(wrapper ${WRAPPER}) +add_executable(test_wrapper ${TEST_WRAPPER}) + target_link_libraries(wrapper oracle) target_link_libraries(wrapper quartz_runtime) +target_link_libraries(test_wrapper oracle) +target_link_libraries(test_wrapper quartz_runtime) + add_library(librpc STATIC IMPORTED) set_property(TARGET librpc PROPERTY IMPORTED_LOCATION /home/pengyul/lib/usr/local/lib/librpc.a) -target_link_libraries(wrapper librpc) \ No newline at end of file +target_link_libraries(wrapper librpc) +target_link_libraries(test_wrapper librpc) \ No newline at end of file diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rust/test_wrapper.cpp index 8badd8d1..e5aa55a9 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rust/test_wrapper.cpp @@ -1,52 +1,12 @@ #include "oracle.h" #include "quartz/tasograph/substitution.h" #include "quartz/tasograph/tasograph.h" - -#include using namespace quartz; -void task() { - std::string my_circ = std::string(R"(OPENQASM 2.0; - include "qelib1.inc"; - qreg q[24]; - cx q[5], q[8]; - rz(-0.123) q[11]; - rz(-0.234) q[12]; - rz(-0.7853981633974483) q[18]; - rz(-0.7853981633974483) q[19]; - cx q[5], q[6]; - rz(0.7853981633974483) q[8]; - cx q[12], q[11]; - cx q[19], q[18]; - rz(-0.7853981633974483) q[6]; - h q[8]; - cx q[12], q[14]; - cx q[19], q[21]; - cx q[5], q[6]; - cx q[8], q[10]; - cx q[9], q[12]; - h q[14]; - cx q[15], q[19]; - h q[21]; - h q[21];)"); - auto supercontext = get_context_("Nam", 24, - "/home/pengyul/quicr/soam/resources/" - "Nam_4_3_complete_ECC_set.json"); - for (int i = 0; i < 5; ++i) { - optimize_(my_circ, "Gate", 1, supercontext); - std::cout << "Optimization " << i << " done." << std::endl; - } -} int main() { - std::vector threads; - - // for (int i = 0; i < 64; ++i) { - // threads.emplace_back(task); - // } + auto supercontext = get_context_( + "Nam", 48, + "/home/pengyul/quicr/soam/resources/Nam_4_3_complete_ECC_set.json"); - // for (auto& thread : threads) { - // thread.join(); - // } - task(); return 0; } \ No newline at end of file diff --git a/src/wrapper/rust/wrapper_rpc.cpp b/src/wrapper/rust/wrapper_rpc.cpp index 6fd7fe34..b2d11bd6 100644 --- a/src/wrapper/rust/wrapper_rpc.cpp +++ b/src/wrapper/rust/wrapper_rpc.cpp @@ -17,6 +17,7 @@ int main(int argc, char **argv) { int nqubits = atoi(argv[6]); rpc::server srv(port); auto supercontext = get_context_(argv[2], nqubits, argv[3]); + std::cout << "Server started on port " << port << std::endl; srv.bind("optimize", [supercontext, timeout, argv](std::string my_circ) { return optimize_(my_circ, argv[4], timeout, supercontext); }); From 5b155af9d20ea213d75896047962a494105dc758 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 13 Mar 2024 18:40:12 -0400 Subject: [PATCH 12/38] Reorganize files --- src/wrapper/CMakeLists.txt | 20 +++++++++---------- src/wrapper/{rust => }/oracle.cpp | 0 src/wrapper/{rust => }/oracle.h | 0 .../test_wrapper.cpp => rpc/test_rpc.cpp} | 2 +- src/wrapper/{rust => rpc}/wrapper_rpc.cpp | 4 ++-- .../rust/{wrapper.cpp => wrapper_rust.cpp} | 0 .../rust/{wrapper.h => wrapper_rust.h} | 0 7 files changed, 13 insertions(+), 13 deletions(-) rename src/wrapper/{rust => }/oracle.cpp (100%) rename src/wrapper/{rust => }/oracle.h (100%) rename src/wrapper/{rust/test_wrapper.cpp => rpc/test_rpc.cpp} (90%) rename src/wrapper/{rust => rpc}/wrapper_rpc.cpp (89%) rename src/wrapper/rust/{wrapper.cpp => wrapper_rust.cpp} (100%) rename src/wrapper/rust/{wrapper.h => wrapper_rust.h} (100%) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 0111608f..4e022cc0 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -3,22 +3,22 @@ include_directories("..") link_directories("../..") -file(GLOB_RECURSE WRAPPER "wrapper_rpc.cpp") -file(GLOB_RECURSE TEST_WRAPPER "test_wrapper.cpp") +file(GLOB_RECURSE WRAPPER_RPC "rpc/wrapper_rpc.cpp") +file(GLOB_RECURSE TEST_RPC "rpc/test_rpc.cpp") file(GLOB_RECURSE ORACLE "oracle.cpp") add_library(oracle SHARED ${ORACLE}) -add_executable(wrapper ${WRAPPER}) -add_executable(test_wrapper ${TEST_WRAPPER}) +add_executable(wrapper_rpc ${WRAPPER_RPC}) +add_executable(test_rpc ${TEST_RPC}) -target_link_libraries(wrapper oracle) -target_link_libraries(wrapper quartz_runtime) +target_link_libraries(wrapper_rpc oracle) +target_link_libraries(wrapper_rpc quartz_runtime) -target_link_libraries(test_wrapper oracle) -target_link_libraries(test_wrapper quartz_runtime) +target_link_libraries(test_rpc oracle) +target_link_libraries(test_rpc quartz_runtime) add_library(librpc STATIC IMPORTED) set_property(TARGET librpc PROPERTY IMPORTED_LOCATION /home/pengyul/lib/usr/local/lib/librpc.a) -target_link_libraries(wrapper librpc) -target_link_libraries(test_wrapper librpc) \ No newline at end of file +target_link_libraries(wrapper_rpc librpc) +target_link_libraries(test_rpc librpc) \ No newline at end of file diff --git a/src/wrapper/rust/oracle.cpp b/src/wrapper/oracle.cpp similarity index 100% rename from src/wrapper/rust/oracle.cpp rename to src/wrapper/oracle.cpp diff --git a/src/wrapper/rust/oracle.h b/src/wrapper/oracle.h similarity index 100% rename from src/wrapper/rust/oracle.h rename to src/wrapper/oracle.h diff --git a/src/wrapper/rust/test_wrapper.cpp b/src/wrapper/rpc/test_rpc.cpp similarity index 90% rename from src/wrapper/rust/test_wrapper.cpp rename to src/wrapper/rpc/test_rpc.cpp index e5aa55a9..8f99f7e7 100644 --- a/src/wrapper/rust/test_wrapper.cpp +++ b/src/wrapper/rpc/test_rpc.cpp @@ -1,6 +1,6 @@ -#include "oracle.h" #include "quartz/tasograph/substitution.h" #include "quartz/tasograph/tasograph.h" +#include "wrapper/oracle.h" using namespace quartz; int main() { diff --git a/src/wrapper/rust/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp similarity index 89% rename from src/wrapper/rust/wrapper_rpc.cpp rename to src/wrapper/rpc/wrapper_rpc.cpp index b2d11bd6..e8d9797d 100644 --- a/src/wrapper/rust/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -1,7 +1,7 @@ -#include "oracle.h" #include "quartz/tasograph/substitution.h" #include "quartz/tasograph/tasograph.h" #include "rpc/server.h" +#include "wrapper/oracle.h" #include using namespace quartz; @@ -16,7 +16,7 @@ int main(int argc, char **argv) { float timeout = atof(argv[5]); int nqubits = atoi(argv[6]); rpc::server srv(port); - auto supercontext = get_context_(argv[2], nqubits, argv[3]); + auto supercontext = get_context_(argv[2], 1, argv[3]); std::cout << "Server started on port " << port << std::endl; srv.bind("optimize", [supercontext, timeout, argv](std::string my_circ) { return optimize_(my_circ, argv[4], timeout, supercontext); diff --git a/src/wrapper/rust/wrapper.cpp b/src/wrapper/rust/wrapper_rust.cpp similarity index 100% rename from src/wrapper/rust/wrapper.cpp rename to src/wrapper/rust/wrapper_rust.cpp diff --git a/src/wrapper/rust/wrapper.h b/src/wrapper/rust/wrapper_rust.h similarity index 100% rename from src/wrapper/rust/wrapper.h rename to src/wrapper/rust/wrapper_rust.h From 5917041b439c6edb876adec49338ba99d22b82e2 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Sat, 16 Mar 2024 16:00:13 -0400 Subject: [PATCH 13/38] Support CliffordT gateset --- src/wrapper/oracle.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index 912515ec..44c78988 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -19,8 +19,9 @@ class SuperContext { GateType::h, GateType::rz, GateType::x, GateType::add}; } else if (gate_set == "CliffordT") { - std::cerr << "Not implemented yet." << std::endl; - assert(false); + gates = {GateType::input_qubit, GateType::input_param, GateType::t, + GateType::tdg, GateType::h, GateType::x, + GateType::cx, GateType::add}; } else { std::cerr << "Invalid gate set." << std::endl; assert(false); @@ -30,8 +31,7 @@ class SuperContext { } SuperContext(const std::string &gate_set, int n_qubits, const std::string &ecc_path) - : param_info(0), - ctx(createContext(gate_set, n_qubits, param_info)) { + : param_info(0), ctx(createContext(gate_set, n_qubits, param_info)) { xfers = std::vector(); EquivalenceSet eqs; if (!eqs.load_json(&ctx, ecc_path, false)) { From 7ed6d6341b0de02006807908d4fc444199e1a7c3 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 19 Mar 2024 15:51:05 -0400 Subject: [PATCH 14/38] Add preprocess script --- src/test/CMakeLists.txt | 3 ++ src/test/preprocess.cpp | 71 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/test/preprocess.cpp diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index dc4fbe77..420cbc3c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -32,6 +32,8 @@ file(GLOB_RECURSE TEST_FROM_AND_TO_QASM "test_from_and_to_qasm.cpp") file(GLOB_RECURSE TEST_OPTIMIZE "test_optimize.cpp") file(GLOB_RECURSE TEST_CREATE_GRAPHXFER_FROM_QASM "test_create_graphXfer_from_qasm.cpp") file(GLOB_RECURSE TEST_PARTITION "test_partition.cpp") +file(GLOB_RECURSE PREPROCESS "preprocess.cpp") + if(USE_ARBLIB) file(GLOB_RECURSE TEST_ARB "test_arb.cpp") endif() @@ -68,6 +70,7 @@ add_executable(test_from_and_to_qasm ${TEST_FROM_AND_TO_QASM} ) add_executable(test_optimize ${TEST_OPTIMIZE} ) add_executable(test_create_graphXfer_from_qasm ${TEST_CREATE_GRAPHXFER_FROM_QASM} ) add_executable(test_partition ${TEST_PARTITION} ) +add_executable(preprocess ${PREPROCESS} ) if(USE_ARBLIB) add_executable(test_arb ${TEST_ARB} ) endif() diff --git a/src/test/preprocess.cpp b/src/test/preprocess.cpp new file mode 100644 index 00000000..5f6a4e8f --- /dev/null +++ b/src/test/preprocess.cpp @@ -0,0 +1,71 @@ + +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" + +using namespace quartz; + +void parse_args(char **argv, int argc, std::string &input_filename) { + assert(argv[1] != nullptr); + input_filename = std::string(argv[1]); +} + +int main(int argc, char **argv) { + std::string input_fn; + + parse_args(argv, argc, input_fn); + std::cout << "input_fn: " << input_fn << std::endl; + auto fn = input_fn.substr(input_fn.rfind('/') + 1); + auto param_info = ParamInfo(0); + Context src_ctx({GateType::h, GateType::ccz, GateType::x, GateType::cx, + GateType::add, GateType::input_qubit, GateType::input_param}, + 3, ¶m_info); + Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add, + GateType::cx, GateType::input_qubit, GateType::input_param}, + 3, ¶m_info); + Context dst2_ctx({GateType::h, GateType::x, GateType::t, GateType::tdg, + GateType::s, GateType::sdg, GateType::z, GateType::add, + GateType::cx, GateType::input_qubit, GateType::input_param}, + 3, ¶m_info); + + auto union_ctx = union_contexts(&src_ctx, &dst_ctx); + auto union2_ctx = union_contexts(&dst_ctx, &dst2_ctx); + + auto xfer_pair = GraphXfer::ccz_cx_rz_xfer(&src_ctx, &dst_ctx, &union_ctx); + // Load qasm file + QASMParser qasm_parser(&src_ctx); + CircuitSeq *dag = nullptr; + if (!qasm_parser.load_qasm(input_fn, dag)) { + std::cout << "Parser failed" << std::endl; + } + Graph graph(&src_ctx, dag); + + std::shared_ptr graph_before_search; + + // Greedy toffoli flip + graph_before_search = graph.toffoli_flip_greedy(GateType::rz, xfer_pair.first, + xfer_pair.second); + // graph_before_search->to_qasm(input_fn + ".toffoli_flip", false, false); + std::cout << "toffoli flip + rotation merging done" << std::endl; + + // O(n) rz -> t + graph_before_search->context = &union2_ctx; + auto graph_seq = graph_before_search->to_circuit_sequence(); + auto rz_to_t_seq = graph_seq->get_rz_to_t(&union2_ctx); + auto newGraph = std::make_shared(&dst2_ctx, rz_to_t_seq.get()); + // O(n^2) rz -> t + + // std::cout << "rz -> t done" << std::endl; + + // std::cout << "Optimization results of Quartz for " << fn + // << " on Clifford+T gate set." + // << " Gate count after optimization: " << newGraph->gate_count() + // << ", " + // << "T Count: " + // << newGraph->specific_gate_count(GateType::t) + + // newGraph->specific_gate_count(GateType::tdg) + // << ", " + // << "Circuit depth: " << newGraph->circuit_depth(); + + newGraph->to_qasm(input_fn + ".optimized", false, false); + return 0; +} From fe5193885dda28faf733e58b94af4ab0b9e4056e Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 19 Mar 2024 15:53:46 -0400 Subject: [PATCH 15/38] ecc set with s gate --- src/test/gen_ecc_set.cpp | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/test/gen_ecc_set.cpp b/src/test/gen_ecc_set.cpp index dd09fa1b..71c81a5a 100644 --- a/src/test/gen_ecc_set.cpp +++ b/src/test/gen_ecc_set.cpp @@ -25,20 +25,25 @@ int main() { // gen_ecc_set({GateType::u1, GateType::u2, GateType::u3, GateType::cx, // GateType::add}, // "IBM_4_3_", true, 3, 4, 4); - for (int n = 5; n <= 5; n++) { - for (int q = 3; q <= 3; q++) { - std::string file_prefix = "Nam_"; - file_prefix += std::to_string(n); - file_prefix += "_"; - file_prefix += std::to_string(q); - file_prefix += "_"; - gen_ecc_set( - {GateType::rz, GateType::h, GateType::cx, GateType::x, GateType::add}, - file_prefix, true, true, q, 2, n); - } - } - // gen_ecc_set({GateType::t, GateType::tdg, GateType::h, GateType::x, - // GateType::cx, GateType::add}, - // "eccset/Clifford_T_5_3_", true, false, 3, 0, 5); + // for (int n = 5; n <= 5; n++) { + // for (int q = 3; q <= 3; q++) { + // std::string file_prefix = "Nam_"; + // file_prefix += std::to_string(n); + // file_prefix += "_"; + // file_prefix += std::to_string(q); + // file_prefix += "_"; + // gen_ecc_set( + // {GateType::rz, GateType::h, GateType::cx, GateType::x, + // GateType::add}, file_prefix, true, true, q, 2, n); + // } + // } + // GateType::h, GateType::x, GateType::t, GateType::tdg, + // GateType::s, GateType::sdg, GateType::z, GateType::add, + // GateType::cx, GateType::input_qubit, + // GateType::input_param + gen_ecc_set({GateType::h, GateType::x, GateType::t, GateType::tdg, + GateType::s, GateType::sdg, GateType::z, GateType::cx, + GateType::add}, + "Clifford_T_5_3_", true, false, 3, 0, 5); return 0; } From ea4fa2ba88711a820db63dcf89865a0ede7212a0 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 19 Mar 2024 22:51:03 -0400 Subject: [PATCH 16/38] Add s and z to Clifford gateset --- src/wrapper/oracle.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index 44c78988..b988a7bf 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -19,8 +19,9 @@ class SuperContext { GateType::h, GateType::rz, GateType::x, GateType::add}; } else if (gate_set == "CliffordT") { - gates = {GateType::input_qubit, GateType::input_param, GateType::t, - GateType::tdg, GateType::h, GateType::x, + gates = {GateType::input_qubit, GateType::input_param, GateType::h, + GateType::x, GateType::t, GateType::tdg, + GateType::s, GateType::sdg, GateType::z, GateType::cx, GateType::add}; } else { std::cerr << "Invalid gate set." << std::endl; From 292989ea9975beb3bacfac8667e6d35267a63e0d Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 19 Mar 2024 22:51:17 -0400 Subject: [PATCH 17/38] Add preprocessing with only rotation merging --- src/test/CMakeLists.txt | 2 ++ src/test/preprocess_rotation_merging.cpp | 35 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 src/test/preprocess_rotation_merging.cpp diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 420cbc3c..f036e63d 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -33,6 +33,7 @@ file(GLOB_RECURSE TEST_OPTIMIZE "test_optimize.cpp") file(GLOB_RECURSE TEST_CREATE_GRAPHXFER_FROM_QASM "test_create_graphXfer_from_qasm.cpp") file(GLOB_RECURSE TEST_PARTITION "test_partition.cpp") file(GLOB_RECURSE PREPROCESS "preprocess.cpp") +file(GLOB_RECURSE PREPROCESS_ROT "preprocess_rotation_merging.cpp") if(USE_ARBLIB) file(GLOB_RECURSE TEST_ARB "test_arb.cpp") @@ -71,6 +72,7 @@ add_executable(test_optimize ${TEST_OPTIMIZE} ) add_executable(test_create_graphXfer_from_qasm ${TEST_CREATE_GRAPHXFER_FROM_QASM} ) add_executable(test_partition ${TEST_PARTITION} ) add_executable(preprocess ${PREPROCESS} ) +add_executable(preprocess_rotation_merging ${PREPROCESS_ROT} ) if(USE_ARBLIB) add_executable(test_arb ${TEST_ARB} ) endif() diff --git a/src/test/preprocess_rotation_merging.cpp b/src/test/preprocess_rotation_merging.cpp new file mode 100644 index 00000000..74ddae04 --- /dev/null +++ b/src/test/preprocess_rotation_merging.cpp @@ -0,0 +1,35 @@ + +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" + +using namespace quartz; + +void parse_args(char **argv, int argc, std::string &input_filename) { + assert(argv[1] != nullptr); + input_filename = std::string(argv[1]); +} + +int main(int argc, char **argv) { + std::string input_fn; + + parse_args(argv, argc, input_fn); + std::cout << "input_fn: " << input_fn << std::endl; + auto fn = input_fn.substr(input_fn.rfind('/') + 1); + auto param_info = ParamInfo(0); + + Context ctx({GateType::h, GateType::x, GateType::rz, GateType::add, + GateType::cx, GateType::input_qubit, GateType::input_param}, + 3, ¶m_info); + + // Load qasm file + QASMParser qasm_parser(&ctx); + CircuitSeq *dag = nullptr; + if (!qasm_parser.load_qasm(input_fn, dag)) { + std::cout << "Parser failed" << std::endl; + } + + Graph graph(&ctx, dag); + graph.rotation_merging(GateType::rz); + graph.to_qasm(input_fn + ".optimized", false, false); + return 0; +} From 85de200e50275fb0f56209840a40b0c054e53881 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 27 Mar 2024 12:56:57 -0400 Subject: [PATCH 18/38] configurable preprocess --- src/test/preprocess.cpp | 71 ++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/test/preprocess.cpp b/src/test/preprocess.cpp index 5f6a4e8f..17647bf0 100644 --- a/src/test/preprocess.cpp +++ b/src/test/preprocess.cpp @@ -4,21 +4,39 @@ using namespace quartz; -void parse_args(char **argv, int argc, std::string &input_filename) { +void parse_args(char **argv, int argc, bool &rm_only, std::string &target_gates, + std::string &input_filename) { assert(argv[1] != nullptr); - input_filename = std::string(argv[1]); + assert(argv[2] != nullptr); + assert(argv[3] != nullptr); + rm_only = std::string(argv[1]) == "rmonly"; + target_gates = std::string(argv[2]); + input_filename = std::string(argv[3]); } int main(int argc, char **argv) { std::string input_fn; + bool rm_only; + std::string target_gates; + parse_args(argv, argc, rm_only, target_gates, input_fn); - parse_args(argv, argc, input_fn); std::cout << "input_fn: " << input_fn << std::endl; auto fn = input_fn.substr(input_fn.rfind('/') + 1); auto param_info = ParamInfo(0); - Context src_ctx({GateType::h, GateType::ccz, GateType::x, GateType::cx, - GateType::add, GateType::input_qubit, GateType::input_param}, - 3, ¶m_info); + auto gates = std::vector{}; + if (!rm_only) { + gates = std::vector{GateType::h, GateType::ccz, + GateType::x, GateType::cx, + GateType::add, GateType::input_qubit, + GateType::input_param}; + } else { + gates = std::vector{GateType::h, GateType::x, + GateType::rz, GateType::add, + GateType::cx, GateType::input_qubit, + GateType::input_param}; + } + + Context src_ctx(gates, 3, ¶m_info); Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add, GateType::cx, GateType::input_qubit, GateType::input_param}, 3, ¶m_info); @@ -30,7 +48,6 @@ int main(int argc, char **argv) { auto union_ctx = union_contexts(&src_ctx, &dst_ctx); auto union2_ctx = union_contexts(&dst_ctx, &dst2_ctx); - auto xfer_pair = GraphXfer::ccz_cx_rz_xfer(&src_ctx, &dst_ctx, &union_ctx); // Load qasm file QASMParser qasm_parser(&src_ctx); CircuitSeq *dag = nullptr; @@ -39,32 +56,28 @@ int main(int argc, char **argv) { } Graph graph(&src_ctx, dag); - std::shared_ptr graph_before_search; + std::shared_ptr newGraph; // Greedy toffoli flip - graph_before_search = graph.toffoli_flip_greedy(GateType::rz, xfer_pair.first, - xfer_pair.second); - // graph_before_search->to_qasm(input_fn + ".toffoli_flip", false, false); - std::cout << "toffoli flip + rotation merging done" << std::endl; + if (!rm_only) { + auto xfer_pair = GraphXfer::ccz_cx_rz_xfer(&src_ctx, &dst_ctx, &union_ctx); + newGraph = graph.toffoli_flip_greedy(GateType::rz, xfer_pair.first, + xfer_pair.second); + // graph_before_search->to_qasm(input_fn + ".toffoli_flip", false, false); + std::cout << "toffoli flip + rotation merging done" << std::endl; + } else { + graph.rotation_merging(GateType::rz); + newGraph = + std::make_shared(&dst_ctx, graph.to_circuit_sequence().get()); + } // O(n) rz -> t - graph_before_search->context = &union2_ctx; - auto graph_seq = graph_before_search->to_circuit_sequence(); - auto rz_to_t_seq = graph_seq->get_rz_to_t(&union2_ctx); - auto newGraph = std::make_shared(&dst2_ctx, rz_to_t_seq.get()); - // O(n^2) rz -> t - - // std::cout << "rz -> t done" << std::endl; - - // std::cout << "Optimization results of Quartz for " << fn - // << " on Clifford+T gate set." - // << " Gate count after optimization: " << newGraph->gate_count() - // << ", " - // << "T Count: " - // << newGraph->specific_gate_count(GateType::t) + - // newGraph->specific_gate_count(GateType::tdg) - // << ", " - // << "Circuit depth: " << newGraph->circuit_depth(); + if (target_gates == "clifford") { + newGraph->context = &union2_ctx; + auto graph_seq = newGraph->to_circuit_sequence(); + auto rz_to_t_seq = graph_seq->get_rz_to_t(&union2_ctx); + auto newGraph = std::make_shared(&dst2_ctx, rz_to_t_seq.get()); + } newGraph->to_qasm(input_fn + ".optimized", false, false); return 0; From 8df070f8c27392924ff4eaba4e040172907203f4 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 1 Apr 2024 14:00:01 -0400 Subject: [PATCH 19/38] Remove unused files --- src/test/CMakeLists.txt | 4 -- src/test/preprocess.cpp | 84 ------------------------ src/test/preprocess_rotation_merging.cpp | 35 ---------- 3 files changed, 123 deletions(-) delete mode 100644 src/test/preprocess.cpp delete mode 100644 src/test/preprocess_rotation_merging.cpp diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index f036e63d..70644f4c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -32,8 +32,6 @@ file(GLOB_RECURSE TEST_FROM_AND_TO_QASM "test_from_and_to_qasm.cpp") file(GLOB_RECURSE TEST_OPTIMIZE "test_optimize.cpp") file(GLOB_RECURSE TEST_CREATE_GRAPHXFER_FROM_QASM "test_create_graphXfer_from_qasm.cpp") file(GLOB_RECURSE TEST_PARTITION "test_partition.cpp") -file(GLOB_RECURSE PREPROCESS "preprocess.cpp") -file(GLOB_RECURSE PREPROCESS_ROT "preprocess_rotation_merging.cpp") if(USE_ARBLIB) file(GLOB_RECURSE TEST_ARB "test_arb.cpp") @@ -71,8 +69,6 @@ add_executable(test_from_and_to_qasm ${TEST_FROM_AND_TO_QASM} ) add_executable(test_optimize ${TEST_OPTIMIZE} ) add_executable(test_create_graphXfer_from_qasm ${TEST_CREATE_GRAPHXFER_FROM_QASM} ) add_executable(test_partition ${TEST_PARTITION} ) -add_executable(preprocess ${PREPROCESS} ) -add_executable(preprocess_rotation_merging ${PREPROCESS_ROT} ) if(USE_ARBLIB) add_executable(test_arb ${TEST_ARB} ) endif() diff --git a/src/test/preprocess.cpp b/src/test/preprocess.cpp deleted file mode 100644 index 17647bf0..00000000 --- a/src/test/preprocess.cpp +++ /dev/null @@ -1,84 +0,0 @@ - -#include "quartz/tasograph/substitution.h" -#include "quartz/tasograph/tasograph.h" - -using namespace quartz; - -void parse_args(char **argv, int argc, bool &rm_only, std::string &target_gates, - std::string &input_filename) { - assert(argv[1] != nullptr); - assert(argv[2] != nullptr); - assert(argv[3] != nullptr); - rm_only = std::string(argv[1]) == "rmonly"; - target_gates = std::string(argv[2]); - input_filename = std::string(argv[3]); -} - -int main(int argc, char **argv) { - std::string input_fn; - bool rm_only; - std::string target_gates; - parse_args(argv, argc, rm_only, target_gates, input_fn); - - std::cout << "input_fn: " << input_fn << std::endl; - auto fn = input_fn.substr(input_fn.rfind('/') + 1); - auto param_info = ParamInfo(0); - auto gates = std::vector{}; - if (!rm_only) { - gates = std::vector{GateType::h, GateType::ccz, - GateType::x, GateType::cx, - GateType::add, GateType::input_qubit, - GateType::input_param}; - } else { - gates = std::vector{GateType::h, GateType::x, - GateType::rz, GateType::add, - GateType::cx, GateType::input_qubit, - GateType::input_param}; - } - - Context src_ctx(gates, 3, ¶m_info); - Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add, - GateType::cx, GateType::input_qubit, GateType::input_param}, - 3, ¶m_info); - Context dst2_ctx({GateType::h, GateType::x, GateType::t, GateType::tdg, - GateType::s, GateType::sdg, GateType::z, GateType::add, - GateType::cx, GateType::input_qubit, GateType::input_param}, - 3, ¶m_info); - - auto union_ctx = union_contexts(&src_ctx, &dst_ctx); - auto union2_ctx = union_contexts(&dst_ctx, &dst2_ctx); - - // Load qasm file - QASMParser qasm_parser(&src_ctx); - CircuitSeq *dag = nullptr; - if (!qasm_parser.load_qasm(input_fn, dag)) { - std::cout << "Parser failed" << std::endl; - } - Graph graph(&src_ctx, dag); - - std::shared_ptr newGraph; - - // Greedy toffoli flip - if (!rm_only) { - auto xfer_pair = GraphXfer::ccz_cx_rz_xfer(&src_ctx, &dst_ctx, &union_ctx); - - newGraph = graph.toffoli_flip_greedy(GateType::rz, xfer_pair.first, - xfer_pair.second); - // graph_before_search->to_qasm(input_fn + ".toffoli_flip", false, false); - std::cout << "toffoli flip + rotation merging done" << std::endl; - } else { - graph.rotation_merging(GateType::rz); - newGraph = - std::make_shared(&dst_ctx, graph.to_circuit_sequence().get()); - } - // O(n) rz -> t - if (target_gates == "clifford") { - newGraph->context = &union2_ctx; - auto graph_seq = newGraph->to_circuit_sequence(); - auto rz_to_t_seq = graph_seq->get_rz_to_t(&union2_ctx); - auto newGraph = std::make_shared(&dst2_ctx, rz_to_t_seq.get()); - } - - newGraph->to_qasm(input_fn + ".optimized", false, false); - return 0; -} diff --git a/src/test/preprocess_rotation_merging.cpp b/src/test/preprocess_rotation_merging.cpp deleted file mode 100644 index 74ddae04..00000000 --- a/src/test/preprocess_rotation_merging.cpp +++ /dev/null @@ -1,35 +0,0 @@ - -#include "quartz/tasograph/substitution.h" -#include "quartz/tasograph/tasograph.h" - -using namespace quartz; - -void parse_args(char **argv, int argc, std::string &input_filename) { - assert(argv[1] != nullptr); - input_filename = std::string(argv[1]); -} - -int main(int argc, char **argv) { - std::string input_fn; - - parse_args(argv, argc, input_fn); - std::cout << "input_fn: " << input_fn << std::endl; - auto fn = input_fn.substr(input_fn.rfind('/') + 1); - auto param_info = ParamInfo(0); - - Context ctx({GateType::h, GateType::x, GateType::rz, GateType::add, - GateType::cx, GateType::input_qubit, GateType::input_param}, - 3, ¶m_info); - - // Load qasm file - QASMParser qasm_parser(&ctx); - CircuitSeq *dag = nullptr; - if (!qasm_parser.load_qasm(input_fn, dag)) { - std::cout << "Parser failed" << std::endl; - } - - Graph graph(&ctx, dag); - graph.rotation_merging(GateType::rz); - graph.to_qasm(input_fn + ".optimized", false, false); - return 0; -} From 7b4e263026ae20de55e5e57af062423ff5fb954e Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 1 Apr 2024 14:00:15 -0400 Subject: [PATCH 20/38] Support greedy opt with xfers --- src/quartz/tasograph/tasograph.cpp | 61 ++++++++++++++++++++++++++++-- src/quartz/tasograph/tasograph.h | 4 ++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/quartz/tasograph/tasograph.cpp b/src/quartz/tasograph/tasograph.cpp index efbb5953..72c5d987 100644 --- a/src/quartz/tasograph/tasograph.cpp +++ b/src/quartz/tasograph/tasograph.cpp @@ -1554,6 +1554,64 @@ void Graph::draw_circuit(const std::string &src_file_name, .c_str()); } +std::shared_ptr +Graph::greedy_optimize_with_xfer(const std::vector &xfers, + bool print_message, + std::function cost_function) { + if (cost_function == nullptr) { + cost_function = [](Graph *graph) { return graph->total_cost(); }; + } + + EquivalenceSet eqs; + // Load equivalent dags from file + + auto original_cost = cost_function(this); + + // Get xfers that strictly reduce the cost from the ECC set + + if (print_message) { + std::cout << "greedy_optimize(): Number of xfers that reduce cost: " + << xfers.size() << std::endl; + } + + std::shared_ptr optimized_graph = std::make_shared(*this); + bool optimized_in_this_iteration; + std::vector all_nodes; + optimized_graph->topology_order_ops(all_nodes); + do { + optimized_in_this_iteration = false; + for (auto xfer : xfers) { + bool optimized_this_xfer; + do { + optimized_this_xfer = false; + for (auto const &node : all_nodes) { + auto new_graph = optimized_graph->apply_xfer( + xfer, node, context->has_parameterized_gate()); + if (new_graph) { + optimized_graph.swap(new_graph); + // Update the wires after applying a transformation. + all_nodes.clear(); + optimized_graph->topology_order_ops(all_nodes); + optimized_this_xfer = true; + optimized_in_this_iteration = true; + // Since |all_nodes| has changed, we cannot continue this loop. + break; + } + } + } while (optimized_this_xfer); + } + } while (optimized_in_this_iteration); + + auto optimized_cost = cost_function(optimized_graph.get()); + + if (print_message) { + std::cout << "greedy_optimize(): cost optimized from " << original_cost + << " to " << optimized_cost << std::endl; + } + + return optimized_graph; +} + std::shared_ptr Graph::greedy_optimize(Context *ctx, const std::string &equiv_file_name, bool print_message, @@ -2046,9 +2104,6 @@ Graph::optimize(const std::vector &xfers, double cost_upper_bound, .count() / 1000.0 > timeout) { - // std::cout << "Timeout. Program terminated. Best cost is " << - // best_cost - // << std::endl; return best_graph; } if (new_graph == nullptr) diff --git a/src/quartz/tasograph/tasograph.h b/src/quartz/tasograph/tasograph.h index bf6dfd92..6dc6d3f6 100644 --- a/src/quartz/tasograph/tasograph.h +++ b/src/quartz/tasograph/tasograph.h @@ -215,6 +215,10 @@ class Graph { bool print_message, std::function cost_function = nullptr); std::shared_ptr + greedy_optimize_with_xfer(const std::vector &xfers, + bool print_message, + std::function cost_function); + std::shared_ptr optimize_legacy(float alpha, int budget, bool print_subst, Context *ctx, const std::string &equiv_file_name, bool use_simulated_annealing, bool enable_early_stop, From a5abf681646e9472d5bd48a811b2493d6e1efc74 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 1 Apr 2024 14:00:29 -0400 Subject: [PATCH 21/38] Support preprocess with rpc --- src/wrapper/oracle.cpp | 60 ++++++++++++++++++++++++++++++--- src/wrapper/oracle.h | 18 +++++++++- src/wrapper/rpc/wrapper_rpc.cpp | 22 ++++++++---- 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/src/wrapper/oracle.cpp b/src/wrapper/oracle.cpp index 6ca46a1e..ae9cd006 100644 --- a/src/wrapper/oracle.cpp +++ b/src/wrapper/oracle.cpp @@ -29,8 +29,60 @@ std::string optimize_(std::string circ_string, std::string cost_func, assert(false); } float init_cost = cost_function(graph.get()); - auto newgraph = - graph->optimize(super_context->xfers, init_cost * 1.05, "barenco_tof_3", - "", false, cost_function, timeout); - return newgraph->to_qasm(false, false); + auto start = std::chrono::steady_clock::now(); + auto graph_after_greedy = graph->greedy_optimize_with_xfer( + super_context->xfers_greedy, false, cost_function); + auto end = std::chrono::steady_clock::now(); + double remaining_time = + timeout - + std::chrono::duration_cast(end - start) + .count() / + 1000.0; + if (remaining_time < 0.01) { + return graph_after_greedy->to_qasm(false, false); + } else { + auto graph_after_search = graph_after_greedy->optimize( + super_context->xfers, init_cost * 1.05, "barenco_tof_3", "", false, + cost_function, remaining_time); + return graph_after_search->to_qasm(false, false); + } +} +std::string clifford_decomposition_(std::string circ) { + auto param_info = ParamInfo(0); + + Context src_ctx(std::vector{GateType::h, GateType::ccz, GateType::x, + GateType::cx, GateType::add, + GateType::input_qubit, + GateType::input_param}, + 3, ¶m_info); + Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add, + GateType::cx, GateType::input_qubit, GateType::input_param}, + 3, ¶m_info); + + auto union_ctx = union_contexts(&src_ctx, &dst_ctx); + + auto graph = Graph::from_qasm_str(&src_ctx, circ); + + std::shared_ptr newGraph; + + auto xfer_pair = GraphXfer::ccz_cx_rz_xfer(&src_ctx, &dst_ctx, &union_ctx); + + newGraph = graph->toffoli_flip_greedy(GateType::rz, xfer_pair.first, + xfer_pair.second); + return newGraph->to_qasm(false, false); +} + +std::string rotation_merging_(std::string circ_string) + +{ + auto param_info = ParamInfo(0); + Context src_ctx(std::vector{GateType::h, GateType::x, GateType::rz, + GateType::add, GateType::cx, + GateType::input_qubit, + GateType::input_param}, + 3, ¶m_info); + + auto graph = Graph::from_qasm_str(&src_ctx, circ_string); + graph->rotation_merging(GateType::rz); + return graph->to_qasm(false, false); } \ No newline at end of file diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index b988a7bf..f34eab5e 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -11,6 +11,7 @@ class SuperContext { ParamInfo param_info; Context ctx; std::vector xfers; + std::vector xfers_greedy; static Context createContext(const std::string &gate_set, int n_qubits, ParamInfo ¶m_info) { std::vector gates; @@ -34,6 +35,7 @@ class SuperContext { const std::string &ecc_path) : param_info(0), ctx(createContext(gate_set, n_qubits, param_info)) { xfers = std::vector(); + xfers_greedy = std::vector(); EquivalenceSet eqs; if (!eqs.load_json(&ctx, ecc_path, false)) { std::cout << "Failed to load equivalence file." << std::endl; @@ -53,6 +55,18 @@ class SuperContext { } } } + for (auto &eqcs : ecc) { + for (auto &circ_0 : eqcs) { + for (auto &circ_1 : eqcs) { + if (circ_0->get_num_gates() < circ_1->get_num_gates()) { + auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_1, circ_0, true); + if (xfer != nullptr) { + xfers_greedy.push_back(xfer); + } + } + } + } + } }; ~SuperContext() = default; }; @@ -62,4 +76,6 @@ std::shared_ptr get_context_(const std::string gate_set, const std::string ecc_path); std::string optimize_(std::string circ_string, std::string cost_func, float timeout, - std::shared_ptr super_context); \ No newline at end of file + std::shared_ptr super_context); +std::string rotation_merging_(std::string circ_string); +std::string clifford_decomposition_(std::string circ); \ No newline at end of file diff --git a/src/wrapper/rpc/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp index e8d9797d..6ec75e5c 100644 --- a/src/wrapper/rpc/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -7,20 +7,28 @@ using namespace quartz; int main(int argc, char **argv) { - if (argc != 7) { + if (argc != 6) { std::cerr << "Usage: " << argv[0] - << " \n"; + << " " + "\n"; return 1; } int port = atoi(argv[1]); + std::string optimization_gateset = argv[2]; + std::string eccfile = argv[3]; + std::string cost = argv[4]; float timeout = atof(argv[5]); - int nqubits = atoi(argv[6]); rpc::server srv(port); - auto supercontext = get_context_(argv[2], 1, argv[3]); - std::cout << "Server started on port " << port << std::endl; - srv.bind("optimize", [supercontext, timeout, argv](std::string my_circ) { - return optimize_(my_circ, argv[4], timeout, supercontext); + auto supercontext = get_context_(optimization_gateset, 1, eccfile); + srv.bind("optimize", [supercontext, timeout, cost](std::string my_circ) { + return optimize_(my_circ, cost, timeout, supercontext); + }); + srv.bind("rotation_merging", + [](std::string my_circ) { return rotation_merging_(my_circ); }); + srv.bind("clifford_decomposition", [](std::string my_circ) { + return clifford_decomposition_(my_circ); }); + std::cout << "Server started on port " << port << std::endl; srv.run(); return 0; From 6cb32228ff816c0bb3e27b8121ff4691c5a68798 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 1 Apr 2024 20:37:53 -0400 Subject: [PATCH 22/38] More gateset --- src/wrapper/oracle.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/wrapper/oracle.cpp b/src/wrapper/oracle.cpp index ae9cd006..7d4eec10 100644 --- a/src/wrapper/oracle.cpp +++ b/src/wrapper/oracle.cpp @@ -52,8 +52,9 @@ std::string clifford_decomposition_(std::string circ) { Context src_ctx(std::vector{GateType::h, GateType::ccz, GateType::x, GateType::cx, GateType::add, - GateType::input_qubit, - GateType::input_param}, + GateType::s, GateType::sdg, GateType::t, + GateType::tdg, GateType::input_qubit, + GateType::input_param, GateType::rz}, 3, ¶m_info); Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add, GateType::cx, GateType::input_qubit, GateType::input_param}, From 4b2a81306744e4d8d0ca93d715bf53a341ea6fc7 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 8 Apr 2024 15:47:19 -0400 Subject: [PATCH 23/38] Support greedy for depth and different timeout --- src/quartz/tasograph/tasograph.cpp | 13 ++++++++++--- src/wrapper/oracle.cpp | 24 +++++++++++++++++++++--- src/wrapper/oracle.h | 24 ++++++++++++++++++------ src/wrapper/rpc/wrapper_rpc.cpp | 13 ++++++++----- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/quartz/tasograph/tasograph.cpp b/src/quartz/tasograph/tasograph.cpp index 72c5d987..2db189bb 100644 --- a/src/quartz/tasograph/tasograph.cpp +++ b/src/quartz/tasograph/tasograph.cpp @@ -1558,6 +1558,8 @@ std::shared_ptr Graph::greedy_optimize_with_xfer(const std::vector &xfers, bool print_message, std::function cost_function) { + // std::cout << "Number of xfers:" << xfers.size() << std::endl; + if (cost_function == nullptr) { cost_function = [](Graph *graph) { return graph->total_cost(); }; } @@ -1566,7 +1568,7 @@ Graph::greedy_optimize_with_xfer(const std::vector &xfers, // Load equivalent dags from file auto original_cost = cost_function(this); - + auto current_cost = original_cost; // Get xfers that strictly reduce the cost from the ECC set if (print_message) { @@ -1587,7 +1589,13 @@ Graph::greedy_optimize_with_xfer(const std::vector &xfers, for (auto const &node : all_nodes) { auto new_graph = optimized_graph->apply_xfer( xfer, node, context->has_parameterized_gate()); - if (new_graph) { + if (!new_graph) { + continue; + } + auto new_cost = cost_function(new_graph.get()); + if (new_cost < current_cost) { + current_cost = cost_function(new_graph.get()); + optimized_graph.swap(new_graph); // Update the wires after applying a transformation. all_nodes.clear(); @@ -1619,7 +1627,6 @@ Graph::greedy_optimize(Context *ctx, const std::string &equiv_file_name, if (cost_function == nullptr) { cost_function = [](Graph *graph) { return graph->total_cost(); }; } - EquivalenceSet eqs; // Load equivalent dags from file if (!eqs.load_json(ctx, equiv_file_name, /*from_verifier=*/false)) { diff --git a/src/wrapper/oracle.cpp b/src/wrapper/oracle.cpp index 7d4eec10..36d9d1b9 100644 --- a/src/wrapper/oracle.cpp +++ b/src/wrapper/oracle.cpp @@ -10,28 +10,46 @@ std::shared_ptr get_context_(const std::string gate_set, } std::string optimize_(std::string circ_string, std::string cost_func, - float timeout, std::shared_ptr super_context + std::string timeout_type, float timeout_value, + std::shared_ptr super_context ) { auto graph = Graph::from_qasm_str(&super_context->ctx, circ_string); std::function cost_function; + std::vector greedy_xfers; if (cost_func == "Gate") { cost_function = [](Graph *graph) { return graph->total_cost(); }; + greedy_xfers = super_context->xfers_greedy_gate; } else if (cost_func == "Depth") { cost_function = [](Graph *graph) { return graph->circuit_depth(); }; + greedy_xfers = super_context->xfers; + } else if (cost_func == "Mixed") { cost_function = [](Graph *graph) { return graph->circuit_depth() + 0.1 * graph->total_cost(); }; + greedy_xfers = super_context->xfers; + } else { std::cout << "Invalid cost function." << std::endl; assert(false); } + float timeout = 0; + if (timeout_type == "PerSegment") { + timeout = timeout_value; + } else if (timeout_type == "PerGate") { + timeout = timeout_value * graph->total_cost(); + } else { + std::cout << "Invalid timeout type." << std::endl; + assert(false); + } + float init_cost = cost_function(graph.get()); auto start = std::chrono::steady_clock::now(); - auto graph_after_greedy = graph->greedy_optimize_with_xfer( - super_context->xfers_greedy, false, cost_function); + auto graph_after_greedy = + graph->greedy_optimize_with_xfer(greedy_xfers, false, cost_function); + auto end = std::chrono::steady_clock::now(); double remaining_time = timeout - diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index f34eab5e..06189bea 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -11,7 +11,8 @@ class SuperContext { ParamInfo param_info; Context ctx; std::vector xfers; - std::vector xfers_greedy; + std::vector xfers_greedy_gate; + static Context createContext(const std::string &gate_set, int n_qubits, ParamInfo ¶m_info) { std::vector gates; @@ -35,18 +36,22 @@ class SuperContext { const std::string &ecc_path) : param_info(0), ctx(createContext(gate_set, n_qubits, param_info)) { xfers = std::vector(); - xfers_greedy = std::vector(); + xfers_greedy_gate = std::vector(); EquivalenceSet eqs; if (!eqs.load_json(&ctx, ecc_path, false)) { std::cout << "Failed to load equivalence file." << std::endl; assert(false); } - + int n_xfer_1q = 0; auto ecc = eqs.get_all_equivalence_sets(); for (auto &eqcs : ecc) { for (auto &circ_0 : eqcs) { for (auto &circ_1 : eqcs) { if (circ_0 != circ_1) { + if (circ_0->get_num_qubits() == 1 && + circ_1->get_num_qubits() == 1) { + n_xfer_1q++; + } auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_0, circ_1, true); if (xfer != nullptr) { xfers.push_back(xfer); @@ -55,19 +60,24 @@ class SuperContext { } } } + // Only representatives. + // std::cout << "Number of 1q xfers: " << n_xfer_1q << std::endl; + // std::cout << "Number of xfers: " << xfers.size() << std::endl; + for (auto &eqcs : ecc) { for (auto &circ_0 : eqcs) { for (auto &circ_1 : eqcs) { if (circ_0->get_num_gates() < circ_1->get_num_gates()) { auto xfer = GraphXfer::create_GraphXfer(&ctx, circ_1, circ_0, true); if (xfer != nullptr) { - xfers_greedy.push_back(xfer); + xfers_greedy_gate.push_back(xfer); } } } } } }; + ~SuperContext() = default; }; @@ -75,7 +85,9 @@ std::shared_ptr get_context_(const std::string gate_set, int n_qubits, const std::string ecc_path); std::string optimize_(std::string circ_string, std::string cost_func, - float timeout, - std::shared_ptr super_context); + std::string timeout_type, float timeout_value, + std::shared_ptr super_context + +); std::string rotation_merging_(std::string circ_string); std::string clifford_decomposition_(std::string circ); \ No newline at end of file diff --git a/src/wrapper/rpc/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp index 6ec75e5c..035a3847 100644 --- a/src/wrapper/rpc/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -7,21 +7,24 @@ using namespace quartz; int main(int argc, char **argv) { - if (argc != 6) { + if (argc != 7) { std::cerr << "Usage: " << argv[0] << " " - "\n"; + " "; return 1; } int port = atoi(argv[1]); std::string optimization_gateset = argv[2]; std::string eccfile = argv[3]; std::string cost = argv[4]; - float timeout = atof(argv[5]); + std::string timeout_type = argv[5]; + float timeout_value = atof(argv[6]); rpc::server srv(port); + auto supercontext = get_context_(optimization_gateset, 1, eccfile); - srv.bind("optimize", [supercontext, timeout, cost](std::string my_circ) { - return optimize_(my_circ, cost, timeout, supercontext); + srv.bind("optimize", [supercontext, cost, timeout_type, + timeout_value](std::string my_circ) { + return optimize_(my_circ, cost, timeout_type, timeout_value, supercontext); }); srv.bind("rotation_merging", [](std::string my_circ) { return rotation_merging_(my_circ); }); From 02f7f86e1c4b5148f0147f1551da6f77ac407a6a Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 9 Apr 2024 12:06:13 -0400 Subject: [PATCH 24/38] bug fix --- src/wrapper/oracle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/oracle.cpp b/src/wrapper/oracle.cpp index 36d9d1b9..e14a3ef0 100644 --- a/src/wrapper/oracle.cpp +++ b/src/wrapper/oracle.cpp @@ -27,7 +27,7 @@ std::string optimize_(std::string circ_string, std::string cost_func, } else if (cost_func == "Mixed") { cost_function = [](Graph *graph) { - return graph->circuit_depth() + 0.1 * graph->total_cost(); + return 10 * graph->circuit_depth() + graph->total_cost(); }; greedy_xfers = super_context->xfers; From 52b951dbedaf1172fb13286357d8ad9d26a05b2e Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 15 Apr 2024 12:44:09 -0400 Subject: [PATCH 25/38] O3 optimization --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c405228..6ce37d1d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.16) project(Quartz) SET(CMAKE_BUILD_TYPE "Release") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") # python if (MSVC) From 2f7a9d37af46282448e59a4b7ace1cd4f675fc13 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Mon, 20 May 2024 12:13:19 -0400 Subject: [PATCH 26/38] Update CMake --- src/wrapper/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 4e022cc0..9087035f 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories(${CMAKE_INCLUDE_PATH}) include_directories("..") link_directories("../..") +include_directories(~/lib/usr/local/include) file(GLOB_RECURSE WRAPPER_RPC "rpc/wrapper_rpc.cpp") file(GLOB_RECURSE TEST_RPC "rpc/test_rpc.cpp") From 73c119bd67d6e5aec641e40de11f13f90ac64940 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 28 May 2024 12:55:55 -0400 Subject: [PATCH 27/38] Support barrier gate --- src/quartz/gate/all_gates.h | 4 +++- src/quartz/gate/b1.h | 24 ++++++++++++++++++++++++ src/quartz/gate/b2.h | 25 +++++++++++++++++++++++++ src/quartz/gate/gates.inc.h | 2 ++ src/wrapper/CMakeLists.txt | 5 +++++ src/wrapper/oracle.h | 6 ++++++ src/wrapper/test_oracle.cpp | 29 +++++++++++++++++++++++++++++ 7 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 src/quartz/gate/b1.h create mode 100644 src/quartz/gate/b2.h create mode 100644 src/wrapper/test_oracle.cpp diff --git a/src/quartz/gate/all_gates.h b/src/quartz/gate/all_gates.h index 55f1d905..1dd78911 100644 --- a/src/quartz/gate/all_gates.h +++ b/src/quartz/gate/all_gates.h @@ -1,6 +1,8 @@ #pragma once #include "add.h" +#include "b1.h" +#include "b2.h" #include "ccx.h" #include "ccz.h" #include "ch.h" @@ -36,4 +38,4 @@ #include "u3.h" #include "x.h" #include "y.h" -#include "z.h" +#include "z.h" \ No newline at end of file diff --git a/src/quartz/gate/b1.h b/src/quartz/gate/b1.h new file mode 100644 index 00000000..e905ff95 --- /dev/null +++ b/src/quartz/gate/b1.h @@ -0,0 +1,24 @@ +#pragma once + +#include "../math/matrix.h" +#include "gate.h" + +#include + +namespace quartz { +class B1Gate : public Gate { + public: + B1Gate() : Gate(GateType::b1, 1 /*num_qubits*/, 1 /*num_parameters*/) {} + MatrixBase *get_matrix() override { + assert(false); + auto mat = std::make_unique>(Matrix<2>({{0, 0}, {0, 0}})); + + return mat.get(); + } + bool is_symmetric() const override { return true; } + bool is_sparse() const override { return true; } + bool is_diagonal() const override { return true; } + int get_num_control_qubits() const override { return 1; } +}; + +} // namespace quartz diff --git a/src/quartz/gate/b2.h b/src/quartz/gate/b2.h new file mode 100644 index 00000000..96a7f499 --- /dev/null +++ b/src/quartz/gate/b2.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../math/matrix.h" +#include "gate.h" + +#include + +namespace quartz { +class B2Gate : public Gate { + public: + B2Gate() : Gate(GateType::b2, 2 /*num_qubits*/, 1 /*num_parameters*/) {} + MatrixBase *get_matrix() override { + assert(false); + auto mat = std::make_unique>( + Matrix<4>({{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}})); + + return mat.get(); + } + bool is_symmetric() const override { return true; } + bool is_sparse() const override { return true; } + bool is_diagonal() const override { return true; } + int get_num_control_qubits() const override { return 1; } +}; + +} // namespace quartz diff --git a/src/quartz/gate/gates.inc.h b/src/quartz/gate/gates.inc.h index bb5d7337..e75e1e55 100644 --- a/src/quartz/gate/gates.inc.h +++ b/src/quartz/gate/gates.inc.h @@ -36,3 +36,5 @@ PER_GATE(ry3, RY3Gate) PER_GATE(rxx1, RXX1Gate) PER_GATE(rxx3, RXX3Gate) PER_GATE(sx, SXGate) +PER_GATE(b1, B1Gate) +PER_GATE(b2, B2Gate) \ No newline at end of file diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 9087035f..08f5d3cf 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -6,12 +6,14 @@ include_directories(~/lib/usr/local/include) file(GLOB_RECURSE WRAPPER_RPC "rpc/wrapper_rpc.cpp") file(GLOB_RECURSE TEST_RPC "rpc/test_rpc.cpp") +file(GLOB_RECURSE TEST_ORACLE "test_oracle.cpp") file(GLOB_RECURSE ORACLE "oracle.cpp") add_library(oracle SHARED ${ORACLE}) add_executable(wrapper_rpc ${WRAPPER_RPC}) add_executable(test_rpc ${TEST_RPC}) +add_executable(test_oracle ${TEST_ORACLE}) target_link_libraries(wrapper_rpc oracle) target_link_libraries(wrapper_rpc quartz_runtime) @@ -19,6 +21,9 @@ target_link_libraries(wrapper_rpc quartz_runtime) target_link_libraries(test_rpc oracle) target_link_libraries(test_rpc quartz_runtime) +target_link_libraries(test_oracle oracle) +target_link_libraries(test_oracle quartz_runtime) + add_library(librpc STATIC IMPORTED) set_property(TARGET librpc PROPERTY IMPORTED_LOCATION /home/pengyul/lib/usr/local/lib/librpc.a) target_link_libraries(wrapper_rpc librpc) diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index 06189bea..add6580b 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -25,6 +25,12 @@ class SuperContext { GateType::x, GateType::t, GateType::tdg, GateType::s, GateType::sdg, GateType::z, GateType::cx, GateType::add}; + } else if (gate_set == "Nam_B") { + gates = { + GateType::input_qubit, GateType::input_param, GateType::cx, + GateType::h, GateType::rz, GateType::x, + GateType::add, GateType::b1, GateType::b2, + }; } else { std::cerr << "Invalid gate set." << std::endl; assert(false); diff --git a/src/wrapper/test_oracle.cpp b/src/wrapper/test_oracle.cpp new file mode 100644 index 00000000..00e1421b --- /dev/null +++ b/src/wrapper/test_oracle.cpp @@ -0,0 +1,29 @@ +#include "quartz/tasograph/substitution.h" +#include "quartz/tasograph/tasograph.h" +#include "wrapper/oracle.h" + +#include +using namespace quartz; + +int main(int argc, char **argv) { + if (argc != 7) { + std::cerr << "Usage: " << argv[0] + << " " + " "; + return 1; + } + std::string optimization_gateset = argv[2]; + std::string eccfile = argv[3]; + std::string cost = argv[4]; + std::string timeout_type = argv[5]; + std::string circ_path = argv[1]; + std::ifstream circ_file(circ_path); + std::string my_circ((std::istreambuf_iterator(circ_file)), + std::istreambuf_iterator()); + float timeout_value = atof(argv[6]); + + auto supercontext = get_context_(optimization_gateset, 1, eccfile); + std::string new_circ = + optimize_(my_circ, cost, timeout_type, timeout_value, supercontext); + std::cout << new_circ << std::endl; +} \ No newline at end of file From 914927a827c4d3ccddad255eabbd1690b22072b2 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 29 May 2024 01:00:36 -0400 Subject: [PATCH 28/38] Remove B1 gate and do not mod 2pi while reading --- src/quartz/gate/all_gates.h | 1 - src/quartz/gate/b1.h | 24 ------------------------ src/quartz/gate/gates.inc.h | 1 - src/quartz/tasograph/tasograph.cpp | 6 +++--- src/wrapper/oracle.h | 2 +- 5 files changed, 4 insertions(+), 30 deletions(-) delete mode 100644 src/quartz/gate/b1.h diff --git a/src/quartz/gate/all_gates.h b/src/quartz/gate/all_gates.h index 1dd78911..2987db19 100644 --- a/src/quartz/gate/all_gates.h +++ b/src/quartz/gate/all_gates.h @@ -1,7 +1,6 @@ #pragma once #include "add.h" -#include "b1.h" #include "b2.h" #include "ccx.h" #include "ccz.h" diff --git a/src/quartz/gate/b1.h b/src/quartz/gate/b1.h deleted file mode 100644 index e905ff95..00000000 --- a/src/quartz/gate/b1.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../math/matrix.h" -#include "gate.h" - -#include - -namespace quartz { -class B1Gate : public Gate { - public: - B1Gate() : Gate(GateType::b1, 1 /*num_qubits*/, 1 /*num_parameters*/) {} - MatrixBase *get_matrix() override { - assert(false); - auto mat = std::make_unique>(Matrix<2>({{0, 0}, {0, 0}})); - - return mat.get(); - } - bool is_symmetric() const override { return true; } - bool is_sparse() const override { return true; } - bool is_diagonal() const override { return true; } - int get_num_control_qubits() const override { return 1; } -}; - -} // namespace quartz diff --git a/src/quartz/gate/gates.inc.h b/src/quartz/gate/gates.inc.h index e75e1e55..839f7475 100644 --- a/src/quartz/gate/gates.inc.h +++ b/src/quartz/gate/gates.inc.h @@ -36,5 +36,4 @@ PER_GATE(ry3, RY3Gate) PER_GATE(rxx1, RXX1Gate) PER_GATE(rxx3, RXX3Gate) PER_GATE(sx, SXGate) -PER_GATE(b1, B1Gate) PER_GATE(b2, B2Gate) \ No newline at end of file diff --git a/src/quartz/tasograph/tasograph.cpp b/src/quartz/tasograph/tasograph.cpp index 2db189bb..3bd121e0 100644 --- a/src/quartz/tasograph/tasograph.cpp +++ b/src/quartz/tasograph/tasograph.cpp @@ -1470,9 +1470,9 @@ Graph::_from_qasm_stream(Context *ctx, while (p < 0) { p += 2 * PI; } - while (p >= 2 * PI) { - p -= 2 * PI; - } + // while (p >= 2 * PI) { + // p -= 2 * PI; + // } auto src_op = graph->add_parameter(p); int src_idx = 0; auto dst_op = op; diff --git a/src/wrapper/oracle.h b/src/wrapper/oracle.h index add6580b..4f6d4d63 100644 --- a/src/wrapper/oracle.h +++ b/src/wrapper/oracle.h @@ -29,7 +29,7 @@ class SuperContext { gates = { GateType::input_qubit, GateType::input_param, GateType::cx, GateType::h, GateType::rz, GateType::x, - GateType::add, GateType::b1, GateType::b2, + GateType::add, GateType::b2, }; } else { std::cerr << "Invalid gate set." << std::endl; From 91601b86bb4bd4b01aad9371d8363993e67a60aa Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 12 Jun 2024 16:08:21 -0400 Subject: [PATCH 29/38] test --- src/wrapper/test_oracle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/test_oracle.cpp b/src/wrapper/test_oracle.cpp index 00e1421b..36eccca5 100644 --- a/src/wrapper/test_oracle.cpp +++ b/src/wrapper/test_oracle.cpp @@ -26,4 +26,4 @@ int main(int argc, char **argv) { std::string new_circ = optimize_(my_circ, cost, timeout_type, timeout_value, supercontext); std::cout << new_circ << std::endl; -} \ No newline at end of file +} From 9954e342e975bbe374c88f1b64267959507a635c Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 12 Jun 2024 16:16:15 -0400 Subject: [PATCH 30/38] test --- src/wrapper/test_oracle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/test_oracle.cpp b/src/wrapper/test_oracle.cpp index 36eccca5..00e1421b 100644 --- a/src/wrapper/test_oracle.cpp +++ b/src/wrapper/test_oracle.cpp @@ -26,4 +26,4 @@ int main(int argc, char **argv) { std::string new_circ = optimize_(my_circ, cost, timeout_type, timeout_value, supercontext); std::cout << new_circ << std::endl; -} +} \ No newline at end of file From 96c0211e5a91dc81070e3d84432a0603bbe61f2a Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Wed, 12 Jun 2024 20:39:11 -0400 Subject: [PATCH 31/38] Update Cmakelist --- CMakeLists.txt | 3 ++- src/wrapper/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b15e3544..e2c0ce2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.16) project(Quartz) - +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) SET(CMAKE_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 08f5d3cf..b5fbee4f 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -2,7 +2,6 @@ include_directories(${CMAKE_INCLUDE_PATH}) include_directories("..") link_directories("../..") -include_directories(~/lib/usr/local/include) file(GLOB_RECURSE WRAPPER_RPC "rpc/wrapper_rpc.cpp") file(GLOB_RECURSE TEST_RPC "rpc/test_rpc.cpp") @@ -10,6 +9,7 @@ file(GLOB_RECURSE TEST_ORACLE "test_oracle.cpp") file(GLOB_RECURSE ORACLE "oracle.cpp") add_library(oracle SHARED ${ORACLE}) +target_link_libraries(oracle quartz_runtime) add_executable(wrapper_rpc ${WRAPPER_RPC}) add_executable(test_rpc ${TEST_RPC}) @@ -25,6 +25,6 @@ target_link_libraries(test_oracle oracle) target_link_libraries(test_oracle quartz_runtime) add_library(librpc STATIC IMPORTED) -set_property(TARGET librpc PROPERTY IMPORTED_LOCATION /home/pengyul/lib/usr/local/lib/librpc.a) +set_property(TARGET librpc PROPERTY IMPORTED_LOCATION $ENV{LIBRPC_PATH}) target_link_libraries(wrapper_rpc librpc) target_link_libraries(test_rpc librpc) \ No newline at end of file From e8e74c0c28fa53c4c7b622213d1de4b4c4dd7063 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 18 Jun 2024 17:16:50 -0400 Subject: [PATCH 32/38] Use relative path --- src/wrapper/rpc/test_rpc.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/wrapper/rpc/test_rpc.cpp b/src/wrapper/rpc/test_rpc.cpp index 8f99f7e7..2f4b8cfb 100644 --- a/src/wrapper/rpc/test_rpc.cpp +++ b/src/wrapper/rpc/test_rpc.cpp @@ -4,9 +4,8 @@ using namespace quartz; int main() { - auto supercontext = get_context_( - "Nam", 48, - "/home/pengyul/quicr/soam/resources/Nam_4_3_complete_ECC_set.json"); + auto supercontext = + get_context_("Nam", 48, "resources/Nam_4_3_complete_ECC_set.json"); return 0; } \ No newline at end of file From f60c96c25e1d73ab0b8d1132c0749d71d30d7176 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Thu, 23 Jan 2025 15:19:07 -0500 Subject: [PATCH 33/38] change unit of time --- src/wrapper/rpc/wrapper_rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/rpc/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp index 035a3847..4da1d452 100644 --- a/src/wrapper/rpc/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -18,7 +18,7 @@ int main(int argc, char **argv) { std::string eccfile = argv[3]; std::string cost = argv[4]; std::string timeout_type = argv[5]; - float timeout_value = atof(argv[6]); + float timeout_value = atof(argv[6]) / 1000; rpc::server srv(port); auto supercontext = get_context_(optimization_gateset, 1, eccfile); From 46b552529d7d059e3712e7b505732d78d8255209 Mon Sep 17 00:00:00 2001 From: Mingkuan Xu Date: Sun, 2 Feb 2025 21:49:07 -0500 Subject: [PATCH 34/38] Update CMakeLists.txt in Wrapper for Windows (#202) * A version that works for OAC on Windows * Restore shared lib --- src/wrapper/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index b5fbee4f..7805d6e0 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -24,7 +24,13 @@ target_link_libraries(test_rpc quartz_runtime) target_link_libraries(test_oracle oracle) target_link_libraries(test_oracle quartz_runtime) +cmake_path(SET LIBRPC_PATH "$ENV{LIBRPC_PATH}") +cmake_path(GET LIBRPC_PATH PARENT_PATH LIBRPC_PARENT_PATH) +cmake_path(GET LIBRPC_PARENT_PATH PARENT_PATH LIBRPC_PARENT_PARENT_PATH) +cmake_path(SET LIBRPC_INCLUDE_DIR "${LIBRPC_PARENT_PARENT_PATH}/include") +include_directories(${LIBRPC_INCLUDE_DIR}) + add_library(librpc STATIC IMPORTED) set_property(TARGET librpc PROPERTY IMPORTED_LOCATION $ENV{LIBRPC_PATH}) target_link_libraries(wrapper_rpc librpc) -target_link_libraries(test_rpc librpc) \ No newline at end of file +target_link_libraries(test_rpc librpc) From b5614e98b35ecf36b963a02d28f950f44ced4494 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 4 Feb 2025 19:21:14 +0000 Subject: [PATCH 35/38] correct time unit --- src/wrapper/rpc/wrapper_rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/rpc/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp index 4da1d452..035a3847 100644 --- a/src/wrapper/rpc/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -18,7 +18,7 @@ int main(int argc, char **argv) { std::string eccfile = argv[3]; std::string cost = argv[4]; std::string timeout_type = argv[5]; - float timeout_value = atof(argv[6]) / 1000; + float timeout_value = atof(argv[6]); rpc::server srv(port); auto supercontext = get_context_(optimization_gateset, 1, eccfile); From 4d8b02abc4a3353f2c095b076f9367fa53c61a70 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 4 Feb 2025 19:21:32 +0000 Subject: [PATCH 36/38] remove prints --- src/quartz/tasograph/tasograph.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/quartz/tasograph/tasograph.cpp b/src/quartz/tasograph/tasograph.cpp index b0058109..0d0d47ad 100644 --- a/src/quartz/tasograph/tasograph.cpp +++ b/src/quartz/tasograph/tasograph.cpp @@ -1941,8 +1941,8 @@ std::shared_ptr Graph::optimize_legacy( .count() / 1000.0 > timeout) { - std::cout << "Timeout. Program terminated. Best cost is " << bestCost - << std::endl; + // std::cout << "Timeout. Program terminated. Best cost is " << bestCost + // << std::endl; bestGraph->constant_and_rotation_elimination(); return bestGraph; } @@ -2153,8 +2153,8 @@ Graph::optimize(const std::vector &xfers, double cost_upper_bound, .count() / 1000.0 > timeout) { - std::cout << "Timeout. Program terminated. Best cost is " << best_cost - << std::endl; + // std::cout << "Timeout. Program terminated. Best cost is " << best_cost + // << std::endl; hit_timeout = true; break; } From 6be1bcb234bc8484ba70c6a4d93994ac807badd2 Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Tue, 4 Feb 2025 19:21:45 +0000 Subject: [PATCH 37/38] use gate greedy even for mixed cost --- src/wrapper/oracle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wrapper/oracle.cpp b/src/wrapper/oracle.cpp index e14a3ef0..0a643c20 100644 --- a/src/wrapper/oracle.cpp +++ b/src/wrapper/oracle.cpp @@ -23,13 +23,13 @@ std::string optimize_(std::string circ_string, std::string cost_func, greedy_xfers = super_context->xfers_greedy_gate; } else if (cost_func == "Depth") { cost_function = [](Graph *graph) { return graph->circuit_depth(); }; - greedy_xfers = super_context->xfers; + greedy_xfers = super_context->xfers_greedy_gate; } else if (cost_func == "Mixed") { cost_function = [](Graph *graph) { return 10 * graph->circuit_depth() + graph->total_cost(); }; - greedy_xfers = super_context->xfers; + greedy_xfers = super_context->xfers_greedy_gate; } else { std::cout << "Invalid cost function." << std::endl; From f9c2dfd2d222a8b0b265b54931caf5d942267bbe Mon Sep 17 00:00:00 2001 From: Pengyu Liu Date: Sun, 9 Feb 2025 22:20:07 -0500 Subject: [PATCH 38/38] remove debugging info --- src/wrapper/rpc/wrapper_rpc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/rpc/wrapper_rpc.cpp b/src/wrapper/rpc/wrapper_rpc.cpp index 035a3847..e7744646 100644 --- a/src/wrapper/rpc/wrapper_rpc.cpp +++ b/src/wrapper/rpc/wrapper_rpc.cpp @@ -31,7 +31,7 @@ int main(int argc, char **argv) { srv.bind("clifford_decomposition", [](std::string my_circ) { return clifford_decomposition_(my_circ); }); - std::cout << "Server started on port " << port << std::endl; + // std::cout << "Server started on port " << port << std::endl; srv.run(); return 0;