def test_lookahead_swap_doesnt_modify_mapped_circuit(self):
        """Test that lookahead mapper 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.
        """

        qr = QuantumRegister(3, name='q')
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[2])
        circuit.cx(qr[0], qr[1])
        original_dag = circuit_to_dag(circuit)

        # Create coupling map which contains all two-qubit gates in the circuit.
        coupling_map = CouplingMap(couplinglist=[(0, 1), (0, 2)])

        pass_manager = PassManager()
        pass_manager.append(LookaheadSwap(coupling_map))
        mapped_dag = transpile_dag(original_dag, pass_manager=pass_manager)

        self.assertEqual(original_dag, mapped_dag)

        second_pass_manager = PassManager()
        second_pass_manager.append(LookaheadSwap(coupling_map))
        remapped_dag = transpile_dag(mapped_dag, pass_manager=second_pass_manager)

        self.assertEqual(mapped_dag, remapped_dag)
Example #2
0
    def test_final_measurement_barrier_for_simulators(self, mock_pass):
        """Verify BarrierBeforeFinalMeasurements pass is in default pipeline for simulators."""
        circ = QuantumCircuit.from_qasm_file(self._get_resource_path('example.qasm', Path.QASMS))
        dag_circuit = circuit_to_dag(circ)
        transpile_dag(dag_circuit)

        self.assertTrue(mock_pass.called)
    def test_final_measurement_barrier_for_devices(self, mock_pass):
        """Verify BarrierBeforeFinalMeasurements pass is called in default pipeline for devices."""

        circ = QuantumCircuit.from_qasm_file(self._get_resource_path('example.qasm', Path.QASMS))
        dag_circuit = circuit_to_dag(circ)
        transpile_dag(dag_circuit, coupling_map=FakeRueschlikon().configuration().coupling_map)

        self.assertTrue(mock_pass.called)
    def test_lookahead_swap_finds_minimal_swap_solution(self):
        """Of many valid SWAPs, test that LookaheadSwap finds the cheapest path.

        For a two CNOT circuit: cx q[0],q[2]; cx q[0],q[1]
        on the initial layout: qN -> qN
        (At least) two solutions exist:
        - SWAP q[0],[1], cx q[0],q[2], cx q[0],q[1]
        - SWAP q[1],[2], cx q[0],q[2], SWAP q[1],q[2], cx q[0],q[1]

        Verify that we find the first solution, as it requires fewer SWAPs.
        """

        qr = QuantumRegister(3)
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[2])
        circuit.cx(qr[0], qr[1])

        dag_circuit = circuit_to_dag(circuit)

        coupling_map = CouplingMap(couplinglist=[(0, 1), (1, 2)])

        pass_manager = PassManager()
        pass_manager.append([LookaheadSwap(coupling_map)])
        mapped_dag = transpile_dag(dag_circuit, pass_manager=pass_manager)

        self.assertEqual(mapped_dag.count_ops().get('swap', 0),
                         dag_circuit.count_ops().get('swap', 0) + 1)
def _generate_latex_source(circuit, filename=None,
                           basis="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
                                 "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap",
                           scale=0.7, style=None, reverse_bits=False,
                           plot_barriers=True):
    """Convert QuantumCircuit to LaTeX string.

    Args:
        circuit (QuantumCircuit): input circuit
        scale (float): image scaling
        filename (str): optional filename to write latex
        basis (str): optional comma-separated list of gate names
        style (dict or str): dictionary of style or file name of style file
        reverse_bits (bool): When set to True reverse the bit order inside
            registers for the output visualization.
        plot_barriers (bool): Enable/disable drawing barriers in the output
            circuit. Defaults to True.

    Returns:
        str: Latex string appropriate for writing to file.
    """
    dag_circuit = DAGCircuit.fromQuantumCircuit(circuit, expand_gates=False)
    json_circuit = transpile_dag(dag_circuit, basis_gates=basis, format='json')
    qcimg = _latex.QCircuitImage(json_circuit, scale, style=style,
                                 plot_barriers=plot_barriers,
                                 reverse_bits=reverse_bits)
    latex = qcimg.latex()
    if filename:
        with open(filename, 'w') as latex_file:
            latex_file.write(latex)
    return latex
    def test_lookahead_swap_maps_measurements(self):
        """Verify measurement nodes are updated to map correct cregs to re-mapped qregs.

        Create a circuit with measures on q0 and q2, following a swap between q0 and q2.
        Since that swap is not in the coupling, one of the two will be required to move.
        Verify that the mapped measure corresponds to one of the two possible layouts following
        the swap.

        """

        qr = QuantumRegister(3)
        cr = ClassicalRegister(2)
        circuit = QuantumCircuit(qr, cr)

        circuit.cx(qr[0], qr[2])
        circuit.measure(qr[0], cr[0])
        circuit.measure(qr[2], cr[1])

        dag_circuit = circuit_to_dag(circuit)

        coupling_map = CouplingMap(couplinglist=[(0, 1), (1, 2)])

        pass_manager = PassManager()
        pass_manager.append([LookaheadSwap(coupling_map)])
        mapped_dag = transpile_dag(dag_circuit, pass_manager=pass_manager)

        mapped_measure_qargs = set(mapped_dag.multi_graph.nodes(data=True)[op]['qargs'][0]
                                   for op in mapped_dag.get_named_nodes('measure'))

        self.assertIn(mapped_measure_qargs,
                      [set(((QuantumRegister(3, 'q'), 0), (QuantumRegister(3, 'q'), 1))),
                       set(((QuantumRegister(3, 'q'), 1), (QuantumRegister(3, 'q'), 2)))])
def _text_circuit_drawer(circuit, filename=None,
                         basis="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
                               "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap", line_length=None,
                         reversebits=False, plotbarriers=True):
    """
    Draws a circuit using ascii art.
    Args:
        circuit (QuantumCircuit): Input circuit
        filename (str): optional filename to write the result
        basis (str): Optional. Comma-separated list of gate names
        line_length (int): Optional. Sometimes, your console is too small of the drawing. Give me
                           you maximum line length your console supports.
        reversebits (bool): Rearrange the bits in reverse order.
        plotbarriers (bool): Draws the barriers when they are there.
    Returns:
        String: The drawing in a loooong string.
    """
    dag_circuit = DAGCircuit.fromQuantumCircuit(circuit, expand_gates=False)
    json_circuit = transpile_dag(dag_circuit, basis_gates=basis, format='json')

    text = "\n".join(
        _text.TextDrawing(json_circuit, reversebits=reversebits, plotbarriers=plotbarriers).lines(
            line_length))

    if filename:
        with open(filename, mode='w', encoding="utf8") as text_file:
            text_file.write(text)
    return text
def _generate_latex_source(circuit,
                           filename=None,
                           basis="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
                           "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap",
                           scale=0.7,
                           style=None):
    """Convert QuantumCircuit to LaTeX string.

    Args:
        circuit (QuantumCircuit): input circuit
        scale (float): image scaling
        filename (str): optional filename to write latex
        basis (str): optional comma-separated list of gate names
        style (dict or str): dictionary of style or file name of style file

    Returns:
        str: Latex string appropriate for writing to file.
    """
    dag_circuit = DAGCircuit.fromQuantumCircuit(circuit, expand_gates=False)
    json_circuit = transpile_dag(dag_circuit, basis_gates=basis, format='json')
    qcimg = _latex.QCircuitImage(json_circuit, scale, style=style)
    latex = qcimg.latex()
    if filename:
        with open(filename, 'w') as latex_file:
            latex_file.write(latex)
    return latex
    def test_pass_manager_none(self):
        """Test passing the default (None) pass manager to the transpiler.

        It should perform the default qiskit flow:
        unroll, swap_mapper, direction_mapper, cx cancellation, optimize_1q_gates
        and should be equivalent to using wrapper.compile
        """
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.h(qr[0])
        circuit.h(qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])

        coupling_map = [[1, 0]]
        basis_gates = 'u1,u2,u3,cx,id'

        dag_circuit = DAGCircuit.fromQuantumCircuit(circuit)
        dag_circuit = transpile_dag(dag_circuit, coupling_map=coupling_map,
                                    basis_gates=basis_gates, pass_manager=None)
        transpiler_json = DagUnroller(dag_circuit, JsonBackend(dag_circuit.basis)).execute()

        qobj = compile(circuit, backend=Aer.get_backend('qasm_simulator_py'),
                       coupling_map=coupling_map, basis_gates=basis_gates)
        compiler_json = qobj.experiments[0].as_dict()

        # Remove extra Qobj header parameters.
        compiler_json.pop('config')
        compiler_json['header'].pop('name')
        compiler_json['header'].pop('compiled_circuit_qasm')

        self.assertDictEqual(transpiler_json, compiler_json)
Example #10
0
    def test_move_measurements(self):
        """Measurements applied AFTER swap mapping.
        """
        backend = FakeRueschlikon()
        cmap = backend.configuration().coupling_map
        circ = QuantumCircuit.from_qasm_file(
            self._get_resource_path('move_measurements.qasm', Path.QASMS))

        dag_circuit = circuit_to_dag(circ)
        lay = {
            ('qa', 0): ('q', 0),
            ('qa', 1): ('q', 1),
            ('qb', 0): ('q', 15),
            ('qb', 1): ('q', 2),
            ('qb', 2): ('q', 14),
            ('qN', 0): ('q', 3),
            ('qN', 1): ('q', 13),
            ('qN', 2): ('q', 4),
            ('qc', 0): ('q', 12),
            ('qNt', 0): ('q', 5),
            ('qNt', 1): ('q', 11),
            ('qt', 0): ('q', 6)
        }
        out_dag = transpile_dag(dag_circuit,
                                initial_layout=lay,
                                coupling_map=cmap)
        meas_nodes = out_dag.named_nodes('measure')
        for n in meas_nodes:
            is_last_measure = all([
                after_measure in out_dag.output_map.values()
                for after_measure in out_dag.quantum_successors(n)
            ])
            self.assertTrue(is_last_measure)
Example #11
0
    def test_optimize_undone_swap(self):
        """ Remove redundant swap
            qr0:--X--X--m--       qr0:--m---
                  |  |  |               |
            qr1:--X--X--|--  ==>  qr1:--|--
                        |               |
            cr0:--------.--       cr0:--.--
        """
        qr = QuantumRegister(2, 'qr')
        cr = ClassicalRegister(1, 'cr')
        circuit = QuantumCircuit(qr, cr)
        circuit.swap(qr[0], qr[1])
        circuit.swap(qr[0], qr[1])
        circuit.measure(qr[0], cr[0])
        dag = circuit_to_dag(circuit)

        expected = QuantumCircuit(qr, cr)
        expected.measure(qr[0], cr[0])

        pass_manager = PassManager()
        pass_manager.append(
            [OptimizeSwapBeforeMeasure(),
             DAGFixedPoint()],
            do_while=lambda property_set: not property_set['dag_fixed_point'])
        after = transpile_dag(dag, pass_manager=pass_manager)

        self.assertEqual(circuit_to_dag(expected), after)
def _text_circuit_drawer(circuit,
                         filename=None,
                         basis="id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
                         "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap",
                         line_length=None,
                         reversebits=False,
                         plotbarriers=True):
    """
    Draws a circuit using ascii art.
    Args:
        circuit (QuantumCircuit): Input circuit
        filename (str): optional filename to write the result
        basis (str): Optional. Comma-separated list of gate names
        line_length (int): Optional. Breaks the circuit drawing to this length. This
                   useful when the drawing does not fit in the console. If
                   None (default), it will try to guess the console width using
                   shutil.get_terminal_size(). If you don't want pagination
                   at all, set line_length=-1.
        reversebits (bool): Rearrange the bits in reverse order.
        plotbarriers (bool): Draws the barriers when they are there.
    Returns:
        TextDrawing: An instances that, when printed, draws the circuit in ascii art.
    """
    dag_circuit = DAGCircuit.fromQuantumCircuit(circuit, expand_gates=False)
    json_circuit = transpile_dag(dag_circuit, basis_gates=basis, format='json')
    text_drawing = _text.TextDrawing(json_circuit, reversebits=reversebits)
    text_drawing.plotbarriers = plotbarriers
    text_drawing.line_length = line_length

    if filename:
        text_drawing.dump(filename)
    return text_drawing
Example #13
0
 def parse_circuit(self, circuit):
     dag_circuit = dagcircuit.DAGCircuit.fromQuantumCircuit(
         circuit, expand_gates=False)
     self._ast = transpiler.transpile_dag(dag_circuit,
                                          basis_gates=self._basis,
                                          format='json')
     self._registers()
     self._ops = self._ast['instructions']
Example #14
0
 def parse_circuit(self, circuit):
     dag_circuit = dagcircuit.DAGCircuit.fromQuantumCircuit(
         circuit, expand_gates=False)
     basis = ("id,u0,u1,u2,u3,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,"
              "cx,cy,cz,ch,crz,cu1,cu3,swap,ccx,cswap")
     self._ast = transpiler.transpile_dag(dag_circuit,
                                          basis_gates=basis,
                                          format='json')
     self._registers()
     self._ops = self._ast['instructions']
Example #15
0
 def assertScheduler(self, dag, passmanager, expected):
     """
     Runs transpiler(dag, passmanager) and checks if the passes run as expected.
     Args:
         dag (DAGCircuit): DAG circuit to transform via transpilation.
         passmanager (PassManager): pass manager instance for the transpilation process
         expected (list): List of things the passes are logging
     """
     with self.assertLogs(logger, level='INFO') as cm:
         dag = transpile_dag(dag, pass_manager=passmanager)
     self.assertIsInstance(dag, DAGCircuit)
     self.assertEqual([record.message for record in cm.records], expected)
    def setUp(self):
        self.seed = 88
        self.qasm_filename = self._get_resource_path('qasm/example.qasm')
        with open(self.qasm_filename, 'r') as qasm_file:
            self.qasm_text = qasm_file.read()
            self.qasm_ast = qasm.Qasm(data=self.qasm_text).parse()
            self.qasm_be = unroll.CircuitBackend(
                ['u1', 'u2', 'u3', 'id', 'cx'])
            self.qasm_circ = unroll.Unroller(self.qasm_ast,
                                             self.qasm_be).execute()
        qr = QuantumRegister(2, 'q')
        cr = ClassicalRegister(2, 'c')
        qc = QuantumCircuit(qr, cr)
        qc.h(qr[0])
        qc.measure(qr[0], cr[0])
        self.qc = qc

        # create qobj
        compiled_circuit1 = QobjExperiment.from_dict(
            transpile_dag(DAGCircuit.fromQuantumCircuit(self.qc),
                          format='json'))

        compiled_circuit2 = QobjExperiment.from_dict(
            transpile_dag(DAGCircuit.fromQuantumCircuit(self.qasm_circ),
                          format='json'))

        self.qobj = Qobj(qobj_id='test_qobj',
                         config=QobjConfig(shots=2000,
                                           memory_slots=1,
                                           max_credits=3,
                                           seed=1111),
                         experiments=[compiled_circuit1, compiled_circuit2],
                         header=QobjHeader(backend_name='qasm_simulator'))
        self.qobj.experiments[0].header.name = 'test_circuit1'
        self.qobj.experiments[0].config = QobjItem(
            basis_gates='u1,u2,u3,cx,id')
        self.qobj.experiments[1].header.name = 'test_circuit2'
        self.qobj.experiments[1].config = QobjItem(
            basis_gates='u1,u2,u3,cx,id')
        self.backend = QasmSimulator()
Example #17
0
    def test_optimize_to_nothing(self):
        """ Optimze gates up to fixed point in the default pipeline
        See https://github.com/Qiskit/qiskit-terra/issues/2035 """
        qr = QuantumRegister(2)
        circ = QuantumCircuit(qr)
        circ.h(qr[0])
        circ.cx(qr[0], qr[1])
        circ.x(qr[0])
        circ.y(qr[0])
        circ.z(qr[0])
        circ.cx(qr[0], qr[1])
        circ.h(qr[0])
        circ.cx(qr[0], qr[1])
        circ.cx(qr[0], qr[1])
        dag_circuit = circuit_to_dag(circ)

        after = transpile_dag(dag_circuit, coupling_map=[[0, 1], [1, 0]])

        expected = QuantumCircuit(QuantumRegister(2, 'q'))
        self.assertEqual(after, circuit_to_dag(expected))
Example #18
0
    def test_two_resets(self):
        """ Remove two initial resets
            qr0:--|0>-|0>--   ==>    qr0:----
        """
        qr = QuantumRegister(1, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.reset(qr[0])
        circuit.reset(qr[0])
        dag = circuit_to_dag(circuit)

        expected = QuantumCircuit(qr)

        pass_manager = PassManager()
        pass_manager.append(
            [RemoveResetInZeroState(),
             DAGFixedPoint()],
            do_while=lambda property_set: not property_set['dag_fixed_point'])
        after = transpile_dag(dag, pass_manager=pass_manager)

        self.assertEqual(circuit_to_dag(expected), after)
    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)
        circuit = QuantumCircuit(qr)
        circuit.cx(qr[0], qr[2])
        dag_circuit = circuit_to_dag(circuit)

        coupling_map = CouplingMap(couplinglist=[(0, 1), (1, 2)])

        pass_manager = PassManager()
        pass_manager.append([LookaheadSwap(coupling_map)])
        mapped_dag = transpile_dag(dag_circuit, pass_manager=pass_manager)

        self.assertEqual(mapped_dag.count_ops().get('swap', 0),
                         dag_circuit.count_ops().get('swap', 0) + 1)
Example #20
0
def _create_api_job_from_circuit(circuit):
    """Helper function that creates a special job required by the API, from a circuit."""
    api_job = {}
    if not circuit.get('compiled_circuit_qasm'):
        compiled_circuit = transpile_dag(circuit['circuit'])
        circuit['compiled_circuit_qasm'] = compiled_circuit.qasm(qeflag=True)

    if isinstance(circuit['compiled_circuit_qasm'], bytes):
        api_job['qasm'] = circuit['compiled_circuit_qasm'].decode()
    else:
        api_job['qasm'] = circuit['compiled_circuit_qasm']

    if circuit.get('name'):
        api_job['name'] = circuit['name']

    # convert numpy types for json serialization
    compiled_circuit = json.loads(
        json.dumps(circuit['compiled_circuit'], default=_numpy_type_converter))

    api_job['metadata'] = {'compiled_circuit': compiled_circuit}
    return api_job
    def test_pass_manager_empty(self):
        """Test passing an empty PassManager() to the transpiler.

        It should perform no transformations on the circuit.
        """
        qr = QuantumRegister(2)
        circuit = QuantumCircuit(qr)
        circuit.h(qr[0])
        circuit.h(qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        dag_circuit = DAGCircuit.fromQuantumCircuit(circuit)
        resources_before = dag_circuit.count_ops()

        pass_manager = PassManager()
        dag_circuit = transpile_dag(dag_circuit, pass_manager=pass_manager)
        resources_after = dag_circuit.count_ops()

        self.assertDictEqual(resources_before, resources_after)
Example #22
0
    def test_pass_cx_cancellation(self):
        """Test the cx cancellation pass.

        It should cancel consecutive cx pairs on same qubits.
        """
        qr = QuantumRegister(2)
        circuit = QuantumCircuit(qr)
        circuit.h(qr[0])
        circuit.h(qr[0])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[0], qr[1])
        circuit.cx(qr[1], qr[0])
        circuit.cx(qr[1], qr[0])
        dag_circuit = circuit_to_dag(circuit)

        pass_manager = PassManager()
        pass_manager.append(CXCancellation())
        dag_circuit = transpile_dag(dag_circuit, pass_manager=pass_manager)
        resources_after = dag_circuit.count_ops()

        self.assertNotIn('cx', resources_after)