Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into profile-thresholds
Browse files Browse the repository at this point in the history
  • Loading branch information
hhorii committed Mar 26, 2021
2 parents 6ea3ab8 + 25a6d91 commit 5c45c50
Show file tree
Hide file tree
Showing 84 changed files with 2,430 additions and 536 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = [
"setuptools",
"wheel",
"conan>=1.31.2",
"scikit-build",
"scikit-build>=0.11.0",
"cmake!=3.17.1,!=3.17.0",
"ninja",
"pybind11>2.6",
Expand Down
5 changes: 3 additions & 2 deletions qiskit/providers/aer/aerjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import logging
import functools

from qiskit.providers import BaseJob, JobStatus, JobError
from qiskit.providers import JobV1 as Job
from qiskit.providers import JobStatus, JobError

logger = logging.getLogger(__name__)

Expand All @@ -43,7 +44,7 @@ def _wrapper(self, *args, **kwargs):
return _wrapper


class AerJob(BaseJob):
class AerJob(Job):
"""AerJob class.
Attributes:
Expand Down
11 changes: 4 additions & 7 deletions qiskit/providers/aer/aerprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

# pylint: disable=invalid-name, bad-continuation

# pylint: disable=invalid-name
"""Provider for Qiskit Aer backends."""

from qiskit.providers import BaseProvider
from qiskit.providers import ProviderV1 as Provider
from qiskit.providers.providerutils import filter_backends

from .backends.qasm_simulator import QasmSimulator
Expand All @@ -24,12 +23,10 @@
from .profile import profile_performance_options


class AerProvider(BaseProvider):
class AerProvider(Provider):
"""Provider for Qiskit Aer backends."""

def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)

def __init__(self):
# Populate the list of Aer simulator backends.
self._backends = [
('qasm_simulator', QasmSimulator),
Expand Down
169 changes: 94 additions & 75 deletions qiskit/providers/aer/backends/aerbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
from abc import ABC, abstractmethod
from numpy import ndarray

from qiskit.providers import BaseBackend
from qiskit.providers import BackendV1 as Backend
from qiskit.providers.models import BackendStatus
from qiskit.result import Result
from qiskit.utils import deprecate_arguments
from qiskit.qobj import QasmQobj, PulseQobj
from qiskit.compiler import assemble

from qiskit.providers.aer.profile import get_performance_options

Expand Down Expand Up @@ -57,7 +60,7 @@ def default(self, obj):
return super().default(obj)


class AerBackend(BaseBackend, ABC):
class AerBackend(Backend, ABC):
"""Qiskit Aer Backend class."""
def __init__(self,
configuration,
Expand All @@ -78,45 +81,46 @@ def __init__(self,
defaults (PulseDefaults or None): Optional, backend pulse defaults.
available_methods (list or None): Optional, the available simulation methods
if backend supports multiple methods.
provider (BaseProvider): Optional, provider responsible for this backend.
provider (Provider): Optional, provider responsible for this backend.
backend_options (dict or None): Optional set custom backend options.
Raises:
AerError: if there is no name in the configuration
"""
# Init configuration and provider in BaseBackend
# Init configuration and provider in Backend
configuration.simulator = True
configuration.local = True
super().__init__(configuration, provider=provider)

# Initialize backend properties and pulse defaults.
self._properties = properties
self._defaults = defaults

# Custom configuration, properties, and pulse defaults which will store
# any configured modifications to the base simulator values.
self._custom_configuration = None
self._custom_properties = None
self._custom_defaults = None
# Custom option values for config, properties, and defaults
self._options_configuration = {}
self._options_defaults = {}
self._options_properties = {}

# Set available methods
self._available_methods = [] if available_methods is None else available_methods

# Set custom configured options from backend_options dictionary
self._options = {}
# Set options from backend_options dictionary
if backend_options is not None:
for key, val in backend_options.items():
self._set_option(key, val)
self.set_option(key, val)

# pylint: disable=arguments-differ
@deprecate_arguments({'qobj': 'circuits'})
def run(self,
qobj,
circuits,
backend_options=None, # DEPRECATED
validate=False,
**run_options):
"""Run a qobj on the backend.
Args:
qobj (QasmQobj): The Qobj to be executed.
circuits (QuantumCircuit or list): The QuantumCircuit (or list
of QuantumCircuit objects) to run
backend_options (dict or None): DEPRECATED dictionary of backend options
for the execution (default: None).
validate (bool): validate the Qobj before running (default: False).
Expand All @@ -135,6 +139,18 @@ 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 Down Expand Up @@ -172,9 +188,14 @@ def configuration(self):
Returns:
BackendConfiguration: the configuration for the backend.
"""
if self._custom_configuration is not None:
return self._custom_configuration
return self._configuration
config = copy.copy(self._configuration)
for key, val in self._options_configuration.items():
setattr(config, key, val)
# If config has custom instructions add them to
# basis gates to include them for the terra transpiler
if hasattr(config, 'custom_instructions'):
config.basis_gates += config.custom_instructions
return config

def properties(self):
"""Return the simulator backend properties if set.
Expand All @@ -183,9 +204,10 @@ def properties(self):
BackendProperties: The backend properties or ``None`` if the
backend does not have properties set.
"""
if self._custom_properties is not None:
return self._custom_properties
return self._properties
properties = copy.copy(self._properties)
for key, val in self._options_properties.items():
setattr(properties, key, val)
return properties

def defaults(self):
"""Return the simulator backend pulse defaults.
Expand All @@ -194,26 +216,21 @@ def defaults(self):
PulseDefaults: The backend pulse defaults or ``None`` if the
backend does not support pulse.
"""
if self._custom_defaults is not None:
return self._custom_defaults
return self._defaults

@property
def options(self):
"""Return the current simulator options"""
return self._options
defaults = copy.copy(self._defaults)
for key, val in self._options_defaults.items():
setattr(defaults, key, val)
return defaults

def set_options(self, **backend_options):
"""Set the simulator options"""
for key, val in backend_options.items():
self._set_option(key, val)
@classmethod
def _default_options(cls):
pass

def clear_options(self):
"""Reset the simulator options to default values."""
self._custom_configuration = None
self._custom_properties = None
self._custom_defaults = None
self._options = {}
self._options = self._default_options()
self._options_configuration = {}
self._options_properties = {}
self._options_defaults = {}

def available_methods(self):
"""Return the available simulation methods."""
Expand Down Expand Up @@ -293,7 +310,7 @@ def _validate(self, qobj):
"""Validate the qobj for the backend"""
pass

def _set_option(self, key, value):
def set_option(self, key, value):
"""Special handling for setting backend options.
This method should be extended by sub classes to
Expand All @@ -306,22 +323,6 @@ def _set_option(self, key, value):
Raises:
AerError: if key is 'method' and val isn't in available methods.
"""
# Check for key in configuration, properties, and defaults
# If the key requires modification of one of these fields a copy
# will be generated that can store the modified values without
# changing the original object
if hasattr(self._configuration, key):
self._set_configuration_option(key, value)
return

if hasattr(self._properties, key):
self._set_properties_option(key, value)
return

if hasattr(self._defaults, key):
self._set_defaults_option(key, value)
return

# If key is method, we validate it is one of the available methods
if key == 'method' and value not in self._available_methods:
raise AerError("Invalid simulation method {}. Available methods"
Expand All @@ -331,30 +332,48 @@ def _set_option(self, key, value):
# TODO: in the future this could be replaced with an options class
# for the simulators like configuration/properties to show all
# available options
if value is not None:
# Only add an option if its value is not None
self._options[key] = value
elif key in self._options:
# If setting an existing option to None remove it from options dict
self._options.pop(key)
if hasattr(self._configuration, key):
self._set_configuration_option(key, value)
elif hasattr(self._properties, key):
self._set_properties_option(key, value)
elif hasattr(self._defaults, key):
self._set_defaults_option(key, value)
else:
if not hasattr(self._options, key):
raise AerError("Invalid option %s" % key)
if value is not None:
# Only add an option if its value is not None
setattr(self._options, key, value)
else:
# If setting an existing option to None reset it to default
# this is for backwards compatibility when setting it to None would
# remove it from the options dict
setattr(self._options, key, getattr(self._default_options(), key))

def set_options(self, **fields):
for key, value in fields.items():
self.set_option(key, value)

def _set_configuration_option(self, key, value):
"""Special handling for setting backend configuration options."""
if self._custom_configuration is None:
self._custom_configuration = copy.copy(self._configuration)
setattr(self._custom_configuration, key, value)
if value is not None:
self._options_configuration[key] = value
elif key in self._options_configuration:
self._options_configuration.pop(key)

def _set_properties_option(self, key, value):
"""Special handling for setting backend properties options."""
if self._custom_properties is None:
self._custom_properties = copy.copy(self._properties)
setattr(self._custom_properties, key, value)
if value is not None:
self._options_properties[key] = value
elif key in self._options_properties:
self._options_properties.pop(key)

def _set_defaults_option(self, key, value):
"""Special handling for setting backend defaults options."""
if self._custom_defaults is None:
self._custom_defaults = copy.copy(self._defaults)
setattr(self._custom_defaults, key, value)
if value is not None:
self._options_defaults[key] = value
elif key in self._options_defaults:
self._options_defaults.pop(key)

def _format_qobj(self, qobj,
backend_options=None, # DEPRECATED
Expand All @@ -364,8 +383,9 @@ def _format_qobj(self, qobj,
config = qobj.config

# Add options
for key, val in self.options.items():
setattr(config, key, val)
for key, val in self.options.__dict__.items():
if val is not None and not hasattr(config, key):
setattr(config, key, val)

# DEPRECATED backend options
if backend_options is not None:
Expand Down Expand Up @@ -398,9 +418,8 @@ def _run_config(

def __repr__(self):
"""String representation of an AerBackend."""
display = "backend_name='{}'".format(self.name())
name = self.__class__.__name__
display = f"backend_name='{self.name()}'"
if self.provider():
display += ', provider={}()'.format(self.provider())
for key, val in self.options.items():
display += ',\n {}={}'.format(key, repr(val))
return '{}(\n{})'.format(self.__class__.__name__, display)
display += f', provider={self.provider()}()'
return f'{name}({display})'
1 change: 0 additions & 1 deletion qiskit/providers/aer/backends/backend_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def cpp_execute(controller, qobj):
# Location where we put external libraries that will be
# loaded at runtime by the simulator extension
qobj_dict['config']['library_dir'] = LIBRARY_DIR

return controller(qobj_dict)


Expand Down
Loading

0 comments on commit 5c45c50

Please sign in to comment.