quarkcircuit 0.3.0.dev2__tar.gz → 0.3.1__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.0.dev2 → quarkcircuit-0.3.1}/PKG-INFO +1 -1
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/pyproject.toml +1 -1
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/decompose.py +34 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/layout.py +58 -34
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/matrix.py +12 -1
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/quantumcircuit.py +44 -1
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/quantumcircuit_helpers.py +75 -36
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/test_transpiler.py +2 -2
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/translate.py +3 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quarkcircuit.egg-info/PKG-INFO +1 -1
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/README.md +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/__init__.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/backend.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/basepasses.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/dag.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/optimize.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/routing.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/transpiler.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quark/circuit/utils.py +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quarkcircuit.egg-info/SOURCES.txt +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quarkcircuit.egg-info/dependency_links.txt +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quarkcircuit.egg-info/requires.txt +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/quarkcircuit.egg-info/top_level.txt +0 -0
- {quarkcircuit-0.3.0.dev2 → quarkcircuit-0.3.1}/setup.cfg +0 -0
|
@@ -366,6 +366,40 @@ def rzz_decompose(theta:float, qubit1:int, qubit2:int, convert_single_qubit_gate
|
|
|
366
366
|
gates += cx_decompose(qubit1,qubit2,convert_single_qubit_gate_to_u,two_qubit_gate_basis)
|
|
367
367
|
return gates
|
|
368
368
|
|
|
369
|
+
|
|
370
|
+
def cp_decompose(theta:float, control_qubit:int, target_qubit:int, convert_single_qubit_gate_to_u:bool) -> list:
|
|
371
|
+
"""Decompose CPhase gate to U3 gates and CZ gates.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
theta (float): The rotation angle of the gate.
|
|
375
|
+
control_qubit (int): The qubit used as control.
|
|
376
|
+
target_qubit (int): The qubit targeted by the gate.
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
list: A list of U3 gates and CZ gates.
|
|
380
|
+
"""
|
|
381
|
+
gates = []
|
|
382
|
+
if convert_single_qubit_gate_to_u:
|
|
383
|
+
gates.append(h2u(target_qubit))
|
|
384
|
+
else:
|
|
385
|
+
gates.append(('h',target_qubit))
|
|
386
|
+
gates.append(('cz', control_qubit, target_qubit))
|
|
387
|
+
if convert_single_qubit_gate_to_u:
|
|
388
|
+
gates.append(rx2u(theta/2,target_qubit))
|
|
389
|
+
else:
|
|
390
|
+
gates.append(('rx',theta/2,target_qubit))
|
|
391
|
+
gates.append(('cz', control_qubit, target_qubit))
|
|
392
|
+
if convert_single_qubit_gate_to_u:
|
|
393
|
+
gates.append(rz2u(-1*theta/2, control_qubit))
|
|
394
|
+
gates.append(h2u(target_qubit))
|
|
395
|
+
gates.append(rz2u(-1*theta/2,target_qubit))
|
|
396
|
+
else:
|
|
397
|
+
gates.append(('rz',-1*theta/2,control_qubit))
|
|
398
|
+
gates.append(('h',target_qubit))
|
|
399
|
+
gates.append(('rz',-1*theta/2,target_qubit))
|
|
400
|
+
return gates
|
|
401
|
+
|
|
402
|
+
|
|
369
403
|
def ccx_decompose(control_qubit1: int, control_qubit2: int, target_qubit: int,):
|
|
370
404
|
"""Decompose ccx gate. Reference: A biological sequence comparison algorithm using quantum computers
|
|
371
405
|
|
|
@@ -312,6 +312,18 @@ class Layout:
|
|
|
312
312
|
)
|
|
313
313
|
|
|
314
314
|
return linear1_subgraph_list_sort[:num],linear2_subgraph_list_sort[:num],cycle_subgraph_list_sort[:num],nonlinear_subgraph_list_sort[:num]
|
|
315
|
+
|
|
316
|
+
def select_qubit_from_backend(self,):
|
|
317
|
+
# 当线路中只有一个qubit时,挑选单比特门保真度最大的比特
|
|
318
|
+
|
|
319
|
+
for nodes in nx.connected_components(self.graph):
|
|
320
|
+
if len(nodes) > 1:
|
|
321
|
+
subgraph = self.graph.subgraph(nodes)
|
|
322
|
+
break
|
|
323
|
+
node_fidelity_dic = nx.get_node_attributes(subgraph,'fidelity')
|
|
324
|
+
sorted_dict = dict(sorted(node_fidelity_dic.items(), key=lambda item: item[1], reverse=True))
|
|
325
|
+
qubit = list(sorted_dict.keys())[0]
|
|
326
|
+
return qubit, sorted_dict[qubit]
|
|
315
327
|
|
|
316
328
|
def select_layout_from_backend(self,
|
|
317
329
|
key: Literal['fidelity_mean', 'fidelity_var'] = 'fidelity_var',
|
|
@@ -391,47 +403,59 @@ class Layout:
|
|
|
391
403
|
if is_connected is False:
|
|
392
404
|
raise(ValueError(f'The physical qubit layout {target_qubits} constructed from target_qubits is not connected.'))
|
|
393
405
|
coupling_map = list(subgraph.edges)
|
|
394
|
-
print(f'Physical qubits layout {target_qubits} are user-defined, with the corresponding coupling being {coupling_map}.')
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
406
|
+
print(f'Physical qubits layout {target_qubits} are user-defined, with the corresponding coupling being {coupling_map}.')
|
|
407
|
+
|
|
408
|
+
if len(subgraph.edges())>0:
|
|
409
|
+
subgraph_fidelity = np.array([data['fidelity'] for _, _, data in subgraph.edges(data=True)])
|
|
410
|
+
fidelity_mean = np.mean(subgraph_fidelity)
|
|
411
|
+
fidelity_var = np.var(subgraph_fidelity)
|
|
412
|
+
print(f'The average fidelity of the coupler(s) between the selected qubits is {fidelity_mean}, and the variance of the fidelity is {fidelity_var}.')
|
|
399
413
|
return subgraph
|
|
400
|
-
if use_chip_priority: #
|
|
414
|
+
if use_chip_priority: # 如果列表中没有满足的比特则启动筛选,如果是单比特则保留原比特,不再筛选,todos:把筛选机制转成数据库
|
|
401
415
|
priority_qubits_list = self.priority_qubits
|
|
402
416
|
for qubits in priority_qubits_list:
|
|
403
417
|
if len(qubits) == self.nqubits:
|
|
404
418
|
subgraph = self.graph.subgraph(qubits)
|
|
405
419
|
coupling_map = list(subgraph.edges)
|
|
406
420
|
print(f'Physical qubits layout {list(qubits)} are derived from the chip backend priority qubits, with the corresponding coupling being {coupling_map}.')
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
421
|
+
if len(subgraph.edges())>0:
|
|
422
|
+
subgraph_fidelity = np.array([data['fidelity'] for _, _, data in subgraph.edges(data=True)])
|
|
423
|
+
fidelity_mean = np.mean(subgraph_fidelity)
|
|
424
|
+
fidelity_var = np.var(subgraph_fidelity)
|
|
425
|
+
print(f'The average fidelity of the coupler(s) between the selected qubits is {fidelity_mean}, and the variance of the fidelity is {fidelity_var}.')
|
|
411
426
|
return subgraph
|
|
412
427
|
print(f'No priority qubits with {self.nqubits} qubits found. it will check the select_criteria for search')
|
|
413
428
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
429
|
+
if self.nqubits == 1:
|
|
430
|
+
qubit, fidelity = self.select_qubit_from_backend()
|
|
431
|
+
#The selected qubit has the highest single-qubit gate fidelity.
|
|
432
|
+
print(f'The selected physical qubit {qubit} is recommend, with single-qubit gate fidelity {fidelity}')
|
|
433
|
+
subgraph = self.graph.subgraph([qubit])
|
|
434
|
+
return subgraph
|
|
435
|
+
elif self.nqubits > 1:
|
|
436
|
+
key_first = select_criteria['key']
|
|
437
|
+
topology_first = select_criteria['topology']
|
|
438
|
+
all_keys = ['fidelity_var','fidelity_mean']
|
|
439
|
+
all_topologys = ['linear1','linear2','cycle','nonlinear']
|
|
440
|
+
all_keys.remove(key_first)
|
|
441
|
+
all_topologys.remove(topology_first)
|
|
442
|
+
sorted_keys = [key_first,] + all_keys
|
|
443
|
+
sorted_topologys = [topology_first,] + all_topologys
|
|
444
|
+
physical_qubits_layout = []
|
|
445
|
+
for key, topology in product(sorted_keys,sorted_topologys):
|
|
446
|
+
physical_qubits_layout = self.select_layout_from_backend(key=key,topology=topology)
|
|
447
|
+
if physical_qubits_layout != []:
|
|
448
|
+
break
|
|
449
|
+
if physical_qubits_layout == []:
|
|
450
|
+
raise(ValueError(f'Unable to find a suitable layout. If this message appears, please contact the developer for assistance.'))
|
|
451
|
+
physical_qubits_layout = list(physical_qubits_layout)
|
|
452
|
+
subgraph = self.graph.subgraph(physical_qubits_layout)
|
|
453
|
+
coupling_map = list(subgraph.edges)
|
|
454
|
+
print(f'Physical qubits layout {physical_qubits_layout} are selected by the Transpile algorithm using key = {key} and topology = {topology}, \nwith the corresponding coupling being {coupling_map}.')
|
|
455
|
+
subgraph_fidelity = np.array([data['fidelity'] for _, _, data in subgraph.edges(data=True)])
|
|
456
|
+
fidelity_mean = np.mean(subgraph_fidelity)
|
|
457
|
+
fidelity_var = np.var(subgraph_fidelity)
|
|
458
|
+
print(f'The average fidelity of the coupler(s) between the selected qubits is {fidelity_mean}, and the variance of the fidelity is {fidelity_var}.')
|
|
459
|
+
return subgraph
|
|
460
|
+
else:
|
|
461
|
+
raise(ValueError('Wrong qubits error!'))
|
|
@@ -316,6 +316,16 @@ def rzz_mat(theta: float) -> np.ndarray:
|
|
|
316
316
|
], dtype=complex
|
|
317
317
|
)
|
|
318
318
|
|
|
319
|
+
def cp_mat(theta: float) -> np.ndarray:
|
|
320
|
+
return np.array(
|
|
321
|
+
[
|
|
322
|
+
[1, 0, 0, 0],
|
|
323
|
+
[0, 1, 0, 0],
|
|
324
|
+
[0, 0, 1, 0],
|
|
325
|
+
[0, 0, 0, np.exp(1j*theta)]
|
|
326
|
+
], dtype=complex
|
|
327
|
+
)
|
|
328
|
+
|
|
319
329
|
gate_matrix_dict = {
|
|
320
330
|
'id':id_mat, 'x':x_mat, 'y':y_mat, 'z':z_mat, 'h':h_mat,
|
|
321
331
|
's':s_mat, 'sdg':sdg_mat, 't':t_mat, 'tdg':tdg_mat, 'sx':sx_mat, 'sxdg':sxdg_mat,
|
|
@@ -323,5 +333,6 @@ gate_matrix_dict = {
|
|
|
323
333
|
'cx':cx_mat, 'cnot':cx_mat, 'cy':cy_mat, 'cz':cz_mat,
|
|
324
334
|
'rx':rx_mat, 'ry':ry_mat, 'rz':rz_mat,
|
|
325
335
|
'p':p_mat, 'u':u_mat,'r':r_mat,
|
|
326
|
-
'rxx':rxx_mat,'ryy':ryy_mat,'rzz':rzz_mat,'
|
|
336
|
+
'rxx':rxx_mat,'ryy':ryy_mat,'rzz':rzz_mat, 'cp':cp_mat,
|
|
337
|
+
'ccz':ccz_mat,'ccx':ccx_mat,'cswap':cswap_mat,
|
|
327
338
|
}
|
|
@@ -802,7 +802,40 @@ class QuantumCircuit:
|
|
|
802
802
|
raise ValueError(f"Qubit index conflict: qubit1 and qubit2 are both {qubit1}")
|
|
803
803
|
else:
|
|
804
804
|
raise ValueError("Qubit index out of range")
|
|
805
|
-
|
|
805
|
+
|
|
806
|
+
def cp(self, theta: float, control_qubit: int, target_qubit:int) -> None:
|
|
807
|
+
r"""
|
|
808
|
+
Add a Cphase gate.
|
|
809
|
+
|
|
810
|
+
$$
|
|
811
|
+
Rzz(\theta) = I \otimes |0\rangle\lange 0| + P \otimes |1\rangle\langle 1| =
|
|
812
|
+
\begin{bmatrix}
|
|
813
|
+
1 & 0 & 0 & 0 \\
|
|
814
|
+
0 & 1 & 0 & 0 \\
|
|
815
|
+
0 & 0 & 1 & 0 \\
|
|
816
|
+
0 & 0 & 0 & e^{i\theta}
|
|
817
|
+
\end{bmatrix}.
|
|
818
|
+
$$
|
|
819
|
+
|
|
820
|
+
Args:
|
|
821
|
+
theta (float): The rotation angle of the gate.
|
|
822
|
+
control_qubit (int): The qubit to apply the gate to.
|
|
823
|
+
target_qubit (int): The qubit to apply the gate to.
|
|
824
|
+
|
|
825
|
+
Raises:
|
|
826
|
+
ValueError: If qubit out of circuit range.
|
|
827
|
+
"""
|
|
828
|
+
if max(control_qubit, target_qubit) < self.nqubits:
|
|
829
|
+
if control_qubit != target_qubit:
|
|
830
|
+
self.gates.append(('cp', theta, control_qubit, target_qubit))
|
|
831
|
+
self._add_qubits(control_qubit, target_qubit)
|
|
832
|
+
if isinstance(theta,str):
|
|
833
|
+
self.params_value[theta] = theta
|
|
834
|
+
else:
|
|
835
|
+
raise ValueError(f"Qubit index conflict: qubit1 and qubit2 are both {control_qubit}")
|
|
836
|
+
else:
|
|
837
|
+
raise ValueError("Qubit index out of range")
|
|
838
|
+
|
|
806
839
|
def shallow_apply_value(self,params_dic):
|
|
807
840
|
for k,v in self.params_value.items():
|
|
808
841
|
self.params_value[k] = k
|
|
@@ -1183,6 +1216,15 @@ class QuantumCircuit:
|
|
|
1183
1216
|
qlisp.append(('iSWAP', tuple('Q'+str(i) for i in gate_info[1:])))
|
|
1184
1217
|
elif gate in three_qubit_gates_available.keys():
|
|
1185
1218
|
qlisp.append((gate.upper(), tuple('Q'+str(i) for i in gate_info[1:])))
|
|
1219
|
+
elif gate in ['cp']:
|
|
1220
|
+
if isinstance(gate_info[1],float):
|
|
1221
|
+
qlisp.append(((gate.upper(), gate_info[1]),tuple('Q'+str(i) for i in gate_info[1:])))
|
|
1222
|
+
elif isinstance(gate_info[1],str):
|
|
1223
|
+
param = self.params_value[gate_info[1]]
|
|
1224
|
+
if isinstance(param,float):
|
|
1225
|
+
qlisp.append(((gate.upper(), param),tuple('Q'+str(i) for i in gate_info[2:])))
|
|
1226
|
+
else:
|
|
1227
|
+
raise(ValueError(f'please apply value for parameter {param}'))
|
|
1186
1228
|
elif gate in ['rx', 'ry', 'rz', 'p']:
|
|
1187
1229
|
if isinstance(gate_info[1],float):
|
|
1188
1230
|
qlisp.append(((gate.capitalize(), gate_info[1]), 'Q'+str(gate_info[2])))
|
|
@@ -1328,6 +1370,7 @@ class QuantumCircuit:
|
|
|
1328
1370
|
'rxx':qc.rxx,
|
|
1329
1371
|
'ryy':qc.ryy,
|
|
1330
1372
|
'rzz':qc.rzz,
|
|
1373
|
+
'cp':qc.cp,
|
|
1331
1374
|
}
|
|
1332
1375
|
functional_gates_in_qiskit = {
|
|
1333
1376
|
'barrier':qc.barrier,
|
|
@@ -30,10 +30,10 @@ one_qubit_gates_available = {
|
|
|
30
30
|
}
|
|
31
31
|
two_qubit_gates_available = {
|
|
32
32
|
'cx':'●X', 'cnot':'●X', 'cy':'●Y', 'cz':'●Z', 'swap':'XX', 'iswap':'✶✶',
|
|
33
|
-
}
|
|
34
|
-
three_qubit_gates_available = {'ccz':'●●●','ccx':'●●X','cswap':'●XX'}
|
|
33
|
+
}
|
|
34
|
+
three_qubit_gates_available = {'ccz':'●●●','ccx':'●●X','cswap':'●XX'}
|
|
35
35
|
one_qubit_parameter_gates_available = {'rx':'Rx', 'ry':'Ry', 'rz':'Rz', 'p':'P', 'u':'U', 'u3':'U', 'r':'R'}
|
|
36
|
-
two_qubit_parameter_gates_available = {'rxx':'Rxx', 'ryy':'Ryy', 'rzz':'Rzz',}
|
|
36
|
+
two_qubit_parameter_gates_available = {'rxx':'Rxx', 'ryy':'Ryy', 'rzz':'Rzz','cp':'●P'} # CPhase
|
|
37
37
|
functional_gates_available = {'barrier':'░', 'measure':'M', 'reset':'|0>','delay':'Delay'}
|
|
38
38
|
|
|
39
39
|
def convert_gate_info_to_dag_info(nqubits:int,qubits:list,gates:list,show_qubits:bool=True) -> tuple[list,list]:
|
|
@@ -271,6 +271,9 @@ def parse_openqasm2_to_gates(openqasm2_str) -> None:
|
|
|
271
271
|
continue
|
|
272
272
|
else:
|
|
273
273
|
raise(ValueError(f"Sorry, an unrecognized OpenQASM 2.0 syntax {gate} was detected by quarkcircuit. Please contact the developer for assistance."))
|
|
274
|
+
|
|
275
|
+
if cbit_used == []:
|
|
276
|
+
cbit_used = [i for i in range(len(set(qubit_used)))]
|
|
274
277
|
return new,set(qubit_used),set(cbit_used)
|
|
275
278
|
|
|
276
279
|
def parse_qlisp_to_gates(qlisp: list) -> tuple[list, list, list]:
|
|
@@ -338,6 +341,12 @@ def parse_qlisp_to_gates(qlisp: list) -> tuple[list, list, list]:
|
|
|
338
341
|
#elif gate[0] in ['rfUnitary']:
|
|
339
342
|
# qubit0 = int(gate_info[1].split('Q')[1])
|
|
340
343
|
# new.append(('r', gate[1], gate[2], qubit0))
|
|
344
|
+
elif gate[0] in ['CU']:
|
|
345
|
+
qubit1 = int(gate_info[1][0].split('Q')[1])
|
|
346
|
+
qubit2 = int(gate_info[1][1].split('Q')[1])
|
|
347
|
+
new.append((gate[0].lower(),gate[1],qubit1,qubit2))
|
|
348
|
+
qubit_used.append(qubit1)
|
|
349
|
+
qubit_used.append(qubit2)
|
|
341
350
|
elif gate in ['Cnot']:
|
|
342
351
|
qubit1 = int(gate_info[1][0].split('Q')[1])
|
|
343
352
|
qubit2 = int(gate_info[1][1].split('Q')[1])
|
|
@@ -483,41 +492,71 @@ def generate_gates_layerd(nqubits:int,ncbits:int,gates:list,params_value:dict) -
|
|
|
483
492
|
gates_layerd[idx+1][i] = '│'
|
|
484
493
|
break
|
|
485
494
|
elif gate in two_qubit_parameter_gates_available.keys():
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
gates_layerd[idx+1][2*pos0] = '┌' + '─'*dif0 +'0'+'─'*dif0 + '┐'
|
|
505
|
-
gates_layerd[idx+1][2*pos1] = '└' + '─'*dif0 +'1'+'─'*dif0 + '┘'
|
|
506
|
-
lines_use.append(2*pos0)
|
|
507
|
-
lines_use.append(2*pos0 + 1)
|
|
508
|
-
lines_use.append(2*pos1)
|
|
509
|
-
lines_use.append(2*pos1 + 1)
|
|
510
|
-
elif pos0 == gate_info[3]:
|
|
511
|
-
gates_layerd[idx+1][2*pos0] = '┌' + '─'*dif0 +'1'+'─'*dif0 + '┐'
|
|
512
|
-
gates_layerd[idx+1][2*pos1] = '└' + '─'*dif0 +'0'+'─'*dif0 + '┘'
|
|
495
|
+
if gate in ['cp']:
|
|
496
|
+
pos0 = min(gate_info[2],gate_info[3])
|
|
497
|
+
pos1 = max(gate_info[2],gate_info[3])
|
|
498
|
+
if isinstance(gate_info[1],float):
|
|
499
|
+
theta0_str = is_multiple_of_pi(gate_info[1])
|
|
500
|
+
elif isinstance(gate_info[1],str):
|
|
501
|
+
param = params_value[gate_info[1]]
|
|
502
|
+
if isinstance(param,float):
|
|
503
|
+
theta0_str = is_multiple_of_pi(param)
|
|
504
|
+
elif isinstance(param,str):
|
|
505
|
+
theta0_str = param
|
|
506
|
+
gate_express = two_qubit_parameter_gates_available[gate][1]+f'({theta0_str})'
|
|
507
|
+
if len(gate_express) % 2 == 0:
|
|
508
|
+
gate_express = two_qubit_parameter_gates_available[gate][1]+f'({theta0_str})─'
|
|
509
|
+
for idx in range(len(gates_layerd)-1,-1,-1):
|
|
510
|
+
if gates_layerd[idx][2*pos0:2*pos1+1] != list('─ ')*(pos1-pos0)+['─']:
|
|
511
|
+
gates_layerd[idx+1][2*gate_info[2]] = (len(gate_express)//2)*'─' + two_qubit_parameter_gates_available[gate][0] + (len(gate_express)//2)*'─'
|
|
512
|
+
gates_layerd[idx+1][2*gate_info[3]] = gate_express
|
|
513
513
|
lines_use.append(2*pos0)
|
|
514
|
-
lines_use.append(2*pos0
|
|
514
|
+
lines_use.append(2*pos0+1)
|
|
515
515
|
lines_use.append(2*pos1)
|
|
516
|
-
lines_use.append(2*pos1
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
516
|
+
lines_use.append(2*pos1+1)
|
|
517
|
+
for i in range(2*pos0+1,2*pos1):
|
|
518
|
+
if i % 2 == 0:
|
|
519
|
+
gates_layerd[idx+1][i] = (len(gate_express)//2)*'─' + '│' + (len(gate_express)//2)*'─'
|
|
520
|
+
else:
|
|
521
|
+
gates_layerd[idx+1][i] = (len(gate_express)//2)*' ' + '│' + (len(gate_express)//2)*' '
|
|
522
|
+
|
|
523
|
+
break
|
|
524
|
+
|
|
525
|
+
else:
|
|
526
|
+
pos0 = min(gate_info[2],gate_info[3])
|
|
527
|
+
pos1 = max(gate_info[2],gate_info[3])
|
|
528
|
+
if isinstance(gate_info[1],float):
|
|
529
|
+
theta0_str = is_multiple_of_pi(gate_info[1])
|
|
530
|
+
elif isinstance(gate_info[1],str):
|
|
531
|
+
param = params_value[gate_info[1]]
|
|
532
|
+
if isinstance(param,float):
|
|
533
|
+
theta0_str = is_multiple_of_pi(param)
|
|
534
|
+
elif isinstance(param,str):
|
|
535
|
+
theta0_str = param
|
|
536
|
+
gate_express = two_qubit_parameter_gates_available[gate]+f'({theta0_str})'
|
|
537
|
+
if len(gate_express)%2 == 0:
|
|
538
|
+
gate_express += ' '
|
|
539
|
+
for idx in range(len(gates_layerd)-1,-1,-1):
|
|
540
|
+
if gates_layerd[idx][2*pos0:2*pos1+1] != list('─ ')*(pos1-pos0)+['─']:
|
|
541
|
+
dif0 = (len(gate_express) - 1)//2
|
|
542
|
+
if pos0 == gate_info[2]:
|
|
543
|
+
gates_layerd[idx+1][2*pos0] = '┌' + '─'*dif0 +'0'+'─'*dif0 + '┐'
|
|
544
|
+
gates_layerd[idx+1][2*pos1] = '└' + '─'*dif0 +'1'+'─'*dif0 + '┘'
|
|
545
|
+
lines_use.append(2*pos0)
|
|
546
|
+
lines_use.append(2*pos0 + 1)
|
|
547
|
+
lines_use.append(2*pos1)
|
|
548
|
+
lines_use.append(2*pos1 + 1)
|
|
549
|
+
elif pos0 == gate_info[3]:
|
|
550
|
+
gates_layerd[idx+1][2*pos0] = '┌' + '─'*dif0 +'1'+'─'*dif0 + '┐'
|
|
551
|
+
gates_layerd[idx+1][2*pos1] = '└' + '─'*dif0 +'0'+'─'*dif0 + '┘'
|
|
552
|
+
lines_use.append(2*pos0)
|
|
553
|
+
lines_use.append(2*pos0 + 1)
|
|
554
|
+
lines_use.append(2*pos1)
|
|
555
|
+
lines_use.append(2*pos1 + 1)
|
|
556
|
+
for i in range(2*pos0+1,2*pos1):
|
|
557
|
+
gates_layerd[idx+1][i] = '│' + ' '*len(gate_express) + '│'
|
|
558
|
+
gates_layerd[idx+1][2*pos0 + (pos1-pos0)] = '│' + gate_express + '│'
|
|
559
|
+
break
|
|
521
560
|
elif gate in one_qubit_parameter_gates_available.keys():
|
|
522
561
|
if gate == 'u':
|
|
523
562
|
if isinstance(gate_info[1],float):
|
|
@@ -96,7 +96,7 @@ def call_quark_transpiler(qc:QuantumCircuit|list|str,chip_name:str,compile:bool,
|
|
|
96
96
|
quarkQC_compiled = SabreRouting(subgraph,initial_mapping='trivial',do_random_choice=False,iterations=5).run(quarkQC)
|
|
97
97
|
else:
|
|
98
98
|
raise(ValueError('More optimize_level is not support now!'))
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
quarkQC_half_compiled = copy.deepcopy(quarkQC_compiled)
|
|
101
101
|
quarkQC_half_compiled = TranslateToBasisGates(convert_single_qubit_gate_to_u=False,two_qubit_gate_basis='cx').run(quarkQC_half_compiled)
|
|
102
102
|
quarkQC_half_compiled = GateCompressor().run(quarkQC_half_compiled)
|
|
@@ -144,7 +144,7 @@ def call_quark_transpiler(qc:QuantumCircuit|list|str,chip_name:str,compile:bool,
|
|
|
144
144
|
|
|
145
145
|
# check CZ
|
|
146
146
|
ncz = quarkQC_compiled.ncz
|
|
147
|
-
if ncz >
|
|
147
|
+
if ncz > 200:
|
|
148
148
|
raise(ValueError(f'The number of two-qubit gates in the circuit is {ncz} exceeds 100.'))
|
|
149
149
|
|
|
150
150
|
if return_qlisp:
|
|
@@ -34,6 +34,7 @@ from .decompose import (cx_decompose,
|
|
|
34
34
|
rxx_decompose,
|
|
35
35
|
ryy_decompose,
|
|
36
36
|
rzz_decompose,
|
|
37
|
+
cp_decompose,
|
|
37
38
|
u3_decompose,
|
|
38
39
|
)
|
|
39
40
|
from .basepasses import TranspilerPass
|
|
@@ -114,6 +115,8 @@ class TranslateToBasisGates(TranspilerPass):
|
|
|
114
115
|
new += ryy_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
115
116
|
elif gate == 'rzz':
|
|
116
117
|
new += rzz_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u,self.two_qubit_gate_basis)
|
|
118
|
+
elif gate == 'cp':
|
|
119
|
+
new += cp_decompose(*gate_info[1:],self.convert_single_qubit_gate_to_u)
|
|
117
120
|
elif gate in functional_gates_available.keys():
|
|
118
121
|
new.append(gate_info)
|
|
119
122
|
else:
|
|
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
|