Exemplo n.º 1
0
def test_qasm_output_args_format():
    a = cirq.NamedQubit('a')
    b = cirq.NamedQubit('b')
    m_a = cirq.measure(a, key='meas_a')
    m_b = cirq.measure(b, key='meas_b')
    args = cirq.QasmArgs(
        precision=4,
        version='2.0',
        qubit_id_map={a: 'aaa[0]', b: 'bbb[0]'},
        meas_key_id_map={'meas_a': 'm_a', 'meas_b': 'm_b'},
    )

    assert args.format('_{0}_', a) == '_aaa[0]_'
    assert args.format('_{0}_', b) == '_bbb[0]_'

    assert args.format('_{0:meas}_', cirq.measurement_key_name(m_a)) == '_m_a_'
    assert args.format('_{0:meas}_', cirq.measurement_key_name(m_b)) == '_m_b_'

    assert args.format('_{0}_', 89.1234567) == '_89.1235_'
    assert args.format('_{0}_', 1.23) == '_1.23_'

    assert args.format('_{0:half_turns}_', 89.1234567) == '_pi*89.1235_'
    assert args.format('_{0:half_turns}_', 1.23) == '_pi*1.23_'

    assert args.format('_{0}_', 'other') == '_other_'
def test_measurement_key_not_implemented():
    class ReturnsNotImplemented:
        def _measurement_key_name_(self):
            return NotImplemented

    with pytest.raises(TypeError, match='NotImplemented'):
        cirq.measurement_key_name(ReturnsNotImplemented())

    assert cirq.measurement_key_name(ReturnsNotImplemented(), None) is None
    assert cirq.measurement_key_name(ReturnsNotImplemented(), NotImplemented) is NotImplemented
    assert cirq.measurement_key_name(ReturnsNotImplemented(), 'a') == 'a'
Exemplo n.º 3
0
def test_matrix_mixture_remap_keys():
    dp = cirq.depolarize(0.1)
    mm = cirq.MixedUnitaryChannel.from_mixture(dp)
    with pytest.raises(TypeError):
        _ = cirq.measurement_key_name(mm)
    assert cirq.with_measurement_key_mapping(mm, {'a': 'b'}) is NotImplemented

    mm_x = cirq.MixedUnitaryChannel.from_mixture(dp, key='x')
    assert cirq.with_measurement_key_mapping(mm_x, {'a': 'b'}) is mm_x
    assert cirq.measurement_key_name(cirq.with_key_path(mm_x, ('path',))) == 'path:x'

    mm_a = cirq.MixedUnitaryChannel.from_mixture(dp, key='a')
    mm_b = cirq.MixedUnitaryChannel.from_mixture(dp, key='b')
    assert mm_a != mm_b
    assert cirq.with_measurement_key_mapping(mm_a, {'a': 'b'}) == mm_b
Exemplo n.º 4
0
    def _write_quil(self, output_func: Callable[[str], None]) -> None:
        """Calls `output_func` for successive lines of QUIL output.

        Args:
            output_func: A function that accepts a string of QUIL. This will likely
                write the QUIL to a file.

        Returns:
            None.
        """
        if self._decompose_operation is None:
            return super()._write_quil(output_func)

        output_func("# Created using Cirq.\n\n")

        if len(self.measurements) > 0:
            measurements_declared: Set[str] = set()
            for m in self.measurements:
                key = cirq.measurement_key_name(m)
                if key in measurements_declared:
                    continue
                measurements_declared.add(key)
                output_func(f"DECLARE {self.measurement_id_map[key]} BIT[{len(m.qubits)}]\n")
            output_func("\n")

        for main_op in self.operations:
            decomposed = self._decompose_operation(main_op)
            for decomposed_op in decomposed:
                output_func(self._op_to_quil(decomposed_op))
Exemplo n.º 5
0
 def _serialize_measurement_gate(
     self, gate: cirq.MeasurementGate, targets: Sequence[int]
 ) -> dict:
     key = cirq.measurement_key_name(gate)
     if chr(31) in key or chr(30) in key:
         raise ValueError(
             'Measurement gates for IonQ API cannot have a key with a ascii unit'
             f'or record separator in it. Key was {key}'
         )
     return {'gate': 'meas', 'key': key, 'targets': ','.join(str(t) for t in targets)}
Exemplo n.º 6
0
def test_matrix_mixture_from_unitaries():
    q0 = cirq.LineQubit(0)
    mix = [(0.5, np.array([[1, 0], [0, 1]])), (0.5, np.array([[0, 1], [1, 0]]))]
    half_flip = cirq.MixedUnitaryChannel(mix, key='flip')
    assert cirq.measurement_key_name(half_flip) == 'flip'

    circuit = cirq.Circuit(half_flip.on(q0), cirq.measure(q0, key='m'))
    sim = cirq.Simulator(seed=0)

    results = sim.simulate(circuit)
    assert 'flip' in results.measurements
    assert results.measurements['flip'] == results.measurements['m']
Exemplo n.º 7
0
def test_measurement_key():
    class ReturnsStr:
        def _measurement_key_name_(self):
            return 'door locker'

    class DeprecatedMagicMethod(cirq.SingleQubitGate):
        def _measurement_key_(self):
            return 'door locker'

    assert cirq.is_measurement(ReturnsStr())
    with cirq.testing.assert_deprecated(deadline="v0.13"):
        assert cirq.measurement_key(ReturnsStr()) == 'door locker'
    with cirq.testing.assert_deprecated(deadline="v0.13"):
        assert cirq.measurement_key_name(
            DeprecatedMagicMethod()) == 'door locker'
    with cirq.testing.assert_deprecated(deadline="v0.13"):
        assert (cirq.measurement_key_name(DeprecatedMagicMethod().on(
            cirq.LineQubit(0))) == 'door locker')

    assert cirq.measurement_key_name(ReturnsStr()) == 'door locker'

    assert cirq.measurement_key_name(ReturnsStr(), None) == 'door locker'
    assert cirq.measurement_key_name(ReturnsStr(),
                                     NotImplemented) == 'door locker'
    assert cirq.measurement_key_name(ReturnsStr(), 'a') == 'door locker'
Exemplo n.º 8
0
def test_kraus_channel_from_channel():
    q0 = cirq.LineQubit(0)
    dp = cirq.depolarize(0.1)
    kc = cirq.KrausChannel.from_channel(dp, key='dp')
    assert cirq.measurement_key_name(kc) == 'dp'

    circuit = cirq.Circuit(kc.on(q0))
    sim = cirq.Simulator(seed=0)

    results = sim.simulate(circuit)
    assert 'dp' in results.measurements
    # The depolarizing channel has four Kraus operators.
    assert results.measurements['dp'] in range(4)
Exemplo n.º 9
0
def _measure_to_proto(gate: cirq.MeasurementGate, qubits: Sequence[cirq.Qid]):
    if len(qubits) == 0:
        raise ValueError('Measurement gate on no qubits.')

    invert_mask = None
    if gate.invert_mask:
        invert_mask = gate.invert_mask + (False, ) * (gate.num_qubits() -
                                                      len(gate.invert_mask))

    if invert_mask and len(invert_mask) != len(qubits):
        raise ValueError('Measurement gate had invert mask of length '
                         'different than number of qubits it acts on.')
    return operations_pb2.Measurement(
        targets=[_qubit_to_proto(q) for q in qubits],
        key=cirq.measurement_key_name(gate),
        invert_mask=invert_mask,
    )
Exemplo n.º 10
0
    def _sample_measure_results(
        self,
        program: cirq.Circuit,
        repetitions: int = 1,
    ) -> Dict[str, np.ndarray]:
        """Samples from measurement gates in the circuit.

        Note that this will execute the circuit 'repetitions' times.

        Args:
            program: The circuit to sample from.
            repetitions: The number of samples to take.

        Returns:
            A dictionary from measurement gate key to measurement
            results. Measurement results are stored in a 2-dimensional
            numpy array, the first dimension corresponding to the repetition
            and the second to the actual boolean measurement results (ordered
            by the qubits being measured.)

        Raises:
            ValueError: If there are multiple MeasurementGates with the same key,
                or if repetitions is negative.
        """

        # Add noise to the circuit if a noise model was provided.
        all_qubits = program.all_qubits()
        program = qsimc.QSimCircuit(
            self.noise.noisy_moments(program, sorted(all_qubits))
            if self.noise is not cirq.NO_NOISE else program, )

        # Compute indices of measured qubits
        ordered_qubits = cirq.QubitOrder.DEFAULT.order_for(all_qubits)
        num_qubits = len(ordered_qubits)

        qubit_map = {
            qubit: index
            for index, qubit in enumerate(ordered_qubits)
        }

        # Compute:
        # - number of qubits for each measurement key.
        # - measurement ops for each measurement key.
        # - measurement info for each measurement.
        # - total number of measured bits.
        measurement_ops = [
            op for _, op, _ in program.findall_operations_with_gate_type(
                cirq.MeasurementGate)
        ]
        num_qubits_by_key: Dict[str, int] = {}
        meas_ops: Dict[str, List[cirq.GateOperation]] = {}
        meas_infos: List[MeasInfo] = []
        num_bits = 0
        for op in measurement_ops:
            gate = op.gate
            key = cirq.measurement_key_name(gate)
            meas_ops.setdefault(key, [])
            i = len(meas_ops[key])
            meas_ops[key].append(op)
            n = len(op.qubits)
            if key in num_qubits_by_key:
                if n != num_qubits_by_key[key]:
                    raise ValueError(
                        f"repeated key {key!r} with different numbers of qubits: "
                        f"{num_qubits_by_key[key]} != {n}")
            else:
                num_qubits_by_key[key] = n
            meas_infos.append(
                MeasInfo(
                    key=key,
                    idx=i,
                    invert_mask=gate.full_invert_mask(),
                    start=num_bits,
                    end=num_bits + n,
                ))
            num_bits += n

        # Set qsim options
        options = {**self.qsim_options}

        results = {
            key: np.ndarray(shape=(repetitions, len(meas_ops[key]), n),
                            dtype=int)
            for key, n in num_qubits_by_key.items()
        }

        noisy = _needs_trajectories(program)
        if not noisy and program.are_all_measurements_terminal(
        ) and repetitions > 1:
            # Measurements must be replaced with identity gates to sample properly.
            # Simply removing them may omit qubits from the circuit.
            for i in range(len(program.moments)):
                program.moments[i] = cirq.Moment(
                    op if not isinstance(op.gate, cirq.MeasurementGate) else
                    [cirq.IdentityGate(1).on(q) for q in op.qubits]
                    for op in program.moments[i])
            translator_fn_name = "translate_cirq_to_qsim"
            options["c"], _ = self._translate_circuit(
                program,
                translator_fn_name,
                cirq.QubitOrder.DEFAULT,
            )
            options["s"] = self.get_seed()
            raw_results = self._sim_module.qsim_sample_final(
                options, repetitions)
            full_results = np.array([[
                bool(result & (1 << q)) for q in reversed(range(num_qubits))
            ] for result in raw_results])

            for key, oplist in meas_ops.items():
                for i, op in enumerate(oplist):
                    meas_indices = [qubit_map[qubit] for qubit in op.qubits]
                    invert_mask = op.gate.full_invert_mask()
                    # Apply invert mask to re-ordered results
                    results[
                        key][:,
                             i, :] = full_results[:,
                                                  meas_indices] ^ invert_mask

        else:
            if noisy:
                translator_fn_name = "translate_cirq_to_qtrajectory"
                sampler_fn = self._sim_module.qtrajectory_sample
            else:
                translator_fn_name = "translate_cirq_to_qsim"
                sampler_fn = self._sim_module.qsim_sample

            options["c"], _ = self._translate_circuit(
                program,
                translator_fn_name,
                cirq.QubitOrder.DEFAULT,
            )
            measurements = np.empty(shape=(repetitions, num_bits), dtype=int)
            for i in range(repetitions):
                options["s"] = self.get_seed()
                measurements[i] = sampler_fn(options)

            for m in meas_infos:
                results[m.key][:, m.idx, :] = (measurements[:, m.start:m.end]
                                               ^ m.invert_mask)

        return results
Exemplo n.º 11
0
def test_measurement_key():
    a = cirq.NamedQubit('a')
    assert cirq.measurement_key_name(cirq.measure(a, key='lock')) == 'lock'