Skip to content

Commit

Permalink
Support BackendV2 (Qiskit#1875)
Browse files Browse the repository at this point in the history
* Support backendv2

* Change API of aerbackend init

* fix lint

* Fix lint

* Add reset gate

* Return None if the configuration does not have max_experiments

* Change function to constant

* Update code to pass the test

* Remove print

* Fix lint

* Change num of qubits in Estimator

* Skip transpilation

* Change transpile optimization level

* Add release notes

* Change process of cirucit compose by the number of qubits in estimator

* use passmanager for measurement circuits

* refactor (change line order)

* Fix lint

* Add a detail description to the release note

---------

Co-authored-by: ikkoham <ikkoham@users.noreply.github.com>
Co-authored-by: Hiroshi Horii <hhorii@users.noreply.github.com>
Co-authored-by: Jun Doi <doichan@jp.ibm.com>
Co-authored-by: Matthew Treinish <mtreinish@kortar.org>
  • Loading branch information
5 people authored Oct 26, 2023
1 parent 3dc4504 commit cfe67ed
Show file tree
Hide file tree
Showing 16 changed files with 411 additions and 32 deletions.
7 changes: 4 additions & 3 deletions qiskit_aer/backends/aer_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
BASIS_GATES,
)

# pylint: disable=import-error, no-name-in-module
# pylint: disable=import-error, no-name-in-module, abstract-method
from .controller_wrappers import aer_controller_execute

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -784,7 +784,7 @@ def __repr__(self):
pad = " " * (len(self.__class__.__name__) + 1)
return f"{display[:-1]}\n{pad}noise_model={repr(noise_model)})"

def name(self):
def _name(self):
"""Format backend name string for simulator"""
name = self._configuration.backend_name
method = getattr(self.options, "method", None)
Expand Down Expand Up @@ -813,6 +813,7 @@ def from_backend(cls, backend, **options):
max_shots=int(1e6),
coupling_map=list(backend.coupling_map.get_edges()),
max_experiments=backend.max_circuits,
description=backend.description,
)
properties = target_to_backend_properties(backend.target)
elif isinstance(backend, BackendV1):
Expand Down Expand Up @@ -866,7 +867,7 @@ def configuration(self):
]
config.basis_gates = self._cached_basis_gates + config.custom_instructions
# Update simulator name
config.backend_name = self.name()
config.backend_name = self._name()
return config

def _execute_circuits(self, aer_circuits, noise_model, config):
Expand Down
44 changes: 32 additions & 12 deletions qiskit_aer/backends/aerbackend.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@

from qiskit.circuit import QuantumCircuit, ParameterExpression, Delay
from qiskit.compiler import assemble
from qiskit.providers import BackendV1 as Backend
from qiskit.providers import BackendV2 as Backend
from qiskit.providers import convert_to_target
from qiskit.providers.models import BackendStatus
from qiskit.pulse import Schedule, ScheduleBlock
from qiskit.qobj import QasmQobj, PulseQobj
Expand All @@ -34,8 +35,9 @@
from ..noise.errors.quantum_error import QuantumChannelInstruction
from .aer_compiler import compile_circuit, assemble_circuits, generate_aer_config
from .backend_utils import format_save_type, circuit_optypes
from .name_mapping import NAME_MAPPING

# pylint: disable=import-error, no-name-in-module
# pylint: disable=import-error, no-name-in-module, abstract-method
from .controller_wrappers import AerConfig

# Logger
Expand Down Expand Up @@ -67,16 +69,24 @@ def __init__(
# Init configuration and provider in Backend
configuration.simulator = True
configuration.local = True
super().__init__(configuration, provider=provider)
super().__init__(
provider=provider,
name=configuration.backend_name,
description=configuration.description,
backend_version=configuration.backend_version,
)

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

# Custom option values for config, properties, and defaults
self._options_configuration = {}
self._options_defaults = {}
self._options_properties = {}
self._target = None
self._mapping = NAME_MAPPING

# Set options from backend_options dictionary
if backend_options is not None:
Expand Down Expand Up @@ -332,9 +342,19 @@ def defaults(self):
setattr(defaults, key, val)
return defaults

@classmethod
def _default_options(cls):
pass
@property
def max_circuits(self):
if hasattr(self.configuration(), "max_experiments"):
return self.configuration().max_experiments
else:
return None

@property
def target(self):
self._target = convert_to_target(
self.configuration(), self.properties(), self.defaults(), self._mapping
)
return self._target

def clear_options(self):
"""Reset the simulator options to default values."""
Expand All @@ -350,7 +370,7 @@ def status(self):
BackendStatus: the status of the backend.
"""
return BackendStatus(
backend_name=self.name(),
backend_name=self.name,
backend_version=self.configuration().backend_version,
operational=True,
pending_jobs=0,
Expand Down Expand Up @@ -388,15 +408,15 @@ def _execute_qobj_job(self, qobj, job_id="", format_result=True):

# Validate output
if not isinstance(output, dict):
logger.error("%s: simulation failed.", self.name())
logger.error("%s: simulation failed.", self.name)
if output:
logger.error("Output: %s", output)
raise AerError("simulation terminated without returning valid output.")

# Format results
output["job_id"] = job_id
output["date"] = datetime.datetime.now().isoformat()
output["backend_name"] = self.name()
output["backend_name"] = self.name
output["backend_version"] = self.configuration().backend_version

# Push metadata to experiment headers
Expand Down Expand Up @@ -454,15 +474,15 @@ def _execute_circuits_job(

# Validate output
if not isinstance(output, dict):
logger.error("%s: simulation failed.", self.name())
logger.error("%s: simulation failed.", self.name)
if output:
logger.error("Output: %s", output)
raise AerError("simulation terminated without returning valid output.")

# Format results
output["job_id"] = job_id
output["date"] = datetime.datetime.now().isoformat()
output["backend_name"] = self.name()
output["backend_name"] = self.name
output["backend_version"] = self.configuration().backend_version

# Push metadata to experiment headers
Expand Down Expand Up @@ -725,5 +745,5 @@ def _set_defaults_option(self, key, value):
def __repr__(self):
"""String representation of an AerBackend."""
name = self.__class__.__name__
display = f"'{self.name()}'"
display = f"'{self.name}'"
return f"{name}({display})"
8 changes: 8 additions & 0 deletions qiskit_aer/backends/backend_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"pauli",
"mcx_gray",
"ecr",
"reset",
"switch_case",
]
),
Expand Down Expand Up @@ -150,6 +151,7 @@
"delay",
"pauli",
"ecr",
"reset",
"switch_case",
]
),
Expand Down Expand Up @@ -193,6 +195,7 @@
"cswap",
"diagonal",
"initialize",
"reset",
"switch_case",
]
),
Expand All @@ -213,6 +216,7 @@
"swap",
"delay",
"pauli",
"reset",
"ecr",
"rx",
"ry",
Expand Down Expand Up @@ -243,6 +247,7 @@
"ccz",
"delay",
"pauli",
"reset",
]
),
"unitary": sorted(
Expand Down Expand Up @@ -304,6 +309,7 @@
"delay",
"pauli",
"ecr",
"reset",
]
),
"superop": sorted(
Expand Down Expand Up @@ -343,6 +349,7 @@
"diagonal",
"delay",
"pauli",
"reset",
]
),
"tensor_network": sorted(
Expand Down Expand Up @@ -405,6 +412,7 @@
"delay",
"pauli",
"mcx_gray",
"reset",
]
),
}
Expand Down
Loading

0 comments on commit cfe67ed

Please sign in to comment.