Source code for qlauncher.routines.qiskit.backends.gate_circuit_backend
1from abc import ABC, abstractmethod
2from typing import Any, Generic, TypeVar, get_args, get_origin
3
4import qiskit
5from qiskit.primitives import BaseSamplerV1, BaseSamplerV2
6from qiskit.transpiler.passes import RemoveBarriers
7
8from qlauncher.base import Backend
9from qlauncher.routines.circuits import CIRCUIT_FORMATS
10
11_AllowedCircuit = TypeVar('_AllowedCircuit', bound=CIRCUIT_FORMATS)
12
13
[docs]
14class GateCircuitBackend(Backend, Generic[_AllowedCircuit], ABC):
15 sampler: BaseSamplerV2
16 samplerV1: BaseSamplerV1
17
18 basis_gates: list[str] = []
19 circuit_class_mapping: dict[type, 'GateCircuitBackend'] = {}
20
21 def __init_subclass__(cls):
22 super().__init_subclass__()
23
24 if GateCircuitBackend not in cls.__bases__: # Skip subclasses of subclasses and further
25 return
26
27 for base in getattr(cls, '__orig_bases__', ()):
28 origin = get_origin(base)
29 if origin is GateCircuitBackend:
30 (allowed_circuit,) = get_args(base)
31 cls.compatible_circuit = allowed_circuit
32 GateCircuitBackend.circuit_class_mapping[cls.compatible_circuit] = cls('local_simulator')
33
[docs]
34 @staticmethod
35 def get_translation(circuit: CIRCUIT_FORMATS, output_format: type[CIRCUIT_FORMATS]) -> CIRCUIT_FORMATS:
36 """Transpiles circuit into given languages basis_gates, translates it to qasm, and from qasm into desired languages object."""
37 circuit_qasm_translator = GateCircuitBackend.circuit_class_mapping[circuit.__class__]
38 qasm_circuit_translator = GateCircuitBackend.circuit_class_mapping[output_format]
39
40 if isinstance(circuit, qiskit.QuantumCircuit):
41 transpiled_circuit = GateCircuitBackend.transpile_circuit(circuit, qasm_circuit_translator.basis_gates)
42 else:
43 transpiled_circuit = circuit # Transpilation is usually not needed
44
45 qasm = circuit_qasm_translator.to_qasm(transpiled_circuit)
46 return qasm_circuit_translator.from_qasm(qasm)
47
[docs]
48 @staticmethod
49 def transpile_circuit(qc: qiskit.QuantumCircuit, basis_gates: list[str]) -> qiskit.QuantumCircuit:
50 """Makes circuit compatible with cirq
51
52 Args:
53 qc (qiskit.QuantumCircuit): circuit
54
55 Returns:
56 qiskit.QuantumCircuit: transpiled circuit
57 """
58 qc_transpiled = qiskit.transpile(qc, basis_gates=basis_gates, optimization_level=3)
59
60 return RemoveBarriers()(qc_transpiled)
61
[docs]
62 @staticmethod
63 @abstractmethod
64 def to_qasm(circuit: _AllowedCircuit) -> str:
65 pass
66
[docs]
67 @staticmethod
68 @abstractmethod
69 def from_qasm(qasm: str) -> _AllowedCircuit:
70 pass
71
[docs]
72 @abstractmethod
73 def sample_circuit(self, circuit: CIRCUIT_FORMATS, shots: int = 1024) -> dict[str, int]:
74 pass