|
17 | 17 | from ast import literal_eval
|
18 | 18 | from collections import Counter
|
19 | 19 | import json
|
| 20 | +from time import sleep |
20 | 21 | from typing import (
|
21 | 22 | cast,
|
22 | 23 | List,
|
|
33 | 34 | import qiskit # type: ignore
|
34 | 35 | from qiskit import IBMQ
|
35 | 36 | from qiskit.primitives import SamplerResult # type: ignore
|
36 |
| -from qiskit.tools.monitor import job_monitor # type: ignore |
| 37 | + |
| 38 | + |
| 39 | +# RuntimeJob has no queue_position attribute, which is referenced |
| 40 | +# via job_monitor see-> https://github.com/CQCL/pytket-qiskit/issues/48 |
| 41 | +# therefore we can't use job_monitor until fixed |
| 42 | +# from qiskit.tools.monitor import job_monitor # type: ignore |
37 | 43 | from qiskit.result.distributions import QuasiDistribution # type: ignore
|
38 | 44 | from qiskit_ibm_runtime import ( # type: ignore
|
39 | 45 | QiskitRuntimeService,
|
@@ -113,6 +119,23 @@ def __init__(self) -> None:
|
113 | 119 | )
|
114 | 120 |
|
115 | 121 |
|
| 122 | +def _save_ibmq_auth(qiskit_config: Optional[QiskitConfig]) -> None: |
| 123 | + token = None |
| 124 | + if qiskit_config is not None: |
| 125 | + token = qiskit_config.ibmq_api_token |
| 126 | + if not IBMQ.active_account(): |
| 127 | + if IBMQ.stored_account(): |
| 128 | + IBMQ.load_account() |
| 129 | + else: |
| 130 | + if token is not None: |
| 131 | + IBMQ.save_account(token) |
| 132 | + else: |
| 133 | + raise NoIBMQAccountError() |
| 134 | + if not QiskitRuntimeService.saved_accounts(): |
| 135 | + if token is not None: |
| 136 | + QiskitRuntimeService.save_account(channel="ibm_quantum", token=token) |
| 137 | + |
| 138 | + |
116 | 139 | class IBMQBackend(Backend):
|
117 | 140 | _supports_shots = False
|
118 | 141 | _supports_counts = True
|
@@ -189,17 +212,7 @@ def _get_provider(
|
189 | 212 | project: Optional[str],
|
190 | 213 | qiskit_config: Optional[QiskitConfig],
|
191 | 214 | ) -> "AccountProvider":
|
192 |
| - if not IBMQ.active_account(): |
193 |
| - if IBMQ.stored_account(): |
194 |
| - IBMQ.load_account() |
195 |
| - else: |
196 |
| - if ( |
197 |
| - qiskit_config is not None |
198 |
| - and qiskit_config.ibmq_api_token is not None |
199 |
| - ): |
200 |
| - IBMQ.save_account(qiskit_config.ibmq_api_token) |
201 |
| - else: |
202 |
| - raise NoIBMQAccountError() |
| 215 | + _save_ibmq_auth(qiskit_config) |
203 | 216 | provider_kwargs: Dict[str, Optional[str]] = {}
|
204 | 217 | if hub:
|
205 | 218 | provider_kwargs["hub"] = hub
|
@@ -251,19 +264,39 @@ def _get_backend_info(cls, backend: "_QiskIBMQBackend") -> BackendInfo:
|
251 | 264 | filtered_characterisation = {
|
252 | 265 | k: v for k, v in characterisation.items() if k in characterisation_keys
|
253 | 266 | }
|
| 267 | + # see below for references for config definitions |
| 268 | + # quantum-computing.ibm.com/services/resources/docs/resources/manage/systems/: |
| 269 | + # midcircuit-measurement/ |
| 270 | + # dynamic-circuits/feature-table |
254 | 271 | supports_mid_measure = config.simulator or config.multi_meas_enabled
|
255 |
| - supports_fast_feedforward = False |
| 272 | + supports_fast_feedforward = ( |
| 273 | + hasattr(config, "supported_features") |
| 274 | + and "qasm3" in config.supported_features |
| 275 | + ) |
| 276 | + |
256 | 277 | # simulator i.e. "ibmq_qasm_simulator" does not have `supported_instructions`
|
257 | 278 | # attribute
|
| 279 | + supports_reset = ( |
| 280 | + hasattr(config, "supported_instructions") |
| 281 | + and "reset" in config.supported_instructions |
| 282 | + ) |
258 | 283 | gate_set = _tk_gate_set(backend)
|
259 | 284 | backend_info = BackendInfo(
|
260 | 285 | cls.__name__,
|
261 | 286 | backend.name(),
|
262 | 287 | __extension_version__,
|
263 | 288 | arch,
|
264 |
| - gate_set, |
| 289 | + gate_set.union( |
| 290 | + { |
| 291 | + OpType.RangePredicate, |
| 292 | + OpType.Conditional, |
| 293 | + } |
| 294 | + ) |
| 295 | + if supports_fast_feedforward |
| 296 | + else gate_set, |
265 | 297 | supports_midcircuit_measurement=supports_mid_measure,
|
266 | 298 | supports_fast_feedforward=supports_fast_feedforward,
|
| 299 | + supports_reset=supports_reset, |
267 | 300 | all_node_gate_errors=characterisation["NodeErrors"],
|
268 | 301 | all_edge_gate_errors=characterisation["EdgeErrors"],
|
269 | 302 | all_readout_errors=characterisation["ReadoutErrors"],
|
@@ -382,6 +415,7 @@ def process_circuits(
|
382 | 415 | Supported kwargs: `postprocess`.
|
383 | 416 | """
|
384 | 417 | circuits = list(circuits)
|
| 418 | + |
385 | 419 | n_shots_list = Backend._get_n_shots_as_list(
|
386 | 420 | n_shots,
|
387 | 421 | len(circuits),
|
@@ -428,7 +462,10 @@ def process_circuits(
|
428 | 462 | options.transpilation.skip_transpilation = True
|
429 | 463 | options.execution.shots = n_shots
|
430 | 464 | sampler = Sampler(session=self._session, options=options)
|
431 |
| - job = sampler.run(circuits=qcs) |
| 465 | + job = sampler.run( |
| 466 | + circuits=qcs, |
| 467 | + dynamic=self.backend_info.supports_fast_feedforward, |
| 468 | + ) |
432 | 469 | job_id = job.job_id
|
433 | 470 | for i, ind in enumerate(indices_chunk):
|
434 | 471 | handle_list[ind] = ResultHandle(
|
@@ -484,9 +521,16 @@ def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResul
|
484 | 521 | except Exception as e:
|
485 | 522 | warn(f"Unable to retrieve job {jobid}: {e}")
|
486 | 523 | raise CircuitNotRunError(handle)
|
487 |
| - |
| 524 | + # RuntimeJob has no queue_position attribute, which is referenced |
| 525 | + # via job_monitor see-> https://github.com/CQCL/pytket-qiskit/issues/48 |
| 526 | + # therefore we can't use job_monitor until fixed |
488 | 527 | if self._monitor and job:
|
489 |
| - job_monitor(job) |
| 528 | + # job_monitor(job) |
| 529 | + status = job.status() |
| 530 | + while status.name not in ["DONE", "CANCELLED", "ERROR"]: |
| 531 | + status = job.status() |
| 532 | + print("Job status is", status.name) |
| 533 | + sleep(10) |
490 | 534 |
|
491 | 535 | res = job.result(timeout=kwargs.get("timeout", None))
|
492 | 536 | for circ_index, (r, d) in enumerate(zip(res.quasi_dists, res.metadata)):
|
|
0 commit comments