quarkcircuit 0.3.4__tar.gz → 0.3.6.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/PKG-INFO +1 -1
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/pyproject.toml +1 -1
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/backend.py +18 -18
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/decompose.py +165 -44
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/layout.py +10 -7
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/routing.py +1 -1
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/test_transpiler.py +11 -4
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/translate.py +14 -12
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/transpiler.py +1 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/PKG-INFO +1 -1
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/README.md +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/__init__.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/basepasses.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/dag.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/matrix.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/optimize.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/quantumcircuit.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/quantumcircuit_helpers.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/utils.py +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/SOURCES.txt +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/dependency_links.txt +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/requires.txt +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/top_level.txt +0 -0
- {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/setup.cfg +0 -0
|
@@ -142,7 +142,7 @@ class Backend:
|
|
|
142
142
|
|
|
143
143
|
def draw(self,show_couplers_fidelity:bool = False, show_qubits_attributes:Literal['T1','T2','fidelity','frequency','']='',
|
|
144
144
|
show_qubits_index:bool=False,show_couplers_index:bool=False,
|
|
145
|
-
highlight_nodes:list = [], save_svg_fname: str|None = None):
|
|
145
|
+
highlight_nodes:list = [], save_svg_fname: str|None = None,edge_fidelity_thres=0.0):
|
|
146
146
|
"""Draw the chip layout.
|
|
147
147
|
|
|
148
148
|
Args:
|
|
@@ -174,9 +174,9 @@ class Backend:
|
|
|
174
174
|
from matplotlib.colors import Normalize,LinearSegmentedColormap
|
|
175
175
|
from matplotlib.cm import ScalarMappable
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
edge_fidelity = nx.get_edge_attributes(
|
|
179
|
-
node_attributes = nx.get_node_attributes(
|
|
177
|
+
graph_show = self.edge_filtered_graph(thres=edge_fidelity_thres)
|
|
178
|
+
edge_fidelity = nx.get_edge_attributes(graph_show, 'fidelity')
|
|
179
|
+
node_attributes = nx.get_node_attributes(graph_show,show_qubits_attributes)
|
|
180
180
|
if show_couplers_fidelity:
|
|
181
181
|
if set(list(edge_fidelity.values())) == {0}:
|
|
182
182
|
print('The two-qubit gate fidelity is N/A now.')
|
|
@@ -197,7 +197,7 @@ class Backend:
|
|
|
197
197
|
edge_cmap = LinearSegmentedColormap.from_list('truncated_blues', plt.get_cmap('Blues')(np.linspace(0.31, 1.0, 1000))) #plt.get_cmap('Blues')
|
|
198
198
|
edge_colors = [ScalarMappable(norm = edge_norm, cmap = edge_cmap).to_rgba(fidelity) for fidelity in edge_fidelity.values()]
|
|
199
199
|
else:
|
|
200
|
-
edge_colors = ['#083776' for edge in
|
|
200
|
+
edge_colors = ['#083776' for edge in graph_show.edges()]
|
|
201
201
|
|
|
202
202
|
edge_labels = {}
|
|
203
203
|
for k,v in edge_fidelity.items():
|
|
@@ -207,11 +207,11 @@ class Backend:
|
|
|
207
207
|
fidelity = np.round(v, 3)
|
|
208
208
|
if show_couplers_fidelity is True and is_edge_info_avaliable is True:
|
|
209
209
|
if show_couplers_index:
|
|
210
|
-
edge_labels[k] =
|
|
210
|
+
edge_labels[k] = graph_show.edges[k].get('index')
|
|
211
211
|
else:
|
|
212
212
|
edge_labels[k] = fidelity
|
|
213
213
|
else:
|
|
214
|
-
edge_labels[k] =
|
|
214
|
+
edge_labels[k] = graph_show.edges[k].get('index')
|
|
215
215
|
|
|
216
216
|
if show_qubits_attributes != '' and is_node_info_avaliable is True:
|
|
217
217
|
min_attributes = sorted(list(node_attributes.values()))[0]
|
|
@@ -221,12 +221,12 @@ class Backend:
|
|
|
221
221
|
node_colors = [ScalarMappable(norm = node_norm, cmap = node_cmap).to_rgba(attribute) for attribute in node_attributes.values()]
|
|
222
222
|
if show_qubits_attributes == 'fidelity':
|
|
223
223
|
if show_qubits_index:
|
|
224
|
-
node_labels = {node:node for node in
|
|
224
|
+
node_labels = {node:node for node in graph_show.nodes()}
|
|
225
225
|
else:
|
|
226
226
|
node_labels = {node: np.round(attr, 3) for node, attr in node_attributes.items()} # 保留三位有效数字
|
|
227
227
|
else:
|
|
228
228
|
if show_qubits_index:
|
|
229
|
-
node_labels = {node:node for node in
|
|
229
|
+
node_labels = {node:node for node in graph_show.nodes()}
|
|
230
230
|
else:
|
|
231
231
|
node_labels = {node: np.round(attr, 2) for node, attr in node_attributes.items()} # 保留两位有效数字
|
|
232
232
|
node_font_size = 8
|
|
@@ -235,8 +235,8 @@ class Backend:
|
|
|
235
235
|
else:
|
|
236
236
|
figsize = (15, 13.5)
|
|
237
237
|
else:
|
|
238
|
-
node_colors = ['#083776' for node in
|
|
239
|
-
node_labels = {node:node for node in
|
|
238
|
+
node_colors = ['#083776' for node in graph_show.nodes()]
|
|
239
|
+
node_labels = {node:node for node in graph_show.nodes()}
|
|
240
240
|
node_font_size = 10
|
|
241
241
|
if show_couplers_fidelity is True and is_edge_info_avaliable is True:
|
|
242
242
|
figsize = (15, 13.5)
|
|
@@ -248,7 +248,7 @@ class Backend:
|
|
|
248
248
|
highlight_nodes = list(set(e for sub in highlight_nodes for e in sub))
|
|
249
249
|
node_colors_update = []
|
|
250
250
|
node_labels_update = {}
|
|
251
|
-
for idx, node in enumerate(
|
|
251
|
+
for idx, node in enumerate(graph_show.nodes()):
|
|
252
252
|
if node in highlight_nodes:
|
|
253
253
|
node_colors_update.append(node_colors[idx])
|
|
254
254
|
node_labels_update[node] = node_labels[node]
|
|
@@ -258,10 +258,10 @@ class Backend:
|
|
|
258
258
|
node_colors = node_colors_update
|
|
259
259
|
node_labels = node_labels_update
|
|
260
260
|
|
|
261
|
-
subgraph =
|
|
261
|
+
subgraph = graph_show.subgraph(highlight_nodes)
|
|
262
262
|
edge_colors_update = []
|
|
263
263
|
edge_labels_update = {}
|
|
264
|
-
for idx, edge in enumerate(
|
|
264
|
+
for idx, edge in enumerate(graph_show.edges()):
|
|
265
265
|
if edge in subgraph.edges():
|
|
266
266
|
edge_colors_update.append(edge_colors[idx])
|
|
267
267
|
edge_labels_update[edge] = edge_labels[edge]
|
|
@@ -272,10 +272,10 @@ class Backend:
|
|
|
272
272
|
edge_labels = edge_labels_update
|
|
273
273
|
|
|
274
274
|
fig, ax = plt.subplots(figsize=figsize) #facecolor='none'
|
|
275
|
-
pos = nx.get_node_attributes(
|
|
276
|
-
nx.draw(
|
|
277
|
-
nx.draw_networkx_labels(
|
|
278
|
-
nx.draw_networkx_edge_labels(
|
|
275
|
+
pos = nx.get_node_attributes(graph_show, 'coordinate')
|
|
276
|
+
nx.draw(graph_show, pos,ax=ax, with_labels=False, node_color=node_colors, node_size=800, edgecolors='white',edge_color = edge_colors ,width = 18,)
|
|
277
|
+
nx.draw_networkx_labels(graph_show,pos,labels=node_labels,font_size=node_font_size, font_color='white')
|
|
278
|
+
nx.draw_networkx_edge_labels(graph_show, pos, edge_labels=edge_labels,font_size=8, font_color='white',bbox=dict(facecolor='none', edgecolor='none'),rotate=False)
|
|
279
279
|
|
|
280
280
|
if show_qubits_attributes != '' and is_node_info_avaliable is True:
|
|
281
281
|
if show_qubits_attributes == 'T1':
|
|
@@ -121,7 +121,96 @@ def rz2u(theta:float,qubit:int) -> tuple:
|
|
|
121
121
|
"""
|
|
122
122
|
return ('u',0.0,0.0,theta,qubit)
|
|
123
123
|
|
|
124
|
-
def
|
|
124
|
+
def convert_cx_to_iswap(control_qubit,target_qubit,convert_single_qubit_gate_to_u:bool):
|
|
125
|
+
gates0 = [
|
|
126
|
+
('rz', -1.5707963267948966, control_qubit),
|
|
127
|
+
('ry', 1.5707963267948966, control_qubit),
|
|
128
|
+
('rz', 1.5707963267948966, control_qubit),
|
|
129
|
+
('ry', -1.5707963267948966, target_qubit),
|
|
130
|
+
('rz', -1.0094094858814842, target_qubit),
|
|
131
|
+
('iswap', control_qubit, target_qubit),
|
|
132
|
+
('rz', -1.5707963267948966, control_qubit),
|
|
133
|
+
('ry', 3.141592653589793, control_qubit),
|
|
134
|
+
('rz', 1.5707963267948966, target_qubit),
|
|
135
|
+
('ry', -1.5707963267948966, target_qubit),
|
|
136
|
+
('iswap', control_qubit, target_qubit),
|
|
137
|
+
('rz', -3.141592653589793, control_qubit),
|
|
138
|
+
('ry', -1.5707963267948966, control_qubit),
|
|
139
|
+
('rz', -1.0094094858814842, target_qubit),
|
|
140
|
+
('ry', -1.5707963267948966, target_qubit)]
|
|
141
|
+
|
|
142
|
+
new = []
|
|
143
|
+
if convert_single_qubit_gate_to_u:
|
|
144
|
+
for gate_info in gates0:
|
|
145
|
+
if gate_info[0] =='rz':
|
|
146
|
+
new_gate_info = rz2u(gate_info[1],gate_info[2])
|
|
147
|
+
new.append(new_gate_info)
|
|
148
|
+
elif gate_info[0] == 'ry':
|
|
149
|
+
new_gate_info = ry2u(gate_info[1],gate_info[2])
|
|
150
|
+
new.append(new_gate_info)
|
|
151
|
+
else:
|
|
152
|
+
new.append(gate_info)
|
|
153
|
+
gates0 = new
|
|
154
|
+
return gates0
|
|
155
|
+
|
|
156
|
+
def convert_cz_to_iswap(control_qubit,target_qubit,convert_single_qubit_gate_to_u:bool):
|
|
157
|
+
gates0 = [
|
|
158
|
+
('rz', -1.5707963267948966, control_qubit),
|
|
159
|
+
('ry', 1.5707963267948966, control_qubit),
|
|
160
|
+
('rz', 1.5707963267948966, control_qubit),
|
|
161
|
+
('rz', -1.5707963267948966, target_qubit),
|
|
162
|
+
('ry', 3.141592653589793, target_qubit),
|
|
163
|
+
('iswap', control_qubit, target_qubit),
|
|
164
|
+
('rz', -1.5707963267948966, control_qubit),
|
|
165
|
+
('ry', 3.141592653589793, control_qubit),
|
|
166
|
+
('rz', 1.5707963267948966, target_qubit),
|
|
167
|
+
('ry', -1.5707963267948966, target_qubit),
|
|
168
|
+
('iswap', control_qubit, target_qubit),
|
|
169
|
+
('ry', 1.5707963267948966, control_qubit),
|
|
170
|
+
('rz', 1.5707963267948966, target_qubit)]
|
|
171
|
+
new = []
|
|
172
|
+
if convert_single_qubit_gate_to_u:
|
|
173
|
+
for gate_info in gates0:
|
|
174
|
+
if gate_info[0] =='rz':
|
|
175
|
+
new_gate_info = rz2u(gate_info[1],gate_info[2])
|
|
176
|
+
new.append(new_gate_info)
|
|
177
|
+
elif gate_info[0] == 'ry':
|
|
178
|
+
new_gate_info = ry2u(gate_info[1],gate_info[2])
|
|
179
|
+
new.append(new_gate_info)
|
|
180
|
+
else:
|
|
181
|
+
new.append(gate_info)
|
|
182
|
+
gates0 = new
|
|
183
|
+
return gates0
|
|
184
|
+
|
|
185
|
+
def cz_decompose(control_qubit: int, target_qubit: int,convert_single_qubit_gate_to_u:bool,two_qubit_gate_basis:Literal['cx','cz','iswap']) -> list:
|
|
186
|
+
""" Decompose CZ gate to U3 gates and CZ gates.
|
|
187
|
+
|
|
188
|
+
Args:
|
|
189
|
+
control_qubit (int): The qubit used as control.
|
|
190
|
+
target_qubit (int): The qubit targeted by the gate.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
list: A list of U3 gates and CZ gates.
|
|
194
|
+
"""
|
|
195
|
+
gates = []
|
|
196
|
+
if two_qubit_gate_basis == 'cz':
|
|
197
|
+
gates.append(('cz',control_qubit,target_qubit))
|
|
198
|
+
elif two_qubit_gate_basis == 'cx':
|
|
199
|
+
if convert_single_qubit_gate_to_u:
|
|
200
|
+
gates.append(h2u(target_qubit))
|
|
201
|
+
else:
|
|
202
|
+
gates.append(('h',target_qubit))
|
|
203
|
+
gates.append(('cx', control_qubit, target_qubit))
|
|
204
|
+
if convert_single_qubit_gate_to_u:
|
|
205
|
+
gates.append(h2u(target_qubit))
|
|
206
|
+
else:
|
|
207
|
+
gates.append(('h',target_qubit))
|
|
208
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
209
|
+
gates += convert_cz_to_iswap(control_qubit,target_qubit,convert_single_qubit_gate_to_u)
|
|
210
|
+
|
|
211
|
+
return gates
|
|
212
|
+
|
|
213
|
+
def cx_decompose(control_qubit: int, target_qubit: int,convert_single_qubit_gate_to_u:bool,two_qubit_gate_basis:Literal['cx','cz','iswap']) -> list:
|
|
125
214
|
""" Decompose CX gate to U3 gates and CZ gates.
|
|
126
215
|
|
|
127
216
|
Args:
|
|
@@ -144,9 +233,11 @@ def cx_decompose(control_qubit: int, target_qubit: int,convert_single_qubit_gate
|
|
|
144
233
|
gates.append(('h',target_qubit))
|
|
145
234
|
elif two_qubit_gate_basis == 'cx':
|
|
146
235
|
gates.append(('cx',control_qubit,target_qubit))
|
|
236
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
237
|
+
gates += convert_cx_to_iswap(control_qubit,target_qubit,convert_single_qubit_gate_to_u)
|
|
147
238
|
return gates
|
|
148
239
|
|
|
149
|
-
def cy_decompose(control_qubit: int, target_qubit: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
240
|
+
def cy_decompose(control_qubit: int, target_qubit: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
150
241
|
""" Decompose CY gate to U3 gates and CZ gates.
|
|
151
242
|
|
|
152
243
|
Args:
|
|
@@ -167,6 +258,8 @@ def cy_decompose(control_qubit: int, target_qubit: int, convert_single_qubit_gat
|
|
|
167
258
|
gates += cx_decompose(control_qubit,target_qubit,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
168
259
|
elif two_qubit_gate_basis == 'cx':
|
|
169
260
|
gates.append(('cx',control_qubit,target_qubit))
|
|
261
|
+
elif two_qubit_gate_basis =='iswap':
|
|
262
|
+
gates += convert_cx_to_iswap(control_qubit,target_qubit,convert_single_qubit_gate_to_u)
|
|
170
263
|
|
|
171
264
|
if convert_single_qubit_gate_to_u:
|
|
172
265
|
gates.append(s2u(target_qubit))
|
|
@@ -174,7 +267,7 @@ def cy_decompose(control_qubit: int, target_qubit: int, convert_single_qubit_gat
|
|
|
174
267
|
gates.append(('s',target_qubit))
|
|
175
268
|
return gates
|
|
176
269
|
|
|
177
|
-
def swap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
270
|
+
def swap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
178
271
|
"""Decompose SWAP gate to U3 gates and CZ gates.
|
|
179
272
|
|
|
180
273
|
Args:
|
|
@@ -214,9 +307,17 @@ def swap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:bool
|
|
|
214
307
|
gates.append(('cx',qubit1,qubit2))
|
|
215
308
|
gates.append(('cx',qubit2,qubit1))
|
|
216
309
|
gates.append(('cx',qubit1,qubit2))
|
|
310
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
311
|
+
gates = []
|
|
312
|
+
gates.append(('iswap',qubit1,qubit2))
|
|
313
|
+
gates.append(('sx',qubit2))
|
|
314
|
+
gates.append(('iswap',qubit1,qubit2))
|
|
315
|
+
gates.append(('sx',qubit1))
|
|
316
|
+
gates.append(('iswap',qubit1,qubit2))
|
|
317
|
+
gates.append(('sx',qubit2))
|
|
217
318
|
return gates
|
|
218
319
|
|
|
219
|
-
def iswap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
320
|
+
def iswap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
220
321
|
""" Decompose iswap gate with qiskit decompose algorithm.
|
|
221
322
|
|
|
222
323
|
Args:
|
|
@@ -227,44 +328,44 @@ def iswap_decompose(qubit1: int, qubit2: int, convert_single_qubit_gate_to_u:boo
|
|
|
227
328
|
list: A list of U3 gates and CZ gates.
|
|
228
329
|
"""
|
|
229
330
|
# iswap = R_{XX+YY}(-pi/2) = e^{i*pi/4*(X\otimesX + Y\otimesY)}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
gates.append(
|
|
233
|
-
gates.append(rx2u(np.pi/2,qubit1))
|
|
234
|
-
gates.append(rx2u(-np.pi/2,qubit2))
|
|
235
|
-
else:
|
|
236
|
-
gates.append(('x', qubit1))
|
|
237
|
-
gates.append(('rx', np.pi/2, qubit1))
|
|
238
|
-
gates.append(('rx',-np.pi/2, qubit2))
|
|
239
|
-
|
|
240
|
-
if two_qubit_gate_basis == 'cx':
|
|
241
|
-
gates.append(('cx', qubit1, qubit2))
|
|
242
|
-
elif two_qubit_gate_basis == 'cz':
|
|
243
|
-
gates += cx_decompose(qubit1, qubit2, convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
244
|
-
|
|
245
|
-
if convert_single_qubit_gate_to_u:
|
|
246
|
-
gates.append(rx2u(-np.pi/2,qubit1))
|
|
247
|
-
gates.append(rz2u(-np.pi/2,qubit2))
|
|
248
|
-
else:
|
|
249
|
-
gates.append(('rx',-np.pi/2, qubit1))
|
|
250
|
-
gates.append(('rz',-np.pi/2, qubit2))
|
|
251
|
-
|
|
252
|
-
if two_qubit_gate_basis == 'cx':
|
|
253
|
-
gates.append(('cx', qubit1, qubit2))
|
|
254
|
-
elif two_qubit_gate_basis == 'cz':
|
|
255
|
-
gates += cx_decompose(qubit1, qubit2, convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
256
|
-
|
|
257
|
-
if convert_single_qubit_gate_to_u:
|
|
258
|
-
gates.append(rx2u(-np.pi/2, qubit1))
|
|
259
|
-
gates.append(rx2u(np.pi/2, qubit2))
|
|
260
|
-
gates.append(x2u(qubit1))
|
|
331
|
+
if two_qubit_gate_basis == 'iswap':
|
|
332
|
+
gates = []
|
|
333
|
+
gates.append(('iswap',qubit1,qubit2))
|
|
261
334
|
else:
|
|
262
|
-
gates
|
|
263
|
-
|
|
264
|
-
|
|
335
|
+
gates = []
|
|
336
|
+
if convert_single_qubit_gate_to_u:
|
|
337
|
+
gates.append(x2u(qubit1))
|
|
338
|
+
gates.append(rx2u(np.pi/2,qubit1))
|
|
339
|
+
gates.append(rx2u(-np.pi/2,qubit2))
|
|
340
|
+
else:
|
|
341
|
+
gates.append(('x', qubit1))
|
|
342
|
+
gates.append(('rx', np.pi/2, qubit1))
|
|
343
|
+
gates.append(('rx',-np.pi/2, qubit2))
|
|
344
|
+
if two_qubit_gate_basis == 'cx':
|
|
345
|
+
gates.append(('cx', qubit1, qubit2))
|
|
346
|
+
elif two_qubit_gate_basis == 'cz':
|
|
347
|
+
gates += cx_decompose(qubit1, qubit2, convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
348
|
+
if convert_single_qubit_gate_to_u:
|
|
349
|
+
gates.append(rx2u(-np.pi/2,qubit1))
|
|
350
|
+
gates.append(rz2u(-np.pi/2,qubit2))
|
|
351
|
+
else:
|
|
352
|
+
gates.append(('rx',-np.pi/2, qubit1))
|
|
353
|
+
gates.append(('rz',-np.pi/2, qubit2))
|
|
354
|
+
if two_qubit_gate_basis == 'cx':
|
|
355
|
+
gates.append(('cx', qubit1, qubit2))
|
|
356
|
+
elif two_qubit_gate_basis == 'cz':
|
|
357
|
+
gates += cx_decompose(qubit1, qubit2, convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
358
|
+
if convert_single_qubit_gate_to_u:
|
|
359
|
+
gates.append(rx2u(-np.pi/2, qubit1))
|
|
360
|
+
gates.append(rx2u(np.pi/2, qubit2))
|
|
361
|
+
gates.append(x2u(qubit1))
|
|
362
|
+
else:
|
|
363
|
+
gates.append(('rx',-np.pi/2, qubit1))
|
|
364
|
+
gates.append(('rx', np.pi/2, qubit2))
|
|
365
|
+
gates.append(('x', qubit1))
|
|
265
366
|
return gates
|
|
266
367
|
|
|
267
|
-
def rxx_decompose(theta:float,qubit1:int,qubit2:int,convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
368
|
+
def rxx_decompose(theta:float,qubit1:int,qubit2:int,convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
268
369
|
"""Decompose RXX gate to U3 gates and CZ gates.
|
|
269
370
|
|
|
270
371
|
Args:
|
|
@@ -286,6 +387,9 @@ def rxx_decompose(theta:float,qubit1:int,qubit2:int,convert_single_qubit_gate_to
|
|
|
286
387
|
gates.append(('cx',qubit1,qubit2))
|
|
287
388
|
elif two_qubit_gate_basis == 'cz':
|
|
288
389
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
390
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
391
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
392
|
+
|
|
289
393
|
if convert_single_qubit_gate_to_u:
|
|
290
394
|
gates.append(rz2u(theta,qubit2))
|
|
291
395
|
else:
|
|
@@ -294,6 +398,9 @@ def rxx_decompose(theta:float,qubit1:int,qubit2:int,convert_single_qubit_gate_to
|
|
|
294
398
|
gates.append(('cx',qubit1,qubit2))
|
|
295
399
|
elif two_qubit_gate_basis == 'cz':
|
|
296
400
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
401
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
402
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
403
|
+
|
|
297
404
|
if convert_single_qubit_gate_to_u:
|
|
298
405
|
gates.append(h2u(qubit1))
|
|
299
406
|
gates.append(h2u(qubit2))
|
|
@@ -302,7 +409,7 @@ def rxx_decompose(theta:float,qubit1:int,qubit2:int,convert_single_qubit_gate_to
|
|
|
302
409
|
gates.append(('h', qubit2))
|
|
303
410
|
return gates
|
|
304
411
|
|
|
305
|
-
def ryy_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
412
|
+
def ryy_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
306
413
|
"""Decompose RYY gate to U3 gates and CZ gates.
|
|
307
414
|
|
|
308
415
|
Args:
|
|
@@ -324,6 +431,8 @@ def ryy_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
324
431
|
gates.append(('cx', qubit1, qubit2))
|
|
325
432
|
elif two_qubit_gate_basis == 'cz':
|
|
326
433
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
434
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
435
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
327
436
|
if convert_single_qubit_gate_to_u:
|
|
328
437
|
gates.append(rz2u(theta,qubit2))
|
|
329
438
|
else:
|
|
@@ -332,6 +441,8 @@ def ryy_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
332
441
|
gates.append(('cx', qubit1, qubit2))
|
|
333
442
|
elif two_qubit_gate_basis == 'cz':
|
|
334
443
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
444
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
445
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
335
446
|
if convert_single_qubit_gate_to_u:
|
|
336
447
|
gates.append(rx2u(-np.pi/2,qubit1))
|
|
337
448
|
gates.append(rx2u(-np.pi/2,qubit2))
|
|
@@ -340,7 +451,7 @@ def ryy_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
340
451
|
gates.append(('rx', -np.pi/2, qubit2))
|
|
341
452
|
return gates
|
|
342
453
|
|
|
343
|
-
def rzz_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx']) -> list:
|
|
454
|
+
def rzz_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate_to_u:bool, two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
344
455
|
"""Decompose RZZ gate to U3 gates and CZ gates.
|
|
345
456
|
|
|
346
457
|
Args:
|
|
@@ -356,6 +467,8 @@ def rzz_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
356
467
|
gates.append(('cx', qubit1, qubit2))
|
|
357
468
|
elif two_qubit_gate_basis == 'cz':
|
|
358
469
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
470
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
471
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
359
472
|
if convert_single_qubit_gate_to_u:
|
|
360
473
|
gates.append(rz2u(theta,qubit2))
|
|
361
474
|
else:
|
|
@@ -364,10 +477,12 @@ def rzz_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
364
477
|
gates.append(('cx', qubit1, qubit2))
|
|
365
478
|
elif two_qubit_gate_basis == 'cz':
|
|
366
479
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
480
|
+
elif two_qubit_gate_basis == 'iswap':
|
|
481
|
+
gates += convert_cx_to_iswap(qubit1,qubit2,convert_single_qubit_gate_to_u)
|
|
367
482
|
return gates
|
|
368
483
|
|
|
369
484
|
|
|
370
|
-
def cp_decompose(theta:float, control_qubit:int, target_qubit:int, convert_single_qubit_gate_to_u:bool) -> list:
|
|
485
|
+
def cp_decompose(theta:float, control_qubit:int, target_qubit:int, convert_single_qubit_gate_to_u:bool,two_qubit_gate_basis:Literal['cz','cx','iswap']) -> list:
|
|
371
486
|
"""Decompose CPhase gate to U3 gates and CZ gates. ref: Quantum Sci. Technol. 7 (2022) 025021
|
|
372
487
|
|
|
373
488
|
Args:
|
|
@@ -383,12 +498,18 @@ def cp_decompose(theta:float, control_qubit:int, target_qubit:int, convert_singl
|
|
|
383
498
|
gates.append(h2u(target_qubit))
|
|
384
499
|
else:
|
|
385
500
|
gates.append(('h',target_qubit))
|
|
386
|
-
|
|
501
|
+
|
|
502
|
+
#gates.append(('cz', control_qubit, target_qubit))
|
|
503
|
+
gates += cz_decompose(control_qubit,target_qubit,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
504
|
+
|
|
387
505
|
if convert_single_qubit_gate_to_u:
|
|
388
506
|
gates.append(rx2u(theta/2,target_qubit))
|
|
389
507
|
else:
|
|
390
508
|
gates.append(('rx',theta/2,target_qubit))
|
|
391
|
-
|
|
509
|
+
|
|
510
|
+
#gates.append(('cz', control_qubit, target_qubit))
|
|
511
|
+
gates += cz_decompose(control_qubit,target_qubit,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
512
|
+
|
|
392
513
|
if convert_single_qubit_gate_to_u:
|
|
393
514
|
gates.append(rz2u(-1*theta/2, control_qubit))
|
|
394
515
|
gates.append(h2u(target_qubit))
|
|
@@ -349,7 +349,9 @@ class Layout:
|
|
|
349
349
|
raise(ValueError(f'The physical qubit {node} in target_qubits does not exit'))
|
|
350
350
|
# check edge fidelity
|
|
351
351
|
is_connected = nx.is_connected(subgraph)
|
|
352
|
-
|
|
352
|
+
if is_connected is False:
|
|
353
|
+
raise(ValueError(f'The physical qubit layout {target_qubits} constructed from target_qubits is not connected.'))
|
|
354
|
+
for _, fidelity in nx.get_edge_attributes(subgraph,'fidelity').items(): # it will be []
|
|
353
355
|
if fidelity == 0.:
|
|
354
356
|
is_connected = False
|
|
355
357
|
if is_connected is False:
|
|
@@ -424,7 +426,7 @@ class Layout:
|
|
|
424
426
|
raise(ValueError('Wrong qubits error!'))
|
|
425
427
|
|
|
426
428
|
# large qubit layour
|
|
427
|
-
def get_one_component(self,thres=0.
|
|
429
|
+
def get_one_component(self,thres=0.90):
|
|
428
430
|
def edge_filter(u,v):
|
|
429
431
|
return self.graph[u][v].get("fidelity") >= thres
|
|
430
432
|
subgraph_view = nx.subgraph_view(self.graph,filter_edge=edge_filter)
|
|
@@ -446,12 +448,13 @@ class Layout:
|
|
|
446
448
|
# self.graph = chip_backend.graph #chip_backend.edge_filtered_graph(thres=0.95)
|
|
447
449
|
|
|
448
450
|
one_subgraph = self.get_one_component()
|
|
451
|
+
start_node = np.random.choice(list(one_subgraph.nodes))
|
|
449
452
|
|
|
450
|
-
if self.priority_qubits is None:
|
|
451
|
-
|
|
452
|
-
else:
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
# if self.priority_qubits is None:
|
|
454
|
+
# start_node = np.random.choice(list(one_subgraph.nodes))
|
|
455
|
+
# else:
|
|
456
|
+
# priority_qubits_list = list(set(i for sublist in self.priority_qubits for i in sublist))
|
|
457
|
+
# start_node = np.random.choice(priority_qubits_list)
|
|
455
458
|
|
|
456
459
|
visited = set([start_node])
|
|
457
460
|
queue = [(start_node, 0)]
|
|
@@ -281,7 +281,7 @@ class SabreRouting(TranspilerPass):
|
|
|
281
281
|
for node in front_layer:
|
|
282
282
|
for node_successor in self._dag_successors(node):
|
|
283
283
|
gate = node_successor.split('_')[0]
|
|
284
|
-
if gate in two_qubit_gates and len(E) <=
|
|
284
|
+
if gate in two_qubit_gates and len(E) <= len(self.v2p):
|
|
285
285
|
E.update([node_successor])
|
|
286
286
|
self.extended_successor_set = list(E)
|
|
287
287
|
else:
|
|
@@ -34,6 +34,8 @@ def call_quark_transpiler(qc:QuantumCircuit|list|str,chip_name:str,compile:bool,
|
|
|
34
34
|
else:
|
|
35
35
|
chip_backend = Backend(chip_name)
|
|
36
36
|
|
|
37
|
+
two_qubit_gate_basis = chip_backend.chip_info['global_info']['two_qubit_gate_basis'].lower()
|
|
38
|
+
|
|
37
39
|
# 初始化线路,检查线路中的门是否都支持。
|
|
38
40
|
if isinstance(qc, QuantumCircuit):
|
|
39
41
|
quarkQC = qc
|
|
@@ -103,21 +105,26 @@ def call_quark_transpiler(qc:QuantumCircuit|list|str,chip_name:str,compile:bool,
|
|
|
103
105
|
raise(ValueError('More optimize_level is not support now!'))
|
|
104
106
|
|
|
105
107
|
quarkQC_half_compiled = copy.deepcopy(quarkQC_compiled)
|
|
106
|
-
quarkQC_half_compiled = TranslateToBasisGates(convert_single_qubit_gate_to_u=False,two_qubit_gate_basis=
|
|
108
|
+
quarkQC_half_compiled = TranslateToBasisGates(convert_single_qubit_gate_to_u=False,two_qubit_gate_basis=two_qubit_gate_basis).run(quarkQC_half_compiled)
|
|
107
109
|
quarkQC_half_compiled = GateCompressor().run(quarkQC_half_compiled)
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
if two_qubit_gate_basis == 'cx':
|
|
112
|
+
two_qubit_gate_basis = 'cz'
|
|
113
|
+
quarkQC_compiled = TranslateToBasisGates(convert_single_qubit_gate_to_u=True,two_qubit_gate_basis=two_qubit_gate_basis).run(quarkQC_compiled)
|
|
110
114
|
quarkQC_compiled = GateCompressor().run(quarkQC_compiled)
|
|
111
115
|
else:
|
|
112
116
|
gates_availale = list(one_qubit_gates_available.keys()) \
|
|
113
117
|
+ list(one_qubit_parameter_gates_available.keys()) \
|
|
114
|
-
+ ['
|
|
118
|
+
+ ['barrier','measure','delay'] + [two_qubit_gate_basis]#chip 支持的语法
|
|
119
|
+
if 'cz' in gates_availale:
|
|
120
|
+
gates_availale.append('cx')
|
|
121
|
+
|
|
115
122
|
collect_two_qubit_gates = []
|
|
116
123
|
for gate_info in quarkQC.gates:
|
|
117
124
|
gate = gate_info[0]
|
|
118
125
|
if gate not in gates_availale:
|
|
119
126
|
raise(ValueError(f'The {gate} gate you provided is not supported by the current chip. Please convert to basis gates.'))
|
|
120
|
-
if gate in ['cx','cz']:
|
|
127
|
+
if gate in ['cx','cz','iswap']:
|
|
121
128
|
collect_two_qubit_gates.append(gate_info)
|
|
122
129
|
|
|
123
130
|
# check qubits existance and fidelity
|
|
@@ -30,15 +30,16 @@ from .quantumcircuit_helpers import (one_qubit_gates_available,
|
|
|
30
30
|
)
|
|
31
31
|
from .matrix import gate_matrix_dict
|
|
32
32
|
from .decompose import (cx_decompose,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
33
|
+
cz_decompose,
|
|
34
|
+
cy_decompose,
|
|
35
|
+
swap_decompose,
|
|
36
|
+
iswap_decompose,
|
|
37
|
+
rxx_decompose,
|
|
38
|
+
ryy_decompose,
|
|
39
|
+
rzz_decompose,
|
|
40
|
+
cp_decompose,
|
|
41
|
+
u3_decompose,
|
|
42
|
+
)
|
|
42
43
|
from .basepasses import TranspilerPass
|
|
43
44
|
|
|
44
45
|
class TranslateToBasisGates(TranspilerPass):
|
|
@@ -47,7 +48,7 @@ class TranslateToBasisGates(TranspilerPass):
|
|
|
47
48
|
Args:
|
|
48
49
|
TranspilerPass (class): The base class that provides the structure for the transpiler pass.
|
|
49
50
|
"""
|
|
50
|
-
def __init__(self,convert_single_qubit_gate_to_u:bool=True, two_qubit_gate_basis: Literal['cz','cx']='cz'):
|
|
51
|
+
def __init__(self,convert_single_qubit_gate_to_u:bool=True, two_qubit_gate_basis: Literal['cz','cx','iswap']='cz'):
|
|
51
52
|
"""Initializes the TranslateToBasisGates class with the specified settings.
|
|
52
53
|
|
|
53
54
|
Args:
|
|
@@ -95,7 +96,8 @@ class TranslateToBasisGates(TranspilerPass):
|
|
|
95
96
|
new.append(gate_info)
|
|
96
97
|
elif gate in two_qubit_gates_available.keys():
|
|
97
98
|
if gate in ['cz']:
|
|
98
|
-
|
|
99
|
+
_cz = cz_decompose(gate_info[1],gate_info[2],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
100
|
+
new += _cz
|
|
99
101
|
elif gate in ['cx', 'cnot']:
|
|
100
102
|
_cx = cx_decompose(gate_info[1],gate_info[2],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
101
103
|
new += _cx
|
|
@@ -118,7 +120,7 @@ class TranslateToBasisGates(TranspilerPass):
|
|
|
118
120
|
elif gate == 'rzz':
|
|
119
121
|
new += rzz_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
120
122
|
elif gate == 'cp':
|
|
121
|
-
new += cp_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u)
|
|
123
|
+
new += cp_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
122
124
|
elif gate in functional_gates_available.keys():
|
|
123
125
|
new.append(gate_info)
|
|
124
126
|
else:
|
|
@@ -59,6 +59,7 @@ class Transpiler:
|
|
|
59
59
|
raise TypeError("Expected a Quark QuantumCircuit or OpenQASM 2.0 or qlisp, but got a {}.".format(type(qc)))
|
|
60
60
|
|
|
61
61
|
if self.chip_backend is None:
|
|
62
|
+
print('Warning: No chip specified, defaulting to a linearly connected layout for simulation.')
|
|
62
63
|
import networkx as nx
|
|
63
64
|
subgraph = nx.Graph()
|
|
64
65
|
qubits = list(sorted(qc.qubits))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|