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
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), }
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
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)
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), }
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
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)
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
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 }
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