def test_default_pass_manager_two(self): """Test default_pass_manager.run(circuitS). circuit1 and circuit2: qr0:-[H]--.------------ -> 1 | qr1:-----(+)--.-------- -> 2 | qr2:---------(+)--.---- -> 3 | qr3:-------------(+)--- -> 5 device: 0 - 1 - 2 - 3 - 4 - 5 - 6 | | | | | | 13 - 12 - 11 - 10 - 9 - 8 - 7 """ qr = QuantumRegister(4, 'qr') circuit1 = QuantumCircuit(qr) circuit1.h(qr[0]) circuit1.cx(qr[0], qr[1]) circuit1.cx(qr[1], qr[2]) circuit1.cx(qr[2], qr[3]) circuit2 = QuantumCircuit(qr) circuit2.cx(qr[1], qr[2]) circuit2.cx(qr[0], qr[1]) circuit2.cx(qr[2], qr[3]) coupling_map = FakeMelbourne().configuration().coupling_map basis_gates = FakeMelbourne().configuration().basis_gates initial_layout = [None, qr[0], qr[1], qr[2], None, qr[3]] pass_manager = level_1_pass_manager( PassManagerConfig( basis_gates=basis_gates, coupling_map=CouplingMap(coupling_map), initial_layout=Layout.from_qubit_list(initial_layout), seed_transpiler=42)) new_circuits = pass_manager.run([circuit1, circuit2]) for new_circuit in new_circuits: for gate, qargs, _ in new_circuit.data: if isinstance(gate, CXGate): self.assertIn([x.index for x in qargs], coupling_map)
def test_two_qubit_synthesis_to_directional_cx_from_coupling_map_natural_false( self): """Verify natural cx direction is used when specified in coupling map when natural_direction is None.""" # TODO: should make check more explicit e.g. explicitly set gate # direction in test instead of using specific fake backend backend = FakeVigo() conf = backend.configuration() qr = QuantumRegister(2) coupling_map = CouplingMap([[0, 1], [1, 2], [1, 3], [3, 4]]) triv_layout_pass = TrivialLayout(coupling_map) qc = QuantumCircuit(qr) qc.unitary(random_unitary(4, seed=12), [0, 1]) unisynth_pass = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=False, ) pm = PassManager([triv_layout_pass, unisynth_pass]) qc_out = pm.run(qc) unisynth_pass_nat = UnitarySynthesis( basis_gates=conf.basis_gates, coupling_map=coupling_map, backend_props=backend.properties(), pulse_optimize=True, natural_direction=False, ) pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat]) qc_out_nat = pm_nat.run(qc) # the decomposer defaults to the [1, 0] direction but the coupling # map specifies a [0, 1] direction. Check that this is respected. self.assertTrue( all( # pylint: disable=no-member ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out.get_instructions("cx")))) self.assertTrue( all( # pylint: disable=no-member ([qr[1], qr[0]] == qlist for _, qlist, _ in qc_out_nat.get_instructions("cx")))) self.assertEqual(Operator(qc), Operator(qc_out)) self.assertEqual(Operator(qc), Operator(qc_out_nat))
def test_default_pass_manager_single(self): """Test default_pass_manager.run(circuit). circuit: qr0:-[H]--.------------ -> 1 | qr1:-----(+)--.-------- -> 2 | qr2:---------(+)--.---- -> 3 | qr3:-------------(+)--- -> 5 device: 0 - 1 - 2 - 3 - 4 - 5 - 6 | | | | | | 13 - 12 - 11 - 10 - 9 - 8 - 7 """ qr = QuantumRegister(4, "qr") circuit = QuantumCircuit(qr) circuit.h(qr[0]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[1], qr[2]) circuit.cx(qr[2], qr[3]) coupling_map = FakeMelbourne().configuration().coupling_map basis_gates = FakeMelbourne().configuration().basis_gates initial_layout = [None, qr[0], qr[1], qr[2], None, qr[3]] pass_manager = level_1_pass_manager( PassManagerConfig( basis_gates=basis_gates, coupling_map=CouplingMap(coupling_map), initial_layout=Layout.from_qubit_list(initial_layout), seed_transpiler=42, )) new_circuit = pass_manager.run(circuit) bit_indices = { bit: idx for idx, bit in enumerate(new_circuit.qregs[0]) } for gate, qargs, _ in new_circuit.data: if isinstance(gate, CXGate): self.assertIn([bit_indices[x] for x in qargs], coupling_map)
def test_do_not_run_cxdirection_with_symmetric_cm(self): """When the coupling map is symmetric, do not run CXDirection.""" circ = QuantumCircuit.from_qasm_file( self._get_resource_path('example.qasm', Path.QASMS)) layout = Layout.generate_trivial_layout(*circ.qregs) coupling_map = [] for node1, node2 in FakeRueschlikon().configuration().coupling_map: coupling_map.append([node1, node2]) coupling_map.append([node2, node1]) cxdir_pass = CXDirection(CouplingMap(coupling_map)) with unittest.mock.patch.object(CXDirection, 'run', wraps=cxdir_pass.run) as mock_pass: transpile(circ, coupling_map=coupling_map, initial_layout=layout) self.assertFalse(mock_pass.called)
def test_len_coupling_vs_dag(self): """Test error if coupling map and dag are not the same size.""" coupling = CouplingMap([[0, 1], [1, 2], [2, 3], [3, 4]]) qr = QuantumRegister(4, 'q') cr = ClassicalRegister(4, 'c') circuit = QuantumCircuit(qr, cr) circuit.h(qr[0]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[2]) circuit.cx(qr[0], qr[3]) circuit.measure(qr, cr) dag = circuit_to_dag(circuit) pass_ = StochasticSwap(coupling) with self.assertRaises(TranspilerError): _ = pass_.run(dag)
def test_ignore_initial_layout(self): """Ignoring initial layout even when it is supplied""" coupling = CouplingMap([[0, 1], [0, 2]]) circuit = QuantumCircuit(3) circuit.cx(1, 2) property_set = { "layout": Layout.generate_trivial_layout(*circuit.qubits) } actual = BIPMapping(coupling)(circuit, property_set) q = QuantumRegister(3, name="q") expected = QuantumCircuit(q) expected.cx(q[0], q[1]) self.assertEqual(expected, actual)
def test_lookahead_swap_hang_in_min_case(self): """Verify LookaheadSwap does not stall in minimal case.""" # ref: https://github.com/Qiskit/qiskit-terra/issues/2171 qr = QuantumRegister(14, "q") qc = QuantumCircuit(qr) qc.cx(qr[0], qr[13]) qc.cx(qr[1], qr[13]) qc.cx(qr[1], qr[0]) qc.cx(qr[13], qr[1]) dag = circuit_to_dag(qc) cmap = CouplingMap(FakeMelbourne().configuration().coupling_map) out = LookaheadSwap(cmap, search_depth=4, search_width=4).run(dag) self.assertIsInstance(out, DAGCircuit)
def test_heavy_hex_factory_bidirectional(self): coupling = CouplingMap.from_heavy_hex(3, bidirectional=True) edges = coupling.get_edges() expected = [ (0, 9), (0, 13), (1, 13), (1, 14), (2, 14), (3, 9), (3, 15), (4, 15), (4, 16), (5, 12), (5, 16), (6, 17), (7, 17), (7, 18), (8, 12), (8, 18), (9, 0), (9, 3), (10, 14), (10, 16), (11, 15), (11, 17), (12, 5), (12, 8), (13, 0), (13, 1), (14, 1), (14, 2), (14, 10), (15, 3), (15, 4), (15, 11), (16, 4), (16, 5), (16, 10), (17, 6), (17, 7), (17, 11), (18, 7), (18, 8), ] self.assertEqual(set(edges), set(expected))
def test_global_phase_preservation(self): """Test that LookaheadSwap preserves global phase""" qr = QuantumRegister(3, "q") circuit = QuantumCircuit(qr) circuit.global_phase = pi / 3 circuit.cx(qr[0], qr[2]) dag_circuit = circuit_to_dag(circuit) coupling_map = CouplingMap([[0, 1], [1, 2]]) mapped_dag = LookaheadSwap(coupling_map).run(dag_circuit) self.assertEqual(mapped_dag.global_phase, circuit.global_phase) self.assertEqual( mapped_dag.count_ops().get("swap", 0), dag_circuit.count_ops().get("swap", 0) + 1 )
def test_never_modify_mapped_circuit(self): """Test that the mapping is idempotent. It should not modify a circuit which is already compatible with the coupling map, and can be applied repeatedly without modifying the circuit. """ coupling = CouplingMap([[0, 1], [0, 2]]) circuit = QuantumCircuit(3, 2) circuit.cx(1, 2) circuit.measure(1, 0) circuit.measure(2, 1) dag = circuit_to_dag(circuit) mapped_dag = BIPMapping(coupling).run(dag) remapped_dag = BIPMapping(coupling).run(mapped_dag) self.assertEqual(mapped_dag, remapped_dag)
def test_3q_circuit_3q_coupling_non_induced(self): """A simple example, check for non-induced subgraph 1 qr0 -> qr1 -> qr2 / \ 0 - 2 """ cmap = CouplingMap([[0, 1], [1, 2], [2, 0]]) qr = QuantumRegister(3, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) # qr0-> qr1 circuit.cx(qr[1], qr[2]) # qr1-> qr2 dag = circuit_to_dag(circuit) pass_ = VF2Layout(cmap, seed=-1, max_trials=1) pass_.run(dag) self.assertLayout(dag, cmap, pass_.property_set)
def test_do_not_run_gatedirection_with_symmetric_cm(self): """When the coupling map is symmetric, do not run GateDirection.""" qasm_dir = os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'qasm') circ = QuantumCircuit.from_qasm_file( os.path.join(qasm_dir, 'example.qasm')) layout = Layout.generate_trivial_layout(*circ.qregs) coupling_map = [] for node1, node2 in FakeRueschlikon().configuration().coupling_map: coupling_map.append([node1, node2]) coupling_map.append([node2, node1]) orig_pass = GateDirection(CouplingMap(coupling_map)) with patch.object(GateDirection, 'run', wraps=orig_pass.run) as mock_pass: transpile(circ, coupling_map=coupling_map, initial_layout=layout) self.assertFalse(mock_pass.called)
def test_len_cm_vs_dag(self): """Test error if the coupling map is smaller than the dag.""" coupling = CouplingMap([[0, 1], [1, 2]]) qr = QuantumRegister(4, 'q') cr = ClassicalRegister(4, 'c') circuit = QuantumCircuit(qr, cr) circuit.h(qr[0]) circuit.cx(qr[0], qr[1]) circuit.cx(qr[0], qr[2]) circuit.cx(qr[0], qr[3]) circuit.measure(qr, cr) dag = circuit_to_dag(circuit) pass_ = StochasticSwap(coupling) with self.assertRaises(TranspilerError): _ = pass_.run(dag)
def test_2q_circuit_2q_coupling(self): """ A simple example, without considering the direction 0 - 1 qr0 - qr1 """ qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.cx(qr[1], qr[0]) # qr1 -> qr0 dag = circuit_to_dag(circuit) pass_ = CSPLayout(CouplingMap([[0, 1]]), strict_direction=False, seed=self.seed) pass_.run(dag) layout = pass_.property_set['layout'] self.assertEqual(layout[qr[0]], 0) self.assertEqual(layout[qr[1]], 1) self.assertEqual(pass_.property_set['CSPLayout_stop_reason'], 'solution found')
def _parse_coupling_map(coupling_map, backend, num_circuits): # try getting coupling_map from user, else backend if coupling_map is None: backend_version = getattr(backend, "version", 0) if not isinstance(backend_version, int): backend_version = 0 if backend_version <= 1: if getattr(backend, "configuration", None): configuration = backend.configuration() if hasattr(configuration, "coupling_map") and configuration.coupling_map: faulty_map = _create_faulty_qubits_map(backend) if faulty_map: faulty_edges = [gate.qubits for gate in backend.properties().faulty_gates()] functional_gates = [ edge for edge in configuration.coupling_map if edge not in faulty_edges ] coupling_map = CouplingMap() for qubit1, qubit2 in functional_gates: if faulty_map[qubit1] is not None and faulty_map[qubit2] is not None: coupling_map.add_edge(faulty_map[qubit1], faulty_map[qubit2]) if configuration.n_qubits != coupling_map.size(): warnings.warn( "The backend has currently some qubits/edges out of service." " This temporarily reduces the backend size from " f"{configuration.n_qubits} to {coupling_map.size()}", UserWarning, ) else: coupling_map = CouplingMap(configuration.coupling_map) else: coupling_map = backend.coupling_map # coupling_map could be None, or a list of lists, e.g. [[0, 1], [2, 1]] if coupling_map is None or isinstance(coupling_map, CouplingMap): coupling_map = [coupling_map] * num_circuits elif isinstance(coupling_map, list) and all( isinstance(i, list) and len(i) == 2 for i in coupling_map ): coupling_map = [coupling_map] * num_circuits coupling_map = [CouplingMap(cm) if isinstance(cm, list) else cm for cm in coupling_map] return coupling_map
def get_device_info(token, hub, group, project, device_name, fields, datetime): dirname = './devices/%s' % datetime.date() filename = '%s/%s.pckl' % (dirname, device_name) _device_info = read_dict(filename=filename) if len(_device_info) == 0: if not os.path.exists(dirname): os.makedirs(dirname) else: subprocess.run(['rm', '-r', dirname]) os.makedirs(dirname) provider = load_IBMQ(token=token, hub=hub, group=group, project=project) for x in provider.backends(): if 'qasm' not in str(x): device = provider.get_backend(str(x)) properties = device.properties(datetime=datetime) num_qubits = len(properties.qubits) print('Download device_info for %d-qubit %s' % (num_qubits, x)) coupling_map = CouplingMap(device.configuration().coupling_map) noise_model = NoiseModel.from_backend(properties) basis_gates = noise_model.basis_gates _device_info = { 'properties': properties, 'coupling_map': coupling_map, 'noise_model': noise_model, 'basis_gates': basis_gates } pickle.dump(_device_info, open('%s/%s.pckl' % (dirname, str(x)), 'wb')) print('-' * 50) _device_info = read_dict(filename=filename) device_info = {} for field in fields: if field == 'device': provider = load_IBMQ(token=token, hub=hub, group=group, project=project) device = provider.get_backend(device_name) device_info[field] = device else: device_info[field] = _device_info[field] return device_info
def get_device_info(token, hub, group, project, device_name, fields, datetime): dirname = "./devices/%s" % datetime.date() filename = "%s/%s.pckl" % (dirname, device_name) _device_info = read_dict(filename=filename) if len(_device_info) == 0: if not os.path.exists(dirname): os.makedirs(dirname) else: subprocess.run(["rm", "-r", dirname]) os.makedirs(dirname) provider = load_IBMQ(token=token, hub=hub, group=group, project=project) for x in provider.backends(): if "simulator" not in str(x): device = provider.get_backend(str(x)) properties = device.properties(datetime=datetime) num_qubits = device.configuration().n_qubits print("Download device_info for %d-qubit %s" % (num_qubits, x)) coupling_map = CouplingMap(device.configuration().coupling_map) noise_model = NoiseModel.from_backend(device) basis_gates = device.configuration().basis_gates _device_info = { "properties": properties, "coupling_map": coupling_map, "noise_model": noise_model, "basis_gates": basis_gates, } pickle.dump(_device_info, open("%s/%s.pckl" % (dirname, str(x)), "wb")) print("-" * 50) _device_info = read_dict(filename=filename) device_info = {} for field in fields: if field == "device": provider = load_IBMQ(token=token, hub=hub, group=group, project=project) device = provider.get_backend(device_name) device_info[field] = device else: device_info[field] = _device_info[field] return device_info, filename
def test_preserves_conditions(self): """Verify CXDirection preserves conditional on CX gates. ┌───┐ ┌───┐ q_0: |0>───■────┤ X ├───■──┤ X ├ ┌─┴─┐ └─┬─┘ ┌─┴─┐└─┬─┘ q_1: |0>─┤ X ├────■───┤ X ├──■── └─┬─┘ │ └───┘ ┌──┴──┐┌──┴──┐ c_0: 0 ╡ = 0 ╞╡ = 0 ╞══════════ └─────┘└─────┘ """ qr = QuantumRegister(2, 'q') cr = ClassicalRegister(1, 'c') circuit = QuantumCircuit(qr, cr) circuit.cx(qr[0], qr[1]).c_if(cr, 0) circuit.cx(qr[1], qr[0]).c_if(cr, 0) circuit.cx(qr[0], qr[1]) circuit.cx(qr[1], qr[0]) coupling = CouplingMap([[0, 1]]) dag = circuit_to_dag(circuit) expected = QuantumCircuit(qr, cr) expected.cx(qr[0], qr[1]).c_if(cr, 0) # Ordering of u2 is important because DAG comparison will consider # different conditional order on a creg to be a different circuit. # See https://github.com/Qiskit/qiskit-terra/issues/3164 expected.append(U2Gate(0, pi), [[qr[1], qr[0]]]).c_if(cr, 0) expected.cx(qr[0], qr[1]).c_if(cr, 0) expected.append(U2Gate(0, pi), [[qr[1], qr[0]]]).c_if(cr, 0) expected.cx(qr[0], qr[1]) expected.append(U2Gate(0, pi), [[qr[1], qr[0]]]) expected.cx(qr[0], qr[1]) expected.append(U2Gate(0, pi), [[qr[1], qr[0]]]) pass_ = CXDirection(coupling) after = pass_.run(dag) self.assertEqual(circuit_to_dag(expected), after)
def test_single_gates_omitted(self): """Test if single qubit gates are omitted.""" coupling_map = [[0, 1], [1, 0], [1, 2], [1, 3], [2, 1], [3, 1], [3, 4], [4, 3]] # q_0: ──■────────────────── # │ # q_1: ──┼─────────■──────── # │ ┌─┴─┐ # q_2: ──┼───────┤ X ├────── # │ ┌────┴───┴─────┐ # q_3: ──┼──┤ U(1,1.5,0.7) ├ # ┌─┴─┐└──────────────┘ # q_4: ┤ X ├──────────────── # └───┘ qr = QuantumRegister(5, "q") cr = ClassicalRegister(5, "c") circuit = QuantumCircuit(qr, cr) circuit.cx(qr[0], qr[4]) circuit.cx(qr[1], qr[2]) circuit.u(1, 1.5, 0.7, qr[3]) # q_0: ─────────────────X────── # │ # q_1: ───────■─────────X───■── # ┌─┴─┐ │ # q_2: ─────┤ X ├───────────┼── # ┌────┴───┴─────┐ ┌─┴─┐ # q_3: ┤ U(1,1.5,0.7) ├─X─┤ X ├ # └──────────────┘ │ └───┘ # q_4: ─────────────────X────── expected = QuantumCircuit(qr, cr) expected.cx(qr[1], qr[2]) expected.u(1, 1.5, 0.7, qr[3]) expected.swap(qr[0], qr[1]) expected.swap(qr[3], qr[4]) expected.cx(qr[1], qr[3]) expected_dag = circuit_to_dag(expected) stochastic = StochasticSwap(CouplingMap(coupling_map), seed=0) after = PassManager(stochastic).run(circuit) after = circuit_to_dag(after) self.assertEqual(expected_dag, after)
def test_2q_circuit_2q_coupling_sd(self): """A simple example, considering the direction 0 -> 1 qr1 -> qr0 """ cmap = CouplingMap([[0, 1]]) qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[1], qr[0]) # qr1 -> qr0 dag = circuit_to_dag(circuit) pass_ = VF2Layout(cmap, strict_direction=True, seed=self.seed, max_trials=1) pass_.run(dag) self.assertLayout(dag, cmap, pass_.property_set, strict_direction=True)
def test_lookahead_swap_should_add_a_single_swap(self): """Test that LookaheadSwap will insert a SWAP to match layout. For a single cx gate which is not available in the current layout, test that the mapper inserts a single swap to enable the gate. """ qr = QuantumRegister(3, 'q') circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[2]) dag_circuit = circuit_to_dag(circuit) coupling_map = CouplingMap([[0, 1], [1, 2]]) mapped_dag = LookaheadSwap(coupling_map).run(dag_circuit) self.assertEqual(mapped_dag.count_ops().get('swap', 0), dag_circuit.count_ops().get('swap', 0) + 1)
def test_wrongly_mapped(self): """Needs [0]-[1] in a [0]--[2]--[1] qr0:--(+)-- | qr1:---.--- CouplingMap map: [0]->[2]->[1] """ qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) coupling = CouplingMap([[0, 2], [2, 1]]) dag = circuit_to_dag(circuit) pass_ = CheckGateDirection(coupling) pass_.run(dag) self.assertFalse(pass_.property_set["is_direction_mapped"])
def test_direction_correct(self): """The CX is in the right direction qr0:---(+)--- | qr1:----.---- CouplingMap map: [0] -> [1] """ qr = QuantumRegister(2, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) coupling = CouplingMap([[0, 1]]) dag = circuit_to_dag(circuit) pass_ = GateDirection(coupling) after = pass_.run(dag) self.assertEqual(dag, after)
def test_2q_barrier(self): """ A 2q barrier should be ignored qr0:--|-- | qr1:--|-- CouplingMap map: None """ qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.barrier(qr[0], qr[1]) coupling = CouplingMap() dag = circuit_to_dag(circuit) pass_ = CheckGateDirection(coupling) pass_.run(dag) self.assertTrue(pass_.property_set['is_direction_mapped'])
def test_1(self, circuit, level): """Simple coupling map (linear 5 qubits).""" basis = ["u1", "u2", "cx", "swap"] coupling_map = CouplingMap([(0, 1), (1, 2), (2, 3), (3, 4)]) result = transpile( circuit(), optimization_level=level, basis_gates=basis, coupling_map=coupling_map, seed_transpiler=42, initial_layout=[0, 1, 2, 3, 4], ) self.assertIsInstance(result, QuantumCircuit) resulting_basis = { node.name for node in circuit_to_dag(result).op_nodes() } self.assertIn("swap", resulting_basis)
def test_full_factory(self): coupling = CouplingMap.from_full(4) edges = coupling.get_edges() expected = [ (0, 1), (0, 2), (0, 3), (1, 0), (1, 2), (1, 3), (2, 0), (2, 1), (2, 3), (3, 0), (3, 1), (3, 2), ] self.assertEqual(set(edges), set(expected))
def test_swap_mapped_false(self): """ Needs [0]-[1] in a [0]--[2]--[1] qr0:--(+)-- | qr1:---.--- CouplingMap map: [0]--[2]--[1] """ qr = QuantumRegister(2, 'qr') circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) coupling = CouplingMap([[0, 2], [2, 1]]) dag = circuit_to_dag(circuit) pass_ = CheckMap(coupling) pass_.run(dag) self.assertFalse(pass_.property_set['is_swap_mapped'])
def test_coupling_map_and_target(self): """Test that a Target is used instead of a CouplingMap if both are specified.""" cmap = CouplingMap([[0, 1], [1, 2]]) target = Target() target.add_instruction(CXGate(), { (0, 1): None, (1, 2): None, (1, 0): None }) qr = QuantumRegister(3, "qr") circuit = QuantumCircuit(qr) circuit.cx(qr[0], qr[1]) # qr0-> qr1 circuit.cx(qr[1], qr[2]) # qr1-> qr2 circuit.cx(qr[1], qr[0]) # qr1-> qr0 dag = circuit_to_dag(circuit) pass_ = VF2Layout(cmap, seed=-1, max_trials=1, target=target) pass_.run(dag) self.assertLayout(dag, target.build_coupling_map(), pass_.property_set)
def test_qubit_subset(self): """Test if `qubit_subset` option works as expected.""" circuit = QuantumCircuit(3) circuit.cx(0, 1) circuit.cx(1, 2) circuit.cx(0, 2) coupling = CouplingMap([(0, 1), (1, 3), (3, 2)]) qubit_subset = [0, 1, 3] actual = BIPMapping(coupling, qubit_subset=qubit_subset)(circuit) # all used qubits are in qubit_subset bit_indices = {bit: index for index, bit in enumerate(actual.qubits)} for _, qargs, _ in actual.data: for q in qargs: self.assertTrue(bit_indices[q] in qubit_subset) # ancilla qubits are set in the resulting qubit idle = QuantumRegister(1, name="ancilla") self.assertEqual(idle[0], actual._layout[2])
def test_trivial_nop_map(self): """ Trivial map in a circuit without entanglement qr0:---[H]--- qr1:---[H]--- qr2:---[H]--- CouplingMap map: None """ qr = QuantumRegister(3, 'qr') circuit = QuantumCircuit(qr) circuit.h(qr) coupling = CouplingMap() dag = circuit_to_dag(circuit) pass_ = CheckMap(coupling) pass_.run(dag) self.assertTrue(pass_.property_set['is_swap_mapped'])