Skip to content

Commit

Permalink
Fix AerSimulator options (#1204)
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseclectic authored Apr 1, 2021
1 parent c4b88f5 commit bd91677
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 44 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ jobs:
tests-json-input:
runs-on: ${{ matrix.os }}
needs: [sdist, lint]
timeout-minutes: 30
timeout-minutes: 45
strategy:
matrix:
python-version: [3.9]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests_mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ jobs:
tests-json-input:
runs-on: ${{ matrix.os }}
needs: [sdist, lint]
timeout-minutes: 40
timeout-minutes: 45
strategy:
matrix:
python-version: [3.9]
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests_windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ jobs:
tests-json-input:
runs-on: ${{ matrix.os }}
needs: ["lint"]
timeout-minutes: 30
timeout-minutes: 45
strategy:
matrix:
python-version: [3.9]
Expand Down
6 changes: 4 additions & 2 deletions qiskit/providers/aer/backends/aer_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ def _default_options(cls):
return Options(
# Global options
shots=1024,
method=None,
device=None,
method='automatic',
device='CPU',
precision="double",
zero_threshold=1e-10,
validation_threshold=None,
Expand All @@ -498,8 +498,10 @@ def _default_options(cls):
fusion_threshold=14,
accept_distributed_results=None,
blocking_qubits=None,
blocking_enable=False,
memory=None,
noise_model=None,
seed_simulator=None,
# statevector options
statevector_parallel_threshold=14,
statevector_sample_measure_opt=10,
Expand Down
55 changes: 18 additions & 37 deletions qiskit/providers/aer/backends/aerbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,6 @@ def run(self,
and direct kwarg's should be used for options to pass them to
``run_options``.
"""
if isinstance(circuits, (QasmQobj, PulseQobj)):
warnings.warn('Using a qobj for run() is deprecated and will be '
'removed in a future release.',
PendingDeprecationWarning,
stacklevel=2)
qobj = circuits
else:
options_dict = {}
for key, value in self.options.__dict__.items():
if value is not None:
options_dict[key] = value
qobj = assemble(circuits, self, **options_dict)
# DEPRECATED
if backend_options is not None:
warnings.warn(
Expand All @@ -158,9 +146,19 @@ def run(self,
DeprecationWarning,
stacklevel=3)

if isinstance(circuits, (QasmQobj, PulseQobj)):
warnings.warn('Using a qobj for run() is deprecated and will be '
'removed in a future release.',
PendingDeprecationWarning,
stacklevel=2)
qobj = circuits
else:
qobj = assemble(circuits, self)

# Add backend options to the Job qobj
qobj = self._format_qobj(
self._add_options_to_qobj(
qobj, backend_options=backend_options, **run_options)

# Optional validation
if validate:
self._validate(qobj)
Expand Down Expand Up @@ -253,9 +251,10 @@ def _run_job(self, job_id, qobj, backend_options, noise_model, validate):
# type check to swap them back
if not isinstance(job_id, str) and isinstance(qobj, str):
job_id, qobj = qobj, job_id
run_qobj = self._format_qobj(qobj, backend_options=backend_options,
noise_model=noise_model)
return self._run(run_qobj, job_id)
self._add_options_to_qobj(qobj,
backend_options=backend_options,
noise_model=noise_model)
return self._run(qobj, job_id)

def _run(self, qobj, job_id=''):
"""Run a job"""
Expand Down Expand Up @@ -372,9 +371,9 @@ def _set_defaults_option(self, key, value):
elif key in self._options_defaults:
self._options_defaults.pop(key)

def _format_qobj(self, qobj,
backend_options=None, # DEPRECATED
**run_options):
def _add_options_to_qobj(self, qobj,
backend_options=None, # DEPRECATED
**run_options):
"""Return execution sim config dict from backend options."""
# Add options to qobj config overriding any existing fields
config = qobj.config
Expand All @@ -395,24 +394,6 @@ def _format_qobj(self, qobj,

return qobj

def _run_config(
self,
backend_options=None, # DEPRECATED
**run_options):
"""Return execution sim config dict from backend options."""
# Get sim config
run_config = self._options.copy()

# DEPRECATED backend options
if backend_options is not None:
for key, val in backend_options.items():
run_config[key] = val

# Override with run-time options
for key, val in run_options.items():
run_config[key] = val
return run_config

def __repr__(self):
"""String representation of an AerBackend."""
name = self.__class__.__name__
Expand Down
13 changes: 12 additions & 1 deletion src/controllers/aer_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ class Controller {
// Simulation precision
enum class Precision { Double, Single };

const std::unordered_map<Method, std::string> method_names_ = {
{Method::automatic, "automatic"},
{Method::statevector, "statevector"},
{Method::density_matrix, "density_matrix"},
{Method::matrix_product_state, "matrix_product_state"},
{Method::stabilizer, "stabilizer"},
{Method::extended_stabilizer, "extended_stabilizer"},
{Method::unitary, "unitary"},
{Method::superop, "superop"}
};

//-----------------------------------------------------------------------
// Config
//-----------------------------------------------------------------------
Expand Down Expand Up @@ -1844,7 +1855,7 @@ void Controller::run_circuit_helper(const Circuit &circ,

// Output data container
result.set_config(config);
result.metadata.add(state.name(), "method");
result.metadata.add(method_names_.at(method), "method");
if (method == Method::statevector || method == Method::density_matrix ||
method == Method::unitary) {
result.metadata.add(sim_device_name_, "device");
Expand Down
92 changes: 92 additions & 0 deletions test/terra/backends/aer_simulator/test_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# This code is part of Qiskit.
#
# (C) Copyright IBM 2018, 2021.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""
AerSimualtor options tests
"""

from ddt import ddt
from qiskit import QuantumCircuit, transpile
from .aer_simulator_test_case import (
AerSimulatorTestCase, supported_methods)


@ddt
class TestOptions(AerSimulatorTestCase):
"""Tests of AerSimulator options"""

@supported_methods(
['automatic', 'stabilizer', 'statevector', 'density_matrix',
'matrix_product_state', 'extended_stabilizer'])
def test_seed_simulator_option_measure(self, method, device):
"""Test seed_simulator option fixes measurement outcomes"""
backend = self.backend(method=method, device=device,
seed_simulator=111)
qc = QuantumCircuit(2)
qc.h([0, 1])
qc.reset(0)
qc.measure_all()
qc = transpile(qc, backend)

counts1 = backend.run(qc).result().get_counts(0)
counts2 = backend.run(qc).result().get_counts(0)

self.assertEqual(counts1, counts2)

@supported_methods(
['automatic', 'stabilizer', 'statevector', 'density_matrix',
'matrix_product_state', 'extended_stabilizer'])
def test_seed_simulator_run_option_measure(self, method, device):
"""Test seed_simulator option fixes measurement outcomes"""
backend = self.backend(method=method, device=device)
qc = QuantumCircuit(2)
qc.h([0, 1])
qc.reset(0)
qc.measure_all()
qc = transpile(qc, backend)
seed = 1234
counts1 = backend.run(qc, seed_simulator=seed).result().get_counts(0)
counts2 = backend.run(qc, seed_simulator=seed).result().get_counts(0)
self.assertEqual(counts1, counts2)

@supported_methods(
['automatic', 'stabilizer', 'statevector', 'density_matrix',
'matrix_product_state', 'extended_stabilizer', 'unitary', 'superop'])
def test_method(self, method, device):
"""Test seed_simulator option fixes measurement outcomes"""
backend = self.backend(method=method, device=device)
qc = QuantumCircuit(1)
qc.x(0)
qc = transpile(qc, backend)

# Target simulation method
if method == 'automatic':
target = 'stabilizer'
else:
target = method

result = backend.run(qc).result()
value = result.results[0].metadata.get('method', None)
self.assertEqual(value, target)

@supported_methods(
['automatic', 'stabilizer', 'statevector', 'density_matrix',
'matrix_product_state', 'extended_stabilizer', 'unitary', 'superop'])
def test_device(self, method, device):
"""Test seed_simulator option fixes measurement outcomes"""
backend = self.backend(method=method, device=device)
qc = QuantumCircuit(1)
qc.x(0)
qc = transpile(qc, backend)

result = backend.run(qc).result()
value = result.results[0].metadata.get('device', None)
self.assertEqual(value, device)
3 changes: 2 additions & 1 deletion test/terra/extensions/test_wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def _create_qobj(self, backend, noise_model=None):
qobj = assemble(transpile(circuit, backend), backend)
opts = {'max_parallel_threads': 1,
'library_dir': LIBRARY_DIR}
return backend._format_qobj(qobj, **opts, noise_model=noise_model)
backend._add_options_to_qobj(qobj, **opts, noise_model=noise_model)
return qobj

def _map_and_test(self, cfunc, qobj):
n = 2
Expand Down

0 comments on commit bd91677

Please sign in to comment.