-
Notifications
You must be signed in to change notification settings - Fork 27
Pengyu/wrapper #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Pengyu/wrapper #178
Changes from all commits
3f60bb0
0c9ec4d
de04776
ae0e333
af8239a
4832f01
8902441
003d61c
9e35f54
71e5bb4
61ac662
75c14dd
b07aa07
3c206f3
5b155af
5917041
7ed6d63
fe51938
ea4fa2b
292989e
85de200
8df070f
7b4e263
a5abf68
6cb3222
4b2a813
02f7f86
52b951d
2f7a9d3
73c119b
914927a
91601b8
9954e34
342878e
96c0211
e8e74c0
f60c96c
46b5525
b5614e9
4d8b02a
6be1bcb
f9c2dfd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,25 @@ | ||||||||||||
| #pragma once | ||||||||||||
|
|
||||||||||||
| #include "../math/matrix.h" | ||||||||||||
| #include "gate.h" | ||||||||||||
|
|
||||||||||||
| #include <assert.h> | ||||||||||||
|
|
||||||||||||
| namespace quartz { | ||||||||||||
| class B2Gate : public Gate { | ||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||
| public: | ||||||||||||
| B2Gate() : Gate(GateType::b2, 2 /*num_qubits*/, 1 /*num_parameters*/) {} | ||||||||||||
| MatrixBase *get_matrix() override { | ||||||||||||
| assert(false); | ||||||||||||
| auto mat = std::make_unique<Matrix<4>>( | ||||||||||||
| 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 | ||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
| // } | ||
|
Comment on lines
+1473
to
+1475
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just merged #177 into the master branch and please rebase this PR onto it. I think it's better to split out the logic changes to existing code if possible. |
||
| auto src_op = graph->add_parameter(p); | ||
| int src_idx = 0; | ||
| auto dst_op = op; | ||
|
|
@@ -1554,6 +1554,72 @@ void Graph::draw_circuit(const std::string &src_file_name, | |
| .c_str()); | ||
| } | ||
|
|
||
| std::shared_ptr<Graph> | ||
| Graph::greedy_optimize_with_xfer(const std::vector<GraphXfer *> &xfers, | ||
| bool print_message, | ||
| std::function<float(Graph *)> cost_function) { | ||
| // std::cout << "Number of xfers:" << xfers.size() << std::endl; | ||
|
|
||
| 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); | ||
| auto current_cost = original_cost; | ||
| // 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<Graph> optimized_graph = std::make_shared<Graph>(*this); | ||
| bool optimized_in_this_iteration; | ||
| std::vector<Op> 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) { | ||
| 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(); | ||
| 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> | ||
| Graph::greedy_optimize(Context *ctx, const std::string &equiv_file_name, | ||
| bool print_message, | ||
|
|
@@ -1562,7 +1628,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)) { | ||
|
|
@@ -1876,8 +1941,8 @@ std::shared_ptr<Graph> 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; | ||
| } | ||
|
|
@@ -2088,8 +2153,8 @@ Graph::optimize(const std::vector<GraphXfer *> &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; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| include_directories(${CMAKE_INCLUDE_PATH}) | ||
| include_directories("..") | ||
|
|
||
| link_directories("../..") | ||
|
|
||
| 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}) | ||
| target_link_libraries(oracle quartz_runtime) | ||
|
|
||
| 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) | ||
|
|
||
| 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) | ||
|
|
||
| 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) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| #include "oracle.h" | ||
|
|
||
| using namespace quartz; | ||
| std::shared_ptr<SuperContext> get_context_(const std::string gate_set, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it returns a |
||
| int n_qubits, | ||
| const std::string ecc_path) { | ||
| auto super_context = | ||
| std::make_shared<SuperContext>(gate_set, n_qubits, ecc_path); | ||
| return super_context; | ||
| } | ||
|
|
||
| std::string optimize_(std::string circ_string, std::string cost_func, | ||
| std::string timeout_type, float timeout_value, | ||
| std::shared_ptr<SuperContext> super_context | ||
|
|
||
| ) { | ||
| auto graph = Graph::from_qasm_str(&super_context->ctx, circ_string); | ||
|
|
||
| std::function<int(Graph *)> cost_function; | ||
| std::vector<quartz::GraphXfer *> 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_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_gate; | ||
|
|
||
| } 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(greedy_xfers, false, cost_function); | ||
|
|
||
| auto end = std::chrono::steady_clock::now(); | ||
| double remaining_time = | ||
| timeout - | ||
| std::chrono::duration_cast<std::chrono::milliseconds>(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>{GateType::h, GateType::ccz, GateType::x, | ||
| GateType::cx, GateType::add, | ||
| 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}, | ||
| 3, ¶m_info); | ||
|
|
||
| auto union_ctx = union_contexts(&src_ctx, &dst_ctx); | ||
|
|
||
| auto graph = Graph::from_qasm_str(&src_ctx, circ); | ||
|
|
||
| std::shared_ptr<Graph> 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>{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); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove these two lines because we want to set
-O0on debug mode (see lines 82-95).If you need to set
-O3also inCMAKE_C_FLAGS, you can modify these lines.