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_def_gate_as(): perm_gate_str = 'DEFGATE CCNOT AS PERMUTATION:\n 0, 1, 2, 3, 4, 5, 7, 6'.strip() matrix_gate_str = 'DEFGATE CNOT AS MATRIX:\n 1.0, 0.0, 0.0, 0.0\n 0.0, 1.0, 0.0, 0.0\n 0.0, 0.0, 0.0, 1.0\n 0.0, 0.0, 1.0, 0.0'.strip() unknown_gate_str = 'DEFGATE CCNOT AS UNKNOWNTYPE:\n 0, 1, 2, 3, 4, 5, 7, 6'.strip() parse(perm_gate_str) parse(matrix_gate_str) with pytest.raises(RuntimeError): parse(unknown_gate_str)
def load(self, executable): """ Initialize a QAM into a fresh state. Load the executable and parse the expressions in the recalculation table (if any) into pyQuil Expression objects. :param executable: Load a compiled executable onto the QAM. """ super().load(executable) if hasattr(self._executable, "recalculation_table"): recalculation_table = self._executable.recalculation_table for memory_reference, recalc_rule in recalculation_table.items(): # We can only parse complete lines of Quil, so we wrap the arithmetic expression # in a valid Quil instruction to parse it. # TODO: This hack should be replaced after #687 expression = parse(f"RZ({recalc_rule}) 0")[0].params[0] recalculation_table[memory_reference] = expression return self
def test_def_gate_as(): perm_gate_str = "DEFGATE CCNOT AS PERMUTATION:\n 0, 1, 2, 3, 4, 5, 7, 6".strip() matrix_gate_str = """DEFGATE CNOT AS MATRIX: 1.0, 0.0, 0.0, 0.0 0.0, 1.0, 0.0, 0.0 0.0, 0.0, 0.0, 1.0 0.0, 0.0, 1.0, 0.0""".strip() unknown_gate_str = "DEFGATE CCNOT AS UNKNOWNTYPE:\n 0, 1, 2, 3, 4, 5, 7, 6".strip() parse(perm_gate_str) parse(matrix_gate_str) with pytest.raises(UnexpectedToken) as excp: parse(unknown_gate_str) assert excp.value.token == Token("IDENTIFIER", "UNKNOWNTYPE")
def circuit_from_quil(quil: str) -> Circuit: """Convert a Quil program to a Cirq Circuit. Args: quil: The Quil program to convert. Returns: A Cirq Circuit generated from the Quil program. Raises: UnsupportedQuilInstruction: Cirq does not support the specified Quil instruction. UndefinedQuilGate: Cirq does not support the specified Quil gate. References: https://github.com/rigetti/pyquil """ circuit = Circuit() defined_gates = SUPPORTED_GATES.copy() instructions = parse(quil) for inst in instructions: # Add DEFGATE-defined gates to defgates dict using MatrixGate. if isinstance(inst, DefGate): if inst.parameters: raise UnsupportedQuilInstruction( "Parameterized DEFGATEs are currently unsupported.") defined_gates[inst.name] = MatrixGate(inst.matrix) # Pass when encountering a DECLARE. elif isinstance(inst, Declare): pass # Convert pyQuil gates to Cirq operations. elif isinstance(inst, PyQuilGate): quil_gate_name = inst.name quil_gate_params = inst.params line_qubits = list(LineQubit(q.index) for q in inst.qubits) if quil_gate_name not in defined_gates: raise UndefinedQuilGate( f"Quil gate {quil_gate_name} not supported in Cirq.") cirq_gate_fn = defined_gates[quil_gate_name] if quil_gate_params: circuit += cirq_gate_fn(*quil_gate_params)(*line_qubits) else: circuit += cirq_gate_fn(*line_qubits) # Convert pyQuil MEASURE operations to Cirq MeasurementGate objects. elif isinstance(inst, PyQuilMeasurement): line_qubit = LineQubit(inst.qubit.index) if inst.classical_reg is None: raise UnsupportedQuilInstruction( f"Quil measurement {inst} without classical register " f"not currently supported in Cirq.") quil_memory_reference = inst.classical_reg.out() circuit += MeasurementGate(1, key=quil_memory_reference)(line_qubit) # Raise a targeted error when encountering a PRAGMA. elif isinstance(inst, Pragma): raise UnsupportedQuilInstruction(PRAGMA_ERROR) # Raise a targeted error when encountering a RESET. elif isinstance(inst, (Reset, ResetQubit)): raise UnsupportedQuilInstruction(RESET_ERROR) # Raise a general error when encountering an unconsidered type. else: raise UnsupportedQuilInstruction( f"Quil instruction {inst} of type {type(inst)} not currently supported in Cirq." ) return circuit
def test_invalid(): with pytest.raises(RuntimeError): parse("H X")
def _test(quil_string, *instructions): assert list(instructions) == parse(quil_string)
def parse_equals(quil_string, *instructions): expected = list(instructions) actual = parse(quil_string) assert expected == actual
def parse_expression(expression): """ We have to use this as a hack for now, RZ is meaningless. """ return parse(f"RZ({expression}) 0")[0].params[0]
def test_parse_defcal_error_on_mref(): assert parse("DEFCAL RX(%theta) 0:\n NOP") with pytest.raises(ValueError): parse("DEFCAL RX(theta) 0:\n NOP")
def test_parse_template_waveform_strict_values(): prog = """DECLARE foo REAL[2] PULSE 0 "rf" flat(duration: 1.0, iq: foo)""" with pytest.raises(ValueError): parse(prog)
def _test(quil_string, *instructions): # Currently doesn't support Python 2 if sys.version_info.major == 2: return assert parse(quil_string) == list(instructions)
def parse_equals(quil_string, *instructions): assert list(instructions) == parse(quil_string)