예제 #1
0
    def test_default_layout(self):
        """Static method generate_trivial_layout creates a Layout"""
        qr0 = QuantumRegister(3, 'q0')
        qr1 = QuantumRegister(2, 'qr1')
        layout = Layout.generate_trivial_layout(qr0, qr1)

        self.assertEqual(layout[(qr0, 0)], 0)
        self.assertEqual(layout[(qr0, 1)], 1)
        self.assertEqual(layout[(qr0, 2)], 2)
        self.assertEqual(layout[(qr1, 0)], 3)
        self.assertEqual(layout[(qr1, 1)], 4)
예제 #2
0
def transpile_dag(dag,
                  basis_gates=None,
                  coupling_map=None,
                  initial_layout=None,
                  seed_mapper=None,
                  pass_manager=None):
    """Transform a dag circuit into another dag circuit (transpile), through
    consecutive passes on the dag.

    Args:
        dag (DAGCircuit): dag circuit to transform via transpilation
        basis_gates (list[str]): list of basis gate names supported by the
            target. Default: ['u1','u2','u3','cx','id']
        coupling_map (list): A graph of coupling::

            [
             [control0(int), target0(int)],
             [control1(int), target1(int)],
            ]

            eg. [[0, 2], [1, 2], [1, 3], [3, 4]}

        initial_layout (Layout or None): A layout object
        seed_mapper (int): random seed_mapper for the swap mapper
        pass_manager (PassManager): pass manager instance for the transpilation process
            If None, a default set of passes are run.
            Otherwise, the passes defined in it will run.
            If contains no passes in it, no dag transformations occur.

    Returns:
        DAGCircuit: transformed dag
    """
    # TODO: `basis_gates` will be removed after we have the unroller pass.
    # TODO: `coupling_map`, `initial_layout`, `seed_mapper` removed after mapper pass.

    # TODO: move this to the mapper pass

    num_qubits = sum([qreg.size for qreg in dag.qregs.values()])
    if num_qubits == 1:
        coupling_map = None

    if basis_gates is None:
        basis_gates = ['u1', 'u2', 'u3', 'cx', 'id']
    if isinstance(basis_gates, str):
        warnings.warn(
            "The parameter basis_gates is now a list of strings. "
            "For example, this basis ['u1','u2','u3','cx'] should be used "
            "instead of 'u1,u2,u3,cx'. The string format will be "
            "removed after 0.9", DeprecationWarning, 2)
        basis_gates = basis_gates.split(',')

    if initial_layout is None:
        initial_layout = Layout.generate_trivial_layout(*dag.qregs.values())

    if pass_manager is None:
        # default set of passes

        pass_manager = PassManager()
        pass_manager.append(Unroller(basis_gates))

        # if a coupling map is given compile to the map
        if coupling_map:
            coupling = CouplingMap(coupling_map)

            # Extend and enlarge the the dag/layout with ancillas using the full coupling map
            pass_manager.property_set['layout'] = initial_layout
            pass_manager.append(ExtendLayout(coupling))
            pass_manager.append(EnlargeWithAncilla(initial_layout))

            # Swap mapper
            pass_manager.append(
                LegacySwap(coupling,
                           initial_layout,
                           trials=20,
                           seed=seed_mapper))

            # Expand swaps
            pass_manager.append(Decompose(SwapGate))

            # Change CX directions
            pass_manager.append(CXDirection(coupling))

            # Unroll to the basis
            pass_manager.append(Unroller(['u1', 'u2', 'u3', 'id', 'cx']))

            # Simplify single qubit gates and CXs
            pass_manager.append([
                Optimize1qGates(),
                CXCancellation(),
                Depth(),
                FixedPoint('depth')
            ],
                                do_while=lambda property_set: not property_set[
                                    'depth_fixed_point'])

    # run the passes specified by the pass manager
    # TODO return the property set too. See #1086
    name = dag.name
    dag = pass_manager.run_passes(dag)
    dag.name = name

    return dag
예제 #3
0
def transpile_dag(dag,
                  basis_gates=None,
                  coupling_map=None,
                  initial_layout=None,
                  seed_mapper=None,
                  pass_manager=None):
    """Transform a dag circuit into another dag circuit (transpile), through
    consecutive passes on the dag.

    Args:
        dag (DAGCircuit): dag circuit to transform via transpilation
        basis_gates (list[str]): list of basis gate names supported by the
            target. Default: ['u1','u2','u3','cx','id']
        coupling_map (list): A graph of coupling::

            [
             [control0(int), target0(int)],
             [control1(int), target1(int)],
            ]

            eg. [[0, 2], [1, 2], [1, 3], [3, 4]}

        initial_layout (Layout or None): A layout object
        seed_mapper (int): random seed_mapper for the swap mapper
        pass_manager (PassManager): pass manager instance for the transpilation process
            If None, a default set of passes are run.
            Otherwise, the passes defined in it will run.
            If contains no passes in it, no dag transformations occur.

    Returns:
        DAGCircuit: transformed dag
    """
    # TODO: `basis_gates` will be removed after we have the unroller pass.
    # TODO: `coupling_map`, `initial_layout`, `seed_mapper` removed after mapper pass.

    # TODO: move this to the mapper pass

    num_qubits = sum([qreg.size for qreg in dag.qregs.values()])
    if num_qubits == 1:
        coupling_map = None

    if basis_gates is None:
        basis_gates = ['u1', 'u2', 'u3', 'cx', 'id']
    if isinstance(basis_gates, str):
        warnings.warn(
            "The parameter basis_gates is now a list of strings. "
            "For example, this basis ['u1','u2','u3','cx'] should be used "
            "instead of 'u1,u2,u3,cx'. The string format will be "
            "removed after 0.9", DeprecationWarning, 2)
        basis_gates = basis_gates.split(',')

    if initial_layout is None:
        initial_layout = Layout.generate_trivial_layout(*dag.qregs.values())

    if pass_manager:
        # run the passes specified by the pass manager
        # TODO return the property set too. See #1086
        dag = pass_manager.run_passes(dag)
    else:
        # default set of passes
        # TODO: move each step here to a pass, and use a default passmanager below
        name = dag.name

        dag = Unroller(basis_gates).run(dag)
        dag = BarrierBeforeFinalMeasurements().run(dag)

        # if a coupling map is given compile to the map
        if coupling_map:
            logger.info("pre-mapping properties: %s", dag.properties())

            coupling = CouplingMap(coupling_map)

            # Extend and enlarge the the dag/layout with ancillas using the full coupling map
            logger.info("initial layout: %s", initial_layout)
            pass_ = ExtendLayout(coupling)
            pass_.property_set['layout'] = initial_layout
            pass_.run(dag)
            initial_layout = pass_.property_set['layout']
            pass_ = EnlargeWithAncilla(initial_layout)
            dag = pass_.run(dag)
            initial_layout = pass_.property_set['layout']
            logger.info("initial layout (ancilla extended): %s",
                        initial_layout)

            # temporarily build old-style layout dict
            # (TODO: remove after transition to StochasticSwap pass)
            virtual_qubits = initial_layout.get_virtual_bits()
            initial_layout = {(v[0].name, v[1]): ('q', initial_layout[v])
                              for v in virtual_qubits}

            # Swap mapper
            dag, final_layout = swap_mapper(dag,
                                            coupling,
                                            initial_layout,
                                            trials=20,
                                            seed=seed_mapper)
            logger.info("final layout: %s", final_layout)
            # Expand swaps
            dag = Decompose(SwapGate).run(dag)
            # Change cx directions
            dag = CXDirection(coupling).run(dag)
            # Unroll to the basis
            dag = Unroller(['u1', 'u2', 'u3', 'id', 'cx']).run(dag)

            # Simplify single qubit gates and CXs
            pm_4_optimization = PassManager()
            pm_4_optimization.append(
                [Optimize1qGates(),
                 CXCancellation(),
                 DAGFixedPoint()],
                do_while=lambda property_set: not property_set[
                    'dag_fixed_point'])
            dag = transpile_dag(dag, pass_manager=pm_4_optimization)

        dag.name = name

    return dag