qiskit/test/python/transpiler/test_minimum_point.py

290 lines
13 KiB
Python

# This code is part of Qiskit.
#
# (C) Copyright IBM 2023
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
"""MinimumPoint pass testing"""
import math
from qiskit.transpiler.passes import MinimumPoint
from qiskit.dagcircuit import DAGCircuit
from test import QiskitTestCase # pylint: disable=wrong-import-order
class TestMinimumPointtPass(QiskitTestCase):
"""Tests for MinimumPoint pass."""
def test_minimum_point_reached_fixed_point_single_field(self):
"""Test a fixed point is reached with a single field."""
min_pass = MinimumPoint(["depth"], prefix="test")
dag = DAGCircuit()
min_pass.property_set["depth"] = 42
min_pass.run(dag)
# After first iteration state is only initialized but not populated
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 0)
self.assertEqual((math.inf,), state.score)
self.assertIsNone(state.dag)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Second iteration
min_pass.run(dag)
# After second iteration the state is initialized
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual(state.score, (42,))
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Third iteration
out_dag = min_pass.run(dag)
# After 3rd iteration we've reached a fixed point equal to our minimum
# ooint so we return the minimum dag
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual((42,), state.score)
self.assertTrue(min_pass.property_set["test_minimum_point"])
# In case of fixed point we don't return copy but the state of the dag
# after the fixed point so only assert equality
self.assertEqual(out_dag, state.dag)
def test_minimum_point_reached_fixed_point_multiple_fields(self):
"""Test a fixed point is reached with a multiple fields."""
min_pass = MinimumPoint(["fidelity", "depth", "size"], prefix="test")
dag = DAGCircuit()
min_pass.property_set["fidelity"] = 0.875
min_pass.property_set["depth"] = 15
min_pass.property_set["size"] = 20
min_pass.run(dag)
# After first iteration state is only initialized but not populated
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 0)
self.assertEqual((math.inf, math.inf, math.inf), state.score)
self.assertIsNone(state.dag)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Two
min_pass.run(dag)
# After second iteration the state is initialized
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual(state.score, (0.875, 15, 20))
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Three
out_dag = min_pass.run(dag)
# After 3rd iteration we've reached a fixed point equal to our minimum
# ooint so we return the minimum dag
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual(state.score, (0.875, 15, 20))
self.assertTrue(min_pass.property_set["test_minimum_point"])
# In case of fixed point we don't return copy but the state of the dag
# after the fixed point so only assert equality
self.assertEqual(out_dag, state.dag)
def test_min_over_backtrack_range(self):
"""Test minimum returned over backtrack depth."""
min_pass = MinimumPoint(["fidelity", "depth", "size"], prefix="test")
dag = DAGCircuit()
min_pass.property_set["fidelity"] = 0.875
min_pass.property_set["depth"] = 15
min_pass.property_set["size"] = 20
min_pass.run(dag)
# After first iteration state is only initialized but not populated
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 0)
self.assertEqual((math.inf, math.inf, math.inf), state.score)
self.assertIsNone(state.dag)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Two
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 25
min_pass.property_set["size"] = 35
min_pass.run(dag)
# After second iteration we've set a current minimum state
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration three
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 45
min_pass.property_set["size"] = 35
min_pass.run(dag)
# After third iteration score is worse than minimum point just bump since
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 2)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration four
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
min_pass.run(dag)
# After fourth iteration score is worse than minimum point just bump since
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 3)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration five
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
min_pass.run(dag)
# After fifth iteration score is worse than minimum point just bump since
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 4)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration six
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
out_dag = min_pass.run(dag)
# After sixth iteration score is worse, but we've reached backtrack depth and the
# dag copy is returned
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 5)
self.assertEqual((0.775, 25, 35), state.score)
self.assertTrue(min_pass.property_set["test_minimum_point"])
self.assertIs(out_dag, state.dag)
def test_min_reset_backtrack_range(self):
"""Test minimum resets backtrack depth."""
min_pass = MinimumPoint(["fidelity", "depth", "size"], prefix="test")
dag = DAGCircuit()
min_pass.property_set["fidelity"] = 0.875
min_pass.property_set["depth"] = 15
min_pass.property_set["size"] = 20
min_pass.run(dag)
# After first iteration state is only initialized but not populated
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 0)
self.assertEqual((math.inf, math.inf, math.inf), state.score)
self.assertIsNone(state.dag)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration two:
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 25
min_pass.property_set["size"] = 35
min_pass.run(dag)
# After second iteration we've set a current minimum state
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration three:
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 45
min_pass.property_set["size"] = 35
min_pass.run(dag)
# Third iteration the score is worse (because of depth increasing) so do
# not set new minimum point
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 2)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration four:
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
min_pass.run(dag)
# Fourth iteration the score is also worse than minmum although depth
# is better than iteration three it's still higher than the minimum point
# Also size has increased:. Do not update minimum point and since is increased
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 3)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration five
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
min_pass.run(dag)
# Fifth iteration the score is also worse than minmum although the same
# with previous iteration. This means do not update minimum point and bump since
# value
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 4)
self.assertEqual((0.775, 25, 35), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Six
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 10
min_pass.property_set["size"] = 10
min_pass.run(dag)
# Sixth iteration the score is lower (fidelity is the same but depth and size decreased)
# set new minimum point
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 1)
self.assertEqual((0.775, 10, 10), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration seven
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 25
min_pass.property_set["size"] = 35
min_pass.run(dag)
# Iteration seven the score is worse than the minimum point. Do not update minimum point
# and since is bumped
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 2)
self.assertEqual((0.775, 10, 10), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Eight
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 45
min_pass.property_set["size"] = 35
min_pass.run(dag)
# Iteration eight the score is worse than the minimum point. Do not update minimum point
# and since is bumped
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 3)
self.assertEqual((0.775, 10, 10), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration Nine
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
min_pass.run(dag)
# Iteration nine the score is worse than the minium point. Do not update minimum point
# and since is bumped
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 4)
self.assertEqual((0.775, 10, 10), state.score)
self.assertIsNone(min_pass.property_set["test_minimum_point"])
# Iteration 10
min_pass.property_set["fidelity"] = 0.775
min_pass.property_set["depth"] = 36
min_pass.property_set["size"] = 40
out_dag = min_pass.run(dag)
# Iteration 10 score is worse, but we've reached the set backtrack
# depth of 5 iterations since the last minimum so we exit here
state = min_pass.property_set["test_minimum_point_state"]
self.assertEqual(state.since, 5)
self.assertEqual((0.775, 10, 10), state.score)
self.assertTrue(min_pass.property_set["test_minimum_point"])
self.assertIs(out_dag, state.dag)