Skip to content

Commit

Permalink
Change priority of method selection of noise simulation (Qiskit#1989)
Browse files Browse the repository at this point in the history
* Avoid selecting stabilizer method when noise model contains rotational gates

* remove checking noise opsets, change priority selecting density_matrix

* format

* modify test cases use auto method result may change by this PR

* modify one more test case
  • Loading branch information
doichanj committed Nov 9, 2023
1 parent 5db25fd commit b6defad
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Fixed `stabilizer` was selected with `method="automatic" ` when simulating
circuits with rotational gates with noise models for small number of qubits
even it is faster to calculate with `density_matrix` method.
This fix checks if `density_matrix` method with noise model is faster or not
at first and then check using `stabilizer` method.
This is side effect of implementing rotational gates in stabilizer PR #1938
10 changes: 5 additions & 5 deletions src/controllers/aer_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -833,22 +833,22 @@ Controller::simulation_methods(const Config &config,
Method Controller::automatic_simulation_method(
const Config &config, const Circuit &circ,
const Noise::NoiseModel &noise_model) const {
// If circuit and noise model are Clifford run on Stabilizer simulator
if (validate_method(Method::stabilizer, config, circ, noise_model, false)) {
return Method::stabilizer;
}
// For noisy simulations we enable the density matrix method if
// shots > 2 ** num_qubits. This is based on a rough estimate that
// a single shot of the density matrix simulator is approx 2 ** nq
// times slower than a single shot of statevector due the increased
// dimension
if (noise_model.has_quantum_errors() && circ.num_qubits < 64 &&
if (noise_model.has_quantum_errors() && circ.num_qubits < 30 &&
circ.shots > (1ULL << circ.num_qubits) &&
validate_method(Method::density_matrix, config, circ, noise_model,
false) &&
circ.can_sample) {
return Method::density_matrix;
}
// If circuit and noise model are Clifford run on Stabilizer simulator
if (validate_method(Method::stabilizer, config, circ, noise_model, false)) {
return Method::stabilizer;
}

// If the special conditions for stabilizer or density matrix are
// not satisfied we choose simulation method based on supported
Expand Down
30 changes: 23 additions & 7 deletions test/terra/backends/aer_simulator/test_auto_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class TestSimulationMethod(SimulatorTestCase):
# ---------------------------------------------------------------------

def test_auto_method_clifford_circuits(self):
"""Test statevector method is used for Clifford circuit"""
"""Test stabilizer method is used for Clifford circuit"""
# Test circuits
backend = self.backend()
shots = 100
Expand All @@ -59,7 +59,7 @@ def test_auto_method_clifford_circuits(self):
self.compare_result_metadata(result, circuits, "method", "stabilizer")

def test_auto_method_clifford_circuits_and_reset_noise(self):
"""Test statevector method is used for Clifford circuit"""
"""Test stabilizer method is used for Clifford circuit"""
# Test noise model
noise_circs = [Reset(), IGate()]
noise_probs = [0.5, 0.5]
Expand All @@ -69,31 +69,47 @@ def test_auto_method_clifford_circuits_and_reset_noise(self):
backend = self.backend(noise_model=noise_model)

# Test circuits
shots = 100
shots = 4
circuits = ref_2q_clifford.cz_gate_circuits_deterministic(final_measure=True)
result = backend.run(circuits, shots=shots).result()
success = getattr(result, "success", False)
self.assertTrue(success)
self.compare_result_metadata(result, circuits, "method", "stabilizer")

def test_auto_method_clifford_circuits_and_pauli_noise(self):
"""Test statevector method is used for Clifford circuit"""
"""Test stabilizer method is used for Clifford circuit"""
# Noise Model
error = pauli_error([["XX", 0.5], ["II", 0.5]])
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(error, ["cz", "cx"])
backend = self.backend(noise_model=noise_model)

# Test circuits
shots = 100
shots = 4
circuits = ref_2q_clifford.cz_gate_circuits_deterministic(final_measure=True)
result = backend.run(circuits, shots=shots).result()
success = getattr(result, "success", False)
self.assertTrue(success)
self.compare_result_metadata(result, circuits, "method", "stabilizer")

def test_auto_method_clifford_circuits_and_pauli_noise_with_many_shots(self):
"""Test density_matrix method is used for Clifford circuit"""
# Noise Model
error = pauli_error([["XX", 0.5], ["II", 0.5]])
noise_model = NoiseModel()
noise_model.add_all_qubit_quantum_error(error, ["cz", "cx"])
backend = self.backend(noise_model=noise_model)

# Test circuits
shots = 1000
circuits = ref_2q_clifford.cz_gate_circuits_deterministic(final_measure=True)
result = backend.run(circuits, shots=shots).result()
success = getattr(result, "success", False)
self.assertTrue(success)
self.compare_result_metadata(result, circuits, "method", "density_matrix")

def test_auto_method_clifford_circuits_and_unitary_noise(self):
"""Test statevector method is used for Clifford circuit"""
"""Test density_matrix method is used for Clifford circuit"""
# Noise Model
error = mixed_unitary_error(
[(Pauli("XX").to_matrix(), 0.5), (Pauli("II").to_matrix(), 0.5)]
Expand All @@ -110,7 +126,7 @@ def test_auto_method_clifford_circuits_and_unitary_noise(self):
self.compare_result_metadata(result, circuits, "method", "density_matrix")

def test_auto_method_clifford_circuits_and_kraus_noise(self):
"""Test statevector method is used for Clifford circuit"""
"""Test density_matrix method is used for Clifford circuit"""
# Noise Model
error = amplitude_damping_error(0.5)
noise_model = NoiseModel()
Expand Down
3 changes: 2 additions & 1 deletion test/terra/backends/aer_simulator/test_measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ def test_measure_sampling_with_quantum_noise(self, method, device):
targets = ref_measure.measure_counts_deterministic(shots)
result = backend.run(circuits, shots=shots).result()
self.assertSuccess(result)
sampling = method == "density_matrix" or method == "tensor_network"
method_used = result.results[0].metadata.get("method")
sampling = method_used == "density_matrix" or method_used == "tensor_network"
self.compare_result_metadata(result, circuits, "measure_sampling", sampling)

# ---------------------------------------------------------------------
Expand Down
13 changes: 10 additions & 3 deletions test/terra/backends/aer_simulator/test_thread_management.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ def test_parallel_defaults_single_ideal(self):
def test_parallel_defaults_single_noise(self):
"""Test parallel thread assignment defaults"""
backend = self.backend(
noise_model=self.dummy_noise_model(), **self.backend_options_parallel()
method="statevector",
noise_model=self.dummy_noise_model(),
**self.backend_options_parallel(),
)
max_threads = self.available_threads()

Expand Down Expand Up @@ -209,7 +211,9 @@ def test_parallel_defaults_multi_ideal(self):
def test_parallel_defaults_multi_noise(self):
"""Test parallel thread assignment defaults"""
backend = self.backend(
noise_model=self.dummy_noise_model(), **self.backend_options_parallel()
method="statevector",
noise_model=self.dummy_noise_model(),
**self.backend_options_parallel(),
)
max_threads = self.available_threads()

Expand Down Expand Up @@ -295,7 +299,9 @@ def test_parallel_thread_assignment(self, custom_max_threads):
# Test single circuit, with noise
# Parallel experiments should always be 1
# parallel shots should be greater than 1
backend = self.backend(noise_model=self.dummy_noise_model(), **parallel_opts)
backend = self.backend(
method="statevector", noise_model=self.dummy_noise_model(), **parallel_opts
)
circuits = self.dummy_circuit(1)
result = backend.run(circuits, shots=shots).result()
for threads in self.threads_used(result):
Expand Down Expand Up @@ -531,6 +537,7 @@ def test_parallel_shot_thread_multi_noise(self):

max_threads = self.available_threads()
backend = self.backend(
method="statevector",
noise_model=self.dummy_noise_model(),
**self.backend_options_parallel(shot_threads=max_threads),
)
Expand Down

0 comments on commit b6defad

Please sign in to comment.