dimod icon indicating copy to clipboard operation
dimod copied to clipboard

multi-call composite

Open pau557 opened this issue 4 years ago • 0 comments

This composite generalizes making multiple calls to a sampler and aggregating the results together.

On each call, one specifies a different set of kwargs to be sent to the solver. One can also choose to apply spin reversal transformations on each call (default is True).

One can use this composite for doing things such as:

  • using a different chain_strength on each call
  • using a different embedding on each call
  • permuting variables on a clique embedding (variation of the point above)
  • or simply use this instead of the SRT composite (this one batches the child sampler calls and it's non-blocking)

Examples:

# pass a different chain_strength on each call
    bqm = dimod.BQM.from_ising({}, {e:1 for e in itertools.combinations(range(10), 2)})
    sampler = MultiCallComposite(EmbeddingComposite(DWaveSampler()))
    res = sampler.sample(bqm, [dict(chain_strength=val) for val in np.linspace(2, 3, 10)], num_reads=100)

# just do the SRTs
    res = sampler.sample(bqm, [{}]*10, num_reads=100)

Comparison to the SRT composite

    bqm = dimod.BQM.from_ising({}, {e:1 for e in itertools.combinations(range(10), 2)})
    print("with SRT composite")
    sampler = SpinReversalTransformComposite(EmbeddingComposite(DWaveSampler(solver="Advantage_system1.1")))
    t0 = time.time()
    res = sampler.sample(bqm, num_spin_reversal_transforms=10, num_reads=100)
    print(time.time() - t0)
    res.resolve()
    print(time.time() - t0)


    print("with multicall composite")
    sampler = MultiCallComposite(EmbeddingComposite(DWaveSampler(solver="Advantage_system1.1")))
    t0 = time.time()
    res = sampler.sample(bqm, [{}]*10, num_reads=100)
    print(time.time() - t0)
    res.resolve()
    print(time.time() - t0)


    # Output:
    with SRT composite
    6.0239338874816895
    6.023979902267456
    with multicall composite
    0.6741728782653809
    2.0730462074279785


Since passing [{}]*N is not the most elegant thing if you just want the SRTs, we could do something like this

class SpinReversalTransformComposite(MultiCallComposite):
    def sample(self, bqm, num_spin_reversal_transforms, **kwargs):
        return super().sample(bqm, [{}]*num_spin_reversal_transforms, **kwargs)

pau557 avatar Feb 24 '21 05:02 pau557