Esempio n. 1
0
def default_pass_manager_simulator(basis_gates):
    """
    The default pass manager without a coupling map.

    Args:
        basis_gates (list[str]): list of basis gate names to unroll to.

    Returns:
        PassManager: A passmanager that just unrolls, without any optimization.
    """
    pass_manager = PassManager()
    pass_manager.append(Unroller(basis_gates))

    return pass_manager
Esempio n. 2
0
def default_pass_manager_simulator(basis_gates):
    """
    The default pass manager without a coupling map.

    Args:
        basis_gates (list[str]): list of basis gate names to unroll to.

    Returns:
        PassManager: A passmanager that just unrolls, without any optimization.
    """
    pass_manager = PassManager()

    pass_manager.append(Unroller(basis_gates))

    pass_manager.append(
        [RemoveResetInZeroState(),
         Depth(), FixedPoint('depth')],
        do_while=lambda property_set: not property_set['depth_fixed_point'])

    return pass_manager
Esempio n. 3
0
 def __init__(self):
     super().__init__()
     self.requires.append(Unroller(["u1", "u2", "u3", "cx", "id"]))
Esempio n. 4
0
def default_pass_manager(basis_gates, coupling_map, initial_layout,
                         seed_transpiler):
    """
    The default pass manager that maps to the coupling map.

    Args:
        basis_gates (list[str]): list of basis gate names supported by the target.
        coupling_map (CouplingMap): coupling map to target in mapping.
        initial_layout (Layout or None): initial layout of virtual qubits on physical qubits
        seed_transpiler (int or None): random seed for stochastic passes.

    Returns:
        PassManager: A pass manager to map and optimize.
    """
    pass_manager = PassManager()
    pass_manager.property_set['layout'] = initial_layout

    pass_manager.append(Unroller(basis_gates))

    # Use the trivial layout if no layout is found
    pass_manager.append(
        TrivialLayout(coupling_map),
        condition=lambda property_set: not property_set['layout'])

    # if the circuit and layout already satisfy the coupling_constraints, use that layout
    # otherwise layout on the most densely connected physical qubit subset
    pass_manager.append(CheckMap(coupling_map))
    pass_manager.append(
        DenseLayout(coupling_map),
        condition=lambda property_set: not property_set['is_swap_mapped'])

    # Extend the the dag/layout with ancillas using the full coupling map
    pass_manager.append(FullAncillaAllocation(coupling_map))
    pass_manager.append(EnlargeWithAncilla())

    # Circuit must only contain 1- or 2-qubit interactions for swapper to work
    pass_manager.append(Unroll3qOrMore())

    # Swap mapper
    pass_manager.append(
        LegacySwap(coupling_map, trials=20, seed=seed_transpiler))

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

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

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

    # Simplify single qubit gates and CXs
    simplification_passes = [
        Optimize1qGates(),
        CXCancellation(),
        RemoveResetInZeroState()
    ]

    pass_manager.append(
        simplification_passes + [Depth(), FixedPoint('depth')],
        do_while=lambda property_set: not property_set['depth_fixed_point'])

    return pass_manager
Esempio n. 5
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 (dict): A mapping of qubit to qubit::

                              {
                                ("q", start(int)): ("q", final(int)),
                                ...
                              }
                              eg.
                              {
                                ("q", 0): ("q", 0),
                                ("q", 1): ("q", 1),
                                ("q", 2): ("q", 2),
                                ("q", 3): ("q", 3)
                              }
        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 or coupling_map == "all-to-all":
        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 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())
            # Insert swap gates
            coupling = CouplingMap(coupling_map)
            logger.info("initial layout: %s", initial_layout)

            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)
            # Simplify cx gates
            dag = CXCancellation().run(dag)
            # Unroll to the basis
            dag = Unroller(['u1', 'u2', 'u3', 'id', 'cx']).run(dag)
            # Simplify single qubit gates
            dag = Optimize1qGates().run(dag)
            logger.info("post-mapping properties: %s", dag.properties())
        dag.name = name

    return dag
Esempio n. 6
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