Skip to content

← control_flow package

Fold

Fold elements of a collection or iterable using a function that successively combines (reduces) the elements with an initial value.

The basic formula implemented by this node is, for a 3-item list: result = op(op(op(initial, item1), item2), item3) where op is the function given as the loop body, which takes as its first argument the current state and as its second argument the next item in the iterable, and computes the new state. A simple use case of this node is taking the sum of a list of numbers. The initial value would then be set to zero, and the body adds its first and second arguments together. However, this node is really a general purpose loop that can be used to implement imperative-style loops in a functional style. To do this, simply make the initial state a dictionary with your variables before the loop is entered, and the loop body returns a new dictionary that has the new values assigned to the variables. An infinite or counting-based for-style loop can be implemented by using a RangeIterator as the iterable. You can also loop over multiple iterables simultaneously, in which case your loop body and signature must have correspondingly more placeholders for the additional iterables (e.g., state, item1, item2, ..). While packets are not generally iterables, when a packet is passed into this node as the iterable, the node will iterate over the first axis of any chunk in the packet, which all must be of the same length. You can control what axes to iterate over using the MoveAxisFirst node. Beware that the node will drop any chunks that are either empty or are marker chunks. As with arrays, the loop body will receive the k'th slice of the packet with the leading axis dropped from each chunk. If the body is not given, or if the iterable is empty or not given, then the initial value is returned as the result. The body may use the Continue node to skip (drop) the current item and proceed to the next item in the iterable, or the Break node to terminate the loop early, causing the result to be the current state. The body may also have only one argument, in which case only the current state is passed in, and the iterable is solely used to determine the termination condition. More Info... Version 1.0.0

Ports/Properties

body

Reducer function (loop body).

verbose name
Body
default value
None
port type
GraphPort
value type
Graph

body__signature

List of arguments names accepted by the loop body. Since a fold loop, in contrast to a for each loop, carries over state from one iteration to the next, your loop body must accept at least two arguments: the previous iteration's state (or initial value), which must always be the first argument listed here, and the current item from the iterable being looped over. If you wish to loop over multiple iterables (e.g., lists/arrays/iterators) simultaneously (which all must have the same length), you can list additional items here, using any name of your choosing. Your loop body must then have one Placeholder node for each of the loop variables listed here, with its slotname matching the respective name (i.e., state, item1, item2, ...), although you can also choose any other names here. Then, anything downstream of (i.e., depending on the value of) those Placeholders will collectively constitute your loop body. The final node of your loop body is then expected to return the state that will be passed into the next iteration (if you wish to carry over multiple values, you may use e.g., a CreateList node or a CreateDict node for this). The final output node of your loop body is then wired into the "body" input port of the loop node. In graphical UIs, the edge will be drawn in dotted style to indicate that the preceding graph itself is given to the loop node as the loop body (which will then execute it zero or more times), which is in contrast to a regular (solid) edge that indices normal data flow wherein first the preceding node runs, and then its output is passed to the subsequent node. The output of the Fold Loop node itself is then the final state value that it received from your loop body on the last iteration.

verbose name
Body [State, Item]
default value
(state,item)
port type
Port
value type
object (can be None)

iterable1

Iterable 1 to iterate over.

verbose name
Iterable1
default value
None
port type
DataPort
value type
object (can be None)
data direction
IN

iterable2

Iterable 2 to iterate over.

verbose name
Iterable2
default value
None
port type
DataPort
value type
object (can be None)
data direction
IN

iterable3

Iterable 3 to iterate over.

verbose name
Iterable3
default value
None
port type
DataPort
value type
object (can be None)
data direction
IN

iterable4

Iterable 4 to iterate over.

verbose name
Iterable4
default value
None
port type
DataPort
value type
object (can be None)
data direction
IN

iterable5

Iterable 5 to iterate over.

verbose name
Iterable5
default value
None
port type
DataPort
value type
object (can be None)
data direction
IN

iterableN

Additional iterables.. .

verbose name
Iterablen
default value
None
port type
DataPort
value type
list (can be None)
data direction
IN

iterable

Alias for the iterable1 port.

verbose name
Iterable
default value
None
port type
AliasPort
value type
object (can be None)

result

Result of last operation.

verbose name
Result
default value
None
port type
DataPort
value type
object (can be None)
data direction
OUT

initial

Initial value for the state. It is recommended that this has the same structure (e.g., dictionary fields) as what is returned by the loop body. For compiled loops, this is required.

verbose name
Initial
default value
None
port type
Port
value type
object (can be None)

set_breakpoint

Set a breakpoint on this node. If this is enabled, your debugger (if one is attached) will trigger a breakpoint.

verbose name
Set Breakpoint (Debug Only)
default value
False
port type
BoolPort
value type
bool (can be None)

metadata

User-definable meta-data associated with the node. Usually reserved for technical purposes.

verbose name
Metadata
default value
{}
port type
DictPort
value type
dict (can be None)

reverse

If True, process the iterables in reverse order. The output will then be the state after having processed the leftmost element of the iterables.

verbose name
Process In Reverse Order
default value
False
port type
BoolPort
value type
bool (can be None)

log_errors

If True, log exceptions occurring in the loop body.

verbose name
Log Errors
default value
False
port type
BoolPort
value type
bool (can be None)

compile

Whether and how to compile the loop body for more efficient execution. Auto will compile the loop only if it occurs in a context where compilation is necessary, for example inside a model passed to nodes such as DeepLearning, ConvexModel, or one of the Inference nodes. The 'jax' option will generally attempt to compile the loop to run on the jax backend; this comes with a series of limitations -- all nodes in the body have to work with jax data types (numeric values only) and operations, and break/continue nodes cannot be used. 'Off' is the appropriate setting for anything except for the most performance-critical computations consisting of mainly math operations, possibly with some data reformatting. Off can also be useful in a situation where the loop occurs in a compiled context, but the iterable is a static constant (e.g., fixed list) and relatively short; in this case, the loop will be completely unrolled, which can be more efficient than actually looping.

verbose name
Compile
default value
auto
port type
EnumPort
value type
str (can be None)

unroll

Optionally the unrolling factor for this loop, if compiling. Typically this is a small power of two such as 4 or 8. This is mainly an efficiency improvement for extremely tight loops that perform very cheap math operations.

verbose name
Unroll
default value
None
port type
IntPort
value type
int (can be None)