def test_apply_match_delay_qubits(): settings = {FormalArgument("q"): Qubit(0), Parameter("foo"): 1.0} instr = DelayQubits([Qubit(1), FormalArgument("q")], duration=Parameter("foo")) actual = fill_placeholders(instr, settings) expected = DelayQubits([Qubit(1), Qubit(0)], 1.0) assert actual == expected
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_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_compile_with_quilt_calibrations(compiler): device_name = "test_device" mock_url = "http://mock-qpu-compiler" config = PyquilConfig(TEST_CONFIG_PATHS) session = get_session(config=config) mock_adapter = requests_mock.Adapter() session.mount("http://", mock_adapter) headers = { # access token from ./data/user_auth_token_valid.json. "Authorization": "Bearer secret" } mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/get_version_info", status_code=200, json={}, headers=headers, ) mock_adapter.register_uri( "POST", f"{mock_url}/devices/{device_name}/native_quilt_to_binary", status_code=200, json=SIMPLE_RESPONSE, headers=headers, ) device = Device(name="not_actually_device_name", raw={ "device_name": device_name, "isa": DUMMY_ISA_DICT }) compiler = QPUCompiler( quilc_endpoint=session.config.quilc_url, qpu_compiler_endpoint=mock_url, device=device, session=session, ) program = simple_program() q = FormalArgument("q") defn = DefCalibration( "H", [], [q], [RZ(math.pi / 2, q), RX(math.pi / 2, q), RZ(math.pi / 2, q)]) cals = [defn] program._calibrations = cals # this should more or less pass through compilation_result = compiler.quil_to_native_quil(program, protoquil=True) assert compilation_result.calibrations == cals assert program.calibrations == cals assert compilation_result == program
def test_compile_with_quilt_calibrations(compiler: QPUCompiler): program = simple_program() q = FormalArgument("q") defn = DefCalibration("H", [], [q], [RZ(math.pi / 2, q), RX(math.pi / 2, q), RZ(math.pi / 2, q)]) cals = [defn] program._calibrations = cals # this should more or less pass through compilation_result = compiler.quil_to_native_quil(program, protoquil=True) assert compilation_result.calibrations == cals assert program.calibrations == cals assert compilation_result == program
def test_measure_calibration_match(): matches = [ ("DEFCAL MEASURE 0", "MEASURE 0"), ("DEFCAL MEASURE q", "MEASURE 0"), ("DEFCAL MEASURE 0 b", "DECLARE ro BIT\nMEASURE 0 ro[0]"), ("DEFCAL MEASURE q b", "DECLARE ro BIT\nMEASURE 1 ro[0]"), ] for cal, instr in matches: assert _match(cal, instr) is not None assert _match(cal, instr).settings[FormalArgument("q")] == Qubit(1) assert _match(cal, instr).settings[FormalArgument("b")] == MemoryReference("ro") mismatches = [ ("DEFCAL MEASURE 1", "MEASURE 0"), ("DEFCAL MEASURE 0 b", "MEASURE 0"), ("DEFCAL MEASURE q", "DECLARE ro BIT\nMEASURE 0 ro[0]"), ] for cal, instr in mismatches: assert _match(cal, instr) is None
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 test_simple_gate_calibration_match(): matches = [ ("DEFCAL X 0", "X 0"), ("DEFCAL X q", "X 0"), ("DEFCAL FOO q 0", "FOO 1 0"), ("DEFCAL FOO q 0", "FOO 0 0"), ] for cal, instr in matches: assert _match(cal, instr) is not None assert _match(cal, instr).settings[FormalArgument("q")] == Qubit(0) mismatches = [ ("DEFCAL X 0", "X 1"), ("DEFCAL Y 0", "X 0"), # we are case sensitive ("DEFCAL foo 0", "FOO 0"), ] for cal, instr in mismatches: assert _match(cal, instr) is None
def test_parsing_fence(): parse_equals("FENCE 0", Fence([Qubit(0)])) parse_equals("FENCE 0 1", Fence([Qubit(0), Qubit(1)])) parse_equals("FENCE q s", Fence([FormalArgument("q"), FormalArgument("s")])) parse_equals("FENCE", FenceAll())
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