Operator graph optimization tools

These functions are used to restructure the operator graph so that it can be simulated more efficiently when converted into a TensorFlow graph.

nengo_dl.graph_optimizer.mergeable(op, chosen_ops)[source]

Check if the given op can be merged with the candidate group

Parameters:
op : Operator

the operator to be merged

chosen_ops : list of Operator

the operator group to be merged in to

Returns:
bool

True if op can be merged into chosen_ops, else False

nengo_dl.graph_optimizer.greedy_planner(operators)[source]

Combine mergeable operators into groups that will be executed as a single computation.

Parameters:
operators : list of Operator

all the nengo operators in a model (unordered)

Returns:
list of tuple of :class:`~nengo:nengo.builder.Operator`

operators combined into mergeable groups and in execution order

Notes

Originally based on nengo_ocl greedy planner

nengo_dl.graph_optimizer.tree_planner(operators)[source]

Create merged execution plan through exhaustive tree search.

Unlike graph_optimizer.greedy_planner(), this is guaranteed to find the shortest plan. However, depending on the structure of the operator graph, it can take a long time to execute.

Parameters:
operators : list of Operator

all the nengo operators in a model (unordered)

Returns:
list of tuple of :class:`~nengo:nengo.builder.Operator`

operators combined into mergeable groups and in execution order

nengo_dl.graph_optimizer.noop_planner(operators)[source]

Orders operators into a valid execution order, but does not perform any merging.

Parameters:
operators : list of Operator

all the nengo operators in a model (unordered)

Returns:
list of tuple of :class:`~nengo:nengo.builder.Operator`

operators in execution order

nengo_dl.graph_optimizer.order_signals(plan, n_passes=10)[source]

Orders signals and operators to try to structure reads in contiguous blocks.

Parameters:
plan : list of tuple of Operator

operator execution plan (e.g., output from greedy_planner)

n_passes : int, optional

number of repeated passes through the operator reordering stage

Returns:
list of :class:`~nengo:nengo.builder.Signal`

signals organized into the order in which we want them arranged in memory

list of tuple of :class:`~nengo:nengo.builder.Operator`

input plan with operators reordered within groups to align with order of signals

nengo_dl.graph_optimizer.hamming_sort(signals, blocks)[source]

Reorder signals using heuristics to try to place signals that are read by the same operators into adjacent positions (giving priority to larger blocks).

Parameters:
signals : list of Signal

the signals to be sorted

blocks : dict of {Signal: tuple of bool}

dictionary indicating which read blocks each signal is a part of

nengo_dl.graph_optimizer.sort_ops_by_signals(sorted_reads, signals, new_plan, blocks, reads)[source]

Rearrange operators to match the order of signals.

Note: the same operators can be associated with multiple read blocks if they have multiple inputs, so rearranging the operators according to one of those blocks could mess up the order with respect to the other read block. We iterate through the read blocks in increasing size so that the largest blocks win out.

Parameters:
sorted_reads : list of tuple of (Operator, int)

the operators that form each read block, sorted by increasing size of the read block. in the case that a group of operators participate in multiple read blocks, the integer distinguishes which one of those inputs this block is associated with.

signals : list of Signal

signals that have been arranged into a given order by other parts of the algorithm

new_plan : dict of {tuple of Operator: tuple of Operator}

mapping from original operator group to the sorted operators

blocks : dict of {Signal: tuple of bool}

indicates which read blocks each signal participates in

reads : dict of {Operator: list of Signal}

the signals read by each operator

Returns:
new_plan : dict of {tuple of Operator: tuple of Operator}

mapping from original operator group to the sorted operators

signals : list of Signal

signals list, possibly rearranged to match new operator order

nengo_dl.graph_optimizer.sort_signals_by_ops(sorted_reads, signals, new_plan, blocks, reads)[source]

Attempts to rearrange signals so that it is in the same order as operator reads, without changing the overall block order.

Parameters:
sorted_reads : list of tuple of (Operator, int)

the operators that form each read block, sorted by increasing size of the read block. in the case that a group of operators participate in multiple read blocks, the integer distinguishes which one of those inputs this block is associated with.

signals : list of Signal

signals to be sorted

new_plan : dict of {tuple of Operator: tuple of Operator}

mapping from original operator group to the sorted operators

blocks : dict of {Signal: tuple of bool}

indicates which read blocks each signal participates in

reads : dict of {Operator: list of Signal}

the signals read by each operator

Returns:
list of :class:`~nengo:nengo.builder.Signal`

sorted signals

nengo_dl.graph_optimizer.noop_order_signals(plan, **kwargs)[source]

A version of graph_optimizer.order_signals() that doesn’t do any reordering, for debugging.

nengo_dl.graph_optimizer.create_signals(sigs, plan, float_type, minibatch_size)[source]

Groups signal data together into larger arrays, and represent each individual signal as a slice into that array.

Parameters:
signals : list of Signal

base signals arranged into the order in which they should reside in memory (e.g., output from order_signals)

plan : list of tuple of Operator

operator execution plan (only used to get a list of all the operators)

float_type : np.float32 or np.float64

floating point precision to use for signals

minibatch_size : int

number of items in each minibatch

Returns:
base_arrays : dict of {object

combined arrays, containing the initial values for all signals

sig_map : dict of {Signal: signals.TensorSignal}

mapping from nengo Signals to nengo_dl TensorSignals (views into the base arrays)