Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3f60bb0
Add wrapper for Rust
liupengy19 Mar 4, 2024
0c9ec4d
small bug fix
liupengy19 Mar 4, 2024
de04776
Merge branch 'master' into pengyu/wrapper
liupengy19 Mar 4, 2024
ae0e333
Fix a bug
liupengy19 Mar 4, 2024
af8239a
update wrapper
liupengy19 Mar 11, 2024
4832f01
update wrapper with shared_ptr
liupengy19 Mar 11, 2024
8902441
Remove unused arguments
liupengy19 Mar 11, 2024
003d61c
Merge branch 'master' of https://github.com/quantum-compiler/quartz i…
liupengy19 Mar 11, 2024
9e35f54
print less info
liupengy19 Mar 12, 2024
71e5bb4
Add rpc binding method
liupengy19 Mar 12, 2024
61ac662
tiny update
liupengy19 Mar 12, 2024
75c14dd
more configurable
liupengy19 Mar 13, 2024
b07aa07
Add an example for debugging
liupengy19 Mar 13, 2024
3c206f3
Merge branch 'master' of https://github.com/quantum-compiler/quartz i…
liupengy19 Mar 13, 2024
5b155af
Reorganize files
liupengy19 Mar 13, 2024
5917041
Support CliffordT gateset
liupengy19 Mar 16, 2024
7ed6d63
Add preprocess script
liupengy19 Mar 19, 2024
fe51938
ecc set with s gate
liupengy19 Mar 19, 2024
ea4fa2b
Add s and z to Clifford gateset
liupengy19 Mar 20, 2024
292989e
Add preprocessing with only rotation merging
liupengy19 Mar 20, 2024
85de200
configurable preprocess
liupengy19 Mar 27, 2024
8df070f
Remove unused files
liupengy19 Apr 1, 2024
7b4e263
Support greedy opt with xfers
liupengy19 Apr 1, 2024
a5abf68
Support preprocess with rpc
liupengy19 Apr 1, 2024
6cb3222
More gateset
liupengy19 Apr 2, 2024
4b2a813
Support greedy for depth and different timeout
liupengy19 Apr 8, 2024
02f7f86
bug fix
liupengy19 Apr 9, 2024
52b951d
O3 optimization
liupengy19 Apr 15, 2024
2f7a9d3
Update CMake
liupengy19 May 20, 2024
73c119b
Support barrier gate
liupengy19 May 28, 2024
914927a
Remove B1 gate and do not mod 2pi while reading
liupengy19 May 29, 2024
91601b8
test
liupengy19 Jun 12, 2024
9954e34
test
liupengy19 Jun 12, 2024
342878e
Merge branch 'master' into pengyu/wrapper
liupengy19 Jun 12, 2024
96c0211
Update Cmakelist
liupengy19 Jun 13, 2024
e8e74c0
Use relative path
liupengy19 Jun 18, 2024
f60c96c
change unit of time
liupengy19 Jan 23, 2025
46b5525
Update CMakeLists.txt in Wrapper for Windows (#202)
xumingkuan Feb 3, 2025
b5614e9
correct time unit
liupengy19 Feb 4, 2025
4d8b02a
remove prints
liupengy19 Feb 4, 2025
6be1bcb
use gate greedy even for mixed cost
liupengy19 Feb 4, 2025
f9c2dfd
remove debugging info
liupengy19 Feb 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
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")
Comment on lines +6 to +7
Copy link
Collaborator

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 -O0 on debug mode (see lines 82-95).

Suggested change
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")

If you need to set -O3 also in CMAKE_C_FLAGS, you can modify these lines.


# python
set(Python_FIND_VIRTUALENV FIRST)
Expand Down Expand Up @@ -157,4 +160,5 @@ else()
endif()

add_subdirectory(src/test)
add_subdirectory(src/wrapper)
add_subdirectory(src/benchmark)
3 changes: 2 additions & 1 deletion src/quartz/gate/all_gates.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "add.h"
#include "b2.h"
#include "ccx.h"
#include "ccz.h"
#include "ch.h"
Expand Down Expand Up @@ -36,4 +37,4 @@
#include "u3.h"
#include "x.h"
#include "y.h"
#include "z.h"
#include "z.h"
25 changes: 25 additions & 0 deletions src/quartz/gate/b2.h
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 {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
class B2Gate : public Gate {
/**
* A barrier to block 2 qubits and prevent optimizations across it.
*/
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>>(
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
1 change: 1 addition & 0 deletions src/quartz/gate/gates.inc.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ PER_GATE(ry3, RY3Gate)
PER_GATE(rxx1, RXX1Gate)
PER_GATE(rxx3, RXX3Gate)
PER_GATE(sx, SXGate)
PER_GATE(b2, B2Gate)
81 changes: 73 additions & 8 deletions src/quartz/tasograph/tasograph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The 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;
Expand Down Expand Up @@ -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,
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions src/quartz/tasograph/tasograph.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ class Graph {
std::function<float(Graph *)> cost_function = nullptr,
const std::string &store_all_steps_file_prefix = std::string());
std::shared_ptr<Graph>
greedy_optimize_with_xfer(const std::vector<GraphXfer *> &xfers,
bool print_message,
std::function<float(Graph *)> cost_function);
std::shared_ptr<Graph>
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,
Expand Down
1 change: 1 addition & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ 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")

if(USE_ARBLIB)
file(GLOB_RECURSE TEST_ARB "test_arb.cpp")
endif()
Expand Down
36 changes: 36 additions & 0 deletions src/wrapper/CMakeLists.txt
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)
107 changes: 107 additions & 0 deletions src/wrapper/oracle.cpp
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it returns a SuperContext, it's better for the function name to include "super".

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, &param_info);
Context dst_ctx({GateType::h, GateType::x, GateType::rz, GateType::add,
GateType::cx, GateType::input_qubit, GateType::input_param},
3, &param_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, &param_info);

auto graph = Graph::from_qasm_str(&src_ctx, circ_string);
graph->rotation_merging(GateType::rz);
return graph->to_qasm(false, false);
}
Loading