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

Change priority of method selection of noise simulation #1989

Merged
merged 6 commits into from
Nov 8, 2023
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading