Replace properties in jobs and backends with methods.

This commit is contained in:
Salvador de la Puente González 2018-09-04 20:11:34 +02:00
parent 221809c401
commit 3eb9e00599
21 changed files with 101 additions and 100 deletions

View File

@ -74,10 +74,10 @@ try:
interval = 10
while not job_exp.done:
print('Status @ {} seconds'.format(interval * lapse))
print(job_exp.status)
print(job_exp.status())
time.sleep(interval)
lapse += 1
print(job_exp.status)
print(job_exp.status())
exp_result = job_exp.result()
# Show the results

View File

@ -48,15 +48,15 @@ try:
print("(Local Backends)")
for backend_name in available_backends({'local': True}):
backend = get_backend(backend_name)
print(backend.status)
print(backend.status())
my_backend_name = 'local_qasm_simulator'
my_backend = get_backend(my_backend_name)
print("(Local QASM Simulator configuration) ")
pprint.pprint(my_backend.configuration)
pprint.pprint(my_backend.configuration())
print("(Local QASM Simulator calibration) ")
pprint.pprint(my_backend.calibration)
pprint.pprint(my_backend.calibration())
print("(Local QASM Simulator parameters) ")
pprint.pprint(my_backend.parameters)
pprint.pprint(my_backend.parameters())
# Compiling the job
@ -80,7 +80,7 @@ try:
print("\n(Remote Backends)")
for backend_name in available_backends({'local': False}):
backend = get_backend(backend_name)
s = backend.status
s = backend.status()
print(s)
# select least busy available device and execute.
@ -90,11 +90,11 @@ try:
my_backend = get_backend(least_busy_device)
print("(with Configuration) ")
pprint.pprint(my_backend.configuration)
pprint.pprint(my_backend.configuration())
print("(with calibration) ")
pprint.pprint(my_backend.calibration)
pprint.pprint(my_backend.calibration())
print("(with parameters) ")
pprint.pprint(my_backend.parameters)
pprint.pprint(my_backend.parameters())
# Compiling the job
# I want to make it so the compile is only done once and the needing

View File

@ -43,31 +43,26 @@ class BaseBackend(ABC):
"""Run a Qobj on the the backend."""
pass
@property
def configuration(self):
"""Return backend configuration"""
return self._configuration
@property
def calibration(self):
"""Return backend calibration"""
return {}
@property
def parameters(self):
"""Return backend parameters"""
return {}
@property
def status(self):
"""Return backend status"""
return AvailableToOperationalDict(
{'name': self.name, 'operational': True, 'pending_jobs': 0})
{'name': self.name(), 'operational': True, 'pending_jobs': 0})
@property
def name(self):
"""Return backend name"""
return self._configuration['name']
def __str__(self):
return self.name
return self.name()

View File

@ -22,6 +22,11 @@ class BaseJob(ABC):
"""Initializes the asynchronous job"""
pass
@abstractmethod
def submit(self):
"""Submit the job to the backend."""
pass
@abstractmethod
def result(self):
"""Return backend result"""
@ -34,5 +39,5 @@ class BaseJob(ABC):
@abstractmethod
def status(self):
"""Get backend status dictionary"""
"""Return one of the values of ``JobStatus``"""
pass

View File

@ -55,11 +55,10 @@ class IBMQBackend(BaseBackend):
IBMQJob: an instance derived from BaseJob
"""
job = IBMQJob(self._api, not self.configuration['simulator'], qobj=qobj)
job = IBMQJob(self._api, not self.configuration()['simulator'], qobj=qobj)
job.submit()
return job
@property
def calibration(self):
"""Return the online backend calibrations.
@ -72,7 +71,7 @@ class IBMQBackend(BaseBackend):
LookupError: If a configuration for the backend can't be found.
"""
try:
backend_name = self.configuration['name']
backend_name = self.configuration()['name']
calibrations = self._api.backend_calibration(backend_name)
# FIXME a hack to remove calibration data that is none.
# Needs to be fixed in api
@ -89,7 +88,6 @@ class IBMQBackend(BaseBackend):
return calibrations_edit
@property
def parameters(self):
"""Return the online backend parameters.
@ -100,7 +98,7 @@ class IBMQBackend(BaseBackend):
LookupError: If parameters for the backend can't be found.
"""
try:
backend_name = self.configuration['name']
backend_name = self.configuration()['name']
parameters = self._api.backend_parameters(backend_name)
# FIXME a hack to remove parameters data that is none.
# Needs to be fixed in api
@ -117,7 +115,6 @@ class IBMQBackend(BaseBackend):
return parameters_edit
@property
def status(self):
"""Return the online backend status.
@ -128,7 +125,7 @@ class IBMQBackend(BaseBackend):
LookupError: If status for the backend can't be found.
"""
try:
backend_name = self.configuration['name']
backend_name = self.configuration()['name']
status = self._api.backend_status(backend_name)
# FIXME a hack to rename the key. Needs to be fixed in api
status['name'] = status['backend']
@ -188,7 +185,7 @@ class IBMQBackend(BaseBackend):
Raises:
IBMQBackendValueError: status keyword value unrecognized
"""
backend_name = self.configuration['name']
backend_name = self.configuration()['name']
api_filter = {'backend.name': backend_name}
if status:
if isinstance(status, str):

View File

@ -47,18 +47,14 @@ class IBMQJob(BaseJob):
backend.
Creating a ``Job`` instance does not imply running it. You need to do it in
separate steps:
.. highlight::
separate steps::
job = IBMQJob(...)
job.submit() # It won't block.
An error while submitting a job will cause the next call to ``status()`` to
raise. If submitting the job successes, you can inspect the job's status by
using ``status()``. Status can be one of ``JobStatus`` members:
.. highlight::
using ``status()``. Status can be one of ``JobStatus`` members::
from qiskit.backends.jobstatus import JobStatus
@ -79,9 +75,7 @@ class IBMQJob(BaseJob):
The ``submit()`` and ``status()`` methods are examples of non-blocking API.
``Job`` instances also have `id()` and ``result()`` methods which will
block:
.. highlight::
block::
job = IBMQJob(...)
job.submit()

View File

@ -118,7 +118,6 @@ class LocalJob(BaseJob):
self.__class__.__name__))
return _status
@property
def backend_name(self):
"""
Return backend name used for this job

View File

@ -90,7 +90,7 @@ class LocalProvider(BaseProvider):
for backend_cls in SDK_STANDARD_BACKENDS:
try:
backend_instance = cls._get_backend_instance(backend_cls)
backend_name = backend_instance.configuration['name']
backend_name = backend_instance.configuration()['name']
ret[backend_name] = backend_instance
except QISKitError as e:
# Ignore backends that could not be initialized.
@ -120,7 +120,7 @@ class LocalProvider(BaseProvider):
# Verify that the instance has a minimal valid configuration.
try:
_ = backend_instance.configuration['name']
_ = backend_instance.configuration()['name']
except (LookupError, TypeError):
raise QISKitError('Backend %s has an invalid configuration')

View File

@ -178,7 +178,7 @@ class ResultEncoder(json.JSONEncoder):
elif isinstance(o, BaseBackend):
# TODO: replace when the deprecation is completed (see also note in
# Result.__iadd__).
return o.configuration['name']
return o.configuration()['name']
return json.JSONEncoder.default(self, o)

View File

@ -61,7 +61,7 @@ def compile(circuits, backend,
# 1. do all circuits have same coupling map?
# 2. do all circuit have the same basis set?
# 3. do they all have same registers etc?
backend_conf = backend.configuration
backend_conf = backend.configuration()
backend_name = backend_conf['name']
# Check for valid parameters for the experiments.
if hpc is not None and \
@ -84,7 +84,7 @@ def compile(circuits, backend,
# TODO: move this inside mapper pass.
initial_layouts = []
for dag in dags:
if (initial_layout is None and not backend.configuration['simulator']
if (initial_layout is None and not backend.configuration()['simulator']
and not _matches_coupling_map(dag, coupling_map)):
_initial_layout = _pick_best_layout(dag, backend)
initial_layouts.append(_initial_layout)
@ -364,11 +364,11 @@ def _best_subset(backend, n_qubits):
elif n_qubits <= 0:
raise QISKitError('Number of qubits <= 0.')
device_qubits = backend.configuration['n_qubits']
device_qubits = backend.configuration()['n_qubits']
if n_qubits > device_qubits:
raise QISKitError('Number of qubits greater than device.')
cmap = np.asarray(backend.configuration['coupling_map'])
cmap = np.asarray(backend.configuration()['coupling_map'])
data = np.ones_like(cmap[:, 0])
sp_cmap = sp.coo_matrix((data, (cmap[:, 0], cmap[:, 1])),
shape=(device_qubits, device_qubits)).tocsr()

View File

@ -234,8 +234,9 @@ def least_busy(names):
"""
backends = [get_backend(name) for name in names]
try:
return min([b for b in backends if b.status['operational'] and 'pending_jobs' in b.status],
key=lambda b: b.status['pending_jobs']).name
return min([b for b in backends
if b.status()['operational'] and 'pending_jobs' in b.status()],
key=lambda b: b.status()['pending_jobs']).name()
except (ValueError, TypeError):
raise QISKitError("Can only find least_busy backend from a non-empty list.")

View File

@ -52,7 +52,7 @@ class DefaultQISKitProvider(BaseProvider):
e.g. {'local': False, 'simulator': False, 'operational': True}
2) callable: BaseBackend -> bool
e.g. lambda x: x.configuration['n_qubits'] > 5
e.g. lambda x: x.configuration()['n_qubits'] > 5
Returns:
list[BaseBackend]: a list of backend instances available
@ -72,11 +72,11 @@ class DefaultQISKitProvider(BaseProvider):
# e.g. {'n_qubits': 5, 'operational': True}
for key, value in filters.items():
backends = [instance for instance in backends
if instance.configuration.get(key) == value
or instance.status.get(key) == value]
if instance.configuration().get(key) == value
or instance.status().get(key) == value]
elif callable(filters):
# acceptor filter: accept or reject a specific backend
# e.g. lambda x: x.configuration['n_qubits'] > 5
# e.g. lambda x: x.configuration()['n_qubits'] > 5
accepted_backends = []
for backend in backends:
try:
@ -197,7 +197,7 @@ class DefaultQISKitProvider(BaseProvider):
regular available names, nor groups, nor deprecated, nor alias names
"""
resolved_name = ""
available = [b.name for b in self.available_backends(filters=None)]
available = [b.name() for b in self.available_backends(filters=None)]
grouped = self.grouped_backend_names()
deprecated = self.deprecated_backend_names()
aliased = self.aliased_backend_names()

View File

@ -74,7 +74,7 @@ def vqe(molecule='H2', depth=6, max_trials=200, shots=1):
if 'statevector' not in device:
H = group_paulis(pauli_list)
entangler_map = get_backend(device).configuration['coupling_map']
entangler_map = get_backend(device).configuration()['coupling_map']
if entangler_map == 'all-to-all':
entangler_map = {i: [j for j in range(n_qubits) if j != i] for i in range(n_qubits)}

View File

@ -47,7 +47,7 @@ class DummyProvider(BaseProvider):
filters = filters or {}
for key, value in filters.items():
backends = {name: instance for name, instance in backends.items()
if instance.configuration.get(key) == value}
if instance.configuration().get(key) == value}
return list(backends.values())
@ -143,7 +143,7 @@ def new_fake_qobj():
return Qobj(
qobj_id='test-id',
config=QobjConfig(shots=1024, memory_slots=1, max_credits=100),
header=QobjHeader(backend_name=backend.name),
header=QobjHeader(backend_name=backend.name()),
experiments=[QobjExperiment(
instructions=[
QobjInstruction(name='barrier', qubits=[1])
@ -156,5 +156,7 @@ def new_fake_qobj():
class FakeBackend():
"""Fakes qiskit.backends.basebackend.BaseBackend instances."""
def __init__(self):
self.name = 'test-backend'
def name(self):
"""Return the name of the backend."""
return 'test-backend'

View File

@ -193,7 +193,7 @@ class JobTestCase(QiskitTestCase):
status."""
waited = 0
wait = 0.1
while job.status['status'] == JobStatus.INITIALIZING:
while job.status()['status'] == JobStatus.INITIALIZING:
time.sleep(wait)
waited += wait
if waited > timeout:
@ -202,7 +202,7 @@ class JobTestCase(QiskitTestCase):
def assertStatus(self, job, status):
"""Assert the intenal job status is the expected one and also tests
if the shorthand method for that status returns `True`."""
self.assertEqual(job.status['status'], status)
self.assertEqual(job.status()['status'], status)
if status == JobStatus.CANCELLED:
self.assertTrue(job.cancelled)
elif status == JobStatus.DONE:

View File

@ -57,7 +57,7 @@ class TestBackends(QiskitTestCase):
"""
ibmq_provider = IBMQProvider(qe_token, qe_url)
remote = ibmq_provider.available_backends()
remote = [r for r in remote if not r.configuration['simulator']]
remote = [r for r in remote if not r.configuration()['simulator']]
self.log.info(remote)
self.assertTrue(remote)
@ -69,7 +69,7 @@ class TestBackends(QiskitTestCase):
"""
ibmq_provider = IBMQProvider(qe_token, qe_url)
remote = ibmq_provider.available_backends()
remote = [r for r in remote if r.configuration['simulator']]
remote = [r for r in remote if r.configuration()['simulator']]
self.log.info(remote)
self.assertTrue(remote)
@ -80,7 +80,7 @@ class TestBackends(QiskitTestCase):
"""
local_provider = DefaultQISKitProvider()
backend = local_provider.get_backend(name='local_qasm_simulator_py')
self.assertEqual(backend.configuration['name'], 'local_qasm_simulator_py')
self.assertEqual(backend.configuration()['name'], 'local_qasm_simulator_py')
def test_local_backend_status(self):
"""Test backend_status.
@ -92,7 +92,7 @@ class TestBackends(QiskitTestCase):
local_provider = DefaultQISKitProvider()
backend = local_provider.get_backend(name='local_qasm_simulator')
status = backend.status
status = backend.status()
schema_path = self._get_resource_path(
'deprecated/backends/backend_status_schema_py.json', path=Path.SCHEMAS)
with open(schema_path, 'r') as schema_file:
@ -113,8 +113,8 @@ class TestBackends(QiskitTestCase):
remotes = ibmq_provider.available_backends()
remotes = remove_backends_from_list(remotes)
for backend in remotes:
self.log.info(backend.status)
status = backend.status
self.log.info(backend.status())
status = backend.status()
schema_path = self._get_resource_path(
'deprecated/backends/backend_status_schema_py.json', path=Path.SCHEMAS)
with open(schema_path, 'r') as schema_file:
@ -129,7 +129,7 @@ class TestBackends(QiskitTestCase):
local_provider = LocalProvider()
local_backends = local_provider.available_backends()
for backend in local_backends:
configuration = backend.configuration
configuration = backend.configuration()
schema_path = self._get_resource_path(
'deprecated/backends/backend_configuration_schema_old_py.json',
path=Path.SCHEMAS)
@ -147,7 +147,7 @@ class TestBackends(QiskitTestCase):
remotes = ibmq_provider.available_backends()
remotes = remove_backends_from_list(remotes)
for backend in remotes:
configuration = backend.configuration
configuration = backend.configuration()
schema_path = self._get_resource_path(
'deprecated/backends/backend_configuration_schema_old_py.json', path=Path.SCHEMAS)
with open(schema_path, 'r') as schema_file:
@ -162,7 +162,7 @@ class TestBackends(QiskitTestCase):
local_provider = LocalProvider()
local_backends = local_provider.available_backends()
for backend in local_backends:
calibration = backend.calibration
calibration = backend.calibration()
# FIXME test against schema and decide what calibration
# is for a simulator
self.assertEqual(len(calibration), 0)
@ -177,10 +177,10 @@ class TestBackends(QiskitTestCase):
remotes = ibmq_provider.available_backends()
remotes = remove_backends_from_list(remotes)
for backend in remotes:
calibration = backend.calibration
calibration = backend.calibration()
# FIXME test against schema and decide what calibration
# is for a simulator
if backend.configuration['simulator']:
if backend.configuration()['simulator']:
self.assertEqual(len(calibration), 0)
else:
self.assertEqual(len(calibration), 4)
@ -193,7 +193,7 @@ class TestBackends(QiskitTestCase):
local_provider = LocalProvider()
local_backends = local_provider.available_backends()
for backend in local_backends:
parameters = backend.parameters
parameters = backend.parameters()
# FIXME test against schema and decide what parameters
# is for a simulator
self.assertEqual(len(parameters), 0)
@ -208,11 +208,11 @@ class TestBackends(QiskitTestCase):
remotes = ibmq_provider.available_backends()
remotes = remove_backends_from_list(remotes)
for backend in remotes:
self.log.info(backend.name)
parameters = backend.parameters
self.log.info(backend.name())
parameters = backend.parameters()
# FIXME test against schema and decide what parameters
# is for a simulator
if backend.configuration['simulator']:
if backend.configuration()['simulator']:
self.assertEqual(len(parameters), 0)
else:
self.assertTrue(all(key in parameters for key in (

View File

@ -24,14 +24,16 @@ class FakeBackEnd(object):
"""A fake backend.
"""
def __init__(self):
def configuration(self):
qx5_cmap = [[1, 0], [1, 2], [2, 3], [3, 4], [3, 14], [5, 4], [6, 5],
[6, 7], [6, 11], [7, 10], [8, 7], [9, 8], [9, 10], [11, 10],
[12, 5], [12, 11], [12, 13], [13, 4], [13, 14], [15, 0],
[15, 2], [15, 14]]
self.configuration = {'name': 'fake', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 16,
'coupling_map': qx5_cmap}
return {
'name': 'fake', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 16,
'coupling_map': qx5_cmap
}
class TestCompiler(QiskitTestCase):
@ -387,7 +389,7 @@ class TestCompiler(QiskitTestCase):
compiled_ops = qobj.experiments[0].instructions
for operation in compiled_ops:
if operation.name == 'cx':
self.assertIn(operation.qubits, backend.configuration['coupling_map'])
self.assertIn(operation.qubits, backend.configuration()['coupling_map'])
def test_compile_circuits_diff_registers(self):
"""Compile list of circuits with different qreg names.

View File

@ -36,8 +36,8 @@ class TestBackendFilters(QiskitTestCase):
def test_filter_config_callable(self, qe_token, qe_url):
"""Test filtering by lambda function on configuration properties"""
register(qe_token, qe_url)
filtered_backends = available_backends(lambda x: (not x.configuration['simulator'] and
x.configuration['n_qubits'] > 5))
filtered_backends = available_backends(lambda x: (not x.configuration()['simulator'] and
x.configuration()['n_qubits'] > 5))
self.assertTrue(filtered_backends)
@requires_qe_access

View File

@ -34,8 +34,8 @@ def _least_busy(backends):
BaseBackend: least busy backend instance.
"""
return min([b for b in backends if
b.status['operational'] and 'pending_jobs' in b.status],
key=lambda b: b.status['pending_jobs'])
b.status()['operational'] and 'pending_jobs' in b.status()],
key=lambda b: b.status()['pending_jobs'])
class TestIBMQJob(JobTestCase):
@ -95,10 +95,10 @@ class TestIBMQJob(JobTestCase):
def test_run_device(self, qe_token, qe_url):
provider = IBMQProvider(qe_token, qe_url)
backends = [backend for backend in provider.available_backends()
if not backend.configuration['simulator']]
self.log.info('devices: %s', [b.name for b in backends])
if not backend.configuration()['simulator']]
self.log.info('devices: %s', [b.name() for b in backends])
backend = _least_busy(backends)
self.log.info('using backend: %s', backend.name)
self.log.info('using backend: %s', backend.name())
qobj = transpiler.compile(self._qc, backend)
shots = qobj.config.shots
job = backend.run(qobj)
@ -125,7 +125,7 @@ class TestIBMQJob(JobTestCase):
provider = IBMQProvider(qe_token, qe_url)
IBMQJob._executor = futures.ThreadPoolExecutor(max_workers=2)
backend = provider.get_backend('ibmq_qasm_simulator')
self.log.info('submitting to backend %s', backend.name)
self.log.info('submitting to backend %s', backend.name())
num_qubits = 16
qr = QuantumRegister(num_qubits, 'qr')
cr = ClassicalRegister(num_qubits, 'cr')
@ -173,9 +173,9 @@ class TestIBMQJob(JobTestCase):
def test_run_async_device(self, qe_token, qe_url):
provider = IBMQProvider(qe_token, qe_url)
backends = [backend for backend in provider.available_backends()
if not backend.configuration['simulator']]
if not backend.configuration()['simulator']]
backend = _least_busy(backends)
self.log.info('submitting to backend %s', backend.name)
self.log.info('submitting to backend %s', backend.name())
num_qubits = 5
qr = QuantumRegister(num_qubits, 'qr')
cr = ClassicalRegister(num_qubits, 'cr')
@ -255,7 +255,7 @@ class TestIBMQJob(JobTestCase):
start_time = time.time()
job_list = backend.jobs(limit=5, skip=0)
self.log.info('time to get jobs: %0.3f s', time.time() - start_time)
self.log.info('found %s jobs on backend %s', len(job_list), backend.name)
self.log.info('found %s jobs on backend %s', len(job_list), backend.name())
for job in job_list:
self.log.info('status: %s', job.status())
self.assertTrue(isinstance(job.id(), str))
@ -275,7 +275,7 @@ class TestIBMQJob(JobTestCase):
def test_retrieve_job_error(self, qe_token, qe_url):
provider = IBMQProvider(qe_token, qe_url)
backends = [backend for backend in provider.available_backends()
if not backend.configuration['simulator']]
if not backend.configuration()['simulator']]
backend = _least_busy(backends)
self.assertRaises(IBMQBackendError, backend.retrieve_job, 'BAD_JOB_ID')

View File

@ -23,24 +23,30 @@ from .common import QiskitTestCase
class FakeQX4BackEnd(object):
"""A fake QX4 backend.
"""
def __init__(self):
def configuration(self):
qx4_cmap = [[1, 0], [2, 0], [2, 1], [3, 2], [3, 4], [4, 2]]
self.configuration = {'name': 'fake_qx4', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 5,
'coupling_map': qx4_cmap}
return {
'name': 'fake_qx4', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 5,
'coupling_map': qx4_cmap
}
class FakeQX5BackEnd(object):
"""A fake QX5 backend.
"""
def __init__(self):
def configuration(self):
qx5_cmap = [[1, 0], [1, 2], [2, 3], [3, 4], [3, 14], [5, 4], [6, 5],
[6, 7], [6, 11], [7, 10], [8, 7], [9, 8], [9, 10],
[11, 10], [12, 5], [12, 11], [12, 13], [13, 4],
[13, 14], [15, 0], [15, 2], [15, 14]]
self.configuration = {'name': 'fake_qx5', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 16,
'coupling_map': qx5_cmap}
return {
'name': 'fake_qx5', 'basis_gates': 'u1,u2,u3,cx,id',
'simulator': False, 'n_qubits': 16,
'coupling_map': qx5_cmap
}
class MapperTest(QiskitTestCase):
@ -249,7 +255,7 @@ class MapperTest(QiskitTestCase):
"""Measurements applied AFTER swap mapping.
"""
backend = FakeQX5BackEnd()
cmap = backend.configuration['coupling_map']
cmap = backend.configuration()['coupling_map']
circ = qiskit.load_qasm_file(self._get_resource_path('qasm/move_measurements.qasm'),
name='move')
dag_circuit = DAGCircuit.fromQuantumCircuit(circ)

View File

@ -104,7 +104,7 @@ class TestQobj(QiskitTestCase):
"""Test localjob is denied resource request access when given an invalid Qobj instance."""
backend = FakeBackend()
self.bad_qobj.header = QobjHeader(backend_name=backend.name)
self.bad_qobj.header = QobjHeader(backend_name=backend.name())
with self.assertRaises(QobjValidationError):
job = localjob.LocalJob(_nop, self.bad_qobj)
@ -114,7 +114,7 @@ class TestQobj(QiskitTestCase):
"""Test IBMQobj is denied resource request access when given an invalid Qobj instance."""
backend = FakeBackend()
self.bad_qobj.header = QobjHeader(backend_name=backend.name)
self.bad_qobj.header = QobjHeader(backend_name=backend.name())
api_stub = {}
with self.assertRaises(QobjValidationError):