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.
Files changed (24) hide show
  1. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/PKG-INFO +1 -1
  2. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/pyproject.toml +1 -1
  3. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/backend.py +18 -18
  4. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/decompose.py +165 -44
  5. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/layout.py +10 -7
  6. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/routing.py +1 -1
  7. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/test_transpiler.py +11 -4
  8. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/translate.py +14 -12
  9. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/transpiler.py +1 -0
  10. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/PKG-INFO +1 -1
  11. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/README.md +0 -0
  12. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/__init__.py +0 -0
  13. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/basepasses.py +0 -0
  14. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/dag.py +0 -0
  15. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/matrix.py +0 -0
  16. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/optimize.py +0 -0
  17. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/quantumcircuit.py +0 -0
  18. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/quantumcircuit_helpers.py +0 -0
  19. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quark/circuit/utils.py +0 -0
  20. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/SOURCES.txt +0 -0
  21. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/dependency_links.txt +0 -0
  22. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/requires.txt +0 -0
  23. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/quarkcircuit.egg-info/top_level.txt +0 -0
  24. {quarkcircuit-0.3.4 → quarkcircuit-0.3.6.dev0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quarkcircuit
3
- Version: 0.3.4
3
+ Version: 0.3.6.dev0
4
4
  Summary: Construction, visualization, and transpilation of quantum circuits
5
5
  Author-email: Xiaoxiao Xiao <xiaoxx@baqis.ac.cn>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "quarkcircuit"
7
- version = "0.3.4"
7
+ version = "0.3.6dev"
8
8
  authors = [
9
9
  { name="Xiaoxiao Xiao", email="xiaoxx@baqis.ac.cn" }
10
10
  ]
@@ -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(self.graph, 'fidelity')
179
- node_attributes = nx.get_node_attributes(self.graph,show_qubits_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 self.graph.edges()]
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] = self.graph.edges[k].get('index')
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] = self.graph.edges[k].get('index')
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 self.graph.nodes()}
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 self.graph.nodes()}
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 self.graph.nodes()]
239
- node_labels = {node:node for node in self.graph.nodes()}
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(self.graph.nodes()):
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 = self.graph.subgraph(highlight_nodes)
261
+ subgraph = graph_show.subgraph(highlight_nodes)
262
262
  edge_colors_update = []
263
263
  edge_labels_update = {}
264
- for idx, edge in enumerate(self.graph.edges()):
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(self.graph, 'coordinate')
276
- nx.draw(self.graph, 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(self.graph,pos,labels=node_labels,font_size=node_font_size, font_color='white')
278
- nx.draw_networkx_edge_labels(self.graph, pos, edge_labels=edge_labels,font_size=8, font_color='white',bbox=dict(facecolor='none', edgecolor='none'),rotate=False)
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 cx_decompose(control_qubit: int, target_qubit: int,convert_single_qubit_gate_to_u:bool,two_qubit_gate_basis:Literal['cx','cz']) -> list:
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
- gates = []
231
- if convert_single_qubit_gate_to_u:
232
- gates.append(x2u(qubit1))
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.append(('rx',-np.pi/2, qubit1))
263
- gates.append(('rx', np.pi/2, qubit2))
264
- gates.append(('x', qubit1))
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
- gates.append(('cz', control_qubit, target_qubit))
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
- gates.append(('cz', control_qubit, target_qubit))
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
- for _, fidelity in nx.get_edge_attributes(subgraph,'fidelity').items():
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.95):
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
- start_node = np.random.choice(list(one_subgraph.nodes))
452
- else:
453
- priority_qubits_list = list(set(i for sublist in self.priority_qubits for i in sublist))
454
- start_node = np.random.choice(priority_qubits_list)
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) <= 20:
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='cx').run(quarkQC_half_compiled)
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
- quarkQC_compiled = TranslateToBasisGates(convert_single_qubit_gate_to_u=True,two_qubit_gate_basis='cz').run(quarkQC_compiled)
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
- + ['cx','cz','barrier','measure','delay'] #chip 支持的语法
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
- cy_decompose,
34
- swap_decompose,
35
- iswap_decompose,
36
- rxx_decompose,
37
- ryy_decompose,
38
- rzz_decompose,
39
- cp_decompose,
40
- u3_decompose,
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
- new.append(gate_info)
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))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quarkcircuit
3
- Version: 0.3.4
3
+ Version: 0.3.6.dev0
4
4
  Summary: Construction, visualization, and transpilation of quantum circuits
5
5
  Author-email: Xiaoxiao Xiao <xiaoxx@baqis.ac.cn>
6
6
  License-Expression: MIT