Source code for qlauncher.base.translator
1""" Module providing Translation between different universal quantum computers """
2from typing import Any
3from abc import ABC, abstractmethod
4
5import qiskit
6from qiskit import qasm2
7from qiskit.compiler import transpile
8from qiskit.transpiler.passes import RemoveBarriers
9
10from qlauncher.exceptions import DependencyError
11try:
12 import cirq
13 from cirq.contrib.qasm_import.qasm import circuit_from_qasm
14except ImportError as e:
15 raise DependencyError(e, 'cirq') from e
16
17
[docs]
18class Translation(ABC):
19 """ Translation layer for circuits written in different languages """
20 basis_gates: list[str] = []
21 language: str = 'None'
22 circuit_object: type = type
23 language_name_mapping: dict[str, "Translation"] = {}
24 circuit_class_mapping: dict[type, "Translation"] = {}
25
26 def __init_subclass__(cls):
27 Translation.language_name_mapping[cls.language] = cls()
28 Translation.circuit_class_mapping[cls.circuit_object] = cls()
29
[docs]
30 @abstractmethod
31 def to_qasm(self, circuit: Any) -> str:
32 """ Translation from given circuit into qasm (as a string) """
33
[docs]
34 @abstractmethod
35 def from_qasm(self, qasm: str) -> Any:
36 """ Translation given in qasm (as a string) circuit into language specific object """
37
[docs]
38 @staticmethod
39 def get_translation(circuit: Any, language: str) -> Any:
40 """ Transpiles circuit into given languages basis_gates, translates it to qasm, and from qasm into desired languages object. """
41 circuit_qasm_translator = Translation.circuit_class_mapping[circuit.__class__]
42 qasm_circuit_translator = Translation.language_name_mapping[language]
43 if isinstance(circuit, qiskit.QuantumCircuit):
44 transpiled_circuit = transpile_circuit(circuit, qasm_circuit_translator.basis_gates)
45 else:
46 transpiled_circuit = circuit # Transpilation is usually not needed
47 qasm = circuit_qasm_translator.to_qasm(transpiled_circuit)
48 return qasm_circuit_translator.from_qasm(qasm)
49
50
[docs]
51class CirqTranslation(Translation):
52 """ Translation class for Cirq """
53 basis_gates = ['x', 'y', 'z', 'cx', 'h', 'rx', 'ry', 'rz']
54 language: str = 'cirq'
55 circuit_object = cirq.Circuit
56
[docs]
57 def to_qasm(self, circuit: cirq.Circuit) -> str:
58 return circuit.to_qasm()
59
[docs]
60 def from_qasm(self, qasm: str) -> cirq.Circuit:
61 return circuit_from_qasm(qasm)
62
63
[docs]
64class QiskitTranslation(Translation):
65 """ Translation class for Qiskit """
66 basis_gates = ['x', 'y', 'z', 'cx', 'h', 'rx', 'ry', 'rz', 'u']
67 language: str = 'qiskit'
68 circuit_object = qiskit.QuantumCircuit
69
[docs]
70 def to_qasm(self, circuit: qiskit.QuantumCircuit) -> str:
71 return qasm2.dumps(circuit)
72
[docs]
73 def from_qasm(self, qasm: str) -> qiskit.QuantumCircuit:
74 return qiskit.QuantumCircuit.from_qasm_str(qasm)
75
76
[docs]
77def transpile_circuit(qc: qiskit.QuantumCircuit, basis_gates: list[str]) -> qiskit.QuantumCircuit:
78 """Makes circuit compatible with cirq
79
80 Args:
81 qc (qiskit.QuantumCircuit): circuit
82
83 Returns:
84 qiskit.QuantumCircuit: transpiled circuit
85 """
86 qc_transpiled = transpile(
87 qc,
88 basis_gates=basis_gates,
89 optimization_level=3
90 )
91
92 return RemoveBarriers()(qc_transpiled)