def simplify_circuit(circuit: 'cirq.Circuit') -> None: """Simplifies and optimizes the given circuit (in place). Args: circuit (cirq.Circuit): Circuit to simplify. Modified. Currently it * merges any neighboring gates belonging to the same one-parameter family * merges all one-qubit rotations into phased X rotations followed by Z rotations * pushes the Z rotations towards the end of the circuit as far as possible * drops any empty Moments """ # the optimizers cause the immediate decomposition of any gates they insert into the Circuit for _ in range(7): # FIXME This sucks, but it seems that Cirq optimizers have no way of communicating # if they actually made any changes to the Circuit, so we run a fixed number of iterations. # Ideally we would keep doing this until the circuit hits a fixed point and no further changes are made. # all mergeable 2-qubit gates are merged MergeOneParameterGroupGates().optimize_circuit(circuit) optimizers.merge_single_qubit_gates_into_phased_x_z(circuit) # all z rotations are pushed past the first two-qubit gate following them IQMEjectZ(eject_parameterized=True).optimize_circuit(circuit) optimizers.DropEmptyMoments().optimize_circuit(circuit) DropRZBeforeMeasurement().optimize_circuit(circuit) optimizers.DropEmptyMoments().optimize_circuit(circuit) DecomposeGatesFinal().optimize_circuit(circuit)
def _to_xmon_circuit( self, circuit: circuits.Circuit, param_resolver: study.ParamResolver ) -> Tuple[circuits.Circuit, Set[str]]: # TODO: Use one optimization pass. xmon_circuit = protocols.resolve_parameters(circuit, param_resolver) convert_to_xmon_gates.ConvertToXmonGates().optimize_circuit( xmon_circuit) optimizers.DropEmptyMoments().optimize_circuit(xmon_circuit) keys = find_measurement_keys(xmon_circuit) return xmon_circuit, keys
def program_as_schedule(self, program: TProgram) -> schedules.Schedule: if isinstance(program, circuits.Circuit): device = program.device circuit_copy = program.copy() optimizers.DropEmptyMoments().optimize_circuit(circuit_copy) device.validate_circuit(circuit_copy) return schedules.moment_by_moment_schedule(device, circuit_copy) if isinstance(program, schedules.Schedule): return program raise TypeError('Unexpected program type.')
def program_as_schedule( self, program: Union[circuits.Circuit, Schedule]) -> Schedule: if isinstance(program, circuits.Circuit): device = program.device circuit_copy = program.copy() ConvertToXmonGates().optimize_circuit(circuit_copy) optimizers.DropEmptyMoments().optimize_circuit(circuit_copy) device.validate_circuit(circuit_copy) return moment_by_moment_schedule(device, circuit_copy) if isinstance(program, Schedule): return program raise TypeError('Unexpected program type.')
def converted_gate_set( circuit: circuits.Circuit, no_clifford_gates: bool = False, atol: float = 1e-8, ) -> circuits.Circuit: """Returns a new, equivalent circuit using the gate set {SingleQubitCliffordGate, CZ/PauliInteractionGate, PauliStringPhasor}. """ conv_circuit = circuits.Circuit(circuit) optimizers.ConvertToCzAndSingleGates().optimize_circuit(conv_circuit) optimizers.MergeSingleQubitGates().optimize_circuit(conv_circuit) ConvertToPauliStringPhasors( ignore_failures=True, keep_clifford=not no_clifford_gates, atol=atol, ).optimize_circuit(conv_circuit) optimizers.DropEmptyMoments().optimize_circuit(conv_circuit) return conv_circuit