def solve(self, output_mode=None, output_file_name=None): result_depth, list_scheduled_gate_name, list_scheduled_gate_qubits, final_mapping = super( ).solve("IR") circuit = Circuit() for t in range(result_depth): moment = Moment() for i, qubits in enumerate(list_scheduled_gate_qubits[t]): if isinstance(qubits, int): moment = moment.with_operation( GateOperation(list_scheduled_gate_name[t][i], (self.map_to_cirq_qubit[qubits], ))) else: if list_scheduled_gate_name[t][i] == "SWAP": moment = moment.with_operation( GateOperation(SWAP, (self.map_to_cirq_qubit[qubits[0]], self.map_to_cirq_qubit[qubits[1]]))) else: moment = moment.with_operation( GateOperation(list_scheduled_gate_name[t][i], (self.map_to_cirq_qubit[qubits[0]], self.map_to_cirq_qubit[qubits[1]]))) circuit += moment final_cirq_mapping = dict() for i in range(self.count_program_qubit): final_cirq_mapping[self.map_to_cirq_qubit[ final_mapping[i]]] = self.map_program_qubit_to[i] return [circuit, final_cirq_mapping]
def mps_operation_from_gate_operation( gate_operation: cirq.GateOperation, qudit_to_index_map: Dict[cirq.Qid, int]) -> MPSOperation: """Constructs an MPS Operation from a gate operation. Args: gate_operation: A valid cirq.GateOperation or any child class. qudit_to_index_map: Dictionary to map qubits to MPS indices. Raises: CannotConvertToMPSOperation If the gate operation does not have a _unitary_ method. """ num_qudits = len(gate_operation.qubits) qudit_dimension = 2 # TODO: Check if all Cirq ops are qubit ops qudit_indices = tuple( [qudit_to_index_map[qudit] for qudit in gate_operation.qubits]) if not gate_operation._has_unitary_(): raise CannotConvertToMPSOperation( f"Cannot convert operation {gate_operation} into an MPS Operation" " because the operation does not have a unitary.") tensor = gate_operation._unitary_() tensor = np.reshape(tensor, newshape=[qudit_dimension] * 2 * num_qudits) node = tn.Node(tensor) return MPSOperation(node, qudit_indices, qudit_dimension)
def solve(self): """Use the super().solve(...) and output result in Cirq Returns: circuit: result in Cirq Circuit object final__cirq_mapping: from input Cirq qubit to Cirq qubit objective_value: depth/#swap/fidelity depending on setting Note: final_mapping (returned by super().solve(...)): logical qubit index |-> physical qubit index map_to_physical_qubit: qubit index |-> Cirq qubit So the final mapping should be m(i) |-> m(f(i)) """ (result_depth, list_scheduled_gate_name, list_scheduled_gate_qubits, final_mapping, objective_value) = super().solve(output_mode="IR") # constructing the output Cirq Circuit object circuit = Circuit() for t in range(result_depth): moment_with_swap = [] for i, qubits in enumerate(list_scheduled_gate_qubits[t]): if len(qubits) == 1: moment_with_swap.append( GateOperation( list_scheduled_gate_name[t][i], (self.map_to_physical_qubit[qubits[0]], ))) else: if list_scheduled_gate_name[t][i] == "SWAP": moment_with_swap.append( GateOperation( SWAP, (self.map_to_physical_qubit[qubits[0]], self.map_to_physical_qubit[qubits[1]]))) else: op_tmp = list_scheduled_gate_name[t][i] if list_scheduled_gate_name[t][i] == "cx": op_tmp = CNOT moment_with_swap.append( GateOperation( op_tmp, (self.map_to_physical_qubit[qubits[0]], self.map_to_physical_qubit[qubits[1]]))) circuit.append(moment_with_swap) final_cirq_mapping = dict() for i in range(self.count_program_qubit): final_cirq_mapping[ self.map_to_physical_qubit[i] ] = \ self.map_to_physical_qubit[ final_mapping[i] ] return [circuit, final_cirq_mapping, objective_value]
def test_maps_cz_gate(qubit_1, qubit_2): operation = GateOperation(CZPowGate(), [qubit_1, qubit_2]) mapped = map_operation(operation) expected = Instruction(name='cz', qubits=[str(qubit_1), str(qubit_2)], args={}) assert expected == mapped
def test_maps_to_phased_rx(qubit_1, gate, expected_angle, expected_phase): operation = GateOperation(gate, [qubit_1]) mapped = map_operation(operation) assert mapped.name == 'phased_rx' assert mapped.qubits == [str(qubit_1)] # The unit for angle and phase is full turns assert mapped.args['angle_t'] == expected_angle assert mapped.args['phase_t'] == expected_phase
def test_maps_measurement_gate(qubit_1): key = 'test measurement' operation = GateOperation(MeasurementGate(1, key), [qubit_1]) mapped = map_operation(operation) expected = Instruction(name='measurement', qubits=[str(qubit_1)], args={'key': key}) assert expected == mapped
def test_raises_error_for_non_trivial_invert_mask(qubit_1, qubit_2): operation = GateOperation( MeasurementGate(2, 'measurement key', invert_mask=(True, False)), [qubit_1, qubit_2]) with pytest.raises(OperationNotSupportedError): map_operation(operation)
def test_raises_error_for_general_cz_pow_gate(qubit_1, qubit_2): operation = GateOperation(CZPowGate(exponent=0.5), [qubit_1, qubit_2]) with pytest.raises(OperationNotSupportedError): map_operation(operation)
def test_raises_error_for_unsupported_operation(qubit_1): operation = GateOperation(ZPowGate(), [qubit_1]) with pytest.raises(OperationNotSupportedError): map_operation(operation)