Skip to content

Commit

Permalink
Merge pull request qulacs#219 from corryvrequan/feature/add_functions
Browse files Browse the repository at this point in the history
Further SIMD optimization and thread number optimization for Pauli operations
  • Loading branch information
corryvrequan committed Apr 23, 2020
2 parents 9c84efb + 748b38e commit 66e292a
Show file tree
Hide file tree
Showing 15 changed files with 1,788 additions and 490 deletions.
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

0 comments on commit 66e292a

Please sign in to comment.