def test_two_qubit_synthesis_to_directional_cx_from_gate_errors(self):
        """Verify two qubit unitaries are synthesized to match basis gates."""
        # 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(conf.coupling_map)
        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=None,
            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=None,
            backend_props=backend.properties(),
            pulse_optimize=True,
            natural_direction=True,
        )

        pm_nat = PassManager([triv_layout_pass, unisynth_pass_nat])
        qc_out_nat = pm_nat.run(qc)
        self.assertEqual(Operator(qc), Operator(qc_out))
        self.assertEqual(Operator(qc), Operator(qc_out_nat))
 def test_two_qubit_pulse_optimal_none_no_raise(self):
     """Verify pulse optimal decomposition when pulse_optimize==None doesn't
     raise when pulse optimal decomposition unknown."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     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=None,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     try:
         qc_out = pm.run(qc)
     except QiskitError:
         self.fail("pulse_optimize=None raised exception unexpectedly")
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertLessEqual(num_ops["sx"], 14)
    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(((qr[1], qr[0]) == instr.qubits for instr in qc_out.get_instructions("cx")))
        )
        self.assertTrue(
            all(((qr[1], qr[0]) == instr.qubits for instr in qc_out_nat.get_instructions("cx")))
        )
        self.assertEqual(Operator(qc), Operator(qc_out))
        self.assertEqual(Operator(qc), Operator(qc_out_nat))
 def test_two_qubit_natural_direction_true_gate_length_raises(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     for _, nduv in backend.properties()._gates["cx"].items():
         nduv["gate_length"] = (4e-7, nduv["gate_length"][1])
         nduv["gate_error"] = (7e-3, nduv["gate_error"][1])
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [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,
         backend_props=backend.properties(),
         pulse_optimize=True,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(TranspilerError):
         pm.run(qc)
 def test_two_qubit_pulse_optimal_true_raises(self):
     """Verify raises if pulse optimal==True but cx is not in the backend basis."""
     backend = FakeVigo()
     conf = backend.configuration()
     # this assumes iswawp pulse optimal decomposition doesn't exist
     conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     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=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     with self.assertRaises(QiskitError):
         pm.run(qc)
 def test_two_qubit_natural_direction_true_duration_fallback(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     # this assumes iswawp pulse optimal decomposition doesn't exist
     backend = FakeVigo()
     conf = backend.configuration()
     # conf.basis_gates = [gate if gate != "cx" else "iswap" for gate in conf.basis_gates]
     qr = QuantumRegister(2)
     coupling_map = CouplingMap([[0, 1], [1, 0], [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=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     self.assertTrue(
         all(((qr[0], qr[1]) == instr.qubits for instr in qc_out.get_instructions("cx")))
     )
 def test_two_qubit_synthesis_not_pulse_optimal(self):
     """Verify not attempting pulse optimal decomposition when pulse_optimize==False."""
     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=False,
         natural_direction=True,
     )
     pm = PassManager([triv_layout_pass, unisynth_pass])
     qc_out = pm.run(qc)
     if isinstance(qc_out, QuantumCircuit):
         num_ops = qc_out.count_ops()
     else:
         num_ops = qc_out[0].count_ops()
     self.assertIn("sx", num_ops)
     self.assertGreaterEqual(num_ops["sx"], 16)