From 417b472692b22abaa0bec0983debfd221ebeee89 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Fri, 6 Sep 2024 18:37:43 +0900 Subject: [PATCH 01/19] truncate save_expval --- qiskit_aer/VERSION.txt | 2 +- src/framework/circuit.hpp | 47 +++++++++++++++++-- .../extended_stabilizer_state.hpp | 7 ++- src/simulators/state.hpp | 7 ++- 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/qiskit_aer/VERSION.txt b/qiskit_aer/VERSION.txt index a551051694..04a373efe6 100644 --- a/qiskit_aer/VERSION.txt +++ b/qiskit_aer/VERSION.txt @@ -1 +1 @@ -0.15.0 +0.16.0 diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index d5b5655256..6f87dd6525 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -419,7 +419,9 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - qubitset_.insert(op.qubits.begin(), op.qubits.end()); + if (op.type != OpType::save_expval && op.type != OpType::save_expval_var) { + qubitset_.insert(op.qubits.begin(), op.qubits.end()); + } memoryset_.insert(op.memory.begin(), op.memory.end()); registerset_.insert(op.registers.begin(), op.registers.end()); @@ -589,6 +591,22 @@ void Circuit::set_params(bool truncation) { } if (remapped_qubits) { remap_qubits(ops[pos]); + } else if (truncation) { + // truncate save_expval here when remap is not needed + if (ops[pos].type == OpType::save_expval || + ops[pos].type == OpType::save_expval_var) { + int_t nparams = ops[pos].string_params.size(); + for (int_t i = 0; i < nparams; i++) { + std::string new_pauli(ops[pos].string_params[i].end() - + qubitmap_.size(), + ops[pos].string_params[i].end()); + // save original pauli string to restore for output + ops[pos].string_params.push_back(ops[pos].string_params[i]); + + ops[pos].string_params[i] = new_pauli; + } + ops[pos].qubits.resize(qubitmap_.size()); + } } if (pos != op_idx) { ops[op_idx] = std::move(ops[pos]); @@ -653,11 +671,30 @@ void Circuit::set_params(bool truncation) { } void Circuit::remap_qubits(Op &op) const { - reg_t new_qubits; - for (auto &qubit : op.qubits) { - new_qubits.push_back(qubitmap_.at(qubit)); + // truncate save_expval + if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) { + int_t nparams = op.string_params.size(); + for (int_t i = 0; i < nparams; i++) { + uint_t size = op.string_params[i].length(); + // save original pauli string to restore for output + op.string_params.push_back(op.string_params[i]); + + op.string_params[i].resize(size); + for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) { + op.string_params[i][size - 1 - q->second] = + op.string_params[i][size - 1 - q->first]; + } + } + for (int_t i = 0; i < qubitmap_.size(); i++) { + op.qubits[i] = i; + } + } else { + reg_t new_qubits; + for (auto &qubit : op.qubits) { + new_qubits.push_back(qubitmap_.at(qubit)); + } + op.qubits = std::move(new_qubits); } - op.qubits = std::move(new_qubits); } bool Circuit::check_result_ancestor( diff --git a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp index 9fec5d1656..bc5831db45 100644 --- a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp +++ b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp @@ -803,14 +803,17 @@ void State::apply_save_expval(const Operations::Op &op, sq_expval += std::get<2>(param) * val; } } + int_t key = 0; + if (op.string_params.size() > 1) + key = 1; if (variance) { std::vector expval_var(2); expval_var[0] = expval; // mean expval_var[1] = sq_expval - expval * expval; // variance - result.save_data_average(creg(), op.string_params[0], expval_var, op.type, + result.save_data_average(creg(), op.string_params[key], expval_var, op.type, op.save_type); } else { - result.save_data_average(creg(), op.string_params[0], expval, op.type, + result.save_data_average(creg(), op.string_params[key], expval, op.type, op.save_type); } } diff --git a/src/simulators/state.hpp b/src/simulators/state.hpp index 219eaa6bb0..645c240b3a 100644 --- a/src/simulators/state.hpp +++ b/src/simulators/state.hpp @@ -434,14 +434,17 @@ void Base::apply_save_expval(const Operations::Op &op, sq_expval += std::get<2>(param) * val; } } + int_t key = 0; + if (op.string_params.size() > 1) + key = 1; if (variance) { std::vector expval_var(2); expval_var[0] = expval; // mean expval_var[1] = sq_expval - expval * expval; // variance - result.save_data_average(creg(), op.string_params[0], expval_var, op.type, + result.save_data_average(creg(), op.string_params[key], expval_var, op.type, op.save_type); } else { - result.save_data_average(creg(), op.string_params[0], expval, op.type, + result.save_data_average(creg(), op.string_params[key], expval, op.type, op.save_type); } } From 17b5b01ce6e54f475c8d38e2eef8e2c5c1e9f952 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Mon, 9 Sep 2024 11:09:51 +0900 Subject: [PATCH 02/19] fix truncation --- src/framework/circuit.hpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 6f87dd6525..fa4a046aa9 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -498,6 +498,7 @@ void Circuit::set_params(bool truncation) { } // Set qubit and memory size + uint_t num_qubits_orig = num_qubits; num_memory = (memoryset_.empty()) ? 0 : 1 + *memoryset_.rbegin(); num_registers = (registerset_.empty()) ? 0 : 1 + *registerset_.rbegin(); if (remapped_qubits) { @@ -591,19 +592,18 @@ void Circuit::set_params(bool truncation) { } if (remapped_qubits) { remap_qubits(ops[pos]); - } else if (truncation) { + } else if (truncation && qubitmap_.size() != num_qubits_orig) { // truncate save_expval here when remap is not needed if (ops[pos].type == OpType::save_expval || ops[pos].type == OpType::save_expval_var) { int_t nparams = ops[pos].string_params.size(); for (int_t i = 0; i < nparams; i++) { - std::string new_pauli(ops[pos].string_params[i].end() - - qubitmap_.size(), - ops[pos].string_params[i].end()); // save original pauli string to restore for output ops[pos].string_params.push_back(ops[pos].string_params[i]); - ops[pos].string_params[i] = new_pauli; + ops[pos].string_params[i].assign(ops[pos].string_params[i].end() - + qubitmap_.size(), + ops[pos].string_params[i].end()); } ops[pos].qubits.resize(qubitmap_.size()); } @@ -678,12 +678,14 @@ void Circuit::remap_qubits(Op &op) const { uint_t size = op.string_params[i].length(); // save original pauli string to restore for output op.string_params.push_back(op.string_params[i]); + std::string new_pauli; + new_pauli.resize(qubitmap_.size()); - op.string_params[i].resize(size); for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) { - op.string_params[i][size - 1 - q->second] = + new_pauli[qubitmap_.size() - 1 - q->second] = op.string_params[i][size - 1 - q->first]; } + op.string_params[i] = std::move(new_pauli); } for (int_t i = 0; i < qubitmap_.size(); i++) { op.qubits[i] = i; From 41322a7d5f62013e094aa688a351c188931d85d3 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Mon, 9 Sep 2024 14:52:44 +0900 Subject: [PATCH 03/19] fix truncation --- src/framework/circuit.hpp | 21 +++++++------------ .../extended_stabilizer_state.hpp | 7 ++----- src/simulators/state.hpp | 7 ++----- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index fa4a046aa9..9194852d17 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -596,14 +596,10 @@ void Circuit::set_params(bool truncation) { // truncate save_expval here when remap is not needed if (ops[pos].type == OpType::save_expval || ops[pos].type == OpType::save_expval_var) { - int_t nparams = ops[pos].string_params.size(); + int_t nparams = ops[pos].expval_params.size(); for (int_t i = 0; i < nparams; i++) { - // save original pauli string to restore for output - ops[pos].string_params.push_back(ops[pos].string_params[i]); - - ops[pos].string_params[i].assign(ops[pos].string_params[i].end() - - qubitmap_.size(), - ops[pos].string_params[i].end()); + std::string &pauli = std::get<0>(ops[pos].expval_params[i]); + pauli.assign(pauli.end() - qubitmap_.size(), pauli.end()); } ops[pos].qubits.resize(qubitmap_.size()); } @@ -673,19 +669,16 @@ void Circuit::set_params(bool truncation) { void Circuit::remap_qubits(Op &op) const { // truncate save_expval if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) { - int_t nparams = op.string_params.size(); + int_t nparams = op.expval_params.size(); for (int_t i = 0; i < nparams; i++) { - uint_t size = op.string_params[i].length(); - // save original pauli string to restore for output - op.string_params.push_back(op.string_params[i]); + std::string &pauli = std::get<0>(op.expval_params[i]); std::string new_pauli; new_pauli.resize(qubitmap_.size()); - for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) { new_pauli[qubitmap_.size() - 1 - q->second] = - op.string_params[i][size - 1 - q->first]; + pauli[pauli.size() - 1 - q->first]; } - op.string_params[i] = std::move(new_pauli); + pauli = new_pauli; } for (int_t i = 0; i < qubitmap_.size(); i++) { op.qubits[i] = i; diff --git a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp index bc5831db45..9fec5d1656 100644 --- a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp +++ b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp @@ -803,17 +803,14 @@ void State::apply_save_expval(const Operations::Op &op, sq_expval += std::get<2>(param) * val; } } - int_t key = 0; - if (op.string_params.size() > 1) - key = 1; if (variance) { std::vector expval_var(2); expval_var[0] = expval; // mean expval_var[1] = sq_expval - expval * expval; // variance - result.save_data_average(creg(), op.string_params[key], expval_var, op.type, + result.save_data_average(creg(), op.string_params[0], expval_var, op.type, op.save_type); } else { - result.save_data_average(creg(), op.string_params[key], expval, op.type, + result.save_data_average(creg(), op.string_params[0], expval, op.type, op.save_type); } } diff --git a/src/simulators/state.hpp b/src/simulators/state.hpp index 645c240b3a..219eaa6bb0 100644 --- a/src/simulators/state.hpp +++ b/src/simulators/state.hpp @@ -434,17 +434,14 @@ void Base::apply_save_expval(const Operations::Op &op, sq_expval += std::get<2>(param) * val; } } - int_t key = 0; - if (op.string_params.size() > 1) - key = 1; if (variance) { std::vector expval_var(2); expval_var[0] = expval; // mean expval_var[1] = sq_expval - expval * expval; // variance - result.save_data_average(creg(), op.string_params[key], expval_var, op.type, + result.save_data_average(creg(), op.string_params[0], expval_var, op.type, op.save_type); } else { - result.save_data_average(creg(), op.string_params[key], expval, op.type, + result.save_data_average(creg(), op.string_params[0], expval, op.type, op.save_type); } } From 51dadefce127cd7d53e04db4d502ecd4666214f8 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Tue, 10 Sep 2024 18:29:17 +0900 Subject: [PATCH 04/19] add num_original_qubits to aer_circuit to get num_qubits without ancilla qubits --- qiskit_aer/backends/aer_compiler.py | 5 +++++ .../backends/wrappers/aer_circuit_binding.hpp | 2 ++ src/framework/circuit.hpp | 15 ++++++++++++--- .../backends/aer_simulator/test_save_expval.py | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/qiskit_aer/backends/aer_compiler.py b/qiskit_aer/backends/aer_compiler.py index a0c75247cc..c00223e522 100644 --- a/qiskit_aer/backends/aer_compiler.py +++ b/qiskit_aer/backends/aer_compiler.py @@ -695,6 +695,11 @@ def assemble_circuit(circuit: QuantumCircuit, basis_gates=None): aer_circ = AerCircuit() aer_circ.set_header(header) aer_circ.num_qubits = num_qubits + aer_circ.num_original_qubits = num_qubits + if hasattr(circuit, "layout"): + if hasattr(circuit.layout, "final_index_layout"): + if circuit.layout.final_index_layout(True) is not None: + aer_circ.num_original_qubits = len(circuit.layout.final_index_layout(True)) aer_circ.num_memory = num_memory aer_circ.global_phase_angle = global_phase diff --git a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp index 7994b60e1d..43bc98f12e 100644 --- a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp +++ b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp @@ -159,6 +159,8 @@ void bind_aer_circuit(MODULE m) { aer_circuit.def_readwrite("circ_id", &Circuit::circ_id); aer_circuit.def_readwrite("shots", &Circuit::shots); aer_circuit.def_readwrite("num_qubits", &Circuit::num_qubits); + aer_circuit.def_readwrite("num_original_qubits", + &Circuit::num_original_qubits); aer_circuit.def_readwrite("num_memory", &Circuit::num_memory); aer_circuit.def_readwrite("seed", &Circuit::seed); aer_circuit.def_readwrite("ops", &Circuit::ops); diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 9194852d17..002f6a2349 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -46,6 +46,7 @@ class Circuit { uint_t num_qubits = 0; // maximum number of qubits needed for ops uint_t num_memory = 0; // maximum number of memory clbits needed for ops uint_t num_registers = 0; // maximum number of registers clbits needed for ops + uint_t num_original_qubits = 0; // number of qubits without ancilla qubits // Measurement params bool has_conditional = false; // True if any ops are conditional @@ -419,7 +420,10 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - if (op.type != OpType::save_expval && op.type != OpType::save_expval_var) { + if (op.qubits.size() > num_original_qubits) { + qubitset_.insert(op.qubits.begin(), + op.qubits.begin() + num_original_qubits); + } else { qubitset_.insert(op.qubits.begin(), op.qubits.end()); } memoryset_.insert(op.memory.begin(), op.memory.end()); @@ -498,7 +502,6 @@ void Circuit::set_params(bool truncation) { } // Set qubit and memory size - uint_t num_qubits_orig = num_qubits; num_memory = (memoryset_.empty()) ? 0 : 1 + *memoryset_.rbegin(); num_registers = (registerset_.empty()) ? 0 : 1 + *registerset_.rbegin(); if (remapped_qubits) { @@ -592,14 +595,17 @@ void Circuit::set_params(bool truncation) { } if (remapped_qubits) { remap_qubits(ops[pos]); - } else if (truncation && qubitmap_.size() != num_qubits_orig) { + } else if (truncation && qubitmap_.size() < ops[pos].qubits.size()) { // truncate save_expval here when remap is not needed if (ops[pos].type == OpType::save_expval || ops[pos].type == OpType::save_expval_var) { int_t nparams = ops[pos].expval_params.size(); for (int_t i = 0; i < nparams; i++) { std::string &pauli = std::get<0>(ops[pos].expval_params[i]); + std::cout << " before truncate : " << pauli << std::endl; pauli.assign(pauli.end() - qubitmap_.size(), pauli.end()); + std::cout << " after truncate : " + << std::get<0>(ops[pos].expval_params[i]) << std::endl; } ops[pos].qubits.resize(qubitmap_.size()); } @@ -673,12 +679,15 @@ void Circuit::remap_qubits(Op &op) const { for (int_t i = 0; i < nparams; i++) { std::string &pauli = std::get<0>(op.expval_params[i]); std::string new_pauli; + std::cout << " before remap : " << pauli << std::endl; new_pauli.resize(qubitmap_.size()); for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) { new_pauli[qubitmap_.size() - 1 - q->second] = pauli[pauli.size() - 1 - q->first]; } pauli = new_pauli; + std::cout << " after remap : " << std::get<0>(op.expval_params[i]) + << std::endl; } for (int_t i = 0; i < qubitmap_.size(); i++) { op.qubits[i] = i; diff --git a/test/terra/backends/aer_simulator/test_save_expval.py b/test/terra/backends/aer_simulator/test_save_expval.py index 36131907f5..a8b7d05dde 100644 --- a/test/terra/backends/aer_simulator/test_save_expval.py +++ b/test/terra/backends/aer_simulator/test_save_expval.py @@ -20,6 +20,7 @@ from qiskit import QuantumCircuit from qiskit.circuit.library import QuantumVolume from qiskit.compiler import transpile +from qiskit.providers.fake_provider import GenericBackendV2 PAULI2 = [ "II", From b006b324fe1c0dfcadc0e8c7905524e0fa5abef4 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 09:35:52 +0900 Subject: [PATCH 05/19] Fix adding qubitset --- src/framework/circuit.hpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 002f6a2349..3b5eb6d722 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -420,7 +420,7 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - if (op.qubits.size() > num_original_qubits) { + if (num_original_qubits > 0 && op.qubits.size() > num_original_qubits) { qubitset_.insert(op.qubits.begin(), op.qubits.begin() + num_original_qubits); } else { @@ -602,10 +602,7 @@ void Circuit::set_params(bool truncation) { int_t nparams = ops[pos].expval_params.size(); for (int_t i = 0; i < nparams; i++) { std::string &pauli = std::get<0>(ops[pos].expval_params[i]); - std::cout << " before truncate : " << pauli << std::endl; pauli.assign(pauli.end() - qubitmap_.size(), pauli.end()); - std::cout << " after truncate : " - << std::get<0>(ops[pos].expval_params[i]) << std::endl; } ops[pos].qubits.resize(qubitmap_.size()); } @@ -679,15 +676,12 @@ void Circuit::remap_qubits(Op &op) const { for (int_t i = 0; i < nparams; i++) { std::string &pauli = std::get<0>(op.expval_params[i]); std::string new_pauli; - std::cout << " before remap : " << pauli << std::endl; new_pauli.resize(qubitmap_.size()); for (auto q = qubitmap_.cbegin(); q != qubitmap_.cend(); q++) { new_pauli[qubitmap_.size() - 1 - q->second] = pauli[pauli.size() - 1 - q->first]; } pauli = new_pauli; - std::cout << " after remap : " << std::get<0>(op.expval_params[i]) - << std::endl; } for (int_t i = 0; i < qubitmap_.size(); i++) { op.qubits[i] = i; From 00129655b0f4743cf3db0bbdd63b0de480c15630 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 11:00:46 +0900 Subject: [PATCH 06/19] add test case, release note and fix docs --- .github/workflows/docs.yml | 4 +- .../truncate_expval-7fa814c732cca8db.yaml | 8 ++++ .../aer_simulator/test_save_expval.py | 1 - test/terra/primitives/test_estimator_v2.py | 38 +++++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/truncate_expval-7fa814c732cca8db.yaml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 074add47a9..9035a83a15 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 with: @@ -50,7 +50,7 @@ jobs: needs: [docs] strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} diff --git a/releasenotes/notes/truncate_expval-7fa814c732cca8db.yaml b/releasenotes/notes/truncate_expval-7fa814c732cca8db.yaml new file mode 100644 index 0000000000..1c7452328b --- /dev/null +++ b/releasenotes/notes/truncate_expval-7fa814c732cca8db.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + This fix truncates qubits of save_expval operation when EstimatorV2 + is made from existing backends using `from_backend`. + By transpiling on the existing backends, ancilla qubits are filled + to all the qubits that causes memory error on the simulator. + So Aer removes unused qubits for save_expval operation. diff --git a/test/terra/backends/aer_simulator/test_save_expval.py b/test/terra/backends/aer_simulator/test_save_expval.py index a8b7d05dde..36131907f5 100644 --- a/test/terra/backends/aer_simulator/test_save_expval.py +++ b/test/terra/backends/aer_simulator/test_save_expval.py @@ -20,7 +20,6 @@ from qiskit import QuantumCircuit from qiskit.circuit.library import QuantumVolume from qiskit.compiler import transpile -from qiskit.providers.fake_provider import GenericBackendV2 PAULI2 = [ "II", diff --git a/test/terra/primitives/test_estimator_v2.py b/test/terra/primitives/test_estimator_v2.py index cee5d28243..988d8dc743 100644 --- a/test/terra/primitives/test_estimator_v2.py +++ b/test/terra/primitives/test_estimator_v2.py @@ -18,6 +18,7 @@ from test.terra.common import QiskitAerTestCase import numpy as np +from qiskit import transpile from qiskit.circuit import Parameter, QuantumCircuit from qiskit.circuit.library import RealAmplitudes from qiskit.primitives import StatevectorEstimator @@ -26,6 +27,7 @@ from qiskit.primitives.containers.observables_array import ObservablesArray from qiskit.quantum_info import SparsePauliOp from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager +from qiskit.providers.fake_provider import GenericBackendV2 from qiskit_aer import AerSimulator from qiskit_aer.primitives import EstimatorV2 @@ -407,6 +409,42 @@ def test_metadata(self): {"target_precision": 0.1, "circuit_metadata": qc2.metadata}, ) + def test_truncate(self): + """Test for truncation of save_expval""" + qc = QuantumCircuit(2, 2) + qc.h(0) + qc.cx(0, 1) + qc.append(RealAmplitudes(num_qubits=2, reps=2), [0, 1]) + backend_2 = GenericBackendV2(num_qubits=2) + backend_5 = GenericBackendV2(num_qubits=5) + + qc_2 = transpile(qc, backend_2, optimization_level=0) + qc_5 = transpile(qc, backend_5, optimization_level=0) + + estimator_2 = EstimatorV2.from_backend(backend_2, options=self._options) + estimator_5 = EstimatorV2.from_backend(backend_5, options=self._options) + + H1 = self.observable + H1_2 = H1.apply_layout(qc_2.layout) + H1_5 = H1.apply_layout(qc_5.layout) + theta1 = [0, 1, 1, 2, 3, 5] + + result_2 = estimator_2.run( + [ + (qc_2, [H1_2], [theta1]), + ], + precision=0.01, + ).result() + result_5 = estimator_5.run( + [ + (qc_5, [H1_5], [theta1]), + ], + precision=0.01, + ).result() + self.assertAlmostEqual( + result_5[0].data["evs"][0], result_2[0].data["evs"][0], delta=self._rtol + ) + if __name__ == "__main__": unittest.main() From 11461a530af3d442496f4e183de4df022abff6b6 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 11:16:46 +0900 Subject: [PATCH 07/19] fix doc --- .github/workflows/docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 9035a83a15..a38a07f587 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -76,7 +76,6 @@ jobs: pip install -c constraints.txt . pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf<1.7.4" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt sudo apt install -y graphviz pandoc libopenblas-dev - pip check shell: bash - name: Run Tutorials run: | From 2b1dfb29a0df1b92a731c8e1539f56687b01ac95 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 11:28:12 +0900 Subject: [PATCH 08/19] fix doc --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a38a07f587..01f0e20bf8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - python-version: ['3.9'] + python-version: ['3.8'] steps: - uses: actions/checkout@v4 with: @@ -50,7 +50,7 @@ jobs: needs: [docs] strategy: matrix: - python-version: ['3.9'] + python-version: ['3.8'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} From b02ba5e458b5bf9a8788cbd7fccdd430f31d681b Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 11:40:57 +0900 Subject: [PATCH 09/19] fix doc --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 01f0e20bf8..a38a07f587 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 with: @@ -50,7 +50,7 @@ jobs: needs: [docs] strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} From 72a4c1409f9a634036a46fc09ac66e03b9b3e049 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 11:55:12 +0900 Subject: [PATCH 10/19] fix doc --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a38a07f587..b710dad04d 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -74,7 +74,7 @@ jobs: pip install -U -r requirements-dev.txt -c constraints.txt pip install -c constraints.txt git+https://github.com/Qiskit/qiskit pip install -c constraints.txt . - pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf<1.7.4" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt + pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt sudo apt install -y graphviz pandoc libopenblas-dev shell: bash - name: Run Tutorials From e2ecaeddb119ccdf86b7aa0408e870e2f8a1a8cb Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 13:05:54 +0900 Subject: [PATCH 11/19] fix doc --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index b710dad04d..3bb442d847 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -76,6 +76,7 @@ jobs: pip install -c constraints.txt . pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt sudo apt install -y graphviz pandoc libopenblas-dev + pip check shell: bash - name: Run Tutorials run: | From df79a10d3976f10a87e3ff1906f723e558edb197 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 13:46:26 +0900 Subject: [PATCH 12/19] fix doc --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3bb442d847..934c849037 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -74,7 +74,7 @@ jobs: pip install -U -r requirements-dev.txt -c constraints.txt pip install -c constraints.txt git+https://github.com/Qiskit/qiskit pip install -c constraints.txt . - pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt + pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt sudo apt install -y graphviz pandoc libopenblas-dev pip check shell: bash From 9195e1aa4b8116a7e8bd978caf4ddce52f8d5312 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 14:20:54 +0900 Subject: [PATCH 13/19] fix doc --- .github/workflows/docs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 934c849037..074add47a9 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - python-version: ['3.9'] + python-version: ['3.8'] steps: - uses: actions/checkout@v4 with: @@ -50,7 +50,7 @@ jobs: needs: [docs] strategy: matrix: - python-version: ['3.9'] + python-version: ['3.8'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -74,7 +74,7 @@ jobs: pip install -U -r requirements-dev.txt -c constraints.txt pip install -c constraints.txt git+https://github.com/Qiskit/qiskit pip install -c constraints.txt . - pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt + pip install -U "qiskit-ibmq-provider" "z3-solver" "qiskit-ignis" "qiskit-aqua" "pyscf<1.7.4" "matplotlib>=3.3.0" jupyter pylatexenc nbsphinx cvxpy qiskit-sphinx-theme -c constraints.txt sudo apt install -y graphviz pandoc libopenblas-dev pip check shell: bash From 0325a24127d83a5a0973476a021c36eca3f083a8 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 14:33:20 +0900 Subject: [PATCH 14/19] fix doc --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 074add47a9..9035a83a15 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -13,7 +13,7 @@ jobs: timeout-minutes: 60 strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 with: @@ -50,7 +50,7 @@ jobs: needs: [docs] strategy: matrix: - python-version: ['3.8'] + python-version: ['3.9'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} From 1ea2d4ff9e826efab6f908f242d5e36a6fbebd9a Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 15:27:21 +0900 Subject: [PATCH 15/19] change truncation strategy --- qiskit_aer/backends/aer_compiler.py | 5 ----- .../backends/wrappers/aer_circuit_binding.hpp | 2 -- src/framework/circuit.hpp | 15 +++++++++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/qiskit_aer/backends/aer_compiler.py b/qiskit_aer/backends/aer_compiler.py index c00223e522..a0c75247cc 100644 --- a/qiskit_aer/backends/aer_compiler.py +++ b/qiskit_aer/backends/aer_compiler.py @@ -695,11 +695,6 @@ def assemble_circuit(circuit: QuantumCircuit, basis_gates=None): aer_circ = AerCircuit() aer_circ.set_header(header) aer_circ.num_qubits = num_qubits - aer_circ.num_original_qubits = num_qubits - if hasattr(circuit, "layout"): - if hasattr(circuit.layout, "final_index_layout"): - if circuit.layout.final_index_layout(True) is not None: - aer_circ.num_original_qubits = len(circuit.layout.final_index_layout(True)) aer_circ.num_memory = num_memory aer_circ.global_phase_angle = global_phase diff --git a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp index 43bc98f12e..7994b60e1d 100644 --- a/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp +++ b/qiskit_aer/backends/wrappers/aer_circuit_binding.hpp @@ -159,8 +159,6 @@ void bind_aer_circuit(MODULE m) { aer_circuit.def_readwrite("circ_id", &Circuit::circ_id); aer_circuit.def_readwrite("shots", &Circuit::shots); aer_circuit.def_readwrite("num_qubits", &Circuit::num_qubits); - aer_circuit.def_readwrite("num_original_qubits", - &Circuit::num_original_qubits); aer_circuit.def_readwrite("num_memory", &Circuit::num_memory); aer_circuit.def_readwrite("seed", &Circuit::seed); aer_circuit.def_readwrite("ops", &Circuit::ops); diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 3b5eb6d722..b2e9adf5ff 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -46,7 +46,6 @@ class Circuit { uint_t num_qubits = 0; // maximum number of qubits needed for ops uint_t num_memory = 0; // maximum number of memory clbits needed for ops uint_t num_registers = 0; // maximum number of registers clbits needed for ops - uint_t num_original_qubits = 0; // number of qubits without ancilla qubits // Measurement params bool has_conditional = false; // True if any ops are conditional @@ -420,9 +419,17 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - if (num_original_qubits > 0 && op.qubits.size() > num_original_qubits) { - qubitset_.insert(op.qubits.begin(), - op.qubits.begin() + num_original_qubits); + if (op.type == OpType::save_expval || + op.type == OpType::save_expval_var) { + for (int_t j = 0; j < op.expval_params.size(); j++) { + const std::string &pauli = std::get<0>(op.expval_params[j]); + for (int_t i = 0; i < op.qubits.size(); i++) { + // add qubit with non-I operator + if (pauli[pauli.size() - 1 - i] != 'I') { + qubitset_.insert(op.qubits[i]); + } + } + } } else { qubitset_.insert(op.qubits.begin(), op.qubits.end()); } From 9e68cc17e1b15622a289c152928447d673603185 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 15:30:18 +0900 Subject: [PATCH 16/19] format --- src/framework/circuit.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index b2e9adf5ff..c87abeb560 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -46,6 +46,7 @@ class Circuit { uint_t num_qubits = 0; // maximum number of qubits needed for ops uint_t num_memory = 0; // maximum number of memory clbits needed for ops uint_t num_registers = 0; // maximum number of registers clbits needed for ops + uint_t num_original_qubits = 0; // number of qubits without ancilla qubits // Measurement params bool has_conditional = false; // True if any ops are conditional @@ -419,8 +420,8 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - if (op.type == OpType::save_expval || - op.type == OpType::save_expval_var) { + std::cout << op << std::endl; + if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) { for (int_t j = 0; j < op.expval_params.size(); j++) { const std::string &pauli = std::get<0>(op.expval_params[j]); for (int_t i = 0; i < op.qubits.size(); i++) { From 41ae7d5099f5cab969355c9416acc49ebb3a9a54 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 15:40:32 +0900 Subject: [PATCH 17/19] remove print --- src/framework/circuit.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index c87abeb560..7b5d06506f 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -420,7 +420,6 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - std::cout << op << std::endl; if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) { for (int_t j = 0; j < op.expval_params.size(); j++) { const std::string &pauli = std::get<0>(op.expval_params[j]); From f46b08ed0e964e415bd5af7dd66d62b781e86ed5 Mon Sep 17 00:00:00 2001 From: "U-AzureAD\\JUNDOI" Date: Wed, 11 Sep 2024 16:48:09 +0900 Subject: [PATCH 18/19] no truncation when circuit is empty --- src/framework/circuit.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/framework/circuit.hpp b/src/framework/circuit.hpp index 7b5d06506f..eab35cd514 100644 --- a/src/framework/circuit.hpp +++ b/src/framework/circuit.hpp @@ -420,7 +420,8 @@ void Circuit::reset_metadata() { void Circuit::add_op_metadata(const Op &op) { has_conditional |= op.conditional; opset_.insert(op); - if (op.type == OpType::save_expval || op.type == OpType::save_expval_var) { + if (!qubitset_.empty() && + (op.type == OpType::save_expval || op.type == OpType::save_expval_var)) { for (int_t j = 0; j < op.expval_params.size(); j++) { const std::string &pauli = std::get<0>(op.expval_params[j]); for (int_t i = 0; i < op.qubits.size(); i++) { @@ -609,7 +610,9 @@ void Circuit::set_params(bool truncation) { int_t nparams = ops[pos].expval_params.size(); for (int_t i = 0; i < nparams; i++) { std::string &pauli = std::get<0>(ops[pos].expval_params[i]); - pauli.assign(pauli.end() - qubitmap_.size(), pauli.end()); + std::string new_pauli; + new_pauli.assign(pauli.end() - qubitmap_.size(), pauli.end()); + pauli = new_pauli; } ops[pos].qubits.resize(qubitmap_.size()); } From 8cf747bf874f20e34c83e6d27543ba73acbbab96 Mon Sep 17 00:00:00 2001 From: Hiroshi Horii Date: Thu, 12 Sep 2024 17:47:50 +0900 Subject: [PATCH 19/19] Update VERSION.txt revert to 0.15.0 --- qiskit_aer/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit_aer/VERSION.txt b/qiskit_aer/VERSION.txt index 04a373efe6..a551051694 100644 --- a/qiskit_aer/VERSION.txt +++ b/qiskit_aer/VERSION.txt @@ -1 +1 @@ -0.16.0 +0.15.0