Flow Structuring#

Classes that structure (hybrid) workflows.

Classes#

class ArgMin(key=None, **runopts)[source]#

Selects the best state from a sequence of States.

Parameters:

key (callable/str) –

Best state is judged according to a metric defined with a key. The key can be a callable with a signature:

key :: (State s, Ord k) => s -> k

or a string holding a key name/path to be extracted from the input state with operator.attrgetter method.

By default, key == operator.attrgetter(‘samples.first.energy’), thus favoring states containing a sample with the minimal energy.

Examples

This example runs two branches—a classical tabu search interrupted by samples of subproblems returned from a D-Wave system— and selects the state with the minimum-energy sample:

RacingBranches(
    InterruptableTabuSampler(),
    EnergyImpactDecomposer(size=2)
    | QPUSubproblemAutoEmbeddingSampler()
    | SplatComposer()
) | ArgMin()
class Branch(components=(), **runopts)[source]#

Sequentially executed Runnable components.

Parameters:

components (iterable of Runnable) – Complete processing sequence to update a current set of samples, such as: decomposer | sampler | composer.

Input:

Defined by the first branch component.

Output:

Defined by the last branch component.

Examples

This example runs one iteration of a branch comprising a decomposer, local Tabu solver, and a composer. A 10-variable binary quadratic model is decomposed by the energy impact of its variables into a 6-variable subproblem to be sampled twice with a manually set initial state of all -1 values.

>>> import dimod           # Create a binary quadratic model
>>> bqm = dimod.BQM({t: 0 for t in range(10)},
...                 {(t, (t+1) % 10): 1 for t in range(10)},
...                 0, 'SPIN')
>>> # Run one iteration on a branch
>>> branch = (EnergyImpactDecomposer(size=6, min_gain=-10) |
...           TabuSubproblemSampler(num_reads=2) |
...           SplatComposer())
>>> new_state = branch.next(State.from_sample(min_sample(bqm), bqm))
>>> print(new_state.subsamples)      
       4   5   6   7   8   9  energy  num_occ.
   0  +1  -1  -1  +1  -1  +1    -5.0         1
   1  +1  -1  -1  +1  -1  +1    -5.0         1
   [ 2 rows, 6 variables ]
class Branches(*branches, **runopts)[source]#

Runs multiple workflows of type Runnable in parallel, blocking until all finish.

Branches operates similarly to ParallelBranches, but each branch runs on a separate input State (while parallel branches all use the same input state).

Parameters:

*branches ([Runnable]) – Runnable branches listed as positional arguments.

Input:

States

Output:

States

Note

Branches is also available via implicit parallelization binary operator &.

Examples

This example runs two branches, a classical tabu search and a random sampler, until both terminate:

Branches(TabuSubproblemSampler(), RandomSubproblemSampler())

Alternatively:

TabuSubproblemSampler() & RandomSubproblemSampler()
class Const(**consts)[source]#

Set state variables to constant values.

Parameters:

**consts (dict, optional) – Mapping of state variables to constant values, as keyword arguments.

Example

This example defines a workflow that resets the set of samples before a Tabu sampler call in order to avoid using existing samples as initial states. Instead, Tabu will use randomly generated initial states:

random_tabu = Const(samples=None) | TabuProblemSampler(initial_states_generator='random')
class Dup(n, *args, **kwargs)[source]#

Duplicates input State, n times, into output States.

class Identity[source]#

Trivial identity runnable. The output is a direct copy of the input.

class BlockingIdentity(*args, **kwargs)[source]#

Trivial identity runnable that blocks indefinitely before producing output, but is interruptable. The output is a direct copy of the input, but to receive the output, the block has to be explicitly stopped (useful for example in RacingBranches to prevent short-circuiting of racing branches with the identity branch).

BlockingIdentity := Identity | Wait

Due to nature of Identity, BlockingIdentity is functionally equivalent to Wait.

class Lambda(next, error=None, init=None, **runopts)[source]#

Creates a runnable on fly, given just its next function (optionally init and error functions can be specified too).

Parameters:
  • next (callable) – Implementation of runnable’s next method, provided as a callable (usually a lambda expression for simple operations). Signature of the callable has to match the signature of next(); i.e., it accepts two arguments: runnable instance and state instance.

  • error (callable) – Implementation of runnable’s error method. See error().

  • init (callable) – Implementation of runnable’s init method. See init().

Note

Traits are not enforced, apart from the SISO requirement. Also, note Lambda runnables can only implement SISO systems.

Examples

This example creates and runs a simple runnable that multiplies state variables a and b, storing them in c.

>>> Lambda(lambda _, s: s.updated(c=s.a * s.b)).run(State(a=2, b=3)).result()     
{'a': 2, 'b': 3, 'c': 6}

This example applies x += 1 to a sequence of input states.

>>> Map(Lambda(lambda _, s: s.updated(x=s.x + 1))).run(States(State(x=0), State(x=1))).result()
[{'x': 1}, {'x': 2}]
class Log(key, extra=None, outfile=None, buffering=False, memo=False, loglevel=0, **runopts)[source]#

Tracks and logs user-defined data (e.g. state metrics) extracted from state by the key function.

Parameters:
  • key (callable) –

    Data/metric(s) extractor. A callable that receives a state, and returns a mapping of values to names:

    key: Callable[State] -> Mapping[str, Any]
    

    Data returned by the key function is stored under data key of the produced log record. In addition to data, UTC time (in ISO-8601 format) and a monotonic float timestamp (secods since the epoch) are always stored in the log record.

  • extra (dict, optional) – Static extra items to add to each log record.

  • outfile (file, optional) –

    A file opened in text + write/append mode. JSON log record is written on each runnable iteration and optionally flushed, depending on buffering argument.

    Note: Avoid using the same outfile for multiple Log runnables, as file write operation is not thread-safe.

  • buffering (bool, optional, default=True) – When buffering is set to False, output to outfile is flushed on each iteration.

  • memo (boolean/list/queue.Queue, optional, default=False) – Set to True to keep track of all log records produced in the instance-local Log.records list. Alternatively, provide an external list or queue.Queue in which all log records will be pushed.

  • loglevel (int, optional, default=logging.NOTSET) – When loglevel is set, output the log record to standard logger configured for hybrid.flow namespace.

class Loop(*args, **kwargs)[source]#

Alias for LoopUntilNoImprovement.

class LoopUntilNoImprovement(*args, **kwargs)[source]#

Iterates Runnable for up to max_iter times, or until a state quality metric, defined by the key function, shows no improvement for at least convergence number of iterations. Alternatively, maximum allowed runtime can be defined with max_time, or a custom termination Boolean function can be given with terminate (a predicate on key). Loop is always terminated on EndOfStream raised by body runnable.

Parameters:
  • runnable (Runnable) – A runnable that’s looped over.

  • max_iter (int/None, optional, default=None) – Maximum number of times the runnable is run, regardless of other termination criteria. This is the upper bound. By default, an upper bound on the number of iterations is not set.

  • convergence (int/None, optional, default=None) – Terminates upon reaching this number of iterations with unchanged output. By default, convergence is not checked, so the only termination criteria is defined with max_iter. Setting neither creates an infinite loop.

  • max_time (float/None, optional, default=None) – Wall clock runtime termination criterion. Unlimited by default.

  • key (callable/str) –

    Best state is judged according to a metric defined with a key. key can be a callable with a signature:

    key :: (State s, Ord k) => s -> k
    

    or a string holding a key name/path to be extracted from the input state with operator.attrgetter method.

    By default, key == operator.attrgetter(‘samples.first.energy’), thus favoring states containing a sample with the minimal energy.

  • terminate (callable, optional, default=None) –

    Loop termination Boolean function (a predicate on key value):

    terminate :: (Ord k) => k -> Bool
    

class LoopWhileNoImprovement(runnable, max_iter=None, max_tries=None, max_time=None, key=None, terminate=None, **runopts)[source]#

Iterates Runnable until a state quality metric, defined by the key function, shows no improvement for at least max_tries number of iterations or until max_iter number of iterations is exceeded. Alternatively, maximum allowed runtime can be defined with max_time, or a custom termination Boolean function can be given with terminate (a predicate on key).

Note

Unlike LoopUntilNoImprovement/Loop, LoopWhileNoImprovement will run the loop body runnable with the same input if output shows no improvement (up to max_tries times), and it will use the new output if it’s better than the input.

Parameters:
  • runnable (Runnable) – A runnable that’s looped over.

  • max_iter (int/None, optional, default=None) – Maximum number of times the runnable is run, regardless of other termination criteria. This is the upper bound. By default, an upper bound on the number of iterations is not set.

  • max_tries (int, optional, default=None) – Maximum number of times the runnable is run for the same input state. On each improvement, the better state is used for the next input state, and the try/trial counter is reset. Defaults to an infinite loop (unbounded number of tries).

  • max_time (float/None, optional, default=None) – Wall clock runtime termination criterion. Unlimited by default.

  • key (callable/str) –

    Best state is judged according to a metric defined with a key. key can be a callable with a signature:

    key :: (State s, Ord k) => s -> k
    

    or a string holding a key name/path to be extracted from the input state with operator.attrgetter method.

    By default, key == operator.attrgetter(‘samples.first.energy’), thus favoring states containing a sample with the minimal energy.

  • terminate (callable, optional, default=None) –

    Loop termination Boolean function (a predicate on key value):

    terminate :: (Ord k) => k -> Bool
    

class Map(runnable, **runopts)[source]#

Runs a specified Runnable in parallel on all input states.

Parameters:

runnable (Runnable) – A runnable executed for every input state.

Examples

This example runs TabuProblemSampler on two input states in parallel, returning when both are done.

>>> states = States(State(problem=bqm1), State(problem=bqm2))   
>>> Map(TabuProblemSampler()).run(states).result()              
[<state_1_with_solution>, <state_2_with_solution>]
Parallel[source]#

alias of ParallelBranches

class ParallelBranches(*branches, **runopts)[source]#

Runs multiple workflows of type Runnable in parallel, blocking until all finish.

Parallel/ParallelBranches operates similarly to Branches, but every branch re-uses the same input State.

Parameters:

*branches ([Runnable]) – Comma-separated branches.

Input:

State

Output:

States

Note

Parallel is implemented as:

Parallel(*branches) := Dup(len(branches)) | Branches(*branches)

Note

ParallelBranches is also available as Parallel.

Examples

This example runs two branches, a classical tabu search and a random sampler, until both terminate:

Parallel(
    TabuSubproblemSampler(),
    RandomSubproblemSampler()
) | ArgMin()
Race[source]#

alias of RacingBranches

class RacingBranches(*branches, **runopts)[source]#

Runs (races) multiple workflows of type Runnable in parallel, stopping all once the first finishes. Returns the results of all, in the specified order.

Parameters:

*branches ([Runnable]) – Comma-separated branches.

Note

Each branch runnable is called with run option racing_context=True, so it can adapt its behaviour to the context.

Note

RacingBranches is also available as Race.

Examples

This example runs two branches: a classical tabu search interrupted by samples of subproblems returned from a D-Wave system.

RacingBranches(
    InterruptableTabuSampler(),
    EnergyImpactDecomposer(size=2)
    | QPUSubproblemAutoEmbeddingSampler()
    | SplatComposer()
) | ArgMin()
class Reduce(runnable, initial_state=None, **runopts)[source]#

Fold-left using the specified Runnable on a sequence of input states, producing a single output state.

Parameters:
  • runnable (Runnable) – A runnable used as the fold-left operator. It should accept a 2-State input and produce a single State on output.

  • initial_state (State, optional, default=None) – Optional starting state into which input states will be folded in. If undefined, the first input state is used as the initial_state.

class TrackMin(key=None, output=False, input_key='samples', output_key='samples', **runopts)[source]#

Tracks and records the best State according to a metric defined with a key function; typically this is the minimal state.

Parameters:
  • key (callable/str, optional, default=None) –

    Best state is judged according to a metric defined with a key. key can be a callable with a signature:

    key :: (State s, Ord k) => s -> k
    

    or a string holding a key name/path to be extracted from the input state with operator.attrgetter method.

    By default, key == operator.attrgetter(‘samples.first.energy’), thus favoring states containing a sample with the minimal energy.

  • output (bool, optional, default=False) – Update the output state’s output_key with the input_key of the best state seen so far.

  • input_key (str, optional, default='samples') – If output=True, then this defines the variable/key name in the input state that shall be included in the output state.

  • output_key (str, optional, default='samples') – If output=True, then the key under which the input_key from the best state seen so far is stored in the output state.

Note

If output option is turned on, and output_key is not changed, the output will by default change the state’s samples on output.

class Unwind(runnable, **runopts)[source]#

Iterates Runnable until EndOfStream is raised, collecting all output states along the way.

Note

the child runnable is called with run option silent_rewind=False, and it is expected to raise EndOfStream on unwind completion.

class Wait(*args, **kwargs)[source]#

Run indefinitely (effectively blocking branch execution). Has to be explicitly stopped.

Example

To effectively exclude one branch from the race, i.e. prevent premature stopping of the race between the remaining branches, use Wait as the last element in a (fast-executing) racing branch:

Race(
    Identity() | Wait(),
    InterruptableTabuSampler(),
    SimulatedAnnealingProblemSampler()
)

This is functionally identical to:

Parallel(
    Identity(),
    Race(
        InterruptableTabuSampler(),
        SimulatedAnnealingProblemSampler()
    )
)

Methods#

See Primitives for methods inherited from the Runnable superclass.