Skip to content
cpbenchy 0.1.0.dev0 is in alpha: until version 1.0, commands, options, the Python API and the result format may still change. Pin the version you use.

cpbenchy solve

Solves a single instance the way a competition runs a solver.

Updated View as Markdown
CommandBuilt incomes with cpbenchy
cpbenchy solve instance.xml -s ortools --rules xcsp3-2025
Version
cpbenchy 0.1.0.dev0
Last updated
6 Oct 2026 · 1 commit
Authors
ThomSerg
Tags
competitioncommand

What it does

Solves one instance in its own process, the way a competition runs a solver: the competition’s own tool limits and measures it, and reads its output. A submission’s launchers run it.

  • Competition output (from the rules’ output observer) goes to stdout; progress and a summary come as comment lines (c ...).
  • At its time limit (wall or CPU), or on SIGTERM, it prints the best solution it found.
  • Time counts from when the process started, as the competition counts it.

Use it

cpbenchy solve instance.xml -s ortools --rules xcsp3-2025 --cpu-time-limit 60 --seed 7
c [cpbenchy     0.81s] loading instance.xml
o 12
o 9
s OPTIMUM FOUND
v <instantiation type="optimum" cost="9">
...
c cpbenchy: optimal, objective 9; parse 0.07s, transform 0.00s, solve 0.38s

Options

The options of cpbenchy run, for one instance, one solver and at most one seed: -s, -t, --cpu-time-limit, -m, --cores, --seed, -P, --loader, -p, --rules. Files of the run go to a fresh directory under $TMPDIR.

Implementation

The solve in src/cpbenchy/solve.py, lines 43–77 of 77, as of this version of the docs.

src/cpbenchy/solve.pypython
def solve(args: Sequence[str]) -> int:
    config = make_config(args, prog="cpbenchy solve")
    get = config.getoption
    if len(get("solvers")) != 1:
        raise UsageError("solve needs exactly one solver (-s)")
    if len(get("seeds")) > 1:
        raise UsageError("solve runs one seed")
    if get("time_limit") is None and get("cputime_limit_s") is None:
        raise UsageError("no time limit (-t, --cpu-time-limit or --rules)")
    instances = collect_instances(config, config.sources)
    if len(instances) != 1:
        raise UsageError(f"solve needs exactly one instance, got {len(instances)}")
    # the CPU time limit bounds the wall time too when it is the only one, as for a sequential solver
    time_limit = get("time_limit") if get("time_limit") is not None else get("cputime_limit_s")
    spec = RunSpec(
        instances[0],
        get("solvers")[0],
        make_limits(config, time_limit, get("mem_limit_mib"), get("cputime_limit_s")),
        parse_params(get("params")),
        get("seeds")[0] if get("seeds") else None,
        get("cores"),
        get("loader"),
    )
    job = {
        "spec": spec.to_dict(),
        "events": os.devnull,
        "artifacts": tempfile.mkdtemp(prefix="cpbenchy-solve-"),
        "plugins": config.worker_plugins(),
        "disabled": config.blocked,
        "options": {**json.loads(json.dumps(config.worker_options(), default=str)), "stdout": True, "terminate": True},
    }
    from cpbenchy.worker.runtime import execute

    ctx = execute(job, standalone=True, extra_plugins=[_Summary()])
    return 1 if ctx.status == "error" else 0
Navigation

Type to search…

↑↓ navigate↵ selectEsc close