Exemple #1
0
    def test_branch_with_single_component(self):
        """Traits requirements from inner runnable must be reflected in branch."""
        class ValidSISO(Runnable, traits.SISO):
            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(Runnable, traits.SISO):
            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(Runnable, traits.MIMO, traits.SubproblemSampler):
            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)
Exemple #2
0
    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
Exemple #3
0
    def next(self, state):
        output = States()

        while True:
            try:
                state = self.runnable.run(state).result()
                output.append(state)
            except EndOfStream:
                break

        return output
Exemple #4
0
    def test_set_states_var(self):
        """All States have variable set."""

        wrk = Const(x=1)
        inp = States(State(), State(x=0), State(x=None))
        exp = States(State(x=1), State(x=1), State(x=1))
        self.assertEqual(wrk.run(inp).result(), exp)

        wrk = Const(x=None)
        inp = States(State(), State(x=1))
        exp = States(State(x=None), State(x=None))
        self.assertEqual(wrk.run(inp).result(), exp)
Exemple #5
0
    def next(self, state, **runopts):
        samples = state.samples
        if not samples:
            raise ValueError("no input samples")

        states = States()
        n = len(samples)
        for start, stop in zip(range(n), range(1, n + 1)):
            sample = samples.slice(start, stop, sorted_by=None)
            states.append(state.updated(samples=sample))

        return states
Exemple #6
0
    def next(self, state, **runopts):
        output = States()
        runopts.update(executor=immediate_executor, silent_rewind=False)

        while True:
            try:
                state = self.runnable.run(state, **runopts).result()
                output.append(state)
            except EndOfStream:
                break

        return output
    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
Exemple #8
0
    def test_mimo_with_specific_state_traits(self):
        # input: list of states with subproblem
        # output: list of states with subsamples
        class SubproblemSamplerMIMO(Runnable, traits.MIMO, traits.SubproblemSampler):
            def next(self, states):
                return States(State(subsamples=1), State(subsamples=2))

        with self.assertRaises(traits.StateDimensionalityError):
            SubproblemSamplerMIMO().run(State()).result()
        with self.assertRaises(traits.StateTraitMissingError):
            SubproblemSamplerMIMO().run(States(State())).result()

        r = SubproblemSamplerMIMO().run(States(State(subproblem=True))).result()
        self.assertEqual(r[0].subsamples, 1)
        self.assertEqual(r[1].subsamples, 2)
    def test_validation(self):
        bqm1 = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
        bqm2 = dimod.BinaryQuadraticModel({'b': 1}, {}, 0, dimod.SPIN)
        s1 = State.from_sample({'a': +1}, bqm1)
        s2 = State.from_sample({'b': -1}, bqm2)

        # two input states required
        with self.assertRaises(ValueError):
            inp = States(s1, s1, s1)
            IsoenergeticClusterMove().run(inp).result()

        # variables must match
        with self.assertRaises(ValueError):
            inp = States(s1, s2)
            IsoenergeticClusterMove().run(inp).result()
Exemple #10
0
    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
Exemple #11
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)
Exemple #12
0
    def test_not_validated(self):
        class NotValidated(Runnable, traits.NotValidated):
            def next(self, state):
                return state

        self.assertEqual(NotValidated().run(State(x=1)).result().x, 1)
        self.assertEqual(NotValidated().run(States(State(x=1))).result()[0].x, 1)
Exemple #13
0
    def test_dynamic_validation(self):
        class simo(traits.SIMO, Runnable):
            def next(self, state):
                return States(state, state)

        with self.assertRaises(StateDimensionalityError):
            Unwind(simo()).run(States()).result()
Exemple #14
0
    def next(self, states):
        self._futures = [self.runnable.run(state) for state in states]

        concurrent.futures.wait(self._futures,
                                return_when=concurrent.futures.ALL_COMPLETED)

        return States(*(f.result() for f in self._futures))
    def test_bimodal_cluster_sampling_statistics(self):
        bqm = dimod.BQM.from_qubo({'ab': 1, 'bd': 1, 'dc': 1, 'ca': 1})
        nodes = sorted(bqm.variables)

        s1 = State.from_samples(dict(zip(nodes, [0, 1, 0, 0])), bqm)
        s2 = State.from_samples(dict(zip(nodes, [0, 0, 1, 0])), bqm)

        exp1 = SampleSet.from_samples_bqm(dict(zip(nodes, [0, 0, 0, 0])), bqm)
        exp2 = SampleSet.from_samples_bqm(dict(zip(nodes, [0, 1, 1, 0])), bqm)

        icm = IsoenergeticClusterMove(seed=None)
        inp = States(s1, s2)
        exp = [exp1, exp2]

        # split between [exp1, exp2] and [exp2, exp1] as output samples
        # should be ~50%
        cnt = 0
        n = 100
        for _ in range(n):
            res = icm.run(inp).result()
            r1, r2 = pluck(res, 'samples')

            # test responses are valid
            self.assertIn(r1, exp)
            self.assertIn(r2, exp)

            # verify total samples energy doesn't change after ICM
            self.assertEqual(self.total_energy(inp), self.total_energy(res))

            # count responses
            if r1 == exp1 and r2 == exp2:
                cnt += 1

        self.assertLess(cnt, 0.75 * n)
        self.assertGreater(cnt, 0.25 * n)
Exemple #16
0
    def test_basic(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1, 'bc': -1, 'ca': 1}, 0, dimod.SPIN)
        state = State.from_sample(min_sample(bqm), bqm)
        antistate = State.from_sample(max_sample(bqm), bqm)

        result = GreedyPathMerge().run(States(state, antistate)).result()

        self.assertEqual(result.samples.first.energy, -3.0)
Exemple #17
0
    def test_unstructured_runnable(self):
        initial = State(val=10)
        states = States(State(val=2), State(val=3))

        multiply = Lambda(next=lambda self, s: s[0].updated(val=s[0].val * s[1].val))
        result = Reduce(multiply, initial_state=initial).run(states).result()

        self.assertEqual(result.val, 10*2*3)
Exemple #18
0
    def test_validated(self):
        class Validated(traits.SISO, Runnable):
            def next(self, state):
                return state

        with self.assertRaises(traits.StateDimensionalityError):
            Validated().run(States()).result()
        self.assertEqual(Validated().run(State(x=1)).result().x, 1)
Exemple #19
0
    def test_single(self):
        bqm = dimod.BinaryQuadraticModel({}, {'ab': 1}, 0, dimod.SPIN)

        states = States(State.from_sample({'a': 1, 'b': -1}, bqm))

        state = MergeSamples().run(states).result()

        self.assertEqual(state, states[0])
Exemple #20
0
    def test_siso(self):
        class ValidSISO(traits.SISO, Runnable):
            def next(self, state):
                return state

        with self.assertRaises(traits.StateDimensionalityError):
            ValidSISO().run(States()).result()
        self.assertEqual(ValidSISO().run(State(x=1)).result().x, 1)

        class InvalidSISO(traits.SISO, Runnable):
            def next(self, state):
                # should return a single State()
                return States(state, state)

        with self.assertRaises(traits.StateDimensionalityError):
            InvalidSISO().run(State()).result()
            InvalidSISO().run(States()).result()
Exemple #21
0
    def test_invalid_mimo(self):
        class InvalidMIMO(traits.MIMO, Runnable):
            def next(self, states):
                # should return States()
                return State()

        with self.assertRaises(traits.StateDimensionalityError):
            InvalidMIMO().run(States()).result()
Exemple #22
0
 def test_default_fold(self):
     bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
     states = States(
         State.from_sample(min_sample(bqm), bqm),  # energy: -1
         State.from_sample(max_sample(bqm), bqm),  # energy: +1
     )
     best = ArgMin().run(states).result()
     self.assertEqual(best.samples.first.energy, -1)
Exemple #23
0
 def test_custom_fold(self):
     bqm = dimod.BinaryQuadraticModel({'a': 1}, {}, 0, dimod.SPIN)
     states = States(
         State.from_sample(min_sample(bqm), bqm),  # energy: -1
         State.from_sample(max_sample(bqm), bqm),  # energy: +1
     )
     fold = ArgMin(key=lambda s: -s.samples.first.energy)
     best = fold.run(states).result()
     self.assertEqual(best.samples.first.energy, 1)
Exemple #24
0
    def next(self, states):
        """ICM between two first samples in the first two input states."""

        if len(states) > 2:
            raise ValueError("exactly two input states required")

        inp1, inp2 = states
        bqm = inp1.problem

        ss1 = inp1.samples.change_vartype(dimod.BINARY, inplace=False)
        ss2 = inp2.samples.change_vartype(dimod.BINARY, inplace=False)

        # sanity check: we operate on the same set of variables
        if ss1.variables ^ ss2.variables:
            raise ValueError(
                "input samples not over the same set of variables")

        # reorder variables, if necessary
        # (use sequence comparison, not set)
        variables = list(ss1.variables)
        if ss2.variables != variables:
            reorder = [ss2.variables.index(v) for v in variables]
            record = ss2.record[:, reorder]
            ss2 = dimod.SampleSet(record, variables, ss2.info, ss2.vartype)

        # samples' symmetric difference (XOR)
        # (form clusters of input variables with opposite values)
        sample1 = ss1.record.sample[0]
        sample2 = ss2.record.sample[0]
        symdiff = sample1 ^ sample2

        # for cluster detection we'll use a reduced problem graph
        graph = bqm.to_networkx_graph()
        # note: instead of numpy mask indexing of `notcluster`, we enumerate
        # non-cluster variables manually to avoid conversion of potentially
        # unhashable variable names to numpy types
        notcluster = [v for v, d in zip(variables, symdiff) if d == 0]
        graph.remove_nodes_from(notcluster)

        # pick a random variable that belongs to a cluster, then select the cluster
        node = self.random.choice(list(graph.nodes))
        cluster = nx.node_connected_component(graph, node)

        # flip variables from `cluster` in both input samples
        flipper = np.array([1 if v in cluster else 0 for v in variables])
        ss1.record.sample[0] ^= flipper
        ss2.record.sample[0] ^= flipper

        # change vartype back to input's type
        ss1.change_vartype(inp1.samples.vartype)
        ss2.change_vartype(inp2.samples.vartype)

        # update sampleset's energies
        ss1.record.energy = bqm.energies(ss1)
        ss2.record.energy = bqm.energies(ss2)

        return States(inp1.updated(samples=ss1), inp2.updated(samples=ss2))
    def test_map(self):
        class A(Runnable, traits.ProblemDecomposer):
            def next(self, state):
                return state.updated(subproblem=state.problem)

        a = A()
        m = Map(a)
        r = m.run(States(State(problem=1))).result()
        self.assertSetEqual(m.inputs, a.inputs)
        self.assertSetEqual(m.outputs, a.outputs)
    def next(self, states, **runopts):
        self._futures = [self.runnable.run(state, **runopts) for state in states]

        logger.debug("{} running {!r} on {} input states".format(
            self.name, self.runnable, len(states)))

        concurrent.futures.wait(self._futures,
                                return_when=concurrent.futures.ALL_COMPLETED)

        return States(*(f.result() for f in self._futures))
Exemple #27
0
    def test_branch(self):
        class Inc(Runnable):
            def next(self, state):
                return state.updated(cnt=state.cnt + 1)

        states = States(State(cnt=1), State(cnt=2))
        branch = Map(Inc()) | ArgMin('cnt')
        result = branch.run(states).result()

        self.assertEqual(result.cnt, states[0].cnt + 1)
Exemple #28
0
    def test_isolated(self):
        class Inc(Runnable):
            def next(self, state):
                return state.updated(cnt=state.cnt + 1)

        states = States(State(cnt=1), State(cnt=2))
        result = Map(Inc()).run(states).result()

        self.assertEqual(result[0].cnt, states[0].cnt + 1)
        self.assertEqual(result[1].cnt, states[1].cnt + 1)
Exemple #29
0
    def test_mimo(self):
        """Parallel should support branches with States inputs"""

        inp = States(State(x=1), State(x=2))
        wrk = ParallelBranches(Identity(), Identity(), Identity())
        out = wrk.run(inp).result()

        self.assertEqual(len(out), 3)
        self.assertIsInstance(out, States)
        self.assertEqual(out.first, inp)
Exemple #30
0
    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