コード例 #1
0
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(),
    )
コード例 #2
0
    def native_quil_to_executable(
            self, nq_program: Program) -> Optional[BinaryExecutableResponse]:
        if not self.qpu_compiler_client:
            raise UserMessageError(
                "It looks like you're trying to compile to an executable, but "
                "do not have access to the QPU compiler endpoint. Make sure you "
                "are engaged to the QPU before trying to do this.")

        self._connect_qpu_compiler()

        if nq_program.native_quil_metadata is None:
            warnings.warn(
                "It looks like you're trying to call `native_quil_to_binary` on a "
                "Program that hasn't been compiled via `quil_to_native_quil`. This is "
                "ok if you've hand-compiled your program to our native gateset, "
                "but be careful!")

        arithmetic_response = rewrite_arithmetic(nq_program)

        request = BinaryExecutableRequest(quil=arithmetic_response.quil,
                                          num_shots=nq_program.num_shots)
        response: BinaryExecutableResponse = cast(
            BinaryExecutableResponse,
            self.qpu_compiler_client.call("native_quil_to_binary", request),
        )

        # hack! we're storing a little extra info in the executable binary that we don't want to
        # expose to anyone outside of our own private lives: not the user, not the Forest server,
        # not anyone.
        response.recalculation_table = arithmetic_response.recalculation_table  # type: ignore
        response.memory_descriptors = _collect_memory_descriptors(nq_program)
        response.ro_sources = _collect_classical_memory_write_locations(
            nq_program)
        return response
コード例 #3
0
def test_rewrite_arithmetic_simple_mref():
    prog = Program("DECLARE theta REAL", "RZ(theta) 0")
    response = rewrite_arithmetic(prog)
    assert response == RewriteArithmeticResponse(
        original_memory_descriptors={
            "theta": ParameterSpec(length=1, type="REAL")
        },
        quil=Program("DECLARE theta REAL[1]", "RZ(theta[0]) 0").out(),
        recalculation_table={},
    )
コード例 #4
0
def test_rewrite_arithmetic_duplicate_exprs():
    prog = Program(
        "DECLARE theta REAL",
        "RZ(theta*1.5) 0",
        "RX(theta*1.5) 0",  # this is not a native gate, but it is a protoquil program
    )

    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]*1.5/(2*pi)"
        },
        quil=Program("DECLARE __P1 REAL[1]", "DECLARE theta REAL[1]",
                     "RZ(__P1[0]) 0", "RX(__P1[0]) 0").out(),
    )
コード例 #5
0
ファイル: _compiler.py プロジェクト: tocheng/pyquil
    def native_quil_to_executable(
            self,
            nq_program: Program,
            *,
            debug: bool = False) -> Optional[QuiltBinaryExecutableResponse]:
        if not self.qpu_compiler_client:
            raise UserMessageError(
                "It looks like you're trying to compile to an executable, but "
                "do not have access to the QPU compiler endpoint. Make sure you "
                "are engaged to the QPU before trying to do this.")

        self._connect_qpu_compiler()

        arithmetic_response = rewrite_arithmetic(nq_program)

        request = QuiltBinaryExecutableRequest(quilt=arithmetic_response.quil,
                                               num_shots=nq_program.num_shots)
        response = cast(
            QuiltBinaryExecutableResponse,
            self.qpu_compiler_client.call("native_quilt_to_binary",
                                          request,
                                          rpc_timeout=self.timeout),
        )

        response.recalculation_table = arithmetic_response.recalculation_table  # type: ignore
        response.memory_descriptors = _collect_memory_descriptors(nq_program)

        # Convert strings to MemoryReference for downstream processing.
        response.ro_sources = [(parse_mref(mref), source)
                               for mref, source in response.ro_sources]

        # TODO (kalzoo): this is a temporary workaround to migrate memory location parsing from
        # the client side (where it was pre-quilt) to the service side. In some cases, the service
        # won't return ro_sources, and so we can fall back to parsing the change on the client side.
        if response.ro_sources == []:
            response.ro_sources = _collect_classical_memory_write_locations(
                nq_program)

        if not debug:
            response.debug = {}

        return response
コード例 #6
0
    def native_quil_to_executable(self,
                                  nq_program: Program) -> QuantumExecutable:
        arithmetic_response = rewrite_arithmetic(nq_program)

        request = TranslateNativeQuilToEncryptedBinaryRequest(
            quil=arithmetic_response.quil, num_shots=nq_program.num_shots)
        with self._qcs_client() as qcs_client:  # type: httpx.Client
            response = translate_native_quil_to_encrypted_binary(
                client=qcs_client,
                quantum_processor_id=self.quantum_processor_id,
                json_body=request,
            ).parsed

        ro_sources = cast(
            List[List[str]],
            [] if response.ro_sources == UNSET else response.ro_sources)

        def to_expression(rule: str) -> ExpressionDesignator:
            # 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
            return cast(ExpressionDesignator,
                        cast(Gate,
                             parse(f"RZ({rule}) 0")[0]).params[0])

        return EncryptedProgram(
            program=response.program,
            memory_descriptors=_collect_memory_descriptors(nq_program),
            ro_sources={
                parse_mref(mref): source
                for mref, source in ro_sources
            },
            recalculation_table={
                mref: to_expression(rule)
                for mref, rule in
                arithmetic_response.recalculation_table.items()
            },
            _memory=nq_program._memory.copy(),
        )
コード例 #7
0
def test_rewrite_arithmetic_set_scale():
    prog = Program(
        "DECLARE theta REAL",
        'SET-SCALE 0 "rf" 1.0',
        '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]/8"
        },
        quil=Program(
            "DECLARE __P1 REAL[1]",
            "DECLARE theta REAL[1]",
            'SET-SCALE 0 "rf" 1.0',
            'SET-SCALE 0 "rf" __P1[0]',
        ).out(),
    )
コード例 #8
0
def test_rewrite_arithmetic_mixed():
    prog = Program(
        "DECLARE theta REAL",
        "DECLARE beta REAL",
        "RZ(3 * theta) 0",
        "RZ(beta+theta) 0",
    )
    response = rewrite_arithmetic(prog)
    assert response.original_memory_descriptors == {
        "theta": ParameterSpec(length=1, type="REAL"),
        "beta": ParameterSpec(length=1, type="REAL"),
    }
    assert response.recalculation_table == {
        ParameterAref(index=0, name="__P2"): "3*theta[0]/(2*pi)",
        ParameterAref(index=1, name="__P2"): "(beta[0] + theta[0])/(2*pi)",
    }
    assert (response.quil == Program(
        "DECLARE __P2 REAL[2]",
        "DECLARE theta REAL[1]",
        "DECLARE beta REAL[1]",
        "RZ(__P2[0]) 0",
        "RZ(__P2[1]) 0",
    ).out())
コード例 #9
0
def test_rewrite_arithmetic_no_params():
    prog = Program("X 0")
    response = rewrite_arithmetic(prog)
    assert response == RewriteArithmeticResponse(quil=Program("X 0").out())