def test_input_type_invariant(self): inp = State(x=1) ii = BlockingIdentity() fut = ii.run(inp) ii.stop() out = fut.result() self.assertEqual(out, inp) inp = States(State(x=1), State(x=2)) ii = BlockingIdentity() fut = ii.run(inp) ii.stop() out = fut.result() self.assertEqual(out, inp)
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()
def next(self, states): """Collapse all `states` to a single output state using the `self.runnable`.""" states = iter(states) if self.initial_state is None: result = next(states) else: result = self.initial_state for state in states: result = self.runnable.run(States(result, state), executor=immediate_executor).result() return result
def test_branch_with_single_component(self): """Traits requirements from inner runnable must be reflected in branch.""" class ValidSISO(traits.SISO, Runnable): def next(self, state): return state with self.assertRaises(traits.StateDimensionalityError): Branch(components=(ValidSISO(), )).run(States()).result() self.assertEqual( Branch(components=(ValidSISO(), )).run(State(x=1)).result().x, 1) class InvalidSISO(traits.SISO, Runnable): def next(self, state): return States(state, state) with self.assertRaises(traits.StateDimensionalityError): Branch(components=(InvalidSISO(), )).run(State()).result() Branch(components=(InvalidSISO(), )).run(States()).result() # input: list of states with subproblem # output: list of states with subsamples class SubproblemSamplerMIMO(traits.SubproblemSampler, traits.MIMO, Runnable): def next(self, states): return States(State(subsamples=1), State(subsamples=2)) with self.assertRaises(traits.StateDimensionalityError): Branch(components=(SubproblemSamplerMIMO(), )).run( State()).result() with self.assertRaises(traits.StateTraitMissingError): Branch(components=(SubproblemSamplerMIMO(), )).run(States( State())).result() r = Branch(components=(SubproblemSamplerMIMO(), )).run( States(State(subproblem=True))).result() self.assertEqual(r[0].subsamples, 1) self.assertEqual(r[1].subsamples, 2)
def test_continuity(self): class Fast(Runnable): def next(self, state): time.sleep(0.1) return state.updated(x=state.x + 1) class Slow(Runnable): def next(self, state): time.sleep(0.2) return state.updated(x=state.x + 2) bs = Branches(Slow(), Fast(), Slow()) ss = States(*[State(x=0) for _ in range(3)]) res = bs.run(ss).result() self.assertEqual([s.x for s in res], [2, 1, 2])
def next(self, state, **runopts): futures = [ branch.run(state.updated(), **runopts) for branch in self.branches ] # wait for all branches to finish concurrent.futures.wait(futures, return_when=concurrent.futures.ALL_COMPLETED) # collect resolved states (in original order, not completion order) states = States() for f in futures: states.append(f.result()) return states
def next(self, state, **runopts): output = States() runopts.update(executor=immediate_executor, silent_rewind=False) logger.debug("{} unwinding {!r}".format(self.name, self.runnable)) while True: try: state = self.runnable.run(state, **runopts).result() output.append(state) except EndOfStream: break logger.debug("{} collected {} states".format(self.name, len(output))) return output
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()
def test_ising_triangle_flip(self): bqm = dimod.BQM.from_ising({}, {'ab': 1, 'bc': 1, 'ca': 1}) s1 = State.from_samples({'a': -1, 'b': +1, 'c': +1}, bqm) s2 = State.from_samples({'a': +1, 'b': -1, 'c': +1}, bqm) icm = IsoenergeticClusterMove() inp = States(s1, s2) res = icm.run(inp).result() # Expected: ('a', 'b') identified as (the sole) cluster, selected, # resulting in variables {'a', 'b'} flipped. Effectively, input states # are simply swapped. self.assertEqual(res[0].samples, s2.samples) self.assertEqual(res[1].samples, s1.samples) # verify total samples energy doesn't change after ICM self.assertEqual(self.total_energy(inp), self.total_energy(res))
def test_large_sparse(self): "Total energy is preserved after ICM on random samples over random graph." # random Erdős-Rényi sparse graph with 100 nodes and 10% density graph = nx.generators.fast_gnp_random_graph(n=100, p=0.1) bqm = dimod.generators.uniform(graph=graph, vartype=dimod.SPIN) nodes = sorted(bqm.variables) # random input samples s1 = State.from_problem(bqm, samples=random_sample) s2 = State.from_problem(bqm, samples=random_sample) inp = States(s1, s2) icm = IsoenergeticClusterMove() res = icm.run(inp).result() self.assertAlmostEqual(self.total_energy(inp), self.total_energy(res))
def test_simple(self): "Two output states created for two input samples, in correct order." bqm = dimod.BQM.from_ising({}, {'ab': 1}) inp = State.from_samples([{'a': 1, 'b': 1}, {'a': -1, 'b': 1}], bqm) exp = States(State.from_sample({ 'a': 1, 'b': 1 }, bqm), State.from_sample({ 'a': -1, 'b': 1 }, bqm)) out = ExplodeSamples().run(inp).result() self.assertEqual(out, exp)
def test_small_lattice(self): graph = nx.generators.lattice.grid_2d_graph(5, 5) bqm = dimod.generators.uniform(graph, vartype=dimod.BINARY, low=1, high=1) nodes = sorted(bqm.variables) s1 = State.from_samples( dict( zip(nodes, [ 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0 ])), bqm) s2 = State.from_samples( dict( zip(nodes, [ 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0 ])), bqm) exp1 = SampleSet.from_samples_bqm( dict( zip(nodes, [ 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0 ])), bqm) exp2 = SampleSet.from_samples_bqm( dict( zip(nodes, [ 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0 ])), bqm) icm = IsoenergeticClusterMove(seed=1234) inp = States(s1, s2) res = icm.run(inp).result() self.assertEqual(res[0].samples, exp1) self.assertEqual(res[1].samples, exp2) # verify total samples energy doesn't change after ICM self.assertEqual(self.total_energy(inp), self.total_energy(res))
def next(self, states, **runopts): """Collapse all `states` to a single output state using the `self.runnable`.""" logger.debug("{} collapsing {} input states with {!r}".format( self.name, len(states), self.runnable)) states = iter(states) if self.initial_state is None: result = next(states) else: result = self.initial_state runopts['executor'] = immediate_executor for state in states: result = self.runnable.run(States(result, state), **runopts).result() return result
def next(self, states, **runopts): futures = [ branch.run(state.updated(), **runopts) for branch, state in zip(self.branches, states) ] logger.debug("{} running {} branches in parallel".format( self.name, len(futures))) # wait for all branches to finish concurrent.futures.wait(futures, return_when=concurrent.futures.ALL_COMPLETED) # collect resolved states (in original order, not completion order) states = States() for f in futures: states.append(f.result()) return states
def test_parallel_independent_execution(self): class Component(Runnable): def __init__(self, runtime): super(Component, self).__init__() self.runtime = runtime def next(self, state): time.sleep(self.runtime) return state # make sure all branches really run in parallel n = 5 bs = Branches(*[Component(1) for _ in range(n)]) ss = States(*[State() for _ in range(n)]) with tictoc() as tt: bs.run(ss).result() # total runtime has to be smaller that the sum of individual runtimes self.assertTrue(1 <= tt.dt <= 2)
def test_aggregation(self): bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN) states = States(State.from_sample({ 'a': 1, 'b': -1 }, bqm), State.from_sample({ 'a': 1, 'b': -1 }, bqm)) expected = State(problem=bqm, samples=dimod.SampleSet.from_samples_bqm( { 'a': 1, 'b': -1 }, bqm, num_occurrences=[2])) state = MergeSamples(aggregate=True).run(states).result() self.assertEqual(state, expected)
def test_multiple(self): bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN) states = States(State.from_sample({ 'a': 1, 'b': -1 }, bqm), State.from_sample({ 'a': -1, 'b': 1 }, bqm)) expected = State.from_samples([{ 'a': 1, 'b': -1 }, { 'a': -1, 'b': 1 }], bqm) state = MergeSamples().run(states).result() self.assertEqual(state, expected)
def next(self, state, **runopts): runopts.update(racing_context=True) futures = [branch.run(state.updated(), **runopts) for branch in self.branches] # as soon as one is done, stop all others done, _ = concurrent.futures.wait( futures, return_when=concurrent.futures.FIRST_COMPLETED) logger.trace("RacingBranches done set: {}. Stopping remaining.".format(done)) self.stop() # debug info idx = futures.index(done.pop()) branch = self.branches[idx] logger.debug("{name} won idx={idx} branch={branch!r}".format( name=self.name, idx=idx, branch=branch)) # collect resolved states (in original order, not completion order!) states = States() for f in futures: states.append(f.result()) return states
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
def next(self, state): return States(State(embedding=1), State(embedding=2))
def next(self, state): # FAIL: embedding is missing in second state return States(State(embedding=1), State())
def next(self, state): # should return a single State() return States(state, state)
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)
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)
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)
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))
def next(self, state): return States(state, state)
def test_first(self): self.assertEqual(States(1).first, 1) self.assertEqual(States(1, 2).first, 1) with self.assertRaises(IndexError): States().first
def next(self, states): return States(State(subsamples=1), State(subsamples=2))
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)))