def test_def_permutation_gate(): perm_gate = DefPermutationGate("CCNOT", [0, 1, 2, 3, 4, 5, 7, 6]) perm_gate_str = 'DEFGATE CCNOT AS PERMUTATION:\n 0, 1, 2, 3, 4, 5, 7, 6'.strip( ) parse_equals(perm_gate_str, perm_gate)
def test_def_circuit(): defcircuit = """ DEFCIRCUIT bell a b: H a CNOT a b """.strip() parse_equals(defcircuit, RawInstr(defcircuit))
def test_parsing_swap_phase(): parse_equals('SWAP-PHASE 0 "rf" 1 "rf"', SwapPhase(Frame([Qubit(0)], "rf"), Frame([Qubit(1)], "rf"))) parse_equals( 'SWAP-PHASE 0 1 "ff" 1 0 "ff"', SwapPhase(Frame([Qubit(0), Qubit(1)], "ff"), Frame([Qubit(1), Qubit(0)], "ff")), )
def test_messy_modifiers(): s = "FORKED DAGGER CONTROLLED FORKED RX(0.1,0.2,0.3,0.4) 0 1 2 3" parse_equals(s, RX(0.1, 3) .forked(2, [0.2]) .controlled(1) .dagger() .forked(0, [0.3, 0.4]))
def test_parse_reset_qubit(): reset = """ RESET """.strip() parse_equals(reset, Reset()) reset_qubit = """ RESET 5 """.strip() parse_equals(reset_qubit, ResetQubit(Qubit(5)))
def test_parsing_delay(): parse_equals("DELAY 0 1.0", DelayQubits([Qubit(0)], 1.0)) parse_equals("DELAY 0 1", DelayQubits([Qubit(0)], 1)) parse_equals("DELAY 0 1 1e-6", DelayQubits([Qubit(0), Qubit(1)], 1e-6)) parse_equals('DELAY 0 "rf" 1.0', DelayFrames([Frame([Qubit(0)], "rf")], 1.0)) parse_equals( 'DELAY 0 "ro_tx" "ro_rx" 1.0', DelayFrames([Frame([Qubit(0)], "ro_tx"), Frame([Qubit(0)], "ro_rx")], 1.0), )
def test_defcircuit_reset_named_qubit(): defcircuit_reset_named_qubit = """ DEFCIRCUIT test_defcirc_reset_named_qubit a: RESET a """.strip() defcircuit_reset_qubit = """ DEFCIRCUIT test_defcirc_reset_qubit: RESET 1 """.strip() parse_equals(defcircuit_reset_named_qubit, RawInstr(defcircuit_reset_named_qubit)) parse_equals(defcircuit_reset_qubit, RawInstr(defcircuit_reset_qubit))
def test_def_gate_with_variables(): # Note that technically the RX gate includes -i instead of just i but this messes a bit with the test since # it's not smart enough to figure out that -1*i == -i theta = Parameter('theta') rx = np.array([[quil_cos(theta / 2), 1j * quil_sin(theta / 2)], [1j * quil_sin(theta / 2), quil_cos(theta / 2)]]) defgate = 'DEFGATE RX(%theta):\n' \ ' cos(%theta/2), i*sin(%theta/2)\n' \ ' i*sin(%theta/2), cos(%theta/2)\n\n' parse_equals(defgate, DefGate('RX', rx, [theta]))
def test_def_circuit(): defcircuit = """ DEFCIRCUIT bell a b: H a CNOT a b """.strip() defcircuit_no_qubits = """ DEFCIRCUIT bell: H 0 CNOT 0 1 """.strip() parse_equals(defcircuit, RawInstr(defcircuit)) parse_equals(defcircuit_no_qubits, RawInstr(defcircuit_no_qubits))
def test_jumps(): parse_equals("LABEL @test_1", JumpTarget(Label("test_1"))) parse_equals("JUMP @test_1", Jump(Label("test_1"))) parse_equals("JUMP-WHEN @test_1 ro[0]", JumpWhen(Label("test_1"), MemoryReference("ro", 0))) parse_equals("JUMP-UNLESS @test_1 ro[1]", JumpUnless(Label("test_1"), MemoryReference("ro", 1)))
def test_def_gate_with_variables(): # Note that technically the RX gate includes -i instead of just i but this messes a bit with # the test since it's not smart enough to figure out that -1*i == -i theta = Parameter("theta") rx = np.array([ [quil_cos(theta / 2), 1j * quil_sin(theta / 2)], [1j * quil_sin(theta / 2), quil_cos(theta / 2)], ]) defgate = ("DEFGATE RX(%theta):\n" " COS(%theta/2), i*SIN(%theta/2)\n" " i*SIN(%theta/2), COS(%theta/2)\n\n") parse_equals(defgate, DefGate("RX", rx, [theta]))
def test_def_gate(): sqrt_x = DefGate("SQRT-X", np.array([[0.5 + 0.5j, 0.5 - 0.5j], [0.5 - 0.5j, 0.5 + 0.5j]])) hadamard = DefGate("HADAMARD", np.array([[1 / np.sqrt(2), 1 / np.sqrt(2)], [1 / np.sqrt(2), -1 / np.sqrt(2)]])) defgates = """ DEFGATE SQRT-X: 0.5+0.5i, 0.5-0.5i 0.5-0.5i, 0.5+0.5i DEFGATE HADAMARD: 1/sqrt(2), 1/sqrt(2) 1/sqrt(2), -1/sqrt(2) """.strip() parse_equals(defgates, sqrt_x, hadamard)
def test_parsing_raw_capture(): parse_equals( "DECLARE iqs REAL[200000]\n" 'RAW-CAPTURE 0 "ro_rx" 0.001 iqs', Declare("iqs", "REAL", 200000), RawCapture(Frame([Qubit(0)], "ro_rx"), 0.001, MemoryReference("iqs")), ) parse_equals( "DECLARE iqs REAL[200000]\n" 'NONBLOCKING RAW-CAPTURE 0 "ro_rx" 0.001 iqs', Declare("iqs", "REAL", 200000), RawCapture(Frame([Qubit(0)], "ro_rx"), 0.001, MemoryReference("iqs"), nonblocking=True), )
def test_parsing_capture(): wf = FlatWaveform(duration=1.0, iq=1.0) parse_equals( "DECLARE iq REAL[2]\n" 'CAPTURE 0 "ro_rx" flat(duration: 1.0, iq: 1.0) iq', Declare("iq", "REAL", 2), Capture(Frame([Qubit(0)], "ro_rx"), wf, MemoryReference("iq")), ) parse_equals( "DECLARE iq REAL[2]\n" 'NONBLOCKING CAPTURE 0 "ro_rx" flat(duration: 1.0, iq: 1.0) iq', Declare("iq", "REAL", 2), Capture(Frame([Qubit(0)], "ro_rx"), wf, MemoryReference("iq"), nonblocking=True), )
def test_pragma_with_placeholders(): q = QubitPlaceholder() q2 = QubitPlaceholder() p = Program() p.inst(Pragma('FENCE', [q, q2])) address_map = {q: 0, q2: 1} addressed_pragma = address_qubits(p, address_map)[0] parse_equals('PRAGMA FENCE 0 1\n', addressed_pragma) pq = Program(X(q)) pq.define_noisy_readout(q, .8, .9) pq.inst(X(q2)) pq.define_noisy_readout(q2, .9, .8) ret = address_qubits(pq, address_map).out() assert ret == """X 0
def test_parsing_frame_mutations(): ops = [ ("SET-PHASE", SetPhase), ("SHIFT-PHASE", ShiftPhase), ("SET-SCALE", SetScale), ("SET-FREQUENCY", SetFrequency), ("SHIFT-FREQUENCY", ShiftFrequency), ] frames = [ ('0 "rf"', Frame([Qubit(0)], "rf")), ('0 1 "ff"', Frame([Qubit(0), Qubit(1)], "ff")), ('1 0 "ff"', Frame([Qubit(1), Qubit(0)], "ff")), ] values = [("1", 1), ("1.0", 1.0), ("pi/2", np.pi / 2)] # TODO: should we require a float here? for op_str, op in ops: for frame_str, frame in frames: for val_str, val in values: parse_equals(f"{op_str} {frame_str} {val_str}", op(frame, val))
def test_parsing_defcal_measure(): parse_equals("DEFCAL MEASURE 0:\n" " NOP\n", DefMeasureCalibration(Qubit(0), None, [NOP])) wf = FlatWaveform(duration=1.0, iq=1.0) # TODO: note that in a calibration body, reference to the formal argument addr parses # as a memoryreference. parse_equals( "DEFCAL MEASURE q addr:\n" ' PULSE q "ro_tx" flat(duration: 1.0, iq: 1.0+0.0*i)\n' ' CAPTURE q "ro_rx" flat(duration: 1.0, iq: 1.0+0*i) addr[0]\n', DefMeasureCalibration( FormalArgument("q"), FormalArgument("addr"), [ Pulse(Frame([FormalArgument("q")], "ro_tx"), wf), Capture(Frame([FormalArgument("q")], "ro_rx"), wf, MemoryReference("addr")), ], ), )
def test_pragma_with_placeholders(): q = QubitPlaceholder() q2 = QubitPlaceholder() p = Program() p.inst(Pragma("FENCE", [q, q2])) address_map = {q: 0, q2: 1} addressed_pragma = address_qubits(p, address_map)[0] parse_equals("PRAGMA FENCE 0 1\n", addressed_pragma) pq = Program(X(q)) pq.define_noisy_readout(q, 0.8, 0.9) pq.inst(X(q2)) pq.define_noisy_readout(q2, 0.9, 0.8) ret = address_qubits(pq, address_map).out() assert (ret == """X 0 PRAGMA READOUT-POVM 0 "(0.8 0.09999999999999998 0.19999999999999996 0.9)" X 1 PRAGMA READOUT-POVM 1 "(0.9 0.19999999999999996 0.09999999999999998 0.8)" """)
def test_parse_pulse(): wf = FlatWaveform(duration=1.0, iq=1.0) parse_equals('PULSE 0 "rf" flat(duration: 1.0, iq: 1.0)', Pulse(Frame([Qubit(0)], "rf"), wf)) parse_equals('PULSE 0 1 "ff" flat(duration: 1.0, iq: 1.0)', Pulse(Frame([Qubit(0), Qubit(1)], "ff"), wf)) parse_equals( 'NONBLOCKING PULSE 0 "rf" flat(duration: 1.0, iq: 1.0)', Pulse(Frame([Qubit(0)], "rf"), wf, nonblocking=True), )
def test_parsing_defwaveform(): parse_equals("DEFWAVEFORM foo:\n" " 1.0, 1.0, 1.0\n", DefWaveform("foo", [], [1.0, 1.0, 1.0])) parse_equals( "DEFWAVEFORM foo:\n" " 1.0+2.0*i, 1.0-2.0*i, 3.0\n", DefWaveform("foo", [], [1 + 2j, 1 - 2j, 3 + 0j]), ) parse_equals( "DEFWAVEFORM foo(%theta):\n" " 1.0+2.0*i, 1.0-2.0*i, 3.0*%theta\n", DefWaveform( "foo", [Parameter("theta")], [1 + 2j, 1 - 2j, Mul(3.0, Parameter("theta"))]), ) parse_equals( "DEFWAVEFORM q0_ro_rx/filter:\n 1.0, 1.0, 1.0", DefWaveform("q0_ro_rx/filter", [], [1.0, 1.0, 1.0]), )
def test_parsing_defframe(): parse_equals('DEFFRAME 0 "rf"', DefFrame(Frame([Qubit(0)], "rf"))) parse_equals('DEFFRAME 1 0 "ff"', DefFrame(Frame([Qubit(1), Qubit(0)], "ff"))) parse_equals( 'DEFFRAME 0 "rf":\n' " SAMPLE-RATE: 2.0\n", DefFrame(Frame([Qubit(0)], "rf"), sample_rate=2.0), ) parse_equals( 'DEFFRAME 0 "rf":\n' " SAMPLE-RATE: 2.0\n" " INITIAL-FREQUENCY: 10\n", # TODO: should this parse as a float? DefFrame(Frame([Qubit(0)], "rf"), sample_rate=2.0, initial_frequency=10), ) with pytest.raises(UnexpectedToken) as excp: parse('DEFFRAME 0 "rf":\n' " UNSUPPORTED: 2.0\n") assert excp.value.token == Token("IDENTIFIER", "UNSUPPORTED")
def test_defcircuit_measure_qubit(): defcircuit_measure_named_qubits = """ DEFCIRCUIT test_defcirc_measure_named a b: MEASURE a b """.strip() defcircuit_measure_qubits = """ DEFCIRCUIT test_defcirc_measure_qubits: MEASURE 0 ro """.strip() defcircuit_measure_qubits_mixed = """ DEFCIRCUIT test_defcirc_measure_mixed q: MEASURE q ro """.strip() parse_equals(defcircuit_measure_named_qubits, RawInstr(defcircuit_measure_named_qubits)) parse_equals(defcircuit_measure_qubits, RawInstr(defcircuit_measure_qubits)) parse_equals(defcircuit_measure_qubits_mixed, RawInstr(defcircuit_measure_qubits_mixed))
def test_parsing_defcal(): parse_equals("DEFCAL X 0:\n" " NOP\n", DefCalibration("X", [], [Qubit(0)], [NOP])) parse_equals( "DEFCAL X q:\n" " NOP\n" " NOP\n", DefCalibration("X", [], [FormalArgument("q")], [NOP, NOP]), ) parse_equals( "DEFCAL RZ(%theta) 0:\n" ' SHIFT-PHASE 0 "rf" %theta/(-2*pi)\n', DefCalibration( "RZ", [Parameter("theta")], [Qubit(0)], [ ShiftPhase(Frame([Qubit(0)], "rf"), Div(Parameter("theta"), -2 * np.pi)) ], ), )
def test_def_circuit(): defcircuit = """ DEFCIRCUIT bell a b: H a CNOT a b """.strip() defcircuit_no_qubits = """ DEFCIRCUIT bell: H 0 CNOT 0 1 """.strip() defcircuit_param = """ DEFCIRCUIT parameterized(%theta, %phi) a: RX(%theta) a RZ(%phi) a """.strip() parse_equals(defcircuit, RawInstr(defcircuit)) parse_equals(defcircuit_no_qubits, RawInstr(defcircuit_no_qubits)) parse_equals(defcircuit_param, RawInstr(defcircuit_param))
def _expr(expression, expected): parse_equals("RX(" + expression + ") 0", RX(expected, 0))
def test_parameters(): parse_equals("RX(123) 0", RX(123, 0)) parse_equals("CPHASE00(0) 0 1", CPHASE00(0, 0, 1)) parse_equals("A(8,9) 0", Gate("A", [8, 9], [Qubit(0)])) parse_equals("A(8, 9) 0", Gate("A", [8, 9], [Qubit(0)]))
def test_standard_gates(): parse_equals("H 0", H(0)) parse_equals("CNOT 0 1", CNOT(0, 1)) parse_equals("SWAP 0 1", SWAP(0, 1))
def test_simple_gate(): parse_equals("A 0", Gate("A", [], [Qubit(0)])) parse_equals("A 1 10 100", Gate("A", [], [Qubit(1), Qubit(10), Qubit(100)]))
def test_empty_program(): parse_equals("")
def test_pragma(): parse_equals('PRAGMA gate_time H "10 ns"', Pragma('gate_time', ['H'], '10 ns')) parse_equals('PRAGMA qubit 0', Pragma('qubit', [0])) parse_equals('PRAGMA NO-NOISE', Pragma('NO-NOISE'))