Skip to content

Commit

Permalink
Perf: run to target energy for all samplers (factory refactor)
Browse files Browse the repository at this point in the history
  • Loading branch information
randomir committed Jun 12, 2019
1 parent e127429 commit d6e20b1
Showing 1 changed file with 44 additions and 22 deletions.
66 changes: 44 additions & 22 deletions perf/perf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import sys
import json
from itertools import chain
from functools import partial
from collections import OrderedDict
from glob import glob

Expand Down Expand Up @@ -55,15 +56,15 @@

("qbsolv-like",
lambda qpu, **kw: hybrid.Loop(hybrid.Race(
hybrid.InterruptableTabuSampler(quantum_timeout=200),
hybrid.InterruptableTabuSampler(timeout=200),
hybrid.EnergyImpactDecomposer(size=50, rolling=True, rolling_history=0.15)
| hybrid.QPUSubproblemAutoEmbeddingSampler(qpu_sampler=qpu)
| hybrid.SplatComposer()
) | hybrid.ArgMin(), max_iter=100, convergence=10)),

("tiling-chimera",
lambda qpu, **kw: hybrid.Loop(hybrid.Race(
hybrid.InterruptableTabuSampler(quantum_timeout=200),
hybrid.InterruptableTabuSampler(timeout=200),
hybrid.TilingChimeraDecomposer(size=(16,16,4))
| hybrid.QPUSubproblemExternalEmbeddingSampler(qpu_sampler=qpu)
| hybrid.SplatComposer(),
Expand All @@ -72,55 +73,66 @@

samplers = [
("kerberos",
lambda **kw: hybrid.KerberosSampler()),
lambda init_sample, energy_threshold, **kw: partial(
hybrid.KerberosSampler().sample,
init_sample=init_sample, energy_threshold=energy_threshold)),

("qbsolv-classic",
lambda **kw: QBSolv()),
lambda **kw: QBSolv().sample),

("qbsolv-qpu",
lambda qpu, **kw: QBSolv(solver=EmbeddingComposite(qpu))),
lambda qpu, **kw: partial(QBSolv().sample, solver=EmbeddingComposite(qpu))),
]



def run(problems, workflows, samplers, n_runs=1, targets=None):
results = OrderedDict()
targets = targets or {}

def workflow_runner(bqm, workflow, **kwargs):
def workflow_runner(bqm, factory, qpu=None, **kwargs):
workflow = factory(qpu=qpu)
init_state = hybrid.State.from_sample(hybrid.min_sample(bqm), bqm)

with hybrid.tictoc() as timer:
samples = workflow.run(init_state).result().samples

return samples, timer

def sampler_runner(bqm, sampler, energy_threshold=None, **kwargs):
def sampler_runner(bqm, factory, energy_threshold=None, qpu=None, **kwargs):
sampler = factory(
qpu=qpu,
init_sample=lambda: hybrid.min_sample(bqm),
energy_threshold=energy_threshold
)

with hybrid.tictoc() as timer:
samples = sampler.sample(bqm, init_sample=lambda: hybrid.min_sample(bqm),
energy_threshold=energy_threshold)
samples = sampler(bqm)

return samples, timer

# reuse the cloud client
qpu = DWaveSampler()

for problem_filename in problems:
problem_basename = os.path.splitext(os.path.basename(problem_filename))[0]
for path in problems:
problem = os.path.splitext(os.path.basename(path))[0]

target_energy = targets.get(problem_basename)
results[problem_basename] = OrderedDict()
target_energy = targets.get(problem)
results[problem] = OrderedDict()

with open(problem_filename) as fp:
with open(path) as fp:
bqm = dimod.BinaryQuadraticModel.from_coo(fp)

for runner, solvers in [(workflow_runner, workflows), (sampler_runner, samplers)]:
for runner, solvers in [(workflow_runner, workflows),
(sampler_runner, samplers)]:
for solver_name, factory in solvers:
run_results = []

for run in range(n_runs):
case = '{!r} with {!r}, run={!r}, target={!r}'.format(
problem_basename, solver_name, run, target_energy)
problem, solver_name, run, target_energy)

try:
samples, timer = runner(bqm, factory(qpu=qpu),
samples, timer = runner(bqm, factory, qpu=qpu,
energy_threshold=target_energy)

except Exception as exc:
Expand All @@ -129,16 +141,26 @@ def sampler_runner(bqm, sampler, energy_threshold=None, **kwargs):

else:
print("case={case!r}"
" energy={samples.first.energy!r},"
" wallclock={timer.dt!r}".format(**locals()))
" energy={samples.first.energy!r},"
" wallclock={timer.dt!r}".format(**locals()))
run_results.append(dict(energy=samples.first.energy,
wallclock=timer.dt))

results[problem_basename][solver_name] = run_results
results[problem][solver_name] = run_results

return results


if __name__ == "__main__":
results = run(problems[:1], workflows[:0], samplers[:1], n_runs=1)
# Usage: $0 [target_energies_json]
# Outputs info to stdout, json to stderr.

# load target energies, if provided
targets = {}
if len(sys.argv) > 1:
with open(sys.argv[1]) as fp:
targets = json.load(fp)

results = run(problems[:1], workflows, samplers, n_runs=1, targets=targets)

print(json.dumps(results), file=sys.stderr)

0 comments on commit d6e20b1

Please sign in to comment.