From d13775626de465a50a0ff6a529f5624be2b8d5ac Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Wed, 12 Oct 2022 16:24:33 +0000 Subject: [PATCH] Skip classical function tests if tweedledum isn't present (#8876) (#8881) * Skip classical function tests if tweedledum isn't present This commit fixes an oversight in #8849 and #8818 which made tweedledum optional for arm64 macOS systems which was the unittest suite still unconditionally depends on tweedledum being installed to run the classical function compiler tests. This commit fixes this by making the tests skip if tweedledum isn't installed so that M1 mac users are able to run the full test suite again. * Skip other tests requiring tweedledum (cherry picked from commit 75fe9bb157bb5745b00f63711264d1b6c1da3cec) Co-authored-by: Matthew Treinish --- test/python/algorithms/test_grover.py | 3 + .../circuit/library/test_phase_oracle.py | 2 + .../circuit/test_extensions_standard.py | 3 + .../classical_function_compiler/examples.py | 59 ++++++++----------- .../test_boolean_expression.py | 7 ++- .../test_classical_function.py | 10 +++- .../classical_function_compiler/test_parse.py | 11 +++- .../test_simulate.py | 14 +++-- .../test_synthesis.py | 8 ++- .../test_tweedledum2qiskit.py | 12 +++- .../test_typecheck.py | 12 +++- .../classical_function_compiler/test_utils.py | 7 ++- 12 files changed, 94 insertions(+), 54 deletions(-) diff --git a/test/python/algorithms/test_grover.py b/test/python/algorithms/test_grover.py index ad38b59a507d..73828f9a9e09 100644 --- a/test/python/algorithms/test_grover.py +++ b/test/python/algorithms/test_grover.py @@ -25,6 +25,7 @@ from qiskit.circuit.library import GroverOperator, PhaseOracle from qiskit.primitives import Sampler from qiskit.quantum_info import Operator, Statevector +from qiskit.utils.optionals import HAS_TWEEDLEDUM @ddt @@ -100,6 +101,7 @@ def setUp(self): self._sampler = Sampler() self._sampler_with_shots = Sampler(options={"shots": 1024, "seed": 123}) + @unittest.skipUnless(HAS_TWEEDLEDUM, "tweedledum required for this test") @data("ideal", "shots", False) def test_implicit_phase_oracle_is_good_state(self, use_sampler): """Test implicit default for is_good_state with PhaseOracle.""" @@ -278,6 +280,7 @@ def test_max_probability(self, use_sampler): result = grover.amplify(problem) self.assertAlmostEqual(result.max_probability, 1.0) + @unittest.skipUnless(HAS_TWEEDLEDUM, "tweedledum required for this test") @data("ideal", "shots", False) def test_oracle_evaluation(self, use_sampler): """Test oracle_evaluation for PhaseOracle""" diff --git a/test/python/circuit/library/test_phase_oracle.py b/test/python/circuit/library/test_phase_oracle.py index e52aa3dea7b3..825a8c00a802 100644 --- a/test/python/circuit/library/test_phase_oracle.py +++ b/test/python/circuit/library/test_phase_oracle.py @@ -20,8 +20,10 @@ from qiskit.test.base import QiskitTestCase from qiskit.circuit.library import PhaseOracle from qiskit.quantum_info import Statevector +from qiskit.utils.optionals import HAS_TWEEDLEDUM +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests") @ddt class TestPhaseOracle(QiskitTestCase): """Test phase oracle object.""" diff --git a/test/python/circuit/test_extensions_standard.py b/test/python/circuit/test_extensions_standard.py index 1278d605903a..f1a182943809 100644 --- a/test/python/circuit/test_extensions_standard.py +++ b/test/python/circuit/test_extensions_standard.py @@ -41,6 +41,7 @@ from qiskit import BasicAer from qiskit.quantum_info import Pauli from qiskit.quantum_info.operators.predicates import matrix_equal, is_unitary_matrix +from qiskit.utils.optionals import HAS_TWEEDLEDUM class TestStandard1Q(QiskitTestCase): @@ -1399,6 +1400,7 @@ def test_cswap_reg_reg_inv(self): class TestStandardMethods(QiskitTestCase): """Standard Extension Test.""" + @unittest.skipUnless(HAS_TWEEDLEDUM, "tweedledum required for this test") def test_to_matrix(self): """test gates implementing to_matrix generate matrix which matches definition.""" from qiskit.circuit.library.pauli_evolution import PauliEvolutionGate @@ -1444,6 +1446,7 @@ def test_to_matrix(self): self.assertTrue(matrix_equal(definition_unitary, gate_matrix, ignore_phase=True)) self.assertTrue(is_unitary_matrix(gate_matrix)) + @unittest.skipUnless(HAS_TWEEDLEDUM, "tweedledum required for this test") def test_to_matrix_op(self): """test gates implementing to_matrix generate matrix which matches definition using Operator.""" diff --git a/test/python/classical_function_compiler/examples.py b/test/python/classical_function_compiler/examples.py index 8001a27b0868..ebc2bfe0a1fd 100644 --- a/test/python/classical_function_compiler/examples.py +++ b/test/python/classical_function_compiler/examples.py @@ -14,47 +14,40 @@ """These examples should be handle by the classicalfunction compiler""" -from qiskit.circuit.classicalfunction.types import Int1 +from qiskit.utils.optionals import HAS_TWEEDLEDUM +if HAS_TWEEDLEDUM: + from qiskit.circuit.classicalfunction.types import Int1 -def identity(a: Int1) -> Int1: - return a + def identity(a: Int1) -> Int1: + return a + def bit_and(a: Int1, b: Int1) -> Int1: + return a & b -def bit_and(a: Int1, b: Int1) -> Int1: - return a & b + def bit_or(a: Int1, b: Int1) -> Int1: + return a | b + def bool_or(a: Int1, b: Int1) -> Int1: + return a or b -def bit_or(a: Int1, b: Int1) -> Int1: - return a | b + def bool_not(a: Int1) -> Int1: + return not a + def and_and(a: Int1, b: Int1, c: Int1) -> Int1: + return a and b and c -def bool_or(a: Int1, b: Int1) -> Int1: - return a or b + def multiple_binop(a: Int1, b: Int1) -> Int1: + return (a or b) | (b & a) and (a & b) + def id_assing(a: Int1) -> Int1: + b = a + return b -def bool_not(a: Int1) -> Int1: - return not a + def example1(a: Int1, b: Int1) -> Int1: + c = a & b + d = b | a + return c ^ a | d - -def and_and(a: Int1, b: Int1, c: Int1) -> Int1: - return a and b and c - - -def multiple_binop(a: Int1, b: Int1) -> Int1: - return (a or b) | (b & a) and (a & b) - - -def id_assing(a: Int1) -> Int1: - b = a - return b - - -def example1(a: Int1, b: Int1) -> Int1: - c = a & b - d = b | a - return c ^ a | d - - -def grover_oracle(a: Int1, b: Int1, c: Int1, d: Int1) -> Int1: - return not a and b and not c and d + def grover_oracle(a: Int1, b: Int1, c: Int1, d: Int1) -> Int1: + return not a and b and not c and d diff --git a/test/python/classical_function_compiler/test_boolean_expression.py b/test/python/classical_function_compiler/test_boolean_expression.py index 1c19b6103354..e82c1b4e8d24 100644 --- a/test/python/classical_function_compiler/test_boolean_expression.py +++ b/test/python/classical_function_compiler/test_boolean_expression.py @@ -18,9 +18,13 @@ from qiskit.test.base import QiskitTestCase from qiskit import execute, BasicAer -from qiskit.circuit.classicalfunction.boolean_expression import BooleanExpression +from qiskit.utils.optionals import HAS_TWEEDLEDUM +if HAS_TWEEDLEDUM: + from qiskit.circuit.classicalfunction.boolean_expression import BooleanExpression + +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") @ddt class TestBooleanExpression(QiskitTestCase): """Test boolean expression.""" @@ -68,6 +72,7 @@ def test_synth(self, expression, expected): self.assertEqual(bool(int(result)), expected) +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestBooleanExpressionDIMACS(QiskitTestCase): """Loading from a cnf file""" diff --git a/test/python/classical_function_compiler/test_classical_function.py b/test/python/classical_function_compiler/test_classical_function.py index 3d3ada14ec38..66bd5e1a755b 100644 --- a/test/python/classical_function_compiler/test_classical_function.py +++ b/test/python/classical_function_compiler/test_classical_function.py @@ -11,16 +11,20 @@ # that they have been altered from the originals. """Tests ClassicalFunction as a gate.""" -from qiskit.test import QiskitTestCase +import unittest -from qiskit.circuit.classicalfunction import classical_function as compile_classical_function +from qiskit.test import QiskitTestCase from qiskit import QuantumCircuit from qiskit.circuit.library.standard_gates import XGate +from qiskit.utils.optionals import HAS_TWEEDLEDUM -from . import examples +if HAS_TWEEDLEDUM: + from . import examples + from qiskit.circuit.classicalfunction import classical_function as compile_classical_function +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestOracleDecomposition(QiskitTestCase): """Tests ClassicalFunction.decomposition.""" diff --git a/test/python/classical_function_compiler/test_parse.py b/test/python/classical_function_compiler/test_parse.py index dc532900c832..a10b6ad43847 100644 --- a/test/python/classical_function_compiler/test_parse.py +++ b/test/python/classical_function_compiler/test_parse.py @@ -11,13 +11,18 @@ # that they have been altered from the originals. """Tests the classicalfunction parser.""" -from qiskit.circuit.classicalfunction import ClassicalFunctionParseError -from qiskit.circuit.classicalfunction import classical_function as compile_classical_function +import unittest from qiskit.test import QiskitTestCase -from . import bad_examples as examples +from qiskit.utils.optionals import HAS_TWEEDLEDUM +if HAS_TWEEDLEDUM: + from . import bad_examples as examples + from qiskit.circuit.classicalfunction import ClassicalFunctionParseError + from qiskit.circuit.classicalfunction import classical_function as compile_classical_function + +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestParseFail(QiskitTestCase): """Tests bad_examples with the classicalfunction parser.""" diff --git a/test/python/classical_function_compiler/test_simulate.py b/test/python/classical_function_compiler/test_simulate.py index 066def2dc62a..732f9f36c115 100644 --- a/test/python/classical_function_compiler/test_simulate.py +++ b/test/python/classical_function_compiler/test_simulate.py @@ -11,19 +11,25 @@ # that they have been altered from the originals. """Tests LogicNetwork.simulate method.""" +import unittest from ddt import ddt, data -from qiskit.circuit.classicalfunction import classical_function as compile_classical_function from qiskit.test import QiskitTestCase -from .utils import get_truthtable_from_function, example_list +from qiskit.utils.optionals import HAS_TWEEDLEDUM +from . import utils +if HAS_TWEEDLEDUM: + from qiskit.circuit.classicalfunction import classical_function as compile_classical_function + + +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") @ddt class TestSimulate(QiskitTestCase): """Tests LogicNetwork.simulate method""" - @data(*example_list()) + @data(*utils.example_list()) def test_(self, a_callable): """Tests LogicSimulate.simulate() on all the examples""" network = compile_classical_function(a_callable) truth_table = network.simulate_all() - self.assertEqual(truth_table, get_truthtable_from_function(a_callable)) + self.assertEqual(truth_table, utils.get_truthtable_from_function(a_callable)) diff --git a/test/python/classical_function_compiler/test_synthesis.py b/test/python/classical_function_compiler/test_synthesis.py index a3d6ce21407b..33a5da6c9880 100644 --- a/test/python/classical_function_compiler/test_synthesis.py +++ b/test/python/classical_function_compiler/test_synthesis.py @@ -11,16 +11,20 @@ # that they have been altered from the originals. """Tests classicalfunction compiler synthesis.""" +import unittest from qiskit.test import QiskitTestCase -from qiskit.circuit.classicalfunction import classical_function as compile_classical_function from qiskit import QuantumCircuit, QuantumRegister from qiskit.circuit.library.standard_gates import XGate +from qiskit.utils.optionals import HAS_TWEEDLEDUM -from . import examples +if HAS_TWEEDLEDUM: + from qiskit.circuit.classicalfunction import classical_function as compile_classical_function + from . import examples +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestSynthesis(QiskitTestCase): """Tests ClassicalFunction.synth method.""" diff --git a/test/python/classical_function_compiler/test_tweedledum2qiskit.py b/test/python/classical_function_compiler/test_tweedledum2qiskit.py index 62f9b64d21c7..541cbbe4ef1f 100644 --- a/test/python/classical_function_compiler/test_tweedledum2qiskit.py +++ b/test/python/classical_function_compiler/test_tweedledum2qiskit.py @@ -11,16 +11,22 @@ # that they have been altered from the originals. """Tests LogicNetwork.Tweedledum2Qiskit converter.""" -from tweedledum.ir import Circuit -from tweedledum.operators import X +import unittest +from qiskit.utils.optionals import HAS_TWEEDLEDUM from qiskit.test import QiskitTestCase -from qiskit.circuit.classicalfunction.utils import tweedledum2qiskit from qiskit import QuantumCircuit, QuantumRegister from qiskit.circuit.library.standard_gates import XGate +if HAS_TWEEDLEDUM: + from qiskit.circuit.classicalfunction.utils import tweedledum2qiskit + from tweedledum.ir import Circuit + from tweedledum.operators import X + + +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestTweedledum2Qiskit(QiskitTestCase): """Tests qiskit.transpiler.classicalfunction.utils.tweedledum2qiskit function.""" diff --git a/test/python/classical_function_compiler/test_typecheck.py b/test/python/classical_function_compiler/test_typecheck.py index e997ac3b9449..9155063c3497 100644 --- a/test/python/classical_function_compiler/test_typecheck.py +++ b/test/python/classical_function_compiler/test_typecheck.py @@ -11,13 +11,18 @@ # that they have been altered from the originals. """Tests classicalfunction compiler type checker.""" +import unittest + from qiskit.test import QiskitTestCase -from qiskit.circuit.classicalfunction import ClassicalFunctionCompilerTypeError -from qiskit.circuit.classicalfunction import classical_function as compile_classical_function +from qiskit.utils.optionals import HAS_TWEEDLEDUM -from . import examples, bad_examples +if HAS_TWEEDLEDUM: + from . import examples, bad_examples + from qiskit.circuit.classicalfunction import ClassicalFunctionCompilerTypeError + from qiskit.circuit.classicalfunction import classical_function as compile_classical_function +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestTypeCheck(QiskitTestCase): """Tests classicalfunction compiler type checker (good examples).""" @@ -66,6 +71,7 @@ def test_bool_or(self): ) +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestTypeCheckFail(QiskitTestCase): """Tests classicalfunction compiler type checker (bad examples).""" diff --git a/test/python/classical_function_compiler/test_utils.py b/test/python/classical_function_compiler/test_utils.py index b468ef333ae3..70dd6616aeda 100644 --- a/test/python/classical_function_compiler/test_utils.py +++ b/test/python/classical_function_compiler/test_utils.py @@ -10,16 +10,19 @@ # copyright notice, and modified files need to carry a notice indicating # that they have been altered from the originals. """Tests .utils.get_truthtable_from_function function""" +import unittest from qiskit.test import QiskitTestCase +from qiskit.utils.optionals import HAS_TWEEDLEDUM from .utils import get_truthtable_from_function -from .examples import grover_oracle +from . import examples +@unittest.skipUnless(HAS_TWEEDLEDUM, "Tweedledum is required for these tests.") class TestGetTruthtableFromFunction(QiskitTestCase): """Tests .utils.get_truthtable_from_function function""" def test_grover_oracle(self): """Tests get_truthtable_from_function with examples.grover_oracle""" - truth_table = get_truthtable_from_function(grover_oracle) + truth_table = get_truthtable_from_function(examples.grover_oracle) self.assertEqual(truth_table, "0000010000000000")