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_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_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_apply_match_shift_phase(): settings = {FormalArgument("q"): Qubit(0), Parameter("theta"): np.pi} instr = ShiftPhase(Frame([FormalArgument("q")], "ff"), Parameter("theta") / (2.0 * np.pi)) actual = fill_placeholders(instr, settings) expected = ShiftPhase(Frame([Qubit(0)], "ff"), 0.5) assert actual == expected
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_rewrite_arithmetic_mixed_mutations(): fdefn = DefFrame( frame=Frame([Qubit(0)], "rf"), center_frequency=10.0, sample_rate=20.0, ) prog = Program( fdefn, "DECLARE theta REAL", 'SET-FREQUENCY 0 "rf" theta', 'SET-PHASE 0 "rf" theta', 'SET-SCALE 0 "rf" theta', ) response = rewrite_arithmetic(prog) assert response == RewriteArithmeticResponse( original_memory_descriptors={ "theta": ParameterSpec(length=1, type="REAL") }, recalculation_table={ ParameterAref(index=0, name="__P1"): "(theta[0] - 10.0)/20.0", ParameterAref(index=1, name="__P1"): "theta[0]/(2*pi)", ParameterAref(index=2, name="__P1"): "theta[0]/8", }, quil=Program( fdefn, "DECLARE __P1 REAL[3]", "DECLARE theta REAL[1]", 'SET-FREQUENCY 0 "rf" __P1[0]', 'SET-PHASE 0 "rf" __P1[1]', 'SET-SCALE 0 "rf" __P1[2]', ).out(), )
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_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_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(): 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_parsing_defframe_round_trip_with_json(): fdef = DefFrame( frame=Frame(qubits=[FormalArgument("My-Cool-Qubit")], name="bananas"), direction="go west", initial_frequency=123.4, center_frequency=124.5, hardware_object='{"key1": 3.1, "key2": "value2"}', sample_rate=5, ) fdef_out = fdef.out() assert (fdef.out() == r"""DEFFRAME My-Cool-Qubit "bananas": DIRECTION: "go west" INITIAL-FREQUENCY: 123.4 CENTER-FREQUENCY: 124.5 HARDWARE-OBJECT: "{\"key1\": 3.1, \"key2\": \"value2\"}" SAMPLE-RATE: 5 """) parse_equals(fdef_out, fdef)
def wf_agrees(wf_str: str, wf: TemplateWaveform): frame = Frame([Qubit(0)], "rf") pulse_str = 'PULSE 0 "rf" ' + wf_str parse_equals(pulse_str, Pulse(frame, wf))
def fill_placeholders(obj, placeholder_values: Dict[Union[FormalArgument, Parameter], Any]): """Update Parameter and FormalArgument references in objects with their corresponding definitions. It is an error if the object has a Parameter or FormalArgument reference without a corresponding definition in placeholder_values. :param obj: A Quil AST object. :param placeholder_values: A dictionary mapping placeholders to their values. :returns: The updated AST object. """ try: if obj is None or isinstance( obj, (int, float, complex, Qubit, MemoryReference)): return obj elif isinstance(obj, Expression): # defer to the usual PyQuil substitution return substitute( obj, { k: v for k, v in placeholder_values.items() if isinstance(k, Parameter) }) elif isinstance(obj, FormalArgument): return placeholder_values[obj] elif isinstance(obj, Frame): return Frame(fill_placeholders(obj.qubits, placeholder_values), obj.name) elif isinstance(obj, WaveformReference): return obj elif isinstance(obj, TemplateWaveform): return obj.__class__( **fill_placeholders(obj.__dict__, placeholder_values)) elif isinstance(obj, list): return [fill_placeholders(elt, placeholder_values) for elt in obj] elif isinstance(obj, dict): return { k: fill_placeholders(v, placeholder_values) for (k, v) in obj.items() } elif isinstance(obj, tuple): return tuple( [fill_placeholders(item, placeholder_values) for item in obj]) elif isinstance(obj, Pragma) and obj.command == "LOAD-MEMORY": (source, ) = obj.args arg = FormalArgument(obj.freeform_string) if arg in placeholder_values: return Pragma("LOAD-MEMORY", [source], str(placeholder_values[arg])) else: return obj else: specs = { Gate: ["params", "qubits"], Measurement: ["qubit", "classical_reg"], ResetQubit: ["qubit"], Pulse: ["frame", "waveform"], SetFrequency: ["frame", "freq"], ShiftFrequency: ["frame", "freq"], SetPhase: ["frame", "phase"], ShiftPhase: ["frame", "phase"], SwapPhase: ["frameA", "frameB"], SetScale: ["frame", "scale"], Capture: ["frame", "kernel", "memory_region"], RawCapture: ["frame", "duration", "memory_region"], DelayQubits: ["qubits", "duration"], DelayFrames: ["frames", "duration"], Fence: ["qubits"], FenceAll: [], Declare: [], Pragma: [], } if type(obj) in specs: attrs = specs[type(obj)] updated = copy(obj) for attr in attrs: setattr( updated, attr, fill_placeholders(getattr(updated, attr), placeholder_values)) return updated else: raise CalibrationError( f"Unable to fill placeholders in object {obj}.") except Exception as e: raise e