示例#1
0
    def test_infinite_loop_over_interruptable_runnable(self):
        """Stop signal must propagate to child runnable."""
        class IntInc(Runnable):
            def __init__(self):
                super(IntInc, self).__init__()
                self.time_to_stop = threading.Event()
                self.first_run = threading.Event()

            def next(self, state):
                self.first_run.set()
                self.time_to_stop.wait()
                return state.updated(cnt=state.cnt + 1)

            def halt(self):
                self.time_to_stop.set()

        loop = Loop(IntInc())
        s = loop.run(State(cnt=0))

        # make sure loop body runnable is run at least once
        loop.runnable.first_run.wait()

        loop.stop()

        self.assertTrue(s.result().cnt >= 1)
示例#2
0
    def test_finite_loop(self):
        class Inc(Runnable):
            def next(self, state):
                return state.updated(cnt=state.cnt + 1)

        it = Loop(Inc(), 10)
        s = it.run(State(cnt=0)).result()

        self.assertEqual(s.cnt, 10)
示例#3
0
    def test_memo_in_a_loop(self):
        inc = TestLog.Inc()
        log = Log(key=lambda state: state.x, memo=True)
        wrk = Loop(inc | log, max_iter=3)
        inp = State(x=0)
        out = wrk.run(inp).result()

        self.assertEqual(len(log.records), 3)
        self.assertEqual([r['data'] for r in log.records], [1, 2, 3])
示例#4
0
    def test_basic(self):
        class Inc(Runnable):
            def next(self, state):
                return state.updated(cnt=state.cnt + 1)

        it = Loop(Inc(), max_iter=100, convergence=100, key=lambda _: None)
        s = it.run(State(cnt=0)).result()

        self.assertEqual(s.cnt, 100)
示例#5
0
    def test_infinite_loop_stops_before_first_run(self):
        """An infinite loop can be preemptively stopped (before starting)."""
        class Inc(Runnable):
            def next(self, state):
                return state.updated(cnt=state.cnt + 1)

        loop = Loop(Inc())
        loop.stop()
        state = loop.run(State(cnt=0))

        self.assertEqual(state.result().cnt, 0)
示例#6
0
    def test_loop(self):
        class Identity(Runnable, traits.MIMO):
            def next(self, states):
                return states

        prog = Loop(Identity(), max_iter=10, convergence=10, key=lambda _: None)
        ss = States(State(idx=0), State(idx=1))

        res = prog.run(ss).result()
        self.assertEqual(res[0].idx, 0)
        self.assertEqual(res[1].idx, 1)

        with self.assertRaises(traits.StateDimensionalityError):
            prog.run(State()).result()
示例#7
0
    def test_infinite_loop_runs_after_stop(self):
        """An infinite loop can be started again after being stopped."""
        class Inc(Runnable):
            def __init__(self):
                super(Inc, self).__init__()
                self.first_run = threading.Event()

            def next(self, state):
                self.first_run.set()
                return state.updated(cnt=state.cnt + 1)

        loop = Loop(Inc())
        state1 = loop.run(State(cnt=0))

        # make sure loop body runnable is run at least once, then issue stop
        loop.runnable.first_run.wait(timeout=1)
        loop.stop()

        # check the state AND make sure next() finishes (see #111)
        self.assertTrue(state1.result().cnt >= 1)

        # reset our test event object
        loop.runnable.first_run.clear()

        # run loop again
        state2 = loop.run(State(cnt=0))

        # make sure loop body runnable is run at least once, then issue stop
        loop.runnable.first_run.wait(timeout=1)
        loop.stop()

        self.assertTrue(state2.result().cnt >= 1)
示例#8
0
    def test_validation(self):
        class simo(Runnable, traits.SIMO):
            def next(self, state):
                return States(state, state)

        with self.assertRaises(TypeError):
            Loop(simo())
 def test_iter_walk(self):
     flow = Loop(RacingBranches(Runnable(), Runnable()) | ArgMin())
     names = [r.name for r in iter_inorder(flow)]
     self.assertEqual(names, [
         'Loop', 'Branch', 'RacingBranches', 'Runnable', 'Runnable',
         'ArgMin'
     ])
 def test_callback_walk(self):
     flow = Loop(RacingBranches(Runnable(), Runnable()) | ArgMin())
     names = []
     walk_inorder(flow, visit=lambda r, _: names.append(r.name))
     self.assertEqual(names, [
         'Loop', 'Branch', 'RacingBranches', 'Runnable', 'Runnable',
         'ArgMin'
     ])
    def test_loop(self):
        class MIMOIdent(traits.MIMO, Runnable):
            def next(self, state):
                return state

        wrk = Loop(MIMOIdent(),
                   max_iter=10,
                   convergence=10,
                   key=lambda _: None)
        inp = States(State(idx=0), State(idx=1))

        out = wrk.run(inp).result()
        self.assertEqual(out[0].idx, 0)
        self.assertEqual(out[1].idx, 1)

        with self.assertRaises(traits.StateDimensionalityError):
            wrk.run(State()).result()
示例#12
0
    def test_infinite_loop_stops(self):
        """An infinite loop can be stopped after at least one iteration."""
        class Inc(Runnable):
            def __init__(self):
                super(Inc, self).__init__()
                self.first_run = threading.Event()

            def next(self, state):
                self.first_run.set()
                return state.updated(cnt=state.cnt + 1)

        loop = Loop(Inc())
        state = loop.run(State(cnt=0))

        # make sure loop body runnable is run at least once, then issue stop
        loop.runnable.first_run.wait(timeout=1)
        loop.stop()

        self.assertTrue(state.result().cnt >= 1)
    def test_dimensions_match_on_compose(self):
        class A(Runnable, traits.ProblemSampler):
            def next(self, state):
                pass

        # dimensionality check
        Map(A()) | ArgMin()
        with self.assertRaises(TypeError):
            A() | ArgMin()
        with self.assertRaises(TypeError):
            ArgMin() | Map(A())
        with self.assertRaises(TypeError):
            ArgMin() | Map(ArgMin())
        with self.assertRaises(TypeError):
            Loop(ArgMin())
示例#14
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))
示例#15
0
problems = chain(
    sorted(glob('problems/qbsolv/bqp100_*'))[:5],
    sorted(glob('problems/qbsolv/bqp2500_*'))[:5],
    sorted(glob('problems/random-chimera/2048*'))[:5],
    sorted(glob('problems/random-chimera/8192*'))[:5],
    sorted(glob('problems/ac3/*'))[:5],
)

solver_factories = [
    ("10 second Tabu", lambda **kw: TabuProblemSampler(timeout=10000)),
    ("10k sweeps Simulated Annealing", lambda **kw: IdentityDecomposer() |
     SimulatedAnnealingSubproblemSampler(sweeps=10000) | SplatComposer()),
    ("qbsolv-like solver", lambda qpu, **kw: Loop(RacingBranches(
        InterruptableTabuSampler(quantum_timeout=200),
        EnergyImpactDecomposer(max_size=50, rolling=True, rolling_history=0.15)
        | QPUSubproblemAutoEmbeddingSampler(qpu_sampler=qpu)
        | SplatComposer()) | ArgMin(),
                                                  max_iter=100,
                                                  convergence=10)),
    ("tiling chimera solver", lambda qpu, **kw: Loop(RacingBranches(
        InterruptableTabuSampler(quantum_timeout=200),
        TilingChimeraDecomposer(size=(16, 16, 4))
        | QPUSubproblemExternalEmbeddingSampler(qpu_sampler=qpu)
        | SplatComposer(),
    ) | ArgMin(),
                                                     max_iter=100,
                                                     convergence=10)),
    ("qbsolv-classic", lambda **kw: QBSolvProblemSampler()),
    ("qbsolv-qpu", lambda qpu, **kw: QBSolvProblemSampler(qpu_sampler=qpu)),
]
示例#16
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)
示例#17
0
class KerberosSampler(dimod.Sampler):
    """An opinionated dimod-compatible hybrid asynchronous decomposition sampler
    for problems of arbitrary structure and size.

    Examples:
        This example solves a two-variable Ising model.

        >>> import dimod
        >>> response = KerberosSampler().sample_ising(
        ...                     {'a': -0.5, 'b': 1.0}, {('a', 'b'): -1})
        >>> response.data_vectors['energy']
        array([-1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5, -1.5])

    """

    properties = None
    parameters = None
    runnable = None

    def __init__(self):
        self.parameters = {
            'init_sample': [],
            'max_iter': [],
            'convergence': [],
            'num_reads': [],
            'sa_reads': [],
            'sa_sweeps': [],
            'qpu_reads': [],
            'max_subproblem_size': []
        }
        self.properties = {}

    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(),
            IdentityDecomposer()
            | SimulatedAnnealingSubproblemSampler(num_reads=sa_reads,
                                                  sweeps=sa_sweeps)
            | SplatComposer(),
            EnergyImpactDecomposer(
                size=subproblem_size, rolling=True, rolling_history=0.2)
            | 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)
示例#18
0
 def test_loop(self):
     r = Loop(self.RunnableA())
     self.assertEqual(self.children(r), ['RunnableA'])