From 6563fb5a27d91510a276e1409b5c6f2c9c771d3d Mon Sep 17 00:00:00 2001 From: Jun Doi Date: Mon, 3 Jun 2024 18:42:43 +0900 Subject: [PATCH] Add save_expval to extended_stabilizer --- qiskit_aer/backends/aer_simulator.py | 2 + .../extended_stabilizer/ch_runner.hpp | 11 ++++- .../extended_stabilizer_state.hpp | 42 ++++++++++++++----- .../aer_simulator/test_save_expval.py | 14 ++++++- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/qiskit_aer/backends/aer_simulator.py b/qiskit_aer/backends/aer_simulator.py index 541058a4e5..2ae343bf27 100644 --- a/qiskit_aer/backends/aer_simulator.py +++ b/qiskit_aer/backends/aer_simulator.py @@ -607,6 +607,8 @@ class AerSimulator(AerBackend): "roerror", "save_statevector", "reset", + "save_expval", + "save_expval_var", ] ), "unitary": sorted( diff --git a/src/simulators/extended_stabilizer/ch_runner.hpp b/src/simulators/extended_stabilizer/ch_runner.hpp index 489d6b77ad..b5f35a05c0 100644 --- a/src/simulators/extended_stabilizer/ch_runner.hpp +++ b/src/simulators/extended_stabilizer/ch_runner.hpp @@ -411,8 +411,15 @@ double Runner::norm_estimation(uint_t n_samples, uint_t repetitions, std::vector adiag_2(n_samples, 0ULL); std::vector> a(n_samples, std::vector(n_qubits_, 0ULL)); + std::vector rngs(num_threads_); #pragma omp parallel if (num_threads_ > 1) num_threads(num_threads_) { + int tid = omp_get_thread_num(); + // make rng for each threads + if (tid == 0) + rngs[0] = rng; + else + rngs[tid].set_seed(rng.initial_seed() + tid); #ifdef _WIN32 #pragma omp for #else @@ -421,13 +428,13 @@ double Runner::norm_estimation(uint_t n_samples, uint_t repetitions, for (int_t l = 0; l < NSAMPLES; l++) { for (int_t i = 0; i < NQUBITS; i++) { for (int_t j = i; j < NQUBITS; j++) { - if (rng.rand() < 0.5) { + if (rngs[tid].rand() < 0.5) { a[l][i] |= (1ULL << j); a[l][j] |= (1ULL << i); } } adiag_1[l] |= (a[l][i] & (1ULL << i)); - if (rng.rand() < 0.5) { + if (rngs[tid].rand() < 0.5) { adiag_2[l] |= (1ULL << i); } } diff --git a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp index cc8c91adf1..1f292dd7d5 100644 --- a/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp +++ b/src/simulators/extended_stabilizer/extended_stabilizer_state.hpp @@ -42,7 +42,9 @@ const Operations::OpSet StateOpSet( Operations::OpType::bfunc, Operations::OpType::qerror_loc, Operations::OpType::save_statevec, - }, // Operations::OpType::save_expval, Operations::OpType::save_expval_var}, + Operations::OpType::save_expval, + Operations::OpType::save_expval_var, + }, // Gates {"CX", "u0", "u1", "p", "cx", "cz", "swap", "id", "x", "y", "z", "h", "s", "sdg", "sx", "sxdg", @@ -329,7 +331,8 @@ bool State::check_measurement_opt(InputIterator first, if (op->type == Operations::OpType::measure || op->type == Operations::OpType::bfunc || op->type == Operations::OpType::save_statevec || - op->type == Operations::OpType::save_expval) { + op->type == Operations::OpType::save_expval || + op->type == Operations::OpType::save_expval_var) { return false; } } @@ -399,10 +402,10 @@ void State::apply_ops(InputIterator first, InputIterator last, apply_save_statevector(op, result); break; // Disabled until can fix bug in expval - // case Operations::OpType::save_expval: - // case Operations::OpType::save_expval_var: - // apply_save_expval(op, result, rng); - // break; + case Operations::OpType::save_expval: + case Operations::OpType::save_expval_var: + apply_save_expval(op, result, rng); + break; default: throw std::invalid_argument("CH::State::apply_ops does not support " "operations of the type \'" + @@ -783,14 +786,15 @@ double State::expval_pauli(const reg_t &qubits, const std::string &pauli, case 'I': break; case 'X': - paulis[0].X += (1ULL << qubits[pos]); + paulis[0].X |= (1ULL << qubits[pos]); break; case 'Y': - paulis[0].X += (1ULL << qubits[pos]); - paulis[0].Z += (1ULL << qubits[pos]); + paulis[0].X |= (1ULL << qubits[pos]); + paulis[0].Z |= (1ULL << qubits[pos]); + paulis[0].e += 1; break; case 'Z': - paulis[0].Z += (1ULL << qubits[pos]); + paulis[0].Z |= (1ULL << qubits[pos]); break; default: { std::stringstream msg; @@ -799,9 +803,25 @@ double State::expval_pauli(const reg_t &qubits, const std::string &pauli, } } } + paulis[0].e = paulis[0].e % 4; auto g_norm = state_cpy.norm_estimation( norm_estimation_samples_, norm_estimation_repetitions_, paulis, rng); - return (2 * g_norm - phi_norm); + // std::cout << pauli << ", phi_norm = " << phi_norm << " gnorm = "< 0.5) + return 1.0; + else + return 0.0; + } else { + return t; + } } double State::expval_pauli(const reg_t &qubits, const std::string &pauli) { diff --git a/test/terra/backends/aer_simulator/test_save_expval.py b/test/terra/backends/aer_simulator/test_save_expval.py index 36131907f5..c079a3fc02 100644 --- a/test/terra/backends/aer_simulator/test_save_expval.py +++ b/test/terra/backends/aer_simulator/test_save_expval.py @@ -82,6 +82,7 @@ def _test_save_expval(self, circuit, oper, qubits, variance, **options): "density_matrix", "matrix_product_state", "tensor_network", + "extended_stabilizer", ], PAULI2, ) @@ -102,6 +103,7 @@ def test_save_expval_bell_pauli(self, method, device, pauli): "density_matrix", "matrix_product_state", "tensor_network", + "extended_stabilizer", ], PAULI2, ) @@ -121,6 +123,7 @@ def test_save_expval_stabilizer_pauli(self, method, device, pauli): "density_matrix", "matrix_product_state", "tensor_network", + "extended_stabilizer", ], PAULI2, ) @@ -140,6 +143,7 @@ def test_save_expval_var_stabilizer_pauli(self, method, device, pauli): "density_matrix", "matrix_product_state", "tensor_network", + "extended_stabilizer", ], [[0, 1], [1, 0], [0, 2], [2, 0], [1, 2], [2, 1]], ) @@ -158,6 +162,7 @@ def test_save_expval_stabilizer_hermitian(self, method, device, qubits): "density_matrix", "matrix_product_state", "tensor_network", + "extended_stabilizer", ], # , 'extended_stabilizer'], [[0, 1], [1, 0], [0, 2], [2, 0], [1, 2], [2, 1]], ) @@ -169,7 +174,14 @@ def test_save_expval_var_stabilizer_hermitian(self, method, device, qubits): self._test_save_expval(circ, oper, qubits, True, method=method, device=device) @supported_methods( - ["automatic", "statevector", "density_matrix", "matrix_product_state", "tensor_network"], + [ + "automatic", + "statevector", + "density_matrix", + "matrix_product_state", + "tensor_network", + "extended_stabilizer", + ], PAULI2, ) def test_save_expval_nonstabilizer_pauli(self, method, device, pauli):