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)