Skip to content
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

Further SIMD optimization and thread number optimization for Pauli operations #219

Merged
merged 4 commits into from
Apr 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmark/libcsim_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ double benchmark_state_stat_func(UINT n, std::function<T(CTYPE*, ITYPE)>func) {
};

double benchmark_state_norm(UINT n) {
return benchmark_state_func(n, state_norm);
return benchmark_state_func(n, state_norm_squared);
}

double benchmark_gate_single_func(UINT n, UINT target, std::function<void(UINT, CTYPE*, ITYPE)>func) {
Expand Down
3 changes: 2 additions & 1 deletion python/cppsim_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,8 @@ PYBIND11_MODULE(qulacs, m) {
py::class_<QuantumCircuitOptimizer>(mcircuit, "QuantumCircuitOptimizer")
.def(py::init<>(), "Constructor")
.def("optimize", &QuantumCircuitOptimizer::optimize, "Optimize quantum circuit", py::arg("circuit"), py::arg("block_size"))
.def("merge_all", &QuantumCircuitOptimizer::merge_all, pybind11::return_value_policy::take_ownership, py::arg("circuit"))
.def("optimize_light", &QuantumCircuitOptimizer::optimize_light, "Optimize quantum circuit with light method", py::arg("circuit"))
.def("merge_all", &QuantumCircuitOptimizer::merge_all, pybind11::return_value_policy::take_ownership, py::arg("circuit"))
;

py::class_<QuantumCircuitSimulator>(m, "QuantumCircuitSimulator")
Expand Down
76 changes: 76 additions & 0 deletions src/cppsim/circuit_optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,82 @@ void QuantumCircuitOptimizer::optimize(QuantumCircuit* circuit_, UINT max_block_
}
}
}
/*
void QuantumCircuitOptimizer::optimize_light(QuantumCircuit* circuit) {
UINT qubit_count = circuit->qubit_count;
std::vector<std::pair<int, std::vector<UINT>>> current_step(qubit_count, std::make_pair(-1,std::vector<UINT>()));
for (UINT ind1 = 0; ind1 < circuit->gate_list.size(); ++ind1) {
QuantumGateBase* gate = circuit->gate_list[ind1];
std::vector<UINT> target_qubits;
for (auto val : gate->get_target_index_list()) target_qubits.push_back(val);
for (auto val : gate->get_control_index_list()) target_qubits.push_back(val);
std::sort(target_qubits.begin(), target_qubits.end());
if (target_qubits.size() == 1) {
// merge
UINT target_qubit_index = target_qubits[0];
UINT target_gate_index = current_step[target_qubit_index].first;
if (target_gate_index != -1) {
auto merged_gate = gate::merge(circuit->gate_list[target_gate_index], gate);
circuit->remove_gate(ind1);
circuit->add_gate(merged_gate, target_gate_index+1);
circuit->remove_gate(target_gate_index);
ind1--;
}
else {
current_step[target_qubit_index] = std::make_pair(ind1, target_qubits);
}
}
else {
for (auto target_qubit : target_qubits) {
current_step[target_qubit] = make_pair(ind1, target_qubits);
}
}
}
}
*/

void QuantumCircuitOptimizer::optimize_light(QuantumCircuit* circuit) {
UINT qubit_count = circuit->qubit_count;
std::vector<std::pair<int, std::vector<UINT>>> current_step(qubit_count, std::make_pair(-1, std::vector<UINT>()));
for (UINT ind1 = 0; ind1 < circuit->gate_list.size(); ++ind1) {
QuantumGateBase* gate = circuit->gate_list[ind1];
std::vector<UINT> target_qubits;
std::vector<UINT> parent_qubits;

for (auto val : gate->get_target_index_list()) target_qubits.push_back(val);
for (auto val : gate->get_control_index_list()) target_qubits.push_back(val);
std::sort(target_qubits.begin(), target_qubits.end());

int pos = -1;
int hit = -1;
for (UINT target_qubit : target_qubits) {
if (current_step[target_qubit].first > pos) {
pos = current_step[target_qubit].first;
hit = target_qubit;
}
}
if(hit!=-1)
parent_qubits = current_step[hit].second;
if (std::includes(parent_qubits.begin(), parent_qubits.end(), target_qubits.begin(), target_qubits.end())) {
auto merged_gate = gate::merge(circuit->gate_list[pos], gate);
circuit->remove_gate(ind1);
circuit->add_gate(merged_gate, pos + 1);
circuit->remove_gate(pos);
ind1--;

//std::cout << "merge ";
//for (auto val : target_qubits) std::cout << val << " ";
//std::cout << " into ";
//for (auto val : parent_qubits) std::cout << val << " ";
//std::cout << std::endl;
}
else {
for (auto target_qubit : target_qubits) {
current_step[target_qubit] = make_pair(ind1, target_qubits);
}
}
}
}


QuantumGateMatrix* QuantumCircuitOptimizer::merge_all(const QuantumCircuit* circuit_) {
Expand Down
11 changes: 11 additions & 0 deletions src/cppsim/circuit_optimizer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ class DllExport QuantumCircuitOptimizer{
*/
void optimize(QuantumCircuit* circuit, UINT max_block_size=2);

/**
* \~japanese-en 与えられた量子回路のゲートを指定されたブロックまで纏める。
*
* 与えられた量子回路において、若い添え字から任意の二つのゲートを選び、二つが他のゲートに影響を与えず合成可能なら合成を行う。
* これを合成可能なペアがなくなるまで繰り返す。
* 二つのゲートが合成可能であるとは、二つのゲートそれぞれについて隣接するゲートとの交換を繰り返し、二つのゲートが隣接した位置まで移動できることを指す。
*
* @param[in] circuit 量子回路のインスタンス
*/
void optimize_light(QuantumCircuit* circuit);

/**
* \~japanese-en 量子回路を纏めて一つの巨大な量子ゲートにする
*
Expand Down