Пример #1
0
    def test_composition(self):
        class A(Runnable):
            def next(self, state):
                return state.updated(x=state.x + 1)

        class B(Runnable):
            def next(self, state):
                return state.updated(x=state.x * 7)

        a, b = A(), B()
        s = State(x=1)

        b1 = Branch(components=(a, b))
        self.assertEqual(b1.components, (a, b))
        self.assertEqual(b1.run(s).result().x, (s.x + 1) * 7)

        b2 = b1 | b | a
        self.assertEqual(b2.components, (a, b, b, a))
        self.assertEqual(b2.run(s).result().x, (s.x + 1) * 7 * 7 + 1)

        with self.assertRaises(TypeError):
            a | 1
        with self.assertRaises(TypeError):
            b1 | 1
Пример #2
0
    def test_infinite_loop_stops(self):
        """An infinite loop can be stopped after 10 iterations."""
        class Countdown(Runnable):
            """Countdown runnable that sets a semaphore on reaching zero."""
            def __init__(self):
                super(Countdown, self).__init__()
                self.ring = threading.Event()

            def next(self, state):
                output = state.updated(cnt=state.cnt - 1)
                if output.cnt <= 0:
                    self.ring.set()
                return output

        countdown = Countdown()
        loop = LoopWhileNoImprovement(countdown)
        state = loop.run(State(cnt=10))

        # stop only AFTER countdown reaches zero (10 iterations)
        # timeout in case Countdown failed before setting the flag
        countdown.ring.wait(timeout=1)
        loop.stop()

        self.assertTrue(state.result().cnt <= 0)
Пример #3
0
    def test_custom_qpu_params(self):
        bqm = dimod.BinaryQuadraticModel.from_ising({'a': 1}, {})
        init = State.from_subproblem(bqm)

        # define a mock sampler that exposes some parameters of interest
        mock_sampler = mock.MagicMock()
        mock_sampler.parameters = {
            'num_reads': [],
            'chain_strength': [],
            'future_proof': []
        }

        qpu_params = dict(chain_strength=2, future_proof=True)

        workflow = QPUSubproblemAutoEmbeddingSampler(
            num_reads=10, qpu_sampler=mock_sampler, sampling_params=qpu_params)

        # run mock sampling
        workflow.run(init).result()

        # verify mock sampler received custom kwargs
        mock_sampler.sample.assert_called_once_with(bqm,
                                                    num_reads=10,
                                                    **qpu_params)
Пример #4
0
    def test_initial_state(self):
        initial = State(val=10)
        states = States(State(val=1), State(val=2))
        result = Reduce(self.Sum(), initial_state=initial).run(states).result()

        self.assertEqual(result.val, 10 + 1 + 2)
Пример #5
0
    def test_map_lambda(self):
        states = States(State(cnt=1), State(cnt=2))
        result = Map(Lambda(lambda _, s: s.updated(cnt=s.cnt + 1))).run(states).result()

        self.assertEqual(result[0].cnt, states[0].cnt + 1)
        self.assertEqual(result[1].cnt, states[1].cnt + 1)
Пример #6
0
    def test_valid_output(self):
        class Component(traits.SubproblemProducing, Runnable):
            def next(self, state):
                return state.updated(subproblem=True)

        self.assertTrue(Component().run(State()).result().subproblem)
Пример #7
0
 def next(self, states):
     return States(State(subsamples=1), State(subsamples=2))
Пример #8
0
 def next(self, state):
     return States(State(embedding=1), State(embedding=2))
Пример #9
0
 def next(self, states):
     # should return States()
     return State()
Пример #10
0
 def error(self, exc):
     return State(error=True)
Пример #11
0
 def test_construction(self):
     self.assertDictEqual(State(), dict(samples=None, problem=None))
     self.assertEqual(State(samples=[1]).samples, [1])
     self.assertEqual(State(problem={'a': 1}).problem, {'a': 1})
     self.assertEqual(State(debug={'a': 1}).debug, {'a': 1})
 def test_res(self):
     for val in 1, 'x', True, False, State(problem=1), lambda: None:
         f = Present(result=val)
         self.assertIsInstance(f, Future)
         self.assertTrue(f.done())
         self.assertEqual(f.result(), val)
Пример #13
0
    def test_state_api(self):
        states = States(State(x=1), State(y=1))

        self.assertEqual(states.result(), states)
        self.assertEqual(states.updated(x=2),
                         States(State(x=2), State(x=2, y=1)))
Пример #14
0
    def sample(self,
               bqm,
               init_sample=None,
               max_iter=100,
               convergence=10,
               num_reads=1,
               sa_reads=1,
               sa_sweeps=1000,
               qpu_reads=100,
               qpu_sampler=None,
               max_subproblem_size=50):
        """Run Tabu search, Simulated annealing and QPU subproblem sampling (for
        high energy impact problem variables) in parallel and return the best
        samples.

        Args:
            bqm (:obj:`~dimod.BinaryQuadraticModel`):
                Binary quadratic model to be sampled from.

            init_sample (:class:`~dimod.SampleSet`, callable, ``None``):
                Initial sample set (or sample generator) used for each "read".
                Use a random sample for each read by default.

            max_iter (int):
                Number of iterations in the hybrid algorithm.

            convergence (int):
                Number of iterations with no improvement that terminates sampling.

            num_reads (int):
                Number of reads. Each sample is the result of a single run of the
                hybrid algorithm.

            sa_reads (int):
                Number of reads in the simulated annealing branch.

            sa_sweeps (int):
                Number of sweeps in the simulated annealing branch.

            qpu_reads (int):
                Number of reads in the QPU branch.

            qpu_sampler (:class:`dimod.Sampler`, optional, default=DWaveSampler()):
                Quantum sampler such as a D-Wave system.

            max_subproblem_size (int):
                Maximum size of the subproblem selected in the QPU branch.

        Returns:
            :obj:`~dimod.SampleSet`: A `dimod` :obj:`.~dimod.SampleSet` object.

        """

        if callable(init_sample):
            init_state_gen = lambda: State.from_sample(init_sample(), bqm)
        elif init_sample is None:
            init_state_gen = lambda: State.from_sample(random_sample(bqm), bqm)
        elif isinstance(init_sample, dimod.SampleSet):
            init_state_gen = lambda: State.from_sample(init_sample, bqm)
        else:
            raise TypeError(
                "'init_sample' should be a SampleSet or a SampleSet generator")

        subproblem_size = min(len(bqm), max_subproblem_size)

        iteration = RacingBranches(
            InterruptableTabuSampler(),
            InterruptableSimulatedAnnealingProblemSampler(num_reads=sa_reads,
                                                          sweeps=sa_sweeps),
            EnergyImpactDecomposer(size=subproblem_size,
                                   rolling=True,
                                   rolling_history=0.3,
                                   traversal='bfs')
            | QPUSubproblemAutoEmbeddingSampler(num_reads=qpu_reads,
                                                qpu_sampler=qpu_sampler)
            | SplatComposer(),
        ) | ArgMin()
        self.runnable = Loop(iteration,
                             max_iter=max_iter,
                             convergence=convergence)

        samples = []
        energies = []
        for _ in range(num_reads):
            init_state = init_state_gen()
            final_state = self.runnable.run(init_state)
            # the best sample from each run is one "read"
            ss = final_state.result().samples
            ss.change_vartype(bqm.vartype, inplace=True)
            samples.append(ss.first.sample)
            energies.append(ss.first.energy)

        return dimod.SampleSet.from_samples(samples,
                                            vartype=bqm.vartype,
                                            energy=energies)
Пример #15
0
class TestHybridRunnable(unittest.TestCase):
    bqm = dimod.BinaryQuadraticModel({}, {
        'ab': 1,
        'bc': 1,
        'ca': -1
    }, 0, dimod.SPIN)
    init_state = State.from_sample(min_sample(bqm), bqm)

    def test_generic(self):
        runnable = HybridRunnable(TabuSampler(), fields=('problem', 'samples'))
        response = runnable.run(self.init_state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().samples.record[0].energy, -3.0)

    def test_validation(self):
        with self.assertRaises(TypeError):
            HybridRunnable(1, 'ab')

        with self.assertRaises(ValueError):
            HybridRunnable(TabuSampler(), None)

        with self.assertRaises(ValueError):
            HybridRunnable(TabuSampler(), ('a'))

        self.assertIsInstance(HybridRunnable(TabuSampler(), 'ab'),
                              HybridRunnable)
        self.assertIsInstance(HybridRunnable(TabuSampler(), ('a', 'b')),
                              HybridRunnable)
        self.assertIsInstance(HybridRunnable(TabuSampler(), ['a', 'b']),
                              HybridRunnable)

    def test_problem_sampler_runnable(self):
        runnable = HybridProblemRunnable(TabuSampler())
        response = runnable.run(self.init_state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().samples.record[0].energy, -3.0)

    def test_subproblem_sampler_runnable(self):
        runnable = HybridSubproblemRunnable(TabuSampler())
        state = self.init_state.updated(subproblem=self.bqm)
        response = runnable.run(state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().subsamples.record[0].energy, -3.0)

    def test_runnable_composition(self):
        runnable = IdentityDecomposer() | HybridSubproblemRunnable(
            TabuSampler()) | IdentityComposer()
        response = runnable.run(self.init_state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().samples.record[0].energy, -3.0)

    def test_racing_workflow_with_oracle_subsolver(self):
        workflow = hybrid.LoopUntilNoImprovement(hybrid.RacingBranches(
            hybrid.InterruptableTabuSampler(),
            hybrid.EnergyImpactDecomposer(size=1)
            | HybridSubproblemRunnable(dimod.ExactSolver())
            | hybrid.SplatComposer()) | hybrid.ArgMin(),
                                                 convergence=3)
        state = State.from_sample(min_sample(self.bqm), self.bqm)
        response = workflow.run(state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().samples.record[0].energy, -3.0)

    def test_sampling_parameters_filtering(self):
        class Sampler(dimod.ExactSolver):
            """Exact solver that fails if a sampling parameter is provided."""
            parameters = {}

            def sample(self, bqm):
                return super().sample(bqm)

        workflow = hybrid.LoopUntilNoImprovement(hybrid.RacingBranches(
            hybrid.InterruptableTabuSampler(),
            hybrid.EnergyImpactDecomposer(size=1)
            | HybridSubproblemRunnable(Sampler())
            | hybrid.SplatComposer()) | hybrid.ArgMin(),
                                                 convergence=3)
        state = State.from_sample(min_sample(self.bqm), self.bqm)
        response = workflow.run(state)

        self.assertIsInstance(response, concurrent.futures.Future)
        self.assertEqual(response.result().samples.record[0].energy, -3.0)
Пример #16
0
    def test_basic_runnable(self):
        runnable = Lambda(lambda _, s: s.updated(c=s.a * s.b))
        state = State(a=2, b=3)
        result = runnable.run(state).result()

        self.assertEqual(result.c, state.a * state.b)
Пример #17
0
    def test_input_type_invariant(self):
        inp1 = State(x=1)
        self.assertEqual(Identity().run(inp1).result(), inp1)

        inp2 = States(State(x=1), State(x=2))
        self.assertEqual(Identity().run(inp2).result(), inp2)
Пример #18
0
    def test_updated(self):
        a = SampleSet.from_samples([1, 0, 1], 'SPIN', 0)
        b = SampleSet.from_samples([0, 1, 0], 'SPIN', 0)
        s1 = State(samples=a)
        s2 = State(samples=b, emb={'a': {'b': 1}}, debug={'x': 1})
        s3 = State(debug={'x': {'y': {'z': [1]}}})

        # test simple replace
        self.assertDictEqual(s1.updated(), s1)
        self.assertDictEqual(s1.updated(samples=b), State(samples=b))
        self.assertDictEqual(s2.updated(emb={'b': 1}).emb, {'b': 1})
        self.assertDictEqual(
            s1.updated(samples=b, debug=dict(x=1), emb={'a': {
                'b': 1
            }}), s2)

        # test recursive merge of `debug`
        self.assertDictEqual(s1.updated(debug=dict(x=1)).debug, {'x': 1})
        self.assertDictEqual(s2.updated(debug=dict(x=2)).debug, {'x': 2})
        self.assertDictEqual(
            s2.updated(debug=dict(y=2)).debug, {
                'x': 1,
                'y': 2
            })
        self.assertDictEqual(
            s2.updated(debug=dict(y=2)).debug, {
                'x': 1,
                'y': 2
            })

        self.assertDictEqual(
            s3.updated(debug={
                'x': {
                    'y': {
                        'z': [2]
                    }
                }
            }).debug, {'x': {
                'y': {
                    'z': [2]
                }
            }})
        self.assertDictEqual(
            s3.updated(debug={
                'x': {
                    'y': {
                        'w': 2
                    }
                }
            }).debug, {'x': {
                'y': {
                    'z': [1],
                    'w': 2
                }
            }})

        # test clear
        self.assertEqual(s2.updated(emb=None).emb, None)
        self.assertEqual(s2.updated(debug=None).debug, None)
Пример #19
0
class TestComponentDecomposer(unittest.TestCase):
    bqm = dimod.BinaryQuadraticModel({
        'a': 2,
        'b': -1,
        'd': 1
    }, {
        'bc': 1,
        'cd': 1
    }, 0, dimod.SPIN)
    state = State.from_sample(random_sample(bqm), bqm)

    def test_default(self):
        decomposer = ComponentDecomposer()

        state1 = decomposer.next(self.state)
        self.assertIn(dict(state1.subproblem.linear), ({
            'a': 2
        }, {
            'b': -1,
            'c': 0,
            'd': 1
        }))

        state2 = decomposer.next(state1)
        self.assertIn(dict(state2.subproblem.linear), ({
            'a': 2
        }, {
            'b': -1,
            'c': 0,
            'd': 1
        }))
        self.assertNotEqual(dict(state1.subproblem.linear),
                            dict(state2.subproblem.linear))

        state3 = decomposer.next(
            state2)  # silent_rewind=True, so rewind w/o raising an assertion
        self.assertIn(dict(state3.subproblem.linear), ({
            'a': 2
        }, {
            'b': -1,
            'c': 0,
            'd': 1
        }))

    def test_sort(self):
        decomposer = ComponentDecomposer(key=len)

        state1 = decomposer.next(self.state)
        self.assertDictEqual(dict(state1.subproblem.linear), {
            'b': -1,
            'c': 0,
            'd': 1
        })

    def test_sort_reverse(self):
        decomposer = ComponentDecomposer(key=len, reverse=False)

        state1 = decomposer.next(self.state)
        self.assertDictEqual(dict(state1.subproblem.linear), {'a': 2})

    def test_no_silent_rewind(self):
        decomposer = ComponentDecomposer(silent_rewind=False)
        state1 = decomposer.next(self.state)
        state2 = decomposer.next(state1)

        with self.assertRaises(EndOfStream):
            state3 = decomposer.next(state2)

    def test_key_func(self):
        def sum_linear_biases(component):
            total = 0
            for v in component:
                total += self.bqm.get_linear(v)
            return total

        decomposer = ComponentDecomposer(key=sum_linear_biases)

        state1 = decomposer.next(self.state)
        self.assertDictEqual(dict(state1.subproblem.linear), {'a': 2})

    def test_no_rolling(self):
        decomposer = ComponentDecomposer(rolling=False, key=len)

        state1 = decomposer.next(self.state)
        self.assertDictEqual(dict(state1.subproblem.linear), {
            'b': -1,
            'c': 0,
            'd': 1
        })

        state2 = decomposer.next(state1)
        self.assertDictEqual(dict(state2.subproblem.linear), {
            'b': -1,
            'c': 0,
            'd': 1
        })

    def test_one_component(self):
        bqm = dimod.BinaryQuadraticModel({
            'a': 1,
            'b': -1
        }, {'ab': 1}, 0, dimod.SPIN)
        state = State.from_sample(random_sample(bqm), bqm)

        decomposer = ComponentDecomposer()
        state1 = decomposer.next(state)

        self.assertEqual(bqm, state1.subproblem)

    def test_empty(self):
        bqm = dimod.BinaryQuadraticModel(dimod.SPIN)
        state = State.from_sample(random_sample(bqm), bqm)

        decomposer = ComponentDecomposer()
        state1 = decomposer.next(state)

        self.assertEqual(bqm, state1.subproblem)
Пример #20
0
    def test_set_state_var(self):
        """State variable is properly set/reset/updated."""

        self.assertEqual(Const(x=1).run(State()).result().x, 1)
        self.assertEqual(Const(x=1).run(State(x=0)).result().x, 1)
        self.assertEqual(Const(x=None).run(State(x=0)).result().x, None)
Пример #21
0
 def next(self, state):
     # FAIL: embedding is missing in second state
     return States(State(embedding=1), State())
Пример #22
0
    def test_composition(self):
        class A(Runnable):
            def next(self, state):
                return state.updated(x=state.x + 1)

        class B(Runnable):
            def next(self, state):
                return state.updated(x=state.x * 7)

        a, b = A(), B()

        # single branch

        b1 = Branches(a)
        ss = States(State(x=1))
        res = b1.run(ss).result()

        self.assertEqual(b1.branches, (a, ))
        self.assertEqual(len(res), 1)
        self.assertEqual(res[0].x, ss[0].x + 1)

        # two branches, explicit and implicit construction

        for b2 in [Branches(a, b), a & b]:
            ss = States(State(x=1), State(x=1))
            res = b2.run(ss).result()

            self.assertEqual(b2.branches, (a, b))
            self.assertEqual(len(res), 2)
            self.assertEqual(res[0].x, ss[0].x + 1)
            self.assertEqual(res[1].x, ss[1].x * 7)

        # appending a branch to branches

        b3 = b2 & a
        ss = States(*[State(x=1) for _ in range(3)])
        res = b3.run(ss).result()

        self.assertEqual(b3.branches, (a, b, a))
        self.assertEqual(len(res), 3)
        self.assertEqual(res[0].x, ss[0].x + 1)
        self.assertEqual(res[1].x, ss[1].x * 7)
        self.assertEqual(res[2].x, ss[2].x + 1)

        # prepending a branch to branches
        b4 = b & b2
        ss = States(*[State(x=1) for _ in range(3)])
        res = b4.run(ss).result()

        self.assertEqual(b4.branches, (b, a, b))
        self.assertEqual(len(res), 3)
        self.assertEqual(res[0].x, ss[0].x * 7)
        self.assertEqual(res[1].x, ss[1].x + 1)
        self.assertEqual(res[2].x, ss[2].x * 7)

        # invalid type

        with self.assertRaises(TypeError):
            b & 1
        with self.assertRaises(TypeError):
            b1 & 1
Пример #23
0
    def test_valid_input(self):
        class Component(traits.SubproblemIntaking, Runnable):
            def next(self, state):
                return State()

        self.assertTrue(Component().run(State(subproblem=None)).result())
Пример #24
0
 def test_basic(self):
     s = State(x=1)
     self.assertEqual(Dup(0).run(s).result(), States())
     self.assertEqual(Dup(1).run(s).result(), States(s))
     self.assertEqual(Dup(2).run(s).result(), States(s, s))
Пример #25
0
 def next(self, state):
     return State()
Пример #26
0
    def test_immutability(self):
        s = State(x=1)
        ss = Dup(1).run(s).result()

        s.x = 2
        self.assertEqual(ss[0].x, 1)
Пример #27
0
import dimod

from hybrid.samplers import (QPUSubproblemAutoEmbeddingSampler,
                             InterruptableTabuSampler)
from hybrid.decomposers import EnergyImpactDecomposer
from hybrid.composers import SplatComposer
from hybrid.core import State
from hybrid.flow import RacingBranches, ArgMin, Loop
from hybrid.utils import min_sample

# load a problem
problem = sys.argv[1]
with open(problem) as fp:
    bqm = dimod.BinaryQuadraticModel.from_coo(fp)

# define the solver
iteration = RacingBranches(
    InterruptableTabuSampler(),
    EnergyImpactDecomposer(max_size=50, rolling=True, rolling_history=0.15)
    | QPUSubproblemAutoEmbeddingSampler()
    | SplatComposer()) | ArgMin()
main = Loop(iteration, max_iter=10, convergence=3)

# run solver
init_state = State.from_sample(min_sample(bqm), bqm)
solution = main.run(init_state).result()

# show results
print("Solution: sample={s.samples.first}".format(s=solution))
Пример #28
0
    def test_basic(self):
        states = States(State(val=1), State(val=2), State(val=3))
        result = Reduce(self.Sum()).run(states).result()

        self.assertIsInstance(result, State)
        self.assertEqual(result.val, 1 + 2 + 3)