def synthesize(self, utry: UnitaryMatrix, data: dict[str, Any]) -> Circuit: """Synthesize `utry` into a circuit, see SynthesisPass for more info.""" # 0. Skip any unitaries too small for the configured block. if self.block_size_start > utry.get_size(): _logger.warning( 'Skipping synthesis: block size is larger than input unitary.', ) return Circuit.from_unitary(utry) # 1. Create empty circuit with same size and radixes as `utry`. circuit = Circuit(utry.get_size(), utry.get_radixes()) # 2. Calculate block sizes block_size_end = utry.get_size() - 1 if self.block_size_limit is not None: block_size_end = self.block_size_limit # 3. Calculate relevant coupling_graphs # TODO: Look for topology info in `data`, use all-to-all otherwise. model = MachineModel(utry.get_size()) locations = [ model.get_locations(i) for i in range(self.block_size_start, block_size_end + 1) ] # 3. Bottom-up synthesis: build circuit up one gate at a time layer = 1 last_cost = 1.0 last_loc = None while True: remainder = utry.get_dagger() @ circuit.get_unitary() sorted_locations = self.analyze_remainder(remainder, locations) for loc in sorted_locations: # Never predict the previous location if loc == last_loc: continue _logger.info(f'Trying next predicted location {loc}.') circuit.append_gate(VariableUnitaryGate(len(loc)), loc) circuit.instantiate( utry, **self.instantiate_options, # type: ignore ) cost = self.cost.calc_cost(circuit, utry) _logger.info(f'Instantiated; layers: {layer}, cost: {cost:e}.') if cost < self.success_threshold: _logger.info(f'Circuit found with cost: {cost:e}.') _logger.info('Successful synthesis.') return circuit progress_threshold = self.progress_threshold_a progress_threshold += self.progress_threshold_r * np.abs(cost) if last_cost - cost >= progress_threshold: _logger.info('Progress has been made, depth increasing.') last_loc = loc last_cost = cost layer += 1 break _logger.info('Progress has not been made.') circuit.pop((-1, loc[0]))
def synthesis(utry: UnitaryMatrix, method: str) -> CompilationTask: """Produces a standard synthesis task for the given unitary.""" circuit = Circuit.from_unitary(utry) return CompilationTask(circuit, []) # TODO