class ExecutePassManager(QiskitTestCase): pm_conf = PassManagerConfig(initial_layout=None, basis_gates=['u1', 'u2', 'u3', 'cx', 'id'], coupling_map=CouplingMap([(0, 1), (1, 2), (2, 3), (3, 4)]), backend_properties=None, seed_transpiler=1) backend = Aer.get_backend('qasm_simulator') shots = 2048 def assertEqualCounts(self, result, expected): result_count = result.get_counts() expected_count = expected.get_counts() for key in set(result_count.keys()).union(expected_count.keys()): with self.subTest(key=key): diff = abs( result_count.get(key, 0) - expected_count.get(key, 0)) self.assertLess(diff / self.shots * 100, 2.5) def execute(self, circuit): return execute(circuit, self.backend, basis_gates=['u1', 'u2', 'u3', 'id', 'cx'], seed_simulator=0, seed_transpiler=0, shots=self.shots)
def from_backend(cls, backend, **pass_manager_options): """Construct a configuration based on a backend and user input. This method automatically gererates a PassManagerConfig object based on the backend's features. User options can be used to overwrite the configuration. Args: backend (BackendV1): The backend that provides the configuration. pass_manager_options: User-defined option-value pairs. Returns: PassManagerConfig: The configuration generated based on the arguments. Raises: AttributeError: If the backend does not support a `configuration()` method. """ res = cls(**pass_manager_options) config = backend.configuration() if res.basis_gates is None: res.basis_gates = getattr(config, "basis_gates", None) if res.inst_map is None and hasattr(backend, "defaults"): res.inst_map = backend.defaults().instruction_schedule_map if res.coupling_map is None: res.coupling_map = CouplingMap( getattr(config, "coupling_map", None)) if res.instruction_durations is None: res.instruction_durations = InstructionDurations.from_backend( backend) if res.backend_properties is None: res.backend_properties = backend.properties() return res
def load_coupling_graph(coupling_graph_file_path): coupling_graph = CouplingMap() with open(coupling_graph_file_path, newline='') as coupling_graph_file: csv_reader = csv.reader(coupling_graph_file) for source_qubit, destination_qubit in csv_reader: coupling_graph.add_edge(int(source_qubit), int(destination_qubit)) return coupling_graph
def test_coupling_map(self): self.assertEqual( CouplingMap().get_edges(), self.empty_target.build_coupling_map().get_edges() ) self.assertEqual( set(CouplingMap.from_full(5).get_edges()), set(self.aqt_target.build_coupling_map().get_edges()), ) self.assertEqual( {(0, 1), (1, 0)}, set(self.fake_backend_target.build_coupling_map().get_edges()) ) self.assertEqual( { (3, 4), (4, 3), (3, 1), (1, 3), (1, 2), (2, 1), (0, 1), (1, 0), }, set(self.ibm_target.build_coupling_map().get_edges()), ) self.assertEqual(None, self.ideal_sim_target.build_coupling_map())
def pm_config(seed, backend): return PassManagerConfig(initial_layout=None, basis_gates=['u1', 'u2', 'u3', 'cx', 'id'], coupling_map=CouplingMap( backend().configuration().coupling_map), backend_properties=backend().properties(), seed_transpiler=seed)
def build_coupling_map(self, two_q_gate=None): """Get a :class:`~qiskit.transpiler.CouplingMap` from this target. Args: two_q_gate (str): An optional gate name for a two qubit gate in the Target to generate the coupling map for. If specified the output coupling map will only have edges between qubits where this gate is present. Returns: CouplingMap: The :class:`~qiskit.transpiler.CouplingMap` object for this target. Raises: ValueError: If a non-two qubit gate is passed in for ``two_q_gate``. IndexError: If an Instruction not in the Target is passed in for ``two_q_gate``. """ if None in self._qarg_gate_map: return None if any(len(x) > 2 for x in self.qargs): logger.warning( "This Target object contains multiqubit gates that " "operate on > 2 qubits. This will not be reflected in " "the output coupling map.") if two_q_gate is not None: coupling_graph = rx.PyDiGraph(multigraph=False) coupling_graph.add_nodes_from( list(None for _ in range(self.num_qubits))) for qargs, properties in self._gate_map[two_q_gate].items(): if len(qargs) != 2: raise ValueError( "Specified two_q_gate: %s is not a 2 qubit instruction" % two_q_gate) coupling_graph.add_edge(*qargs, {two_q_gate: properties}) cmap = CouplingMap() cmap.graph = coupling_graph return cmap if self._coupling_graph is None: self._build_coupling_graph() cmap = CouplingMap() cmap.graph = self._coupling_graph return cmap
def test_config_from_backend(self): """Test from_backend() with a valid backend. `FakeAlmaden` is used in this testcase. This backend has `defaults` attribute that contains an instruction schedule map. """ backend = FakeAlmaden() config = PassManagerConfig.from_backend(backend) self.assertEqual(config.basis_gates, backend.configuration().basis_gates) self.assertEqual(config.inst_map, backend.defaults().instruction_schedule_map) self.assertEqual( str(config.coupling_map), str(CouplingMap(backend.configuration().coupling_map)))
def test_from_backend_and_user(self): """Test from_backend() with a backend and user options. `FakeMelbourne` is used in this testcase. This backend does not have `defaults` attribute and thus not provide an instruction schedule map. """ qr = QuantumRegister(4, "qr") initial_layout = [None, qr[0], qr[1], qr[2], None, qr[3]] backend = FakeMelbourne() config = PassManagerConfig.from_backend(backend, basis_gates=["user_gate"], initial_layout=initial_layout) self.assertEqual(config.basis_gates, ["user_gate"]) self.assertNotEqual(config.basis_gates, backend.configuration().basis_gates) self.assertIsNone(config.inst_map) self.assertEqual( str(config.coupling_map), str(CouplingMap(backend.configuration().coupling_map))) self.assertEqual(config.initial_layout, initial_layout)
def CouplingMap(couplinglist=None): warnings.warn( 'qiskit.mapper.CouplingMap has moved to ' 'qiskit.transpiler.CouplingMap.', DeprecationWarning) from qiskit.transpiler.coupling import CouplingMap return CouplingMap(couplinglist)
def plot_gate_map( backend, figsize=None, plot_directed=False, label_qubits=True, qubit_size=None, line_width=4, font_size=None, qubit_color=None, qubit_labels=None, line_color=None, font_color="w", ax=None, filename=None, qubit_coordinates=None, ): """Plots the gate map of a device. Args: backend (Backend): The backend instance that will be used to plot the device gate map. figsize (tuple): Output figure size (wxh) in inches. plot_directed (bool): Plot directed coupling map. label_qubits (bool): Label the qubits. qubit_size (float): Size of qubit marker. line_width (float): Width of lines. font_size (int): Font size of qubit labels. qubit_color (list): A list of colors for the qubits qubit_labels (list): A list of qubit labels line_color (list): A list of colors for each line from coupling_map. font_color (str): The font color for the qubit labels. ax (Axes): A Matplotlib axes instance. filename (str): file path to save image to. qubit_coordinates (Sequence): An optional sequence input (list or array being the most common) of 2d coordinates for each qubit. The length of the sequence much match the number of qubits on the backend. The sequence should be the planar coordinates in a 0-based square grid where each qubit is located. Returns: Figure: A Matplotlib figure instance. Raises: QiskitError: if tried to pass a simulator, or if the backend is None, but one of num_qubits, mpl_data, or cmap is None. MissingOptionalLibraryError: if matplotlib not installed. Example: .. jupyter-execute:: :hide-code: :hide-output: from qiskit.test.ibmq_mock import mock_get_backend mock_get_backend('FakeVigo') .. jupyter-execute:: from qiskit import QuantumCircuit, execute, IBMQ from qiskit.visualization import plot_gate_map %matplotlib inline provider = IBMQ.load_account() accountProvider = IBMQ.get_provider(hub='ibm-q') backend = accountProvider.get_backend('ibmq_vigo') plot_gate_map(backend) """ qubit_coordinates_map = {} qubit_coordinates_map[1] = [[0, 0]] qubit_coordinates_map[5] = [[1, 0], [0, 1], [1, 1], [1, 2], [2, 1]] qubit_coordinates_map[7] = [[0, 0], [0, 1], [0, 2], [1, 1], [2, 0], [2, 1], [2, 2]] qubit_coordinates_map[20] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], ] qubit_coordinates_map[15] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 7], [1, 6], [1, 5], [1, 4], [1, 3], [1, 2], [1, 1], [1, 0], ] qubit_coordinates_map[16] = [ [1, 0], [1, 1], [2, 1], [3, 1], [1, 2], [3, 2], [0, 3], [1, 3], [3, 3], [4, 3], [1, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6], ] qubit_coordinates_map[27] = [ [1, 0], [1, 1], [2, 1], [3, 1], [1, 2], [3, 2], [0, 3], [1, 3], [3, 3], [4, 3], [1, 4], [3, 4], [1, 5], [2, 5], [3, 5], [1, 6], [3, 6], [0, 7], [1, 7], [3, 7], [4, 7], [1, 8], [3, 8], [1, 9], [2, 9], [3, 9], [3, 10], ] qubit_coordinates_map[28] = [ [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 2], [1, 6], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [3, 0], [3, 4], [3, 8], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], ] qubit_coordinates_map[53] = [ [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [1, 2], [1, 6], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [3, 0], [3, 4], [3, 8], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [5, 2], [5, 6], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [7, 0], [7, 4], [7, 8], [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [9, 2], [9, 6], ] qubit_coordinates_map[65] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [1, 0], [1, 4], [1, 8], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [3, 2], [3, 6], [3, 10], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [5, 0], [5, 4], [5, 8], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [7, 2], [7, 6], [7, 10], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [8, 9], [8, 10], ] qubit_coordinates_map[127] = [ [0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10], [0, 11], [0, 12], [0, 13], [1, 0], [1, 4], [1, 8], [1, 12], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [2, 10], [2, 11], [2, 12], [2, 13], [2, 14], [3, 2], [3, 6], [3, 10], [3, 14], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [4, 10], [4, 11], [4, 12], [4, 13], [4, 14], [5, 0], [5, 4], [5, 8], [5, 12], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [6, 10], [6, 11], [6, 12], [6, 13], [6, 14], [7, 2], [7, 6], [7, 10], [7, 14], [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [8, 9], [8, 10], [8, 11], [8, 12], [8, 13], [8, 14], [9, 0], [9, 4], [9, 8], [9, 12], [10, 0], [10, 1], [10, 2], [10, 3], [10, 4], [10, 5], [10, 6], [10, 7], [10, 8], [10, 9], [10, 10], [10, 11], [10, 12], [10, 13], [10, 14], [11, 2], [11, 6], [11, 10], [11, 14], [12, 1], [12, 2], [12, 3], [12, 4], [12, 5], [12, 6], [12, 7], [12, 8], [12, 9], [12, 10], [12, 11], [12, 12], [12, 13], [12, 14], ] backend_version = _get_backend_interface_version(backend) if backend_version <= 1: from qiskit.transpiler.coupling import CouplingMap if backend.configuration().simulator: raise QiskitError("Requires a device backend, not simulator.") config = backend.configuration() num_qubits = config.n_qubits coupling_map = CouplingMap(config.coupling_map) name = backend.name() else: num_qubits = backend.num_qubits coupling_map = backend.coupling_map name = backend.name if qubit_coordinates is None and ("ibm" in name or "fake" in name): qubit_coordinates = qubit_coordinates_map.get(num_qubits, None) if qubit_coordinates is None: # Replace with planar_layout() when retworkx offers it qubit_coordinates_rx = rx.spring_layout(coupling_map.graph, seed=1234) scaling_factor = 10**int(math.log10(num_qubits) + 1) qubit_coordinates = [( int(scaling_factor * qubit_coordinates_rx[i][0]), int(scaling_factor * qubit_coordinates_rx[i][1]), ) for i in range(num_qubits)] if any(x[0] < 0 or x[1] < 0 for x in qubit_coordinates): min_entry = min(qubit_coordinates, key=lambda x: min(x[0], x[1])) negative_offset = 0 - min(min_entry) qubit_coordinates = [(x[0] + negative_offset, x[1] + negative_offset) for x in qubit_coordinates] if len(qubit_coordinates) != num_qubits: raise QiskitError( f"The number of specified qubit coordinates {len(qubit_coordinates)} " f"does not match the device number of qubits: {num_qubits}") return plot_coupling_map( num_qubits, qubit_coordinates, coupling_map.get_edges(), figsize, plot_directed, label_qubits, qubit_size, line_width, font_size, qubit_color, qubit_labels, line_color, font_color, ax, filename, )
def random_circuit(n_qubits, depth, coupling_map=None, basis_gates=None, prob_one_q_op=0.5, reset=False, seed=None): """Generate RQC faithfully according to the given coupling_map and basis_gates. Args: n_qubits (int): the number of qubits, must > largest qubit label in coupling_map depth (int): the number of the layers of operations coupling_map (CouplingMap or list): coupling map specifies allowed CNOTs default: fully connected graph coupling n_qubits basis_gates (list): the list of labels of basis gates used in construction default: all available gates in gate_set prob_one_q_op (float): the probability of selecting a one-qubit operation when two_q_op is allowed default: equal probability 0.5 reset (bool): if True, insert middle resets seed (int): sets random seed (optional) Returns: QuantumCircuit: constructed circuit Raises: CircuitError: when invalid options given """ max_operands = 2 assert max_operands == 2 if isinstance(coupling_map, list): coupling_map = CouplingMap(coupling_map) if coupling_map != None and n_qubits < max( coupling_map.physical_qubits) + 1: raise CircuitError("n_qubits is not enough to accomodate CouplingMap") if basis_gates == None: basis_gates = gate_set one_q_ops = [ label2gate[name] for name in one_q_ops_label & set(basis_gates) ] two_q_ops = [ label2gate[name] for name in two_q_ops_label & set(basis_gates) ] one_param = [ label2gate[name] for name in one_param_label & set(basis_gates) ] two_param = [ label2gate[name] for name in two_param_label & set(basis_gates) ] three_param = [ label2gate[name] for name in three_param_label & set(basis_gates) ] if len(one_q_ops) == 0: raise CircuitError("no available one-qubit gate") if len(two_q_ops) == 0: raise CircuitError("CNOT is not available") qreg = QuantumRegister(n_qubits, 'q') qc = QuantumCircuit(n_qubits) # default coupling_map is fully connected if coupling_map == None: coupling_map = CouplingMap.from_full(n_qubits) if reset: one_q_ops += [Reset] if seed is None: seed = np.random.randint(0, np.iinfo(np.int32).max) rng = np.random.RandomState(seed) for _ in range(depth): remaining_qubits = coupling_map.physical_qubits remaining_edges = coupling_map.get_edges() if remaining_edges: allow_two_q_op = True while remaining_qubits: if allow_two_q_op: max_possible_operands = min(len(remaining_qubits), max_operands) else: max_possible_operands = 1 if max_possible_operands == 1: possible_operands_set = [1] num_operands = 1 else: possible_operands_set = [1, 2] num_operands = (not (rng.uniform() < prob_one_q_op)) + 1 if num_operands == 1: operation = rng.choice(one_q_ops) operands = rng.choice(remaining_qubits) register_operands = [qreg[int(operands)]] operands = [operands] elif num_operands == 2: operation = rng.choice(two_q_ops) operands = remaining_edges[rng.choice( range(len(remaining_edges)))] register_operands = [qreg[i] for i in operands] remaining_qubits = [ q for q in remaining_qubits if q not in operands ] if remaining_edges: remaining_edges = [ pair for pair in remaining_edges if pair[0] not in operands and pair[1] not in operands ] if allow_two_q_op and not remaining_edges: allow_two_q_op = False if operation in one_param: num_angles = 1 elif operation in two_param: num_angles = 2 elif operation in three_param: num_angles = 3 else: num_angles = 0 angles = [rng.uniform(0, 2 * np.pi) for x in range(num_angles)] op = operation(*angles) qc.append(op, register_operands) return qc