示例#1
0
    def test_two_annotation_swap(self):
        """SWAP gate after different annotation should be optimized
         |phi> --annotation------x-             |phi> --
                                |       =>
         |phi>---annotation----x-            |phi> --
         """
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.append(StateAnnotation(0.1, 0.2, 0.3), [qr[0]])
        circuit.append(StateAnnotation(0.4, 0.5, 0.6), [qr[1]])
        circuit.swap(qr[0], qr[1])

        expected = QuantumCircuit(qr)
        expected.u3(0.4, 0.5, 0.6, qr[0])
        expected.u3(0.1, 0.2, 0.3, qr[1])

        passmanager = PassManager()
        passmanager.append(PureStateOnU())
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
示例#2
0
    def test_two_const_swap(self):
        """Input states are the different pure states, replace the swap with two single qubit gates
         |phi> --X----       |phi> --U3--
                 |       =>
         |psi>--X----       |psi> --U3^--
         """
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.u3(1.23, 3.34, 3.04, qr[0])
        circuit.u3(2.22, 1.67, 0.66, qr[1])
        circuit.swap(qr[0], qr[1])

        expected = QuantumCircuit(qr)
        expected.u3(2.22, 1.67, 0.66, qr[0])
        expected.u3(1.23, 3.34, 3.04, qr[1])

        passmanager = PassManager()
        passmanager.append(PureStateOnU())
        passmanager.append(Optimize1qGates())
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
示例#3
0
    def test_two_unknown_swap(self):
        """Input states are the same, remove the swap gate
         |phi> --X----       |phi> --
                 |       =>
         |phi>--X----       |phi> --
         """
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.reset(qr[0])
        circuit.reset(qr[1])
        circuit.swap(qr[0], qr[1])

        expected = QuantumCircuit(qr)
        expected.reset(qr[0])
        expected.reset(qr[1])
        expected.swap(qr[0], qr[1])

        passmanager = PassManager()
        passmanager.append(PureStateOnU())
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
示例#4
0
    def test_empty_annotation(self):
        """Empty circuit with annotation
         |phi> --annotation----       |phi> --
                                  =>
         |phi>--------------        phi> --
         """
        qr = QuantumRegister(2, 'qr')
        circuit = QuantumCircuit(qr)
        circuit.u3(1.23, 2.34, 3.04, qr[0])
        circuit.u3(1.23, 2.34, 3.04, qr[1])
        circuit.swap(qr[0], qr[1])
        circuit.append(StateAnnotation(0.1, 0.2, 0.3), [qr[0]])

        expected = QuantumCircuit(qr)
        expected.u3(1.23, 2.34, 3.04, qr[0])
        expected.u3(1.23, 2.34, 3.04, qr[1])

        passmanager = PassManager()
        passmanager.append(PureStateOnU())
        result = passmanager.run(circuit)

        self.assertEqual(expected, result)
示例#5
0
def level_3_with_contant_pure(pass_manager_config: PassManagerConfig) -> PassManager:
    """
    Args:
        pass_manager_config: configuration of the pass manager.

    Returns:
        a level 3 pass manager.
    """
    basis_gates = pass_manager_config.basis_gates
    coupling_map = pass_manager_config.coupling_map
    initial_layout = pass_manager_config.initial_layout
    layout_method = pass_manager_config.layout_method or 'dense'
    routing_method = pass_manager_config.routing_method or 'stochastic'
    seed_transpiler = pass_manager_config.seed_transpiler
    backend_properties = pass_manager_config.backend_properties

    # 1. Unroll to the basis first, to prepare for noise-adaptive layout
    _unroll = Unroller(basis_gates + ['annotation'])

    # 2. Layout on good qubits if calibration info available, otherwise on dense links
    _given_layout = SetLayout(initial_layout)

    def _choose_layout_condition(property_set):
        return not property_set['layout']

    _choose_layout_1 = CSPLayout(coupling_map, call_limit=10000, time_limit=60)
    if layout_method == 'trivial':
        _choose_layout_2 = TrivialLayout(coupling_map)
    elif layout_method == 'dense':
        _choose_layout_2 = DenseLayout(coupling_map, backend_properties)
    elif layout_method == 'noise_adaptive':
        _choose_layout_2 = NoiseAdaptiveLayout(backend_properties)
    else:
        raise TranspilerError("Invalid layout method %s." % layout_method)

    # 3. Extend dag/layout with ancillas using the full coupling map
    _embed = [FullAncillaAllocation(coupling_map), EnlargeWithAncilla(), ApplyLayout()]

    # 4. Unroll to 1q or 2q gates, swap to fit the coupling map
    _swap_check = CheckMap(coupling_map)

    def _swap_condition(property_set):
        return not property_set['is_swap_mapped']

    _swap = [BarrierBeforeFinalMeasurements(), Unroll3qOrMore()]
    if routing_method == 'basic':
        _swap += [BasicSwap(coupling_map)]
    elif routing_method == 'stochastic':
        _swap += [StochasticSwap(coupling_map, trials=200, seed=seed_transpiler)]
    elif routing_method == 'lookahead':
        _swap += [LookaheadSwap(coupling_map, search_depth=5, search_width=6)]
    else:
        raise TranspilerError("Invalid routing method %s." % routing_method)

    # 5. 1q rotation merge and commutative cancellation iteratively until no more change in depth
    _depth_check = [Depth(), FixedPoint('depth')]

    def _opt_control(property_set):
        return not property_set['depth_fixed_point']

    _opt = [RemoveResetInZeroState(),
            Collect2qBlocks(), ConsolidateBlocks(),
            Unroller(basis_gates),  # unroll unitaries
            Optimize1qGates(basis_gates), CommutativeCancellation(),
            OptimizeSwapBeforeMeasure(), RemoveDiagonalGatesBeforeMeasure()]

    # 6. Fix any CX direction mismatch
    _direction_check = [CheckCXDirection(coupling_map)]

    def _direction_condition(property_set):
        return not property_set['is_direction_mapped']

    _direction = [CXDirection(coupling_map)]

    # Build pass manager
    pm = PassManager()
    pm.append(ConstantsStateOptimization())
    pm.append(_unroll)
    if coupling_map:
        pm.append(_given_layout)
        pm.append(_choose_layout_1, condition=_choose_layout_condition)
        pm.append(_choose_layout_2, condition=_choose_layout_condition)
        pm.append(_embed)
        pm.append(_swap_check)
        pm.append(_swap, condition=_swap_condition)
    pm.append(ConstantsStateOptimization())
    pm.append([Unroller(basis_gates+['swap', 'aswap', 'annotation']),
               Optimize1qGates(), PureStateOnU()])
    pm.append(_depth_check + _opt, do_while=_opt_control)
    if coupling_map and not coupling_map.is_symmetric:
        pm.append(_direction_check)
        pm.append(_direction, condition=_direction_condition)
    return pm