Beispiel #1
0
def test_moment_by_moment_schedule_empty_moment():
    device = _TestDevice()
    circuit = Circuit([
        Moment(),
    ])
    schedule = moment_by_moment_schedule(device, circuit)
    assert len(schedule.scheduled_operations) == 0
Beispiel #2
0
def test_moment_by_moment_schedule_empty_moment_ignored():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit(
        [Moment([ops.H(qubits[0])]),
         Moment([]),
         Moment([ops.H(qubits[0])])])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    twenty_ns = cirq.Timestamp(nanos=20)
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(qubits[0]), zero_ns, device),
        ScheduledOperation.op_at_on(ops.H(qubits[0]), twenty_ns, device),
    }
Beispiel #3
0
def _generate_sample_2q_xeb_tasks(
    zipped_circuits: List[_ZippedCircuit], cycle_depths: Sequence[int]
) -> List[_Sample2qXEBTask]:
    """Helper function used in `sample_2q_xeb_circuits` to prepare circuits in sampling tasks."""
    tasks: List[_Sample2qXEBTask] = []
    for cycle_depth in cycle_depths:
        for zipped_circuit in zipped_circuits:
            circuit_depth = cycle_depth * 2 + 1
            assert circuit_depth <= len(zipped_circuit.wide_circuit)
            # Slicing creates a copy, although this isn't documented
            prepared_circuit = zipped_circuit.wide_circuit[:circuit_depth]
            prepared_circuit += Moment(
                ops.measure(*pair, key=str(pair_i))
                for pair_i, pair in enumerate(zipped_circuit.pairs)
            )
            tasks.append(
                _Sample2qXEBTask(
                    cycle_depth=cycle_depth,
                    layer_i=zipped_circuit.layer_i,
                    combination_i=zipped_circuit.combination_i,
                    prepared_circuit=prepared_circuit,
                    combination=zipped_circuit.combination,
                )
            )
    return tasks
Beispiel #4
0
def test_moment_by_moment_schedule_device_validation_fails():
    device = _TestDevice()
    qubits = device.qubits
    circuit = Circuit(
        [Moment([ops.CZ(qubits[0], qubits[1]),
                 ops.CZ(qubits[2], qubits[3])])])
    with pytest.raises(ValueError, match="Adjacent CZ"):
        _ = moment_by_moment_schedule(device, circuit)
Beispiel #5
0
def test_moment_by_moment_schedule_max_duration():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment([ops.H(qubits[0]),
                ops.CZ(qubits[1], qubits[2])]),
        Moment([ops.H(qubits[0])])
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    fourty_ns = cirq.Timestamp(nanos=40)
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(qubits[0]), zero_ns, device),
        ScheduledOperation.op_at_on(ops.CZ(qubits[1], qubits[2]), zero_ns,
                                    device),
        ScheduledOperation.op_at_on(ops.H(qubits[0]), fourty_ns, device),
    }
Beispiel #6
0
def test_moment_by_moment_schedule_two_moments():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment(ops.H(q) for q in qubits),
        Moment((ops.CZ(qubits[i], qubits[i + 1]) for i in range(0, 9, 3)))
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    twenty_ns = cirq.Timestamp(nanos=20)
    expected_one_qubit = set(
        ScheduledOperation.op_at_on(ops.H(q), zero_ns, device) for q in qubits)
    expected_two_qubit = set(
        ScheduledOperation.op_at_on(ops.CZ(qubits[i], qubits[i + 1]),
                                    twenty_ns, device) for i in range(0, 9, 3))
    expected = expected_one_qubit.union(expected_two_qubit)
    assert set(schedule.scheduled_operations) == expected
Beispiel #7
0
def random_circuit(
        qubits: Union[Sequence[ops.QubitId], int],
        n_moments: int,
        op_density: float,
        gate_domain: Optional[Dict[ops.Gate, int]] = None) -> Circuit:
    """Generates a random circuit.

    Args:
        qubits: the qubits that the circuit acts on. Because the qubits on
            which an operation acts are chosen randomly, not all given qubits
            may be acted upon.
        n_moments: the number of moments in the generated circuit.
        op_density: the expected proportion of qubits that are acted on in any
            moment.
        gate_domain: The set of gates to choose from, with a specified arity.

    Raises:
        ValueError:
            * op_density is not in (0, 1).
            * gate_domain is empty.
            * qubits is an int less than 1 or an empty sequence.

    Returns:
        The randomly generated Circuit.
    """
    if not 0 < op_density < 1:
        raise ValueError('op_density must be in (0, 1).')
    if gate_domain is None:
        gate_domain = DEFAULT_GATE_DOMAIN
    if not gate_domain:
        raise ValueError('gate_domain must be non-empty')
    max_arity = max(gate_domain.values())

    if isinstance(qubits, int):
        qubits = tuple(ops.NamedQubit(str(i)) for i in range(qubits))
    n_qubits = len(qubits)
    if n_qubits < 1:
        raise ValueError('At least one qubit must be specified.')

    moments = []  # type: List[Moment]
    for _ in range(n_moments):
        operations = []
        free_qubits = set(q for q in qubits)
        while len(free_qubits) >= max_arity:
            gate, arity = choice(tuple(gate_domain.items()))
            op_qubits = sample(free_qubits, arity)
            free_qubits.difference_update(op_qubits)
            if random() <= op_density:
                operations.append(gate(*op_qubits))
        moments.append(Moment(operations))

    return Circuit(moments)
Beispiel #8
0
def test_moment_by_moment_schedule_moment_of_two_qubit_ops():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit(
        [Moment((ops.CZ(qubits[i], qubits[i + 1]) for i in range(0, 9, 3)))])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    expected = set(
        ScheduledOperation.op_at_on(ops.CZ(qubits[i], qubits[i + 1]), zero_ns,
                                    device) for i in range(0, 9, 3))
    assert set(schedule.scheduled_operations) == expected
Beispiel #9
0
def test_moment_by_moment_schedule_moment_of_single_qubit_ops():
    device = _TestDevice()
    qubits = device.qubits

    circuit = Circuit([
        Moment(ops.H(q) for q in qubits),
    ])
    schedule = moment_by_moment_schedule(device, circuit)

    zero_ns = cirq.Timestamp()
    assert set(schedule.scheduled_operations) == {
        ScheduledOperation.op_at_on(ops.H(q), zero_ns, device)
        for q in qubits
    }
Beispiel #10
0
    def can_add_operation_into_moment(self, operation: ops.Operation,
                                      moment: circuits.Moment) -> bool:
        """Determines if it's possible to add an operation into a moment.

        An operation can be added if the moment with the operation added is valid.

        Args:
            operation: The operation being added.
            moment: The moment being transformed.

        Returns:
            Whether or not the moment will validate after adding the operation.

        Raises:
            ValueError: If either of the given moment or operation is invalid
        """
        if not super().can_add_operation_into_moment(operation, moment):
            return False
        try:
            self.validate_moment(moment.with_operation(operation))
        except:
            return False
        return True