|
18 | 18 | from qiskit.circuit.quantumcircuitdata import CircuitInstruction
|
19 | 19 | from qiskit.circuit.parametervector import ParameterVectorElement
|
20 | 20 | from qiskit.circuit import Parameter, ParameterExpression
|
21 |
| - import cirq |
22 | 21 | except ImportError:
|
23 | 22 | logger.warning(
|
24 | 23 | "Please first ``pip install -U qiskit`` to enable related functionality in translation module"
|
25 | 24 | )
|
26 | 25 |
|
| 26 | +try: |
| 27 | + import cirq |
| 28 | +except ImportError: |
| 29 | + logger.warning( |
| 30 | + "Please first ``pip install -U cirq`` to enable related functionality in translation module" |
| 31 | + ) |
| 32 | + |
27 | 33 | from . import gates
|
28 | 34 | from .circuit import Circuit
|
29 | 35 | from .densitymatrix import DMCircuit2
|
@@ -82,21 +88,6 @@ def _merge_extra_qir(
|
82 | 88 | nqir += inds[k]
|
83 | 89 | return nqir
|
84 | 90 |
|
85 |
| -class CustomizedCirqGate(cirq.Gate): |
86 |
| - def __init__(self, uMatrix, name, nqubit): |
87 |
| - super(CustomizedCirqGate, self) |
88 |
| - self.uMatrix = uMatrix |
89 |
| - self.name = name |
90 |
| - self.nqubit = nqubit |
91 |
| - |
92 |
| - def _num_qubits_(self): |
93 |
| - return self.nqubit |
94 |
| - |
95 |
| - def _unitary_(self): |
96 |
| - return self.uMatrix |
97 |
| - |
98 |
| - def _circuit_diagram_info_(self, args): |
99 |
| - return [self.name] * self.nqubit |
100 | 91 |
|
101 | 92 | def qir2cirq(
|
102 | 93 | qir: List[Dict[str, Any]], n: int, extra_qir: Optional[List[Dict[str, Any]]] = None
|
@@ -124,51 +115,85 @@ def qir2cirq(
|
124 | 115 | :return: qiskit cirq object
|
125 | 116 | :rtype: Any
|
126 | 117 |
|
127 |
| - todo: |
| 118 | + #TODO(@erertertet): |
128 | 119 | add default theta to iswap gate
|
129 | 120 | add more cirq built-in gate instead of customized
|
130 | 121 | add unitary test with tolerance
|
131 | 122 | add support of cirq built-in ControlledGate for multiplecontroll
|
132 | 123 | support more element in qir, e.g. barrier, measure...
|
133 | 124 | disable outputting controlled bit when creating controlled gate
|
134 | 125 | """
|
| 126 | + |
| 127 | + class CustomizedCirqGate(cirq.Gate): |
| 128 | + def __init__(self, uMatrix: Any, name: str, nqubit: int): |
| 129 | + super(CustomizedCirqGate, self) |
| 130 | + self.uMatrix = uMatrix |
| 131 | + self.name = name |
| 132 | + self.nqubit = nqubit |
| 133 | + |
| 134 | + def _num_qubits_(self) -> int: |
| 135 | + return self.nqubit |
| 136 | + |
| 137 | + def _unitary_(self) -> Any: |
| 138 | + return self.uMatrix |
| 139 | + |
| 140 | + def _circuit_diagram_info_(self) -> List[str]: |
| 141 | + return [self.name] * self.nqubit |
| 142 | + |
135 | 143 | if extra_qir is not None and len(extra_qir) > 0:
|
136 | 144 | qir = _merge_extra_qir(qir, extra_qir)
|
137 | 145 | qbits = cirq.LineQubit.range(n)
|
138 |
| - cmd = [] |
| 146 | + cmd = [] |
139 | 147 | for gate_info in qir:
|
140 | 148 | index = [qbits[i] for i in gate_info["index"]]
|
141 | 149 | gate_name = str(gate_info["gatef"])
|
142 | 150 | if "parameters" in gate_info:
|
143 | 151 | parameters = gate_info["parameters"]
|
144 |
| - if gate_name in ["h","i","x","y","z","s","t","fredkin","toffoli","cnot","swap"]: |
| 152 | + if gate_name in [ |
| 153 | + "h", |
| 154 | + "i", |
| 155 | + "x", |
| 156 | + "y", |
| 157 | + "z", |
| 158 | + "s", |
| 159 | + "t", |
| 160 | + "fredkin", |
| 161 | + "toffoli", |
| 162 | + "cnot", |
| 163 | + "swap", |
| 164 | + ]: |
145 | 165 | cmd.append(getattr(cirq, gate_name.upper())(*index))
|
146 | 166 | elif gate_name in ["rx", "ry", "rz"]:
|
147 |
| - cmd.append(getattr(cirq, gate_name)(_get_float(parameters, "theta")).on(*index)) |
| 167 | + cmd.append( |
| 168 | + getattr(cirq, gate_name)(_get_float(parameters, "theta")).on(*index) |
| 169 | + ) |
148 | 170 | elif gate_name == "iswap":
|
149 |
| - if "theta" not in parameters: |
150 |
| - cmd.append(cirq.ISWAP(*index)) |
151 |
| - # when ISWAP theta is not specified, _get_float will return default value of 0.0 instead of 1.0 |
152 |
| - else: |
153 |
| - cmd.append(cirq.ISwapPowGate(exponent = _get_float(parameters, "theta")).on(*index)) |
| 171 | + cmd.append( |
| 172 | + cirq.ISwapPowGate( |
| 173 | + exponent=_get_float(parameters, "theta", default=1) |
| 174 | + ).on(*index) |
| 175 | + ) |
154 | 176 | elif gate_name in ["mpo", "multicontrol"]:
|
155 | 177 | gatem = np.reshape(
|
156 |
| - backend.numpy(gate_info["gatef"](**parameters).eval_matrix()), |
157 |
| - [2 ** len(index), 2 ** len(index)], |
158 |
| - ) |
| 178 | + backend.numpy(gate_info["gatef"](**parameters).eval_matrix()), |
| 179 | + [2 ** len(index), 2 ** len(index)], |
| 180 | + ) |
159 | 181 | ci_name = gate_info["name"]
|
160 | 182 | cgate = CustomizedCirqGate(gatem, ci_name, len(index))
|
161 | 183 | cmd.append(cgate.on(*index))
|
162 | 184 | else:
|
163 | 185 | # Add Customized Gate if there is no match
|
164 |
| - gatem = np.reshape(gate_info["gate"].tensor,[2 ** len(index), 2 ** len(index)], |
| 186 | + gatem = np.reshape( |
| 187 | + gate_info["gate"].tensor, |
| 188 | + [2 ** len(index), 2 ** len(index)], |
165 | 189 | )
|
166 | 190 | # Note: unitary test is not working for some of the generated matrix, probably add tolerance unitary test later
|
167 | 191 | cgate = CustomizedCirqGate(gatem, gate_name, len(index))
|
168 | 192 | cmd.append(cgate.on(*index))
|
169 | 193 | cirq_circuit = cirq.Circuit(*cmd)
|
170 | 194 | return cirq_circuit
|
171 | 195 |
|
| 196 | + |
172 | 197 | def qir2qiskit(
|
173 | 198 | qir: List[Dict[str, Any]], n: int, extra_qir: Optional[List[Dict[str, Any]]] = None
|
174 | 199 | ) -> Any:
|
|
0 commit comments