Source code for quantum_launcher.routines.qiskit_routines.v2_wrapper

 1from typing import Sequence
 2
 3from qiskit import transpile
 4from qiskit.primitives.base import BaseSamplerV1, BaseSamplerV2
 5from qiskit.primitives import SamplerResult, BasePrimitiveJob
 6from qiskit.result import QuasiDistribution
 7
 8
[docs] 9class RuntimeJobV2Adapter(BasePrimitiveJob): 10 def __init__(self, job, **kwargs): 11 super().__init__(job.job_id(), **kwargs) 12 self.job = job 13
[docs] 14 def result(self): 15 raise NotImplementedError()
16
[docs] 17 def cancel(self): 18 return self.job.cancel()
19
[docs] 20 def status(self): 21 return self.job.status()
22
[docs] 23 def done(self): 24 return self.job.done()
25
[docs] 26 def cancelled(self): 27 return self.job.cancelled()
28
[docs] 29 def running(self): 30 return self.job.running()
31
[docs] 32 def in_final_state(self): 33 return self.job.in_final_state()
34 35
[docs] 36class SamplerV2JobAdapter(RuntimeJobV2Adapter): 37 """ 38 Dummy data holder, returns a v1 SamplerResult from v2 sampler job. 39 """ 40 41 def __init__(self, job, **kwargs): 42 super().__init__(job, **kwargs) 43 44 def _get_quasi_meta(self, res): 45 data = next(iter(res.data.values())) 46 counts = data.get_int_counts() 47 probs = {k: v/data.num_shots for k, v in counts.items()} 48 quasi_dists = QuasiDistribution(probs, shots=data.num_shots) 49 50 metadata = res.metadata 51 metadata["sampler_version"] = 2 # might be useful for debugging 52 53 return quasi_dists, metadata 54
[docs] 55 def result(self): 56 res = self.job.result() 57 qd, metas = [], [] 58 for r in res: 59 quasi_dist, metadata = self._get_quasi_meta(r) 60 qd.append(quasi_dist) 61 metas.append(metadata) 62 63 return SamplerResult(quasi_dists=qd, metadata=metas)
64 65 66def _transpile_circuits(circuits, backend): 67 # Transpile qaoa circuit to backend instruction set, if backend is provided 68 # ? I pass a backend into SamplerV2 as *mode* but here sampler_v2.mode returns None, why? 69 if not backend is None: 70 if isinstance(circuits, Sequence): 71 circuits = [transpile(circuit) for circuit in circuits] 72 else: 73 circuits = transpile(circuits) 74 75 return circuits 76 77
[docs] 78class SamplerV2Adapter(BaseSamplerV1): 79 """ 80 V1 adapter for V2 samplers. 81 """ 82 83 def __init__(self, sampler_v2: BaseSamplerV2, backend=None): 84 """ 85 Args: 86 sampler_v2 (BaseSamplerV2): V2 sampler to be adapted. 87 backend (Optional[Backend]): Backend to transpile circuits to. 88 """ 89 self.sampler_v2 = sampler_v2 90 self.backend = backend 91 super().__init__() 92 93 def _run(self, circuits, parameter_values=None, **run_options) -> SamplerV2JobAdapter: 94 circuits = _transpile_circuits(circuits, self.backend) 95 v2_list = list(zip(circuits, parameter_values)) 96 job = self.sampler_v2.run(pubs=v2_list, **run_options) 97 98 return SamplerV2JobAdapter(job)