diff --git a/tensorcircuit/__init__.py b/tensorcircuit/__init__.py index 8092ec39..57646d0f 100644 --- a/tensorcircuit/__init__.py +++ b/tensorcircuit/__init__.py @@ -26,7 +26,8 @@ from . import basecircuit from . import waveforms from .gates import Gate -from .circuit import Circuit, expectation, Param +from .circuit import Circuit, expectation +from .pulse import Param from .mpscircuit import MPSCircuit from .densitymatrix import DMCircuit as DMCircuit_reference from .densitymatrix import DMCircuit2 diff --git a/tensorcircuit/circuit.py b/tensorcircuit/circuit.py index f90dc404..a389f7eb 100644 --- a/tensorcircuit/circuit.py +++ b/tensorcircuit/circuit.py @@ -17,6 +17,7 @@ from .quantum import QuOperator, identity from .simplify import _full_light_cone_cancel from .basecircuit import BaseCircuit +from .pulse import DefcalBuilder, Param, Frame Gate = gates.Gate Tensor = Any @@ -137,21 +138,22 @@ def add_calibration( }) - def to_tqasm(self, pragma: str) -> str: + def to_tqasm(self, pragma: Optional[str]= None) -> str: qasm_lines = [] - if pragma: - qasm_lines.append(pragma) qasm_lines.append("TQASM 0.2;") + if pragma: + qasm_lines.append(pragma) + qasm_lines.append(f"QREG q[{self._nqubits}];") for cal in getattr(self, "calibrations", []): pname = ", ".join(cal["parameters"]) - qasm_lines.append(f"\ndefcal {cal['name']} {pname} {{") + qasm_lines.append(f"defcal {cal['name']} {pname} {{") for inst in cal["instructions"]: if inst["type"] == "frame": - qasm_lines.append(f" frame {inst['frame']} = newframe({inst['qubit']});") + qasm_lines.append(f" frame {inst['frame'].name} = newframe({inst['qubit']});") elif inst["type"] == "play": args_str = ", ".join(str(x) for x in inst["args"]) wf_type = inst["waveform_type"] @@ -171,7 +173,7 @@ def to_tqasm(self, pragma: str) -> str: for i, gate in enumerate(self._qir): for cal in cals_by_pos.get(i, []): # print(cal) - pname = ", ".join(cal.get("parameters", [])) + pname = ", ".join(f"q[{x}]" for x in cal.get("parameters", [])) qasm_lines.append(f"{cal['name']} {pname};") # print(gate) @@ -189,7 +191,7 @@ def to_tqasm(self, pragma: str) -> str: # 收尾:把 pos == len(self._qir) 的校准放在最后 for cal in cals_by_pos.get(len(self._qir), []): # print(cal) - pname = ", ".join(cal.get("parameters", [])) + pname = ", ".join(f"q[{x}]" for x in cal.get("parameters", [])) qasm_lines.append(f"{cal['name']} {pname};") return ("\n".join(qasm_lines)) @@ -1083,51 +1085,3 @@ def expectation( else: den = 1.0 return num / den - -class Param: - def __init__(self, name: str): - self.name = name - -class Frame: - def __init__(self, name: str): - self.name = name - -class DefcalBuilder: - def __init__(self, circuit, name: str, parameters: List["Param"]): - self.circuit = circuit - self.name = name - self.parameters = parameters - self.instructions = [] - - def new_frame(self, frame_name: str, param: "Param"): - frame = Frame(frame_name) - self.instructions.append({ - "type": "frame", - "frame": frame, - "qubit": param.name, - }) - return frame - - def play(self, frame: Frame, waveform: Any, start_time: int = None): - if not hasattr(waveform, "__dataclass_fields__"): - raise TypeError("Unsupported waveform type") - - waveform_type = waveform.qasm_name() - args = waveform.to_args() - if start_time is not None: - args = [start_time] + args - - self.instructions.append({ - "type": "play", - "frame": frame.name, - "waveform_type": waveform_type, - "args": args, - }) - return self - - def build(self): - self.circuit.def_calibration( - name=self.name, - parameters=[p.name for p in self.parameters], - instructions=self.instructions, - ) diff --git a/tensorcircuit/cloud/__init__.py b/tensorcircuit/cloud/__init__.py index 56d5a724..eb14f9d6 100644 --- a/tensorcircuit/cloud/__init__.py +++ b/tensorcircuit/cloud/__init__.py @@ -3,3 +3,4 @@ from . import wrapper from .wrapper import batch_expectation_ps from .apis import submit_task +from .tencent import Topology diff --git a/tensorcircuit/cloud/tencent.py b/tensorcircuit/cloud/tencent.py index e2428b3e..c89514d0 100644 --- a/tensorcircuit/cloud/tencent.py +++ b/tensorcircuit/cloud/tencent.py @@ -76,7 +76,7 @@ def update_pairs(user_addr1: int, user_addr2: int, add_remove: bool = True): update_pairs(user_addr2, user_addr1, add_remove) return - def pragmam(self) -> str: + def pragma(self) -> str: lines = [] if self._used_chip_qubits == [] or self._used_user_qubits == []: return None @@ -89,7 +89,7 @@ def pragmam(self) -> str: pragma = pragma[:-2] + "]" lines.append(pragma) - pragma = "#pragma qubits.coupling []" + pragma = "#pragma qubits.coupling [" for u1, u2 in getattr(self, "_used_user_pairs", []): pragma += f"[{u1}, {u2}], " pragma = pragma[:-2] + "]" @@ -295,7 +295,7 @@ def c2qasm(c: Any, compiling: bool) -> str: else: prag = None if topology is not None: - prag = topology.praggam() + prag = topology.pragma() s = c.to_tqasm(prag) lang = "TQASM" #s = c.to_openqasm() diff --git a/tensorcircuit/pulse.py b/tensorcircuit/pulse.py new file mode 100644 index 00000000..a09ddac6 --- /dev/null +++ b/tensorcircuit/pulse.py @@ -0,0 +1,50 @@ +from typing import List, Dict, Any + + +class Param: + def __init__(self, name: str): + self.name = name + +class Frame: + def __init__(self, name: str): + self.name = name + +class DefcalBuilder: + def __init__(self, circuit, name: str, parameters: List["Param"]): + self.circuit = circuit + self.name = name + self.parameters = parameters + self.instructions = [] + + def new_frame(self, frame_name: str, param: "Param"): + frame = Frame(frame_name) + self.instructions.append({ + "type": "frame", + "frame": frame, + "qubit": param.name, + }) + return frame + + def play(self, frame: Frame, waveform: Any, start_time: int = None): + if not hasattr(waveform, "__dataclass_fields__"): + raise TypeError("Unsupported waveform type") + + waveform_type = waveform.qasm_name() + args = waveform.to_args() + if start_time is not None: + args = [start_time] + args + + self.instructions.append({ + "type": "play", + "frame": frame.name, + "waveform_type": waveform_type, + "args": args, + }) + return self + + def build(self): + self.circuit.def_calibration( + name=self.name, + parameters=[p.name for p in self.parameters], + instructions=self.instructions, + ) diff --git a/tests/01_test_gate.py b/tests/01_test_gate.py index c196d07b..76566aff 100644 --- a/tests/01_test_gate.py +++ b/tests/01_test_gate.py @@ -27,6 +27,8 @@ def gen_gate_circuit(t): qc.h(0) qc.cnot(0, 1) + print(qc.to_tqasm()) + return qc @@ -43,7 +45,8 @@ def run_circuit(qc): # print(qc.to_tqasm()) # n = qc._nqubits rf = t.results() - print(rf) + # print(rf) + return rf qc = gen_gate_circuit(1.0) result = run_circuit(qc) diff --git a/tests/02_test_param_pulse.py b/tests/02_test_param_pulse.py index 15441fde..5eabe93a 100644 --- a/tests/02_test_param_pulse.py +++ b/tests/02_test_param_pulse.py @@ -27,6 +27,13 @@ def gen_parametric_waveform_circuit(t): param0 = Param("a") + # builder = qc.calibrate("basic_pulse", [param0]) + # builder.new_frame("drive_frame", param0) + # builder.play("drive_frame", waveforms.CosineDrag(t, 0.2, 0.0, 0.0)) + + # builder.build() + # qc.add_calibration('basic_pulse', ['q[0]']) + # 需根据以下定义的方式,修改代码 builder = qc.calibrate("basic_pulse", [param0]) frame = builder.new_frame("drive_frame", param0) @@ -36,7 +43,7 @@ def gen_parametric_waveform_circuit(t): qc.add_calibration(builder, [0]) - # print(qc.to_tqasm()) + print(qc.to_tqasm()) return qc @@ -53,7 +60,8 @@ def run_circuit(qc): # print(qc.to_tqasm()) # n = qc._nqubits rf = t.results() - print(rf) + # print(rf) + return rf qc = gen_parametric_waveform_circuit(1.0) result = run_circuit(qc) diff --git a/tests/03_test_gate_pulse_mix.py b/tests/03_test_gate_pulse_mix.py index a3887598..00ce1f94 100644 --- a/tests/03_test_gate_pulse_mix.py +++ b/tests/03_test_gate_pulse_mix.py @@ -54,7 +54,7 @@ def run_circuit(qc): # print(qc.to_tqasm()) # n = qc._nqubits rf = t.results() - print(rf) + return rf qc = gen_gate_pulse_mix_circuit(1.0) result = run_circuit(qc) diff --git a/tests/04_test_custom_chip.py b/tests/04_test_custom_chip.py index c25584ba..be431e2b 100644 --- a/tests/04_test_custom_chip.py +++ b/tests/04_test_custom_chip.py @@ -7,7 +7,8 @@ sys.path.insert(0, module_path) from tensorcircuit import Circuit, Param, gates, waveforms -from tensorcircuit.cloud.apis import submit_task, get_device, set_provider, set_token, list_devices, list_properties, Topology +from tensorcircuit.cloud.apis import submit_task, get_device, set_provider, set_token, list_devices, list_properties +from tensorcircuit.cloud.tencent import Topology import re # from dotenv import load_dotenv @@ -22,13 +23,15 @@ print(ds) def gen_custom_chip_circuit(t): - qc = Circuit(2) + qc = Circuit(3) - qc.i(0) - qc.cnot(0) + # qc.h(0) + qc.cnot(0, 2) + # qc.cnot(1, 3) + # qc.cnot(0, 3) # print(qc.to_tqasm()) - return qc, tp + return qc def run_circuit(qc): @@ -36,17 +39,17 @@ def run_circuit(qc): d = get_device(device_name) # 以下是两种映射方式 tp = Topology(d) - tp.map_qubits([4,9,8,14]) - tp.map_qubits([4,9,8,14], [3,2,1,0]) + # tp.map_qubits([6,3,4,1]) + # tp.map_qubits([6,3,4,1], [3,2,1,0]) - tp.map_qubit(0, 4) - tp.map_qubit(1, 9) - tp.map_qubit(2, 8) - tp.map_qubit(3, 14) + tp.map_qubit(0, 6) + tp.map_qubit(1, 3) + tp.map_qubit(2, 4) + tp.map_qubit(3, 1) tp.pair_qubit(0, 1) tp.pair_qubit(0, 2) - tp.pair_qubit(1, 3, False) + tp.pair_qubit(1, 3) t = submit_task( circuit=qc, shots=shots_const,