Skip to content

← utilities package

WithCache

Evaluate a computational graph with caching of the results.

This will attempt to reuse results from a disk cache if the computation is being re-run with the same explicit (and optionally implicit) arguments. This will also automatically invalidate the cache if the graph or any of its nodes have changed, if any of the listed dependencies have changed, or if the version is incremented. The cache is by default stored in a directory, named after the topic, under the cache_root directory of NeuroPype. This defaults to ~/.cache/neuropype, but can be overridden either by setting the environment variable NP_CACHE_ROOT, or by overriding the cache_root variable in a script that uses NeuroPype. The cacheable computation is expected to have a single input placeholder, defaulting to 'data', which receives the main input data to the computation. This argument is passed into WithCache as the data port. However, the graph may have additional Placeholders or ParameterPorts, that may be bound downstream of the WithCache node or which may be free parameters of the graph, and these will be accounted for in the cache key, UNLESS they do not occur directly in the graph but in other graphs that are indirectly invoked by function calls (via the Call node). In such cases, the user must explicitly list the names of these arguments in the implicit_args port, otherwise results may be incorrect. Note that any placeholders in the graph whose value is externally determined at the time the graph executes will automatically factor in the cache key, because their values will be implicitly captured as constants into the graph (lambda capture). It is possible to prevent this from happening, which may be useful when these parameters are irrelevant to the result (e.g., verbosity, num_procs settings etc). This can be done by making the placeholders part of the graph, by making them formally depedent on the data placeholder, by drawing an 'update' edge from the data placeholder to the parameter/placeholder node in question. Note that this node will not delete the cache; it is the user's responsibility to delete the cache when it becomes stale or excessively large. This can be done by deleting the respective topic directory or the whole cache_root directory if desired. Version 0.9.0

Ports/Properties

graph

Cached computation.

  • verbose name: Graph
  • default value: None
  • port type: GraphPort
  • value type: Graph

graph__signature

Optionally the name of an argument accepted by the cached computation. If this is not specified, the cached computation is everything that runs under the control of the WithCache node (this can be viewed by Ctrl+clicking on the control (dotted) edge going into this node in a visual editor). If a name is given, then the graph wired into this node must then start with a single Placeholder node whose slotname must match the name listed here (e.g., data), and anything downstream of that placeholder is part of the cacheable computation and may be skipped if the result is already in the cache. In either case, the final node of that graph, which produces the cacheable result, is then connected to the WithCache node by connecting it to the "graph" input port of the WithCache node). As such, the WithCache node follows the cached computation graph, rather than preceding it. In graphical UIs, this edge is drawn in dotted style to indicate that this is not normal forward data flow but that the cached computation graph runs under the control of the WithCache node, which may or may not execute it (depending on whether the result is already in the cache). When your graph executes and a name was specified, the placeholder receives whichever value is passed into the "data" input of the WithCache node, which can, for example, be a filename to load and preprocess or a packet that shall be further processed, and the graph's final node outputs the result that is then written to the cache, and returned as the output of the WithCache node itself. Note that your cached computation is allowed to depend on other external inputs, for example, the content of some imported files or the value of Parameter Ports, that are wired into the graph "from the side", meaning that the nodes producing these potentially variable outputs may not themselves part of the graph that is being cached. The criterion here is that these nodes cannot be downstream of the placeholder that marks the beginning of the cacheable graph. The principle that enables this is that the cache key is computed by hashing the graph (including any of its structure and settings), plus the values of anything that flows into it from the side and the values of any contained placeholders and parameter ports, as well as the primary cache key (if any, i.e., the data argument), and only if all these details match a previously cached result, the cache will be used.

  • verbose name: Graph [Signature]
  • default value: (~)
  • port type: Port
  • value type: object (can be None)

data

Input data to the computation. Can only be provided if a placeholder name is specified.

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

result

Result of the cached computation.

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

enabled

Enable caching. This can be unchecked to bypass the caching mechanism, e.g., when debugging.

  • verbose name: Cache Enabled
  • default value: True
  • port type: BoolPort
  • value type: bool (can be None)

topic

Topic to use for caching. Data is stored in a directory under this topic; this helps when the data for this topic becomes stale and the user wants to delete it.

  • verbose name: Cache Topic
  • default value: default
  • port type: StringPort
  • value type: str (can be None)

dependencies

Optional list of Python code files that the computation depends on. This is used to invalidate the cache when these files change. For beginners or for computations that depend on custom nodes that you are actively editing, [''] is a good choice, which will include the code for all nodes that are part of the graph being cached. However, when you are mainly caching the output of mature nodes that are unlikely to receive bugfixes that affect your outputs, you can also set this to the empty list [] in order to avoid unnecessary cache invalidations resulting from such minor updates, for example when you are updating to a newer NeuroPype release. A good rule of thumb is to use [] for preprocessing and [''] for more advanced analysis that may use node marked beta or that you are actively developing. This list can also include fully specified paths to additional files, for example from utility code that your nodes are using, like ['~/my_code/my_utility_function.py', '']. The default value resolves to [''], but incurs a reminder to make an explicit choice.

  • verbose name: Graph Dependencies
  • default value: ['*']
  • port type: ListPort
  • value type: list (can be None)

ver

Optional version of the graph. This can be used to invalidate the cache when the computation implemented by the graph or one of its nodes changes. The WithCache node will automatically snapshot the graph, its parameters, and the source code of the nodes it employs and make sure that the cache key factors in these details; however, if a node calls some external code (e.g., a library or utility function), then the user needs to make sure that the version is updated when the external code changes. See also dependencies for a tool to protect against this.

  • verbose name: Cache Version
  • default value: 1.0.0
  • port type: StringPort
  • value type: str (can be None)

implicit_args

Optional list of implicit arguments to the computation. These are arguments that are not explicitly passed to the computation but are used by the computation. For example, if the computation calls a node which contains a ParameterPort whose value dynamically resolves to a bound value in an outer call context, then that value is an implicit argument, and the name of the ParameterPort should be listed here.

  • verbose name: Additional Implicit Arguments
  • default value: []
  • port type: ListPort
  • value type: list (can be None)

extra_context

Optional additional context to include in the cache key. This is useful when the computation depends on some external data or code that is not captured by the implicit_args listing, such as the current date or the return value of some system call, if used in the computation.

  • verbose name: Additional Cache Context
  • default value: {}
  • port type: DictPort
  • value type: dict (can be None)

capture_functions

If enabled, the structure of function graphs that are being called (using the Call node) are included in the cache key. This is important when portions of the cached computation are factored into functions, and those functions may be changing or are being updated.

  • verbose name: Capture Functions
  • default value: True
  • port type: BoolPort
  • value type: bool (can be None)

verbose

Verbosity level of diagnostic outputs.

  • verbose name: Verbosity
  • default value: 1
  • port type: EnumPort
  • value type: str (can be None)

no_graph_tracking

If enabled, structural changes to the graph whose output is being cached are not tracked, and will not invalidate the cache. Instead, it is your responsibility to update the version field when you make substantive changes that justify recomputation and recaching. Note that dependencies will still be respected unless you clear that field. WARNING: it is very easy to forget that this field is enabled when you are making changes to the cached graph and expect the computation to be re-run.

  • verbose name: No Graph Tracking
  • default value: False
  • port type: BoolPort
  • value type: bool (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)