While¶
Evaluate the loop body while the condition holds.
This node receives two graphs, each driven by a loop state parameter -- a condition graph and a loop body graph. The basic principle of the while loop is that the entire variable state that the loop acts on is captured in the state variable, which can have any internal structure that the user desires, e.g., a number, list, dictionary, or any other object. The while loop requires two separate graphs wired into it, each of which must accept the state variable as input (via an appropriately named placeholder). The first of these is the "loop condition" -- a graph that takes the state and computes whether the loop should make another loop cycle or terminate. The second graph is the "loop body" -- a graph that takes also the state and computes the new state that will be passed into the next iteration. At the next iteration, again the condition is evaluated first, and if it is True, the loop body is executed. Once the condition no longer holds, the loop terminates, and the node returns the final state value that it received from the loop body on the most recent (final) iteration when it still ran. Note that, if the condition is False from the start, the loop body will not be executed at all. The loop state is by default called "state", but can be overridden using the parameter showing as "Body [loop state]" in a GUI, or equivalently via the Node's body__signature= constructor argument when creating a While node in a Python script. Note that when you rename the state variable, you also need to rename the slot name in the Placeholder nodes used by the condition and body graphs. Note also that of course the loop body (or condition) can depend on any number of other inputs, but these are not allowed to vary over the course of the loop (these are, as is customary in NeuroPype, evaluated before the loop starts). The loop state, on the other hand, is allowed to vary, and it is best practice to keep the structure of the loop state consistent over the course of the loop (i.e., ideally the initial state already has the same structure as the state returned by the loop body). An advanced technique to control execution of the loop is to use the Break and Continue nodes, which can be placed in the loop body to terminate the loop early or skip the rest of the current iteration and proceed to the next one (of these, the Continue node will cause the same state to be passed in again, which only makes sense if the loop body contains nodes that themselves are stateful). When the loop is used in a compiled context (high-performance nodes such as deep learning or convex optimization), this is required and enforced. In this case it is also not allowed to use Break or Continue nodes in the loop body. Note that it is possible to have nodes in the loop body which themselves maintain state (e.g., filters). This is fine, but note that these nodes will be re-initialized when the While loop is encountered again (e.g., due to an outer enclosing loop); also note that stateful nodes of this sort are also not currently compatible with compiled loops. It is possible to omit the loop condition graph, in which case the loop terminates when the loop body declares itself as finished (for example, when all iterators are exhausted); this is however not recommended, since the finished state can at times be somewhat complex to reason about and may not be what you expect. More Info... Version 1.0.0
Ports/Properties¶
condition¶
Loop condition.
- verbose name: Condition
- default value: None
- port type: GraphPort
- value type: Graph
condition__signature¶
Name of the loop variable received by the loop body. In a While loop, the loop body depends on only a single loop variable, namely the current state. Consequently, your loop body should contain a single Placeholder node whose slotname must be set to the name chosen here (e.g., state). Then, anything downstream of (i.e., depending on the value of) that Placeholder will constitute your loop body. 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 While node will then run your loop body for as long as the condition evaluates to True, and eventually returns the value received from the final node of the loop body on the last iteration.
- verbose name: Condition [Loop State]
- default value: (state)
- port type: Port
- value type: object (can be None)
body¶
Graph to repeat (loop body).
- verbose name: Body
- default value: None
- port type: GraphPort
- value type: Graph
body__signature¶
Name of the loop variable received by the loop body. In a While loop, the loop body depends on only a single loop variable, namely the current state. Consequently, your loop body should contain a single Placeholder node whose slotname must be set to the name chosen here (e.g., state). Then, anything downstream of (i.e., depending on the value of) that Placeholder will constitute your loop body. 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 While node will then run your loop body for as long as the condition evaluates to True, and eventually returns the value received from the final node of the loop body on the last iteration.
- verbose name: Body [Loop State]
- default value: (state)
- port type: Port
- 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)
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)
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)
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)