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(),
    )
Beispiel #2
0
    def write_memory(
        self,
        *,
        region_name: str,
        value: Union[int, float, Sequence[int], Sequence[float]],
        offset: Optional[int] = None,
    ) -> "QAM":
        """
        Writes a value or unwraps a list of values into a memory region on
        the QAM at a specified offset.

        :param region_name: Name of the declared memory region on the QAM.
        :param offset: Integer offset into the memory region to write to.
        :param value: Value(s) to store at the indicated location.
        """
        assert self.status in ["loaded", "done"]

        if offset is None:
            offset = 0
        elif isinstance(value, Sequence):
            warnings.warn("offset should be None when value is a Sequence")

        if isinstance(value, (int, float)):
            aref = ParameterAref(name=region_name, index=offset)
            self._variables_shim[aref] = value
        else:
            for index, v in enumerate(value):
                aref = ParameterAref(name=region_name, index=offset + index)
                self._variables_shim[aref] = v

        return self
Beispiel #3
0
def test_reset(forest):
    device = NxDevice(nx.complete_graph(3))
    qc = QuantumComputer(name='testy!',
                         qam=QVM(connection=forest),
                         device=device,
                         compiler=DummyCompiler())
    p = Program(Declare(name='theta', memory_type='REAL'),
                Declare(name='ro', memory_type='BIT'),
                RX(MemoryReference('theta'), 0),
                MEASURE(0, MemoryReference('ro'))).wrap_in_numshots_loop(1000)
    qc.run(executable=p, memory_map={'theta': [np.pi]})

    aref = ParameterAref(name='theta', index=0)
    assert qc.qam._variables_shim[aref] == np.pi
    assert qc.qam._executable == p
    assert qc.qam._memory_results["ro"].shape == (1000, 1)
    assert all([bit == 1 for bit in qc.qam._memory_results["ro"]])
    assert qc.qam.status == 'done'

    qc.reset()

    assert qc.qam._variables_shim == {}
    assert qc.qam._executable is None
    assert qc.qam._memory_results["ro"] is None
    assert qc.qam.status == 'connected'
Beispiel #4
0
    def _resolve_memory_references(
            self, expression: ExpressionDesignator) -> Union[float, int]:
        """
        Traverse the given Expression, and replace any Memory References with whatever values
        have been so far provided by the user for those memory spaces. Declared memory defaults
        to zero.

        :param expression: an Expression
        """
        if isinstance(expression, BinaryExp):
            left = self._resolve_memory_references(expression.op1)
            right = self._resolve_memory_references(expression.op2)
            return cast(Union[float, int], expression.fn(left, right))
        elif isinstance(expression, Function):
            return cast(
                Union[float, int],
                expression.fn(
                    self._resolve_memory_references(expression.expression)),
            )
        elif isinstance(expression, Parameter):
            raise ValueError(
                f"Unexpected Parameter in gate expression: {expression}")
        elif isinstance(expression, (float, int)):
            return expression
        elif isinstance(expression, MemoryReference):
            return self._variables_shim.get(
                ParameterAref(name=expression.name, index=expression.offset),
                0)
        else:
            raise ValueError(
                f"Unexpected expression in gate parameter: {expression}")
 def write_memory(
     self,
     *,
     region_name: str,
     value: Union[int, float, Sequence[int], Sequence[float]],
     offset: Optional[int] = None,
 ) -> "EncryptedProgram":
     self._memory._write_value(parameter=ParameterAref(name=region_name,
                                                       index=(offset or 0)),
                               value=value)
     return self
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 __P1 REAL[1]", "DECLARE theta REAL[1]",
                     "RZ(__P1[0]) 0").out(),
        recalculation_table={
            ParameterAref(index=0, name="__P1"): "theta[0]/(2*pi)"
        },
    )
Beispiel #7
0
    def _write_value(
        self,
        *,
        parameter: Union[ParameterAref, str],
        value: ParameterValue,
    ) -> "Memory":
        """
        Mutate the program to set the given parameter value.

        :param parameter: Name of the memory region, or parameter reference with offset.
        :param value: the value or values to set for this parameter. If a list
        is provided, parameter must be a ``str`` or ``parameter.offset == 0``.
        """
        if isinstance(parameter, str):
            parameter = ParameterAref(name=parameter, index=0)

        import numpy as np

        if isinstance(value, (int, float)):
            self.values[parameter] = value
        elif isinstance(value, (Sequence, np.ndarray)):
            if parameter.index != 0:
                raise ValueError(
                    "Parameter may not have a non-zero index when its value is a sequence"
                )

            for index, v in enumerate(value):
                if not isinstance(v, (int, float)):
                    raise TypeError(
                        f"Parameter must be numeric, not {type(value)}")
                aref = ParameterAref(name=parameter.name, index=index)
                self.values[aref] = v
        else:
            raise TypeError(
                f"Parameter must be numeric or an iterable of numeric values, not {type(value)}"
            )

        return self
Beispiel #8
0
    def write_memory(self, *, region_name: str, offset: int = 0, value=None):
        """
        Writes a value into a memory region on the QAM at a specified offset.

        :param region_name: Name of the declared memory region on the QAM.
        :param offset: Integer offset into the memory region to write to.
        :param value: Value to store at the indicated location.
        """
        assert self.status in ['loaded', 'done']

        aref = ParameterAref(name=region_name, index=offset)
        self._variables_shim[aref] = value

        return self
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())
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(),
    )
def test_reset(client_configuration: QCSClientConfiguration):
    quantum_processor = NxQuantumProcessor(nx.complete_graph(3))
    qc = QuantumComputer(
        name="testy!",
        qam=QVM(client_configuration=client_configuration),
        compiler=DummyCompiler(quantum_processor=quantum_processor,
                               client_configuration=client_configuration),
    )
    p = Program(
        Declare(name="theta", memory_type="REAL"),
        Declare(name="ro", memory_type="BIT"),
        RX(MemoryReference("theta"), 0),
        MEASURE(0, MemoryReference("ro")),
    ).wrap_in_numshots_loop(10)
    p.write_memory(region_name="theta", value=np.pi)
    result = qc.qam.run(p)

    aref = ParameterAref(name="theta", index=0)
    assert p._memory.values[aref] == np.pi
    assert result.readout_data["ro"].shape == (10, 1)
    assert all([bit == 1 for bit in result.readout_data["ro"]])
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(),
    )
Beispiel #13
0
 def aref(ref: MemoryReference) -> ParameterAref:
     return ParameterAref(name=ref.name, index=ref.offset)